Reworked branch adding in prologue. Added check for infinite loops which are not...
authorTanya Lattner <tonic@nondot.org>
Thu, 2 Dec 2004 07:22:15 +0000 (07:22 +0000)
committerTanya Lattner <tonic@nondot.org>
Thu, 2 Dec 2004 07:22:15 +0000 (07:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18419 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp
lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp
lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h

index 29aba158c30d31f2cde358c16aa3f730323e0351..beab69c4db6e5a725d8baaa3d9be01c6ad705745 100644 (file)
@@ -164,9 +164,7 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
 }
 
 bool MSSchedule::constructKernel(int II) {
-  MSchedGraphNode *branchNode = 0;
-  MSchedGraphNode *branchANode = 0;
-
   int stageNum = (schedule.rbegin()->first)/ II;
   DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
   
@@ -178,11 +176,8 @@ bool MSSchedule::constructKernel(int II) {
              E = schedule[i].end(); I != E; ++I) {
          //Check if its a branch
          if((*I)->isBranch()) {
-           if((*I)->getInst()->getOpcode() == V9::BA)
-             branchANode = *I;
-           else
-             branchNode = *I;
            assert(count == 0 && "Branch can not be from a previous iteration");
+           kernel.push_back(std::make_pair(*I, count));
          }
          else
          //FIXME: Check if the instructions in the earlier stage conflict
@@ -193,13 +188,6 @@ bool MSSchedule::constructKernel(int II) {
     }
   }
   
-  //Add Branch to the end
-  kernel.push_back(std::make_pair(branchNode, 0));
-
-  //Add Branch Always to the end
-  kernel.push_back(std::make_pair(branchANode, 0));
-
-
   if(stageNum > 0)
     maxStage = stageNum;
   else
index d31644c91e765373fcef9c0f36e4f6bae5cd5e59..7a3f267450dfb2d6e262f66424ebac64b4899580 100644 (file)
@@ -213,20 +213,20 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
     });
     
     //Finally schedule nodes
-    computeSchedule();
+    bool haveSched = computeSchedule();
     
     //Print out final schedule
     DEBUG(schedule.print(std::cerr));
     
     //Final scheduling step is to reconstruct the loop only if we actual have
     //stage > 0
-    if(schedule.getMaxStage() != 0) {
+    if(schedule.getMaxStage() != 0 && haveSched) {
       reconstructLoop(*BI);
       ++MSLoops;
       Changed = true;
     }
     else
-      DEBUG(std::cerr << "Max stage is 0, so no change in loop\n");
+      DEBUG(std::cerr << "Max stage is 0, so no change in loop or reached cap\n");
 
     //Clear out our maps for the next basic block that is processed
     nodeToAttributesMap.clear();
@@ -292,7 +292,12 @@ bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
   
   if(!isLoop)
     return false;
-    
+
+  //Check that we have a conditional branch (avoiding MS infinite loops)
+  if(BranchInst *b = dyn_cast<BranchInst>(((BasicBlock*) BI->getBasicBlock())->getTerminator()))
+    if(b->isUnconditional())
+      return false;
+
   //Check size of our basic block.. make sure we have more then just the terminator in it
   if(BI->getBasicBlock()->size() == 1)
     return false;
@@ -1139,13 +1144,13 @@ void ModuloSchedulingPass::orderNodes() {
   //return FinalNodeOrder;
 }
 
-void ModuloSchedulingPass::computeSchedule() {
+bool ModuloSchedulingPass::computeSchedule() {
 
   bool success = false;
   
   //FIXME: Should be set to max II of the original loop
   //Cap II in order to prevent infinite loop
-  int capII = 30;
+  int capII = 100;
 
   while(!success) {
 
@@ -1252,8 +1257,12 @@ void ModuloSchedulingPass::computeSchedule() {
       }
     }
     
+    if(II >= capII)
+      return false;
+
     assert(II < capII && "The II should not exceed the original loop number of cycles");
   } 
+  return true;
 }
 
 
@@ -1312,21 +1321,22 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
   std::map<int, std::set<const MachineInstr*> > inKernel;
   int maxStageCount = 0;
 
+  //Keep a map of new values we consumed in case they need to be added back
+  std::map<Value*, std::map<int, Value*> > consumedValues;
+
   MSchedGraphNode *branch = 0;
   MSchedGraphNode *BAbranch = 0;
 
   schedule.print(std::cerr);
 
+  std::vector<MSchedGraphNode*> branches;
+
   for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
     maxStageCount = std::max(maxStageCount, I->second);
     
     //Ignore the branch, we will handle this separately
     if(I->first->isBranch()) {
-      if (I->first->getInst()->getOpcode() != V9::BA)
-       branch = I->first;
-      else
-       BAbranch = I->first;
-
+      branches.push_back(I->first);
       continue;
     }
 
@@ -1357,7 +1367,7 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
          //After cloning, we may need to save the value that this instruction defines
          for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) {
            //get machine operand
-           const MachineOperand &mOp = instClone->getOperand(opNum);
+           MachineOperand &mOp = instClone->getOperand(opNum);
            if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
 
              //Check if this is a value we should save
@@ -1386,12 +1396,23 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
            //We may also need to update the value that we use if its from an earlier prologue
            if(j != 0) {
              if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
-               if(newValues.count(mOp.getVRegValue()))
-                 if(newValues[mOp.getVRegValue()].count(j-1)) {
+               if(newValues.count(mOp.getVRegValue())) {
+                 if(newValues[mOp.getVRegValue()].count(i-1)) {
+                   Value *oldV =  mOp.getVRegValue();
                    DEBUG(std::cerr << "Replaced this value: " << mOp.getVRegValue() << " With:" << (newValues[mOp.getVRegValue()][i-1]) << "\n");
                    //Update the operand with the right value
-                   instClone->getOperand(opNum).setValueReg(newValues[mOp.getVRegValue()][i-1]);
+                   mOp.setValueReg(newValues[mOp.getVRegValue()][i-1]);
+
+                   //Remove this value since we have consumed it
+                   //NOTE: Should this only be done if j != maxStage?
+                   consumedValues[oldV][i-1] = (newValues[oldV][i-1]);
+                   DEBUG(std::cerr << "Deleted value: " << consumedValues[oldV][i-1] << "\n");
+                   newValues[oldV].erase(i-1);
                  }
+               }
+               else
+                 if(consumedValues.count(mOp.getVRegValue()))
+                   assert(!consumedValues[mOp.getVRegValue()].count(i-1) && "Found a case where we need the value");
              }
            }
          }
@@ -1400,17 +1421,15 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
     }
 
 
-    //Stick in branch at the end
-    machineBB->push_back(branch->getInst()->clone());
-    
-    //Add nop
-    BuildMI(machineBB, V9::NOP, 0);
+    for(std::vector<MSchedGraphNode*>::iterator BR = branches.begin(), BE = branches.end(); BR != BE; ++BR) {
+      
+      //Stick in branch at the end
+      machineBB->push_back((*BR)->getInst()->clone());
 
-    //Stick in branch at the end
-    machineBB->push_back(BAbranch->getInst()->clone());
+      //Add nop
+      BuildMI(machineBB, V9::NOP, 0);
+    }
 
-    //Add nop
-    BuildMI(machineBB, V9::NOP, 0);
 
   (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);  
     prologues.push_back(machineBB);
index e1f8d9eef6f4c3a41182e8df85a8f5b41097f8f4..fa523d138ccb39c2ae02e21227be40ccce0f3cdc 100644 (file)
@@ -88,7 +88,7 @@ namespace llvm {
     void addReccurrence(std::vector<MSchedGraphNode*> &recurrence, int II, MSchedGraphNode*, MSchedGraphNode*);
 
     void computePartialOrder();
-    void computeSchedule();
+    bool computeSchedule();
     bool scheduleNode(MSchedGraphNode *node, 
                      int start, int end);