diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp | 151 |
1 files changed, 132 insertions, 19 deletions
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index ff751a9444..0575b41d1f 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -34,6 +34,7 @@ using namespace llvm; STATISTIC(NumBacktracks, "Number of times scheduler backtraced"); +STATISTIC(NumUnfolds, "Number of nodes unfolded"); STATISTIC(NumDups, "Number of duplicated nodes"); STATISTIC(NumCCCopies, "Number of cross class copies"); @@ -385,32 +386,145 @@ void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle, ++NumBacktracks; } -/// isSafeToCopy - True if the SUnit for the given SDNode can safely cloned, -/// i.e. the node does not produce a flag, it does not read a flag and it does -/// not have an incoming chain. -static bool isSafeToCopy(SDNode *N) { +/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled +/// successors to the newly created node. +SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { + if (SU->FlaggedNodes.size()) + return NULL; + + SDNode *N = SU->Node; if (!N) - return true; + return NULL; + SUnit *NewSU; for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) if (N->getValueType(i) == MVT::Flag) - return false; + return NULL; + bool TryUnfold = false; for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { const SDOperand &Op = N->getOperand(i); MVT::ValueType VT = Op.Val->getValueType(Op.ResNo); - if (VT == MVT::Other || VT == MVT::Flag) - return false; + if (VT == MVT::Flag) + return NULL; + else if (VT == MVT::Other) + TryUnfold = true; } - return true; -} + if (TryUnfold) { + SmallVector<SDNode*, 4> NewNodes; + if (!MRI->unfoldMemoryOperand(DAG, N, NewNodes)) + return NULL; + + DOUT << "Unfolding SU # " << SU->NodeNum << "\n"; + assert(NewNodes.size() == 2 && "Expected a load folding node!"); + + N = NewNodes[1]; + SDNode *LoadNode = NewNodes[0]; + std::vector<SDNode*> Deleted; + unsigned NumVals = N->getNumValues(); + unsigned OldNumVals = SU->Node->getNumValues(); + for (unsigned i = 0; i != NumVals; ++i) + DAG.ReplaceAllUsesOfValueWith(SDOperand(SU->Node, i), + SDOperand(N, i), Deleted); + DAG.ReplaceAllUsesOfValueWith(SDOperand(SU->Node, OldNumVals-1), + SDOperand(LoadNode, 1), Deleted); + + SUnit *LoadSU = NewSUnit(LoadNode); + SUnit *NewSU = NewSUnit(N); + SUnitMap[LoadNode].push_back(LoadSU); + SUnitMap[N].push_back(NewSU); + const TargetInstrDescriptor *TID = &TII->get(LoadNode->getTargetOpcode()); + for (unsigned i = 0; i != TID->numOperands; ++i) { + if (TID->getOperandConstraint(i, TOI::TIED_TO) != -1) { + LoadSU->isTwoAddress = true; + break; + } + } + if (TID->Flags & M_COMMUTABLE) + LoadSU->isCommutable = true; -/// CopyAndMoveSuccessors - Clone the specified node and move its scheduled -/// successors to the newly created node. -SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { - DOUT << "Duplicating SU # " << SU->NodeNum << "\n"; + TID = &TII->get(N->getTargetOpcode()); + for (unsigned i = 0; i != TID->numOperands; ++i) { + if (TID->getOperandConstraint(i, TOI::TIED_TO) != -1) { + NewSU->isTwoAddress = true; + break; + } + } + if (TID->Flags & M_COMMUTABLE) + NewSU->isCommutable = true; + + // FIXME: Calculate height / depth and propagate the changes? + LoadSU->Depth = NewSU->Depth = SU->Depth; + LoadSU->Height = NewSU->Height = SU->Height; + ComputeLatency(LoadSU); + ComputeLatency(NewSU); + + SUnit *ChainPred = NULL; + SmallVector<SDep, 4> ChainSuccs; + SmallVector<SDep, 4> LoadPreds; + SmallVector<SDep, 4> NodePreds; + SmallVector<SDep, 4> NodeSuccs; + for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); + I != E; ++I) { + if (I->isCtrl) + ChainPred = I->Dep; + else if (I->Dep->Node && I->Dep->Node->isOperand(LoadNode)) + LoadPreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false)); + else + NodePreds.push_back(SDep(I->Dep, I->Reg, I->Cost, false, false)); + } + for (SUnit::succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); + I != E; ++I) { + if (I->isCtrl) + ChainSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, + I->isCtrl, I->isSpecial)); + else + NodeSuccs.push_back(SDep(I->Dep, I->Reg, I->Cost, + I->isCtrl, I->isSpecial)); + } - SUnit *NewSU = Clone(SU); + SU->removePred(ChainPred, true, false); + LoadSU->addPred(ChainPred, true, false); + for (unsigned i = 0, e = LoadPreds.size(); i != e; ++i) { + SDep *Pred = &LoadPreds[i]; + SU->removePred(Pred->Dep, Pred->isCtrl, Pred->isSpecial); + LoadSU->addPred(Pred->Dep, Pred->isCtrl, Pred->isSpecial, + Pred->Reg, Pred->Cost); + } + for (unsigned i = 0, e = NodePreds.size(); i != e; ++i) { + SDep *Pred = &NodePreds[i]; + SU->removePred(Pred->Dep, Pred->isCtrl, Pred->isSpecial); + NewSU->addPred(Pred->Dep, Pred->isCtrl, Pred->isSpecial, + Pred->Reg, Pred->Cost); + } + for (unsigned i = 0, e = NodeSuccs.size(); i != e; ++i) { + SDep *Succ = &NodeSuccs[i]; + Succ->Dep->removePred(SU, Succ->isCtrl, Succ->isSpecial); + Succ->Dep->addPred(NewSU, Succ->isCtrl, Succ->isSpecial, + Succ->Reg, Succ->Cost); + } + for (unsigned i = 0, e = ChainSuccs.size(); i != e; ++i) { + SDep *Succ = &ChainSuccs[i]; + Succ->Dep->removePred(SU, Succ->isCtrl, Succ->isSpecial); + Succ->Dep->addPred(LoadSU, Succ->isCtrl, Succ->isSpecial, + Succ->Reg, Succ->Cost); + } + NewSU->addPred(LoadSU, false, false); + + AvailableQueue->addNode(LoadSU); + AvailableQueue->addNode(NewSU); + + ++NumUnfolds; + + if (NewSU->NumSuccsLeft == 0) { + NewSU->isAvailable = true; + return NewSU; + } else + SU = NewSU; + } + + DOUT << "Duplicating SU # " << SU->NodeNum << "\n"; + NewSU = Clone(SU); // New SUnit has the exact same predecessors. for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); @@ -452,6 +566,7 @@ void ScheduleDAGRRList::InsertCCCopiesAndMoveSuccs(SUnit *SU, unsigned Reg, const TargetRegisterClass *DestRC, const TargetRegisterClass *SrcRC, SmallVector<SUnit*, 2> &Copies) { + abort(); SUnit *CopyFromSU = NewSUnit(NULL); CopyFromSU->CopySrcRC = SrcRC; CopyFromSU->CopyDstRC = DestRC; @@ -640,10 +755,8 @@ void ScheduleDAGRRList::ListScheduleBottomUp() { assert(LRegs.size() == 1 && "Can't handle this yet!"); unsigned Reg = LRegs[0]; SUnit *LRDef = LiveRegDefs[Reg]; - SUnit *NewDef; - if (isSafeToCopy(LRDef->Node)) - NewDef = CopyAndMoveSuccessors(LRDef); - else { + SUnit *NewDef = CopyAndMoveSuccessors(LRDef); + if (!NewDef) { // Issue expensive cross register class copies. MVT::ValueType VT = getPhysicalRegisterVT(LRDef->Node, Reg, TII); const TargetRegisterClass *RC = |