Remove integer promotion support for FP_EXTEND
[oota-llvm.git] / lib / CodeGen / SelectionDAG / ScheduleDAG.cpp
index 6d6b9c7c0f0c95b476b9d335d8abca393260d063..ac7f6b9f56f4f02fa9eaf37876027af4c1e937b8 100644 (file)
@@ -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<SUnit *> PendingLoads;
+  SUnit *Terminator = 0;
+  SUnit *Chain = 0;
+  SUnit *Defs[TargetRegisterInfo::FirstVirtualRegister] = {};
+  std::vector<SUnit *> 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<SUnit *> &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<SUnit *> &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";