Remove integer promotion support for FP_EXTEND
[oota-llvm.git] / lib / CodeGen / SelectionDAG / ScheduleDAG.cpp
index 8ef493b06e912c5da03b5a6b46e49aa1fc70d4bb..ac7f6b9f56f4f02fa9eaf37876027af4c1e937b8 100644 (file)
@@ -58,9 +58,8 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
 }
 
 SUnit *ScheduleDAG::Clone(SUnit *Old) {
-  SUnit *SU = NewSUnit(Old->Node);
+  SUnit *SU = NewSUnit(Old->getNode());
   SU->OrigNode = Old->OrigNode;
-  SU->FlaggedNodes = Old->FlaggedNodes;
   SU->Latency = Old->Latency;
   SU->isTwoAddress = Old->isTwoAddress;
   SU->isCommutable = Old->isCommutable;
@@ -73,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.
@@ -99,23 +105,19 @@ void ScheduleDAG::BuildSchedUnits() {
     // nodes.  Nodes can have at most one flag input and one flag output.  Flags
     // are required the be the last operand and result of a node.
     
-    // Scan up, adding flagged preds to FlaggedNodes.
+    // Scan up to find flagged preds.
     SDNode *N = NI;
     if (N->getNumOperands() &&
         N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Flag) {
       do {
         N = N->getOperand(N->getNumOperands()-1).getNode();
-        NodeSUnit->FlaggedNodes.push_back(N);
         assert(N->getNodeId() == -1 && "Node already inserted!");
         N->setNodeId(NodeSUnit->NodeNum);
       } while (N->getNumOperands() &&
                N->getOperand(N->getNumOperands()-1).getValueType()== MVT::Flag);
-      std::reverse(NodeSUnit->FlaggedNodes.begin(),
-                   NodeSUnit->FlaggedNodes.end());
     }
     
-    // Scan down, adding this node and any flagged succs to FlaggedNodes if they
-    // have a user of the flag operand.
+    // Scan down to find any flagged succs.
     N = NI;
     while (N->getValueType(N->getNumValues()-1) == MVT::Flag) {
       SDValue FlagVal(N, N->getNumValues()-1);
@@ -126,7 +128,6 @@ void ScheduleDAG::BuildSchedUnits() {
            UI != E; ++UI)
         if (FlagVal.isOperandOf(*UI)) {
           HasFlagUse = true;
-          NodeSUnit->FlaggedNodes.push_back(N);
           assert(N->getNodeId() == -1 && "Node already inserted!");
           N->setNodeId(NodeSUnit->NodeNum);
           N = *UI;
@@ -135,9 +136,10 @@ void ScheduleDAG::BuildSchedUnits() {
       if (!HasFlagUse) break;
     }
     
-    // Now all flagged nodes are in FlaggedNodes and N is the bottom-most node.
-    // Update the SUnit
-    NodeSUnit->Node = N;
+    // If there are flag operands involved, N is now the bottom-most node
+    // of the sequence of nodes that are flagged together.
+    // Update the SUnit.
+    NodeSUnit->setNode(N);
     assert(N->getNodeId() == -1 && "Node already inserted!");
     N->setNodeId(NodeSUnit->NodeNum);
 
@@ -147,7 +149,7 @@ void ScheduleDAG::BuildSchedUnits() {
   // Pass 2: add the preds, succs, etc.
   for (unsigned su = 0, e = SUnits.size(); su != e; ++su) {
     SUnit *SU = &SUnits[su];
-    SDNode *MainNode = SU->Node;
+    SDNode *MainNode = SU->getNode();
     
     if (MainNode->isMachineOpcode()) {
       unsigned Opc = MainNode->getMachineOpcode();
@@ -163,11 +165,7 @@ void ScheduleDAG::BuildSchedUnits() {
     }
     
     // Find all predecessors and successors of the group.
-    // Temporarily add N to make code simpler.
-    SU->FlaggedNodes.push_back(MainNode);
-    
-    for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) {
-      SDNode *N = SU->FlaggedNodes[n];
+    for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
       if (N->isMachineOpcode() &&
           TII->get(N->getMachineOpcode()).getImplicitDefs() &&
           CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs())
@@ -191,9 +189,83 @@ void ScheduleDAG::BuildSchedUnits() {
         SU->addPred(OpSU, isChain, false, PhysReg, Cost);
       }
     }
-    
-    // Remove MainNode from FlaggedNodes again.
-    SU->FlaggedNodes.pop_back();
+  }
+}
+
+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;
   }
 }
 
@@ -209,17 +281,9 @@ void ScheduleDAG::ComputeLatency(SUnit *SU) {
   }
 
   SU->Latency = 0;
-  if (SU->Node->isMachineOpcode()) {
-    unsigned SchedClass = TII->get(SU->Node->getMachineOpcode()).getSchedClass();
-    const InstrStage *S = InstrItins.begin(SchedClass);
-    const InstrStage *E = InstrItins.end(SchedClass);
-    for (; S != E; ++S)
-      SU->Latency += S->Cycles;
-  }
-  for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) {
-    SDNode *FNode = SU->FlaggedNodes[i];
-    if (FNode->isMachineOpcode()) {
-      unsigned SchedClass = TII->get(FNode->getMachineOpcode()).getSchedClass();
+  for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
+    if (N->isMachineOpcode()) {
+      unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
       const InstrStage *S = InstrItins.begin(SchedClass);
       const InstrStage *E = InstrItins.end(SchedClass);
       for (; S != E; ++S)
@@ -376,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";
   }
@@ -395,23 +459,25 @@ 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 (Node)
-    Node->dump(G);
+  if (getNode())
+    getNode()->dump(G->DAG);
   else
     cerr << "CROSS RC COPY ";
   cerr << "\n";
-  if (FlaggedNodes.size() != 0) {
-    for (unsigned i = 0, e = FlaggedNodes.size(); i != e; i++) {
-      cerr << "    ";
-      FlaggedNodes[i]->dump(G);
-      cerr << "\n";
-    }
+  SmallVector<SDNode *, 4> FlaggedNodes;
+  for (SDNode *N = getNode()->getFlaggedNode(); N; N = N->getFlaggedNode())
+    FlaggedNodes.push_back(N);
+  while (!FlaggedNodes.empty()) {
+    cerr << "    ";
+    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";