[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp ScheduleDAGList.cpp ScheduleDAGRRList.cpp

Evan Cheng evan.cheng at apple.com
Sat Nov 4 01:44:45 PST 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

ScheduleDAG.cpp updated: 1.105 -> 1.106
ScheduleDAGList.cpp updated: 1.67 -> 1.68
ScheduleDAGRRList.cpp updated: 1.19 -> 1.20
---
Log message:

Changes to use operand constraints to process two-address instructions.

---
Diffs of the changes:  (+140 -50)

 ScheduleDAG.cpp       |   13 ++-
 ScheduleDAGList.cpp   |    5 -
 ScheduleDAGRRList.cpp |  172 +++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 140 insertions(+), 50 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.105 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.106
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.105	Tue Oct 31 14:01:56 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp	Sat Nov  4 03:44:31 2006
@@ -126,8 +126,13 @@
     
     if (MainNode->isTargetOpcode()) {
       unsigned Opc = MainNode->getTargetOpcode();
-      if (TII->isTwoAddrInstr(Opc))
-        SU->isTwoAddress = true;
+      for (unsigned i = 0, ee = TII->getNumOperands(Opc); i != ee; ++i) {
+        if (TII->getOperandConstraint(Opc, i,
+                                      TargetInstrInfo::TIED_TO) != -1) {
+          SU->isTwoAddress = true;
+          break;
+        }
+      }
       if (TII->isCommutableInstr(Opc))
         SU->isCommutable = true;
     }
@@ -210,7 +215,7 @@
 /// CountResults - The results of target nodes have register or immediate
 /// operands first, then an optional chain, and optional flag operands (which do
 /// not go into the machine instrs.)
-static unsigned CountResults(SDNode *Node) {
+unsigned ScheduleDAG::CountResults(SDNode *Node) {
   unsigned N = Node->getNumValues();
   while (N && Node->getValueType(N - 1) == MVT::Flag)
     --N;
@@ -222,7 +227,7 @@
 /// CountOperands  The inputs to target nodes have any actual inputs first,
 /// followed by an optional chain operand, then flag operands.  Compute the
 /// number of actual operands that  will go into the machine instr.
-static unsigned CountOperands(SDNode *Node) {
+unsigned ScheduleDAG::CountOperands(SDNode *Node) {
   unsigned N = Node->getNumOperands();
   while (N && Node->getOperand(N - 1).getValueType() == MVT::Flag)
     --N;


Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.67 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.68
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.67	Sun Aug 27 07:54:01 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp	Sat Nov  4 03:44:31 2006
@@ -98,7 +98,7 @@
   // Build scheduling units.
   BuildSchedUnits();
 
-  AvailableQueue->initNodes(SUnits);
+  AvailableQueue->initNodes(SUnitMap, SUnits);
   
   ListScheduleTopDown();
   
@@ -331,7 +331,8 @@
     LatencyPriorityQueue() : Queue(latency_sort(this)) {
     }
     
-    void initNodes(std::vector<SUnit> &sunits) {
+    void initNodes(std::map<SDNode*, SUnit*> &sumap,
+                   std::vector<SUnit> &sunits) {
       SUnits = &sunits;
       // Calculate node priorities.
       CalculatePriorities();


Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.19 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.20
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp:1.19	Thu Nov  2 19:28:29 2006
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp	Sat Nov  4 03:44:31 2006
@@ -95,7 +95,7 @@
   CalculateDepths();
   CalculateHeights();
 
-  AvailableQueue->initNodes(SUnits);
+  AvailableQueue->initNodes(SUnitMap, SUnits);
 
   // Execute the actual scheduling loop Top-Down or Bottom-Up as appropriate.
   if (isBottomUp)
@@ -115,7 +115,7 @@
   EmitSchedule();
 }
 
-/// CommuteNodesToReducePressure - Is a node is two-address and commutable, and
+/// CommuteNodesToReducePressure - If a node is two-address and commutable, and
 /// it is not the last use of its first operand, add it to the CommuteSet if
 /// possible. It will be commuted when it is translated to a MI.
 void ScheduleDAGRRList::CommuteNodesToReducePressure() {
@@ -123,23 +123,38 @@
   for (unsigned i = Sequence.size()-1; i != 0; --i) {  // Ignore first node.
     SUnit *SU = Sequence[i];
     if (!SU) continue;
-    if (SU->isTwoAddress && SU->isCommutable) {
-      SDNode *OpN = SU->Node->getOperand(0).Val;
-      SUnit *OpSU = SUnitMap[OpN];
-      if (OpSU && OperandSeen.count(OpSU) == 1) {
-        // Ok, so SU is not the last use of OpSU, but SU is two-address so
-        // it will clobber OpSU. Try to commute it if possible.
-        bool DoCommute = true;
-        for (unsigned j = 1, e = SU->Node->getNumOperands(); j != e; ++j) {
-          OpN = SU->Node->getOperand(j).Val;
-          OpSU = SUnitMap[OpN];
-          if (OpSU && OperandSeen.count(OpSU) == 1) {
-            DoCommute = false;
-            break;
+    if (SU->isCommutable) {
+      unsigned Opc = SU->Node->getTargetOpcode();
+      unsigned NumRes = CountResults(SU->Node);
+      unsigned NumOps = CountOperands(SU->Node);
+      for (unsigned j = 0; j != NumOps; ++j) {
+        if (TII->getOperandConstraint(Opc, j+NumRes,
+                                      TargetInstrInfo::TIED_TO) == -1)
+          continue;
+
+        SDNode *OpN = SU->Node->getOperand(j).Val;
+        SUnit *OpSU = SUnitMap[OpN];
+        if (OpSU && OperandSeen.count(OpSU) == 1) {
+          // Ok, so SU is not the last use of OpSU, but SU is two-address so
+          // it will clobber OpSU. Try to commute SU if no other source operands
+          // are live below.
+          bool DoCommute = true;
+          for (unsigned k = 0; k < NumOps; ++k) {
+            if (k != j) {
+              OpN = SU->Node->getOperand(k).Val;
+              OpSU = SUnitMap[OpN];
+              if (OpSU && OperandSeen.count(OpSU) == 1) {
+                DoCommute = false;
+                break;
+              }
+            }
           }
+          if (DoCommute)
+            CommuteSet.insert(SU->Node);
         }
-        if (DoCommute)
-          CommuteSet.insert(SU->Node);
+
+        // Only look at the first use&def node for now.
+        break;
       }
     }
 
@@ -411,7 +426,8 @@
     RegReductionPriorityQueue() :
     Queue(SF(this)) {}
     
-    virtual void initNodes(std::vector<SUnit> &sunits) {}
+    virtual void initNodes(std::map<SDNode*, SUnit*> &sumap,
+                           std::vector<SUnit> &sunits) {}
     virtual void releaseState() {}
     
     virtual int getSethiUllmanNumber(unsigned NodeNum) const {
@@ -434,21 +450,32 @@
       Queue.pop();
       return V;
     }
+
+    virtual bool isDUOperand(const SUnit *SU1, const SUnit *SU2) {
+      return false;
+    }
   };
 
   template<class SF>
   class VISIBILITY_HIDDEN BURegReductionPriorityQueue
    : public RegReductionPriorityQueue<SF> {
+    // SUnitMap SDNode to SUnit mapping (n -> 1).
+    std::map<SDNode*, SUnit*> *SUnitMap;
+
     // SUnits - The SUnits for the current graph.
     const std::vector<SUnit> *SUnits;
     
     // SethiUllmanNumbers - The SethiUllman number for each node.
     std::vector<int> SethiUllmanNumbers;
 
+    const TargetInstrInfo *TII;
   public:
-    BURegReductionPriorityQueue() {}
+    BURegReductionPriorityQueue(const TargetInstrInfo *tii)
+      : TII(tii) {}
 
-    void initNodes(std::vector<SUnit> &sunits) {
+    void initNodes(std::map<SDNode*, SUnit*> &sumap,
+                   std::vector<SUnit> &sunits) {
+      SUnitMap = &sumap;
       SUnits = &sunits;
       // Add pseudo dependency edges for two-address nodes.
       AddPseudoTwoAddrDeps();
@@ -466,7 +493,21 @@
       return SethiUllmanNumbers[NodeNum];
     }
 
+    bool isDUOperand(const SUnit *SU1, const SUnit *SU2) {
+      unsigned Opc = SU1->Node->getTargetOpcode();
+      unsigned NumRes = ScheduleDAG::CountResults(SU1->Node);
+      unsigned NumOps = ScheduleDAG::CountOperands(SU1->Node);
+      for (unsigned i = 0; i != NumOps; ++i) {
+        if (TII->getOperandConstraint(Opc, i+NumRes,
+                                      TargetInstrInfo::TIED_TO) == -1)
+          continue;
+        if (SU1->Node->getOperand(i).isOperand(SU2->Node))
+          return true;
+      }
+      return false;
+    }
   private:
+    bool canClobber(SUnit *SU, SUnit *Op);
     void AddPseudoTwoAddrDeps();
     void CalculatePriorities();
     int CalcNodePriority(const SUnit *SU);
@@ -475,6 +516,9 @@
 
   template<class SF>
   class TDRegReductionPriorityQueue : public RegReductionPriorityQueue<SF> {
+    // SUnitMap SDNode to SUnit mapping (n -> 1).
+    std::map<SDNode*, SUnit*> *SUnitMap;
+
     // SUnits - The SUnits for the current graph.
     const std::vector<SUnit> *SUnits;
     
@@ -484,7 +528,9 @@
   public:
     TDRegReductionPriorityQueue() {}
 
-    void initNodes(std::vector<SUnit> &sunits) {
+    void initNodes(std::map<SDNode*, SUnit*> &sumap,
+                   std::vector<SUnit> &sunits) {
+      SUnitMap = &sumap;
       SUnits = &sunits;
       // Calculate node priorities.
       CalculatePriorities();
@@ -563,13 +609,11 @@
   // as a def&use operand is preferred.
   if (LIsTarget && RIsTarget) {
     if (left->isTwoAddress && !right->isTwoAddress) {
-      SDNode *DUNode = left->Node->getOperand(0).Val;
-      if (DUNode->isOperand(right->Node))
+      if (SPQ->isDUOperand(left, right))
         LBonus += 2;
     }
     if (!left->isTwoAddress && right->isTwoAddress) {
-      SDNode *DUNode = right->Node->getOperand(0).Val;
-      if (DUNode->isOperand(left->Node))
+      if (SPQ->isDUOperand(right, left))
         RBonus += 2;
     }
   }
@@ -616,32 +660,70 @@
   return Reached;
 }
 
-static SUnit *getDefUsePredecessor(SUnit *SU) {
-  SDNode *DU = SU->Node->getOperand(0).Val;
-  for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
-       I != E; ++I) {
-    if (I->second) continue;  // ignore chain preds
-    SUnit *PredSU = I->first;
-    if (PredSU->Node == DU)
-      return PredSU;
+template<class SF>
+bool BURegReductionPriorityQueue<SF>::canClobber(SUnit *SU, SUnit *Op) {
+  if (SU->isTwoAddress) {
+    unsigned Opc = SU->Node->getTargetOpcode();
+    unsigned NumRes = ScheduleDAG::CountResults(SU->Node);
+    unsigned NumOps = ScheduleDAG::CountOperands(SU->Node);
+    for (unsigned i = 0; i != NumOps; ++i) {
+      if (TII->getOperandConstraint(Opc, i+NumRes,
+                                    TargetInstrInfo::TIED_TO) != -1) {
+        SDNode *DU = SU->Node->getOperand(i).Val;
+        if (Op == (*SUnitMap)[DU])
+          return true;
+      }
+    }
   }
-
-  // Must be flagged.
-  return NULL;
-}
-
-static bool canClobber(SUnit *SU, SUnit *Op) {
-  if (SU->isTwoAddress)
-    return Op == getDefUsePredecessor(SU);
   return false;
 }
 
+
 /// AddPseudoTwoAddrDeps - If two nodes share an operand and one of them uses
 /// it as a def&use operand. Add a pseudo control edge from it to the other
 /// node (if it won't create a cycle) so the two-address one will be scheduled
 /// first (lower in the schedule).
 template<class SF>
 void BURegReductionPriorityQueue<SF>::AddPseudoTwoAddrDeps() {
+#if 1
+  for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
+    SUnit *SU = (SUnit *)&((*SUnits)[i]);
+    if (!SU->isTwoAddress)
+      continue;
+
+    SDNode *Node = SU->Node;
+    if (!Node->isTargetOpcode())
+      continue;
+
+    unsigned Opc = Node->getTargetOpcode();
+    unsigned NumRes = ScheduleDAG::CountResults(Node);
+    unsigned NumOps = ScheduleDAG::CountOperands(Node);
+    for (unsigned j = 0; j != NumOps; ++j) {
+      if (TII->getOperandConstraint(Opc, j+NumRes,
+                                    TargetInstrInfo::TIED_TO) != -1) {
+        SDNode *DU = SU->Node->getOperand(j).Val;
+        SUnit *DUSU = (*SUnitMap)[DU];
+        for (SUnit::succ_iterator I = DUSU->Succs.begin(),E = DUSU->Succs.end();
+             I != E; ++I) {
+          if (I->second) continue;
+          SUnit *SuccSU = I->first;
+          if (SuccSU != SU &&
+              (!canClobber(SuccSU, DUSU) ||
+               (!SU->isCommutable && SuccSU->isCommutable))){
+            if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) {
+              DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum
+                    << " to SU #" << SuccSU->NodeNum << "\n");
+              if (SU->addPred(SuccSU, true))
+                SU->NumChainPredsLeft++;
+              if (SuccSU->addSucc(SU, true))
+                SuccSU->NumChainSuccsLeft++;
+            }
+          }
+        }
+      }
+    }
+  }
+#else
   for (unsigned i = 0, e = SUnits->size(); i != e; ++i) {
     SUnit *SU = (SUnit *)&((*SUnits)[i]);
     SDNode *Node = SU->Node;
@@ -649,7 +731,7 @@
       continue;
 
     if (SU->isTwoAddress) {
-      SUnit *DUSU = getDefUsePredecessor(SU);
+      SUnit *DUSU = getDefUsePredecessor(SU, TII);
       if (!DUSU) continue;
 
       for (SUnit::succ_iterator I = DUSU->Succs.begin(), E = DUSU->Succs.end();
@@ -657,7 +739,7 @@
         if (I->second) continue;
         SUnit *SuccSU = I->first;
         if (SuccSU != SU &&
-            (!canClobber(SuccSU, DUSU) ||
+            (!canClobber(SuccSU, DUSU, TII) ||
              (!SU->isCommutable && SuccSU->isCommutable))){
           if (SuccSU->Depth == SU->Depth && !isReachable(SuccSU, SU)) {
             DEBUG(std::cerr << "Adding an edge from SU # " << SU->NodeNum
@@ -671,6 +753,7 @@
       }
     }
   }
+#endif
 }
 
 /// CalcNodePriority - Priority is the Sethi Ullman number. 
@@ -858,8 +941,9 @@
 llvm::ScheduleDAG* llvm::createBURRListDAGScheduler(SelectionDAGISel *IS,
                                                     SelectionDAG *DAG,
                                                     MachineBasicBlock *BB) {
+  const TargetInstrInfo *TII = DAG->getTarget().getInstrInfo();
   return new ScheduleDAGRRList(*DAG, BB, DAG->getTarget(), true,
-                               new BURegReductionPriorityQueue<bu_ls_rr_sort>());
+                           new BURegReductionPriorityQueue<bu_ls_rr_sort>(TII));
 }
 
 llvm::ScheduleDAG* llvm::createTDRRListDAGScheduler(SelectionDAGISel *IS,






More information about the llvm-commits mailing list