X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FScheduleDAG.cpp;h=ac7f6b9f56f4f02fa9eaf37876027af4c1e937b8;hb=9a6b92de4c2207b427f3b9cd67cd122dafc5b6c6;hp=6d6b9c7c0f0c95b476b9d335d8abca393260d063;hpb=d23e0f81bc76902052e9198cad3a0d87a412a632;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 6d6b9c7c0f0..ac7f6b9f56f 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -72,6 +72,13 @@ SUnit *ScheduleDAG::Clone(SUnit *Old) { /// This SUnit graph is similar to the SelectionDAG, but represents flagged /// together nodes with a single SUnit. void ScheduleDAG::BuildSchedUnits() { + // For post-regalloc scheduling, build the SUnits from the MachineInstrs + // in the MachineBasicBlock. + if (!DAG) { + BuildSchedUnitsFromMBB(); + return; + } + // Reserve entries in the vector for each of the SUnits we are creating. This // ensure that reallocation of the vector won't happen, so SUnit*'s won't get // invalidated. @@ -185,6 +192,83 @@ void ScheduleDAG::BuildSchedUnits() { } } +void ScheduleDAG::BuildSchedUnitsFromMBB() { + SUnits.clear(); + SUnits.reserve(BB->size()); + + std::vector PendingLoads; + SUnit *Terminator = 0; + SUnit *Chain = 0; + SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {}; + std::vector Uses[TargetRegisterInfo::FirstVirtualRegister] = {}; + int Cost = 1; // FIXME + + for (MachineBasicBlock::iterator MII = BB->end(), MIE = BB->begin(); + MII != MIE; --MII) { + MachineInstr *MI = prior(MII); + SUnit *SU = NewSUnit(MI); + + for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) { + const MachineOperand &MO = MI->getOperand(j); + if (!MO.isReg()) continue; + unsigned Reg = MO.getReg(); + if (Reg == 0) continue; + + assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!"); + std::vector &UseList = Uses[Reg]; + SUnit *&Def = Defs[Reg]; + // Optionally add output and anti dependences + if (Def && Def != SU) + Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, + /*PhyReg=*/Reg, Cost); + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + SUnit *&Def = Defs[*Alias]; + if (Def && Def != SU) + Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false, + /*PhyReg=*/*Alias, Cost); + } + + if (MO.isDef()) { + // Add any data dependencies. + for (unsigned i = 0, e = UseList.size(); i != e; ++i) + if (UseList[i] != SU) + UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, + /*PhysReg=*/Reg, Cost); + for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) { + std::vector &UseList = Uses[*Alias]; + for (unsigned i = 0, e = UseList.size(); i != e; ++i) + if (UseList[i] != SU) + UseList[i]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false, + /*PhysReg=*/*Alias, Cost); + } + + UseList.clear(); + Def = SU; + } else { + UseList.push_back(SU); + } + } + bool False = false; + bool True = true; + if (!MI->isSafeToMove(TII, False)) { + if (Chain) + Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); + for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k) + PendingLoads[k]->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); + PendingLoads.clear(); + Chain = SU; + } else if (!MI->isSafeToMove(TII, True)) { + if (Chain) + Chain->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); + PendingLoads.push_back(SU); + } + if (Terminator && SU->Succs.empty()) + Terminator->addPred(SU, /*isCtrl=*/false, /*isSpecial=*/false); + if (MI->getDesc().isTerminator()) + Terminator = SU; + } +} + void ScheduleDAG::ComputeLatency(SUnit *SU) { const InstrItineraryData &InstrItins = TM.getInstrItineraryData(); @@ -356,7 +440,7 @@ unsigned ScheduleDAG::ComputeMemOperandsEnd(SDNode *Node) { void ScheduleDAG::dumpSchedule() const { for (unsigned i = 0, e = Sequence.size(); i != e; i++) { if (SUnit *SU = Sequence[i]) - SU->dump(DAG); + SU->dump(this); else cerr << "**** NOOP ****\n"; } @@ -375,10 +459,10 @@ void ScheduleDAG::Run() { /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or /// a group of nodes flagged together. -void SUnit::dump(const SelectionDAG *G) const { +void SUnit::dump(const ScheduleDAG *G) const { cerr << "SU(" << NodeNum << "): "; if (getNode()) - getNode()->dump(G); + getNode()->dump(G->DAG); else cerr << "CROSS RC COPY "; cerr << "\n"; @@ -387,13 +471,13 @@ void SUnit::dump(const SelectionDAG *G) const { FlaggedNodes.push_back(N); while (!FlaggedNodes.empty()) { cerr << " "; - FlaggedNodes.back()->dump(G); + FlaggedNodes.back()->dump(G->DAG); cerr << "\n"; FlaggedNodes.pop_back(); } } -void SUnit::dumpAll(const SelectionDAG *G) const { +void SUnit::dumpAll(const ScheduleDAG *G) const { dump(G); cerr << " # preds left : " << NumPredsLeft << "\n";