[llvm-commits] CVS: llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp MSSchedule.h MSchedGraph.cpp ModuloScheduling.cpp ModuloScheduling.h

Tanya Brethour tbrethou at cs.uiuc.edu
Sun Oct 10 15:44:50 PDT 2004



Changes in directory llvm/lib/CodeGen/ModuloScheduling:

MSSchedule.cpp updated: 1.5 -> 1.6
MSSchedule.h updated: 1.1 -> 1.2
MSchedGraph.cpp updated: 1.8 -> 1.9
ModuloScheduling.cpp updated: 1.28 -> 1.29
ModuloScheduling.h updated: 1.15 -> 1.16
---
Log message:

Added debug information. Fixed several bugs in the reconstruct loop function. 


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

Index: llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp
diff -u llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp:1.5 llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp:1.6
--- llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp:1.5	Wed Sep  1 17:55:35 2004
+++ llvm/lib/CodeGen/ModuloScheduling/MSSchedule.cpp	Sun Oct 10 17:44:35 2004
@@ -15,6 +15,7 @@
 #include "MSSchedule.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Target/TargetSchedInfo.h"
+#include "../../Target/SparcV9/SparcV9Internals.h"
 
 using namespace llvm;
 
@@ -134,6 +135,7 @@
 
 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");
@@ -146,7 +148,10 @@
 	      E = schedule[i].end(); I != E; ++I) {
 	  //Check if its a branch
 	  if((*I)->isBranch()) {
-	    branchNode = *I;
+	    if((*I)->getInst()->getOpcode() == V9::BA)
+	      branchANode = *I;
+	    else
+	      branchNode = *I;
 	    assert(count == 0 && "Branch can not be from a previous iteration");
 	  }
 	  else
@@ -160,7 +165,16 @@
   
   //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
+    maxStage = 0;
+
   return true;
 }
 


Index: llvm/lib/CodeGen/ModuloScheduling/MSSchedule.h
diff -u llvm/lib/CodeGen/ModuloScheduling/MSSchedule.h:1.1 llvm/lib/CodeGen/ModuloScheduling/MSSchedule.h:1.2
--- llvm/lib/CodeGen/ModuloScheduling/MSSchedule.h:1.1	Wed May 26 01:27:36 2004
+++ llvm/lib/CodeGen/ModuloScheduling/MSSchedule.h	Sun Oct 10 17:44:35 2004
@@ -32,6 +32,9 @@
     //Resulting kernel
     std::vector<std::pair<MSchedGraphNode*, int> > kernel;
 
+    //Max stage count
+    int maxStage;
+
   public:
     MSSchedule(int num) : numIssue(num) {}
     MSSchedule() : numIssue(4) {}
@@ -40,7 +43,7 @@
     void clear() { schedule.clear(); resourceNumPerCycle.clear(); kernel.clear(); }
     std::vector<std::pair<MSchedGraphNode*, int> >* getKernel() { return &kernel; }
     bool constructKernel(int II);
- 
+    int getMaxStage() { return maxStage; }
 
    
     //iterators


Index: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp
diff -u llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.8 llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.9
--- llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.8	Tue Sep 28 09:42:44 2004
+++ llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp	Sun Oct 10 17:44:35 2004
@@ -91,7 +91,7 @@
   //Make sure BB is not null, 
   assert(BB != NULL && "Basic Block is null");
   
-  DEBUG(std::cerr << "Constructing graph for " << bb << "\n");
+  //DEBUG(std::cerr << "Constructing graph for " << bb << "\n");
 
   //Create nodes and edges for this BB
   buildNodesAndEdges();


Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp
diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.28 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.29
--- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.28	Tue Sep 28 09:42:44 2004
+++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp	Sun Oct 10 17:44:35 2004
@@ -123,14 +123,11 @@
   
   bool Changed = false;
   
-  DEBUG(std::cerr << "Creating ModuloSchedGraph for each valid BasicBlock in" + F.getName() + "\n");
+  DEBUG(std::cerr << "Creating ModuloSchedGraph for each valid BasicBlock in " + F.getName() + "\n");
   
   //Get MachineFunction
   MachineFunction &MF = MachineFunction::get(&F);
   
-  //Print out machine function
-  DEBUG(MF.print(std::cerr));
-
   //Worklist
   std::vector<MachineBasicBlock*> Worklist;
   
@@ -139,6 +136,7 @@
     if(MachineBBisValid(BI)) 
       Worklist.push_back(&*BI);
   
+  DEBUG(if(Worklist.size() == 0) std::cerr << "No single basic block loops in function to ModuloSchedule\n");
 
   //Iterate over the worklist and perform scheduling
   for(std::vector<MachineBasicBlock*>::iterator BI = Worklist.begin(),  
@@ -150,7 +148,7 @@
     DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG));
     
     //Print out BB for debugging
-    DEBUG((*BI)->print(std::cerr));
+    DEBUG(std::cerr << "ModuloScheduling BB: \n"; (*BI)->print(std::cerr));
     
     //Calculate Resource II
     int ResMII = calculateResMII(*BI);
@@ -213,7 +211,7 @@
     recurrenceList.clear();
     FinalNodeOrder.clear();
     schedule.clear();
-    
+
     //Clean up. Nuke old MachineBB and llvmBB
     //BasicBlock *llvmBB = (BasicBlock*) (*BI)->getBasicBlock();
     //Function *parent = (Function*) llvmBB->getParent();
@@ -260,7 +258,6 @@
  
   }
   return true;
-
 }
 
 //ResMII is calculated by determining the usage count for each resource
@@ -1021,11 +1018,22 @@
 	succIntersect(*CurrentSet, IntersectCurrent);
 	} //End if BOTTOM_DOWN
 	
+      DEBUG(std::cerr << "Current Intersection Size: " << IntersectCurrent.size() << "\n");
     }
     //End Wrapping while loop
-      
+    DEBUG(std::cerr << "Ending Size of Current Set: " << CurrentSet->size() << "\n");  
   }//End for over all sets of nodes
-   
+  
+  //FIXME: As the algorithm stands it will NEVER add an instruction such as ba (with no
+  //data dependencies) to the final order. We add this manually. It will always be
+  //in the last set of S since its not part of a recurrence
+    //Loop over all the sets and place them in the final node order
+  std::vector<std::vector<MSchedGraphNode*> > ::reverse_iterator LastSet = partialOrder.rbegin();
+  for(std::vector<MSchedGraphNode*>::iterator CurrentNode = LastSet->begin(), LastNode = LastSet->end();
+      CurrentNode != LastNode; ++CurrentNode) {
+    if((*CurrentNode)->getInst()->getOpcode() == V9::BA)
+      FinalNodeOrder.push_back(*CurrentNode);
+  }
   //Return final Order
   //return FinalNodeOrder;
 }
@@ -1080,8 +1088,15 @@
       }
       else {
 	//WARNING: HACK! FIXME!!!!
-	EarlyStart = II-1;
-	LateStart = II-1;
+	if((*I)->getInst()->getOpcode() == V9::BA) {
+	  EarlyStart = II-1;
+	  LateStart = II-1;
+	}
+	else {
+	  EarlyStart = II-1;
+	  LateStart = II-1;
+	  assert( (EarlyStart >= 0) && (LateStart >=0) && "EarlyStart and LateStart must be greater then 0"); 
+	}
 	hasPred = 1;
 	hasSucc = 1;
       }
@@ -1170,20 +1185,24 @@
   return success;
 }
 
-void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, std::vector<Value*> > > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation) {
+void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation) {
 
   //Keep a map to easily know whats in the kernel
   std::map<int, std::set<const MachineInstr*> > inKernel;
   int maxStageCount = 0;
 
   MSchedGraphNode *branch = 0;
+  MSchedGraphNode *BAbranch = 0;
 
   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()) {
-      branch = I->first;
+      if (I->first->getInst()->getOpcode() == V9::BA)
+	BAbranch = I->first;
+      else
+	branch = I->first;
       continue;
     }
 
@@ -1204,27 +1223,30 @@
     for(int j = 0; j <= i; ++j) {
       for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
 	if(inKernel[j].count(&*MI)) {
-	  machineBB->push_back(MI->clone());
+	  MachineInstr *instClone = MI->clone();
+	  machineBB->push_back(instClone);
 	  
+	  DEBUG(std::cerr << "Cloning: " << *MI << "\n");
+
 	  Instruction *tmp;
 
 	  //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 = MI->getOperand(opNum);
+	    const MachineOperand &mOp = instClone->getOperand(opNum);
 	    if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
 
-
 	      //Check if this is a value we should save
 	      if(valuesToSave.count(mOp.getVRegValue())) {
 		//Save copy in tmpInstruction
 		tmp = new TmpInstruction(mOp.getVRegValue());
 		
-		DEBUG(std::cerr << "Value: " << mOp.getVRegValue() << " New Value: " << tmp << " Stage: " << i << "\n");
-		newValues[mOp.getVRegValue()][i].push_back(tmp);
+		DEBUG(std::cerr << "Value: " << *(mOp.getVRegValue()) << " New Value: " << *tmp << " Stage: " << i << "\n");
+		
+		newValues[mOp.getVRegValue()][i]= tmp;
 		newValLocation[tmp] = machineBB;
 
-		DEBUG(std::cerr << "Machine Instr Operands: " << mOp.getVRegValue() << ", 0, " << tmp << "\n");
+		DEBUG(std::cerr << "Machine Instr Operands: " << *(mOp.getVRegValue()) << ", 0, " << *tmp << "\n");
 		
 		//Create machine instruction and put int machineBB
 		MachineInstr *saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
@@ -1232,6 +1254,18 @@
 		DEBUG(std::cerr << "Created new machine instr: " << *saveValue << "\n");
 	      }
 	    }
+
+	    //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)) {
+		    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]);
+		  }
+	      }
+	    }
 	  }
 	}
       }
@@ -1240,6 +1274,9 @@
 
     //Stick in branch at the end
     machineBB->push_back(branch->getInst()->clone());
+    
+    //Stick in BA branch at the end
+    machineBB->push_back(BAbranch->getInst()->clone());
 
   (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);  
     prologues.push_back(machineBB);
@@ -1247,12 +1284,11 @@
   }
 }
 
-void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, std::vector<Value*> > > &newValues,std::map<Value*, MachineBasicBlock*> &newValLocation ) {
+void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues,std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs ) {
   
   std::map<int, std::set<const MachineInstr*> > inKernel;
-  int maxStageCount = 0;
+  
   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())
@@ -1264,62 +1300,80 @@
 
   std::map<Value*, Value*> valPHIs;
 
+  //some debug stuff, will remove later
+  DEBUG(for(std::map<Value*, std::map<int, Value*> >::iterator V = newValues.begin(), E = newValues.end(); V !=E; ++V) {
+    std::cerr << "Old Value: " << *(V->first) << "\n";
+    for(std::map<int, Value*>::iterator I = V->second.begin(), IE = V->second.end(); I != IE; ++I)
+      std::cerr << "Stage: " << I->first << " Value: " << *(I->second) << "\n";
+  });
+
+  //some debug stuff, will remove later
+  DEBUG(for(std::map<Value*, std::map<int, Value*> >::iterator V = kernelPHIs.begin(), E = kernelPHIs.end(); V !=E; ++V) {
+    std::cerr << "Old Value: " << *(V->first) << "\n";
+    for(std::map<int, Value*>::iterator I = V->second.begin(), IE = V->second.end(); I != IE; ++I)
+      std::cerr << "Stage: " << I->first << " Value: " << *(I->second) << "\n";
+  });
+
   //Now write the epilogues
-  for(int i = maxStageCount-1; i >= 0; --i) {
+  for(int i = schedule.getMaxStage()-1; i >= 0; --i) {
     BasicBlock *llvmBB = new BasicBlock("EPILOGUE", (Function*) (origBB->getBasicBlock()->getParent()));
     MachineBasicBlock *machineBB = new MachineBasicBlock(llvmBB);
    
-    DEBUG(std::cerr << " i: " << i << "\n");
+    DEBUG(std::cerr << " Epilogue #: " << i << "\n");
+
 
-    //Spit out phi nodes
-    for(std::map<Value*, std::map<int, std::vector<Value*> > >::iterator V = newValues.begin(), E = newValues.end();
-	V != E; ++V) {
-
-      DEBUG(std::cerr << "Writing phi for" << *(V->first));
-      for(std::map<int, std::vector<Value*> >::iterator I = V->second.begin(), IE = V->second.end(); I != IE; ++I) {
-	if(I->first == i) {
-	  DEBUG(std::cerr << "BLAH " << i << "\n");
-	  
-	  //Vector must have two elements in it:
-	  assert(I->second.size() == 2 && "Vector size should be two\n");
-	  
-	  Instruction *tmp = new TmpInstruction(I->second[0]);
-	  MachineInstr *saveValue = BuildMI(machineBB, V9::PHI, 3).addReg(I->second[0]).addReg(I->second[1]).addRegDef(tmp);
-	  valPHIs[V->first] = tmp;
-	}
-      }
-      
-    }
 
-    for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
-      for(int j=maxStageCount; j > i; --j) {
+
+     for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
+      for(int j=schedule.getMaxStage(); j > i; --j) {
 	if(inKernel[j].count(&*MI)) {
 	  DEBUG(std::cerr << "Cloning instruction " << *MI << "\n");
 	  MachineInstr *clone = MI->clone();
 	  
 	  //Update operands that need to use the result from the phi
-	  for(unsigned i=0; i < clone->getNumOperands(); ++i) {
+	  for(unsigned opNum=0; opNum < clone->getNumOperands(); ++opNum) {
 	    //get machine operand
-	    const MachineOperand &mOp = clone->getOperand(i);
+	    const MachineOperand &mOp = clone->getOperand(opNum);
+
+	  //If this is the last instructions for the max iterations ago, don't update operands
+	    if(j == schedule.getMaxStage() && (i == 0))
+	      continue;
+	    
 	    if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse())) {
+	      
+	      DEBUG(std::cerr << "Writing PHI for " << *(mOp.getVRegValue()) << "\n");
+	      
+	      //Quickly write appropriate phis for this operand
+	      if(newValues.count(mOp.getVRegValue())) {
+		if(newValues[mOp.getVRegValue()].count(i)) {
+		  Instruction *tmp = new TmpInstruction(newValues[mOp.getVRegValue()][i]);
+		  MachineInstr *saveValue = BuildMI(machineBB, V9::PHI, 3).addReg(newValues[mOp.getVRegValue()][i]).addReg(kernelPHIs[mOp.getVRegValue()][i]).addRegDef(tmp);
+		  DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
+		  valPHIs[mOp.getVRegValue()] = tmp;
+		}
+	      }
+	      
 	      if(valPHIs.count(mOp.getVRegValue())) {
 		//Update the operand in the cloned instruction
-		clone->getOperand(i).setValueReg(valPHIs[mOp.getVRegValue()]); 
+		clone->getOperand(opNum).setValueReg(valPHIs[mOp.getVRegValue()]); 
 	      }
 	    }
 	  }
 	  machineBB->push_back(clone);
 	}
       }
-    }
+     }
 
     (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
     epilogues.push_back(machineBB);
     llvm_epilogues.push_back(llvmBB);
+  
+    DEBUG(std::cerr << "EPILOGUE #" << i << "\n");
+    DEBUG(machineBB->print(std::cerr));
   }
 }
 
-void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, std::vector<Value*> > > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation) {
+void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs) {
   
   //Keep track of operands that are read and saved from a previous iteration. The new clone
   //instruction will use the result of the phi instead.
@@ -1329,19 +1383,29 @@
     //Create TmpInstructions for the final phis
  for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
 
+   DEBUG(std::cerr << "Stage: " << I->second << " Inst: " << *(I->first->getInst()) << "\n";);
+
    //Clone instruction
    const MachineInstr *inst = I->first->getInst();
    MachineInstr *instClone = inst->clone();
-   
-   //If this instruction is from a previous iteration, update its operands
-   if(I->second > 0) {
-     //Loop over Machine Operands
-     const MachineInstr *inst = I->first->getInst();
-     for(unsigned i=0; i < inst->getNumOperands(); ++i) {
-       //get machine operand
-       const MachineOperand &mOp = inst->getOperand(i);
 
+   //Insert into machine basic block
+   machineBB->push_back(instClone);
+
+   
+   //Loop over Machine Operands
+   for(unsigned i=0; i < inst->getNumOperands(); ++i) {
+     //get machine operand
+     const MachineOperand &mOp = inst->getOperand(i);
+   
+     if(I->second != 0) {
        if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
+
+	 //Check to see where this operand is defined if this instruction is from max stage
+	 if(I->second == schedule.getMaxStage()) {
+	   DEBUG(std::cerr << "VREG: " << *(mOp.getVRegValue()) << "\n");
+	 }
+
 	 //If its in the value saved, we need to create a temp instruction and use that instead
 	 if(valuesToSave.count(mOp.getVRegValue())) {
 	   TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
@@ -1354,23 +1418,8 @@
 	   newValLocation[tmp] = machineBB;
 	 }
        }
-
      }
-     //Insert into machine basic block
-     machineBB->push_back(instClone);
-
-   }
-   //Otherwise we just check if we need to save a value or not
-   else {
-     //Insert into machine basic block
-     machineBB->push_back(instClone);
-
-     //Loop over Machine Operands
-     const MachineInstr *inst = I->first->getInst();
-     for(unsigned i=0; i < inst->getNumOperands(); ++i) {
-       //get machine operand
-       const MachineOperand &mOp = inst->getOperand(i);
-
+     if(I->second != schedule.getMaxStage()) {
        if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
 	 if(valuesToSave.count(mOp.getVRegValue())) {
 	   
@@ -1382,59 +1431,84 @@
 	   //Save for future cleanup
 	   kernelValue[mOp.getVRegValue()] = tmp;
 	   newValLocation[tmp] = machineBB;
+	   kernelPHIs[mOp.getVRegValue()][schedule.getMaxStage()-1] = tmp;
 	 }
        }
      }
    }
+   
  }
 
- //Clean up by writing phis
- for(std::map<Value*, std::map<int, std::vector<Value*> > >::iterator V = newValues.begin(), E = newValues.end();
-     V != E; ++V) {
+  DEBUG(std::cerr << "KERNEL before PHIs\n");
+  DEBUG(machineBB->print(std::cerr));
 
-   DEBUG(std::cerr << "Writing phi for" << *(V->first));
-  
-   //FIXME
-   int maxStage = 1;
 
-   //Last phi
-   Instruction *lastPHI = 0;
+ //Loop over each value we need to generate phis for
+ for(std::map<Value*, std::map<int, Value*> >::iterator V = newValues.begin(), 
+       E = newValues.end(); V != E; ++V) {
 
-   for(std::map<int, std::vector<Value*> >::iterator I = V->second.begin(), IE = V->second.end();
-       I != IE; ++I) {
-     
-     int stage = I->first;
 
-     DEBUG(std::cerr << "Stage: " << I->first << " vector size: " << I->second.size() << "\n");
+   DEBUG(std::cerr << "Writing phi for" << *(V->first));
+   DEBUG(std::cerr << "\nMap of Value* for this phi\n");
+   DEBUG(for(std::map<int, Value*>::iterator I = V->second.begin(), 
+	       IE = V->second.end(); I != IE; ++I) { 
+     std::cerr << "Stage: " << I->first;
+     std::cerr << " Value: " << *(I->second) << "\n";
+   });
+
+   //If we only have one current iteration live, its safe to set lastPhi = to kernel value
+   if(V->second.size() == 1) {
+     assert(kernelValue[V->first] != 0 && "Kernel value* must exist to create phi");
+     MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(),V9::PHI, 3).addReg(V->second.begin()->second).addReg(kernelValue[V->first]).addRegDef(finalPHIValue[V->first]); 
+     DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
+     kernelPHIs[V->first][schedule.getMaxStage()-1] = kernelValue[V->first];
+   }
+   else {
+
+     //Keep track of last phi created.
+     Instruction *lastPhi = 0;
+     
+     unsigned count = 1;
+     //Loop over the the map backwards to generate phis
+     for(std::map<int, Value*>::reverse_iterator I = V->second.rbegin(), IE = V->second.rend(); 
+	 I != IE; ++I) {
+
+       if(count < (V->second).size()) {
+	 if(lastPhi == 0) {
+	   lastPhi = new TmpInstruction(I->second);
+	   MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(kernelValue[V->first]).addReg(I->second).addRegDef(lastPhi);
+	   DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
+	   newValLocation[lastPhi] = machineBB;
+	 }
+	 else {
+	   Instruction *tmp = new TmpInstruction(I->second);
+	   MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(tmp);
+	   DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
+	   lastPhi = tmp;
+	   kernelPHIs[V->first][I->first] = lastPhi;
+	   newValLocation[lastPhi] = machineBB;
+	 }
+       }
+       //Final phi value
+       else {
+	 //The resulting value must be the Value* we created earlier
+	 assert(lastPhi != 0 && "Last phi is NULL!\n");
+	 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(finalPHIValue[V->first]);
+	 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
+	 kernelPHIs[V->first][I->first] = finalPHIValue[V->first];
+       }
 
-     //Assert if this vector is ever greater then 1. This should not happen
-     //FIXME: Get rid of vector if we convince ourselves this won't happn
-     assert(I->second.size() == 1 && "Vector of values should be of size \n");
-
-     //We must handle the first and last phi specially
-     if(stage == maxStage) {
-       //The resulting value must be the Value* we created earlier
-       assert(lastPHI != 0 && "Last phi is NULL!\n");
-       MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPHI).addReg(I->second[0]).addRegDef(finalPHIValue[V->first]);
-       I->second.push_back(finalPHIValue[V->first]);
-     }
-     else if(stage == 0) {
-       lastPHI = new TmpInstruction(I->second[0]);
-       MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(kernelValue[V->first]).addReg(I->second[0]).addRegDef(lastPHI);
-       I->second.push_back(lastPHI);
-       newValLocation[lastPHI] = machineBB;
-     }
-     else {
-        Instruction *tmp = new TmpInstruction(I->second[0]);
-	MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPHI).addReg(I->second[0]).addRegDef(tmp);
-	lastPHI = tmp;
-	I->second.push_back(lastPHI);
-       newValLocation[tmp] = machineBB;
+       ++count;
      }
+
    }
- }
+ } 
+
+  DEBUG(std::cerr << "KERNEL after PHIs\n");
+  DEBUG(machineBB->print(std::cerr));
 }
 
+
 void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vector<MachineBasicBlock *> &prologues, std::vector<MachineBasicBlock *> &epilogues, MachineBasicBlock *kernelBB, std::map<Value*, MachineBasicBlock*> &newValLocation) {
 
   //Worklist to delete things
@@ -1535,6 +1609,7 @@
 
     //Delete the phis
   for(std::vector<std::pair<MachineBasicBlock*, MachineBasicBlock::iterator> >::iterator I =  worklist.begin(), E = worklist.end(); I != E; ++I) {
+    DEBUG(std::cerr << "Deleting PHI " << I->second << "\n");
     I->first->erase(I->second);
 		    
   }
@@ -1544,26 +1619,66 @@
 
 void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
 
+  DEBUG(std::cerr << "Reconstructing Loop\n");
+
   //First find the value *'s that we need to "save"
   std::map<const Value*, std::pair<const MSchedGraphNode*, int> > valuesToSave;
 
+  //Keep track of instructions we have already seen and their stage because
+  //we don't want to "save" values if they are used in the kernel immediately
+  std::map<const MachineInstr*, int> lastInstrs;
+
   //Loop over kernel and only look at instructions from a stage > 0
   //Look at its operands and save values *'s that are read
   for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
 
-    if(I->second > 0) {
+    if(I->second !=0) {
       //For this instruction, get the Value*'s that it reads and put them into the set.
       //Assert if there is an operand of another type that we need to save
       const MachineInstr *inst = I->first->getInst();
+      lastInstrs[inst] = I->second;
+
       for(unsigned i=0; i < inst->getNumOperands(); ++i) {
 	//get machine operand
 	const MachineOperand &mOp = inst->getOperand(i);
 	
 	if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
 	  //find the value in the map
-	  if (const Value* srcI = mOp.getVRegValue())
-	    valuesToSave[srcI] = std::make_pair(I->first, i);
-	  
+	  if (const Value* srcI = mOp.getVRegValue()) {
+
+	    //Before we declare this Value* one that we should save
+	    //make sure its def is not of the same stage as this instruction
+	    //because it will be consumed before its used
+	    Instruction *defInst = (Instruction*) srcI;
+	    
+	    //Should we save this value?
+	    bool save = true;
+
+	    //Get Machine code for this instruction, and loop backwards over the array
+	    //to find the def
+	    MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defInst);
+	    for (int j = tempMvec.size()-1; j >= 0; j--) {
+	       MachineInstr *temp = tempMvec[j];
+	       
+	       //Loop over instructions
+	       for(unsigned opNum = 0; opNum < temp->getNumOperands(); ++opNum) {
+		 MachineOperand &mDefOp = temp->getOperand(opNum);
+		 
+		 if (mDefOp.getType() == MachineOperand::MO_VirtualRegister && mDefOp.isDef()) {
+		   const Value* defVReg = mDefOp.getVRegValue();
+		   if(defVReg == srcI) {
+		     //Check if instruction has been seen already and is of same stage
+		     if(lastInstrs.count(temp)) {
+		       if(lastInstrs[temp] == I->second)
+			 save = false;
+		     }
+		   }
+		 }
+	       }
+	    }
+	    if(save)
+	      valuesToSave[srcI] = std::make_pair(I->first, i);
+	  }	  
 	}
 	
 	if(mOp.getType() != MachineOperand::MO_VirtualRegister && mOp.isUse()) {
@@ -1576,8 +1691,11 @@
   //The new loop will consist of one or more prologues, the kernel, and one or more epilogues.
 
   //Map to keep track of old to new values
-  std::map<Value*, std::map<int, std::vector<Value*> > > newValues;
+  std::map<Value*, std::map<int, Value*> > newValues;
  
+  //Map to keep track of old to new values in kernel
+  std::map<Value*, std::map<int, Value*> > kernelPHIs;
+
   //Another map to keep track of what machine basic blocks these new value*s are in since
   //they have no llvm instruction equivalent
   std::map<Value*, MachineBasicBlock*> newValLocation;
@@ -1588,18 +1706,25 @@
 
   //Write prologue
   writePrologues(prologues, BB, llvm_prologues, valuesToSave, newValues, newValLocation);
+    
+  //Print out epilogues and prologue
+  DEBUG(for(std::vector<MachineBasicBlock*>::iterator I = prologues.begin(), E = prologues.end(); 
+      I != E; ++I) {
+    std::cerr << "PROLOGUE\n";
+    (*I)->print(std::cerr);
+  });
 
   BasicBlock *llvmKernelBB = new BasicBlock("Kernel", (Function*) (BB->getBasicBlock()->getParent()));
   MachineBasicBlock *machineKernelBB = new MachineBasicBlock(llvmKernelBB);
-  
-  writeKernel(llvmKernelBB, machineKernelBB, valuesToSave, newValues, newValLocation);
   (((MachineBasicBlock*)BB)->getParent())->getBasicBlockList().push_back(machineKernelBB);
+  writeKernel(llvmKernelBB, machineKernelBB, valuesToSave, newValues, newValLocation, kernelPHIs);
+  
  
   std::vector<MachineBasicBlock*> epilogues;
   std::vector<BasicBlock*> llvm_epilogues;
 
   //Write epilogues
-  writeEpilogues(epilogues, BB, llvm_epilogues, valuesToSave, newValues, newValLocation);
+  writeEpilogues(epilogues, BB, llvm_epilogues, valuesToSave, newValues, newValLocation, kernelPHIs);
 
 
   const TargetInstrInfo *TMI = target.getInstrInfo();
@@ -1650,11 +1775,11 @@
     //Push nop onto end of machine basic block
     BuildMI(prologues[I], V9::NOP, 0);
     
-    //Now since I don't trust fall throughs, add a unconditional branch to the next prologue
+    //Add a unconditional branch to the next prologue
     if(I != prologues.size()-1)
-      BuildMI(prologues[I], V9::BA, 1).addReg(llvm_prologues[I+1]);
+      BuildMI(prologues[I], V9::BA, 1).addPCDisp(llvm_prologues[I+1]);
     else
-      BuildMI(prologues[I], V9::BA, 1).addReg(llvmKernelBB);
+      BuildMI(prologues[I], V9::BA, 1).addPCDisp(llvmKernelBB);
 
     //Add one more nop!
     BuildMI(prologues[I], V9::NOP, 0);
@@ -1693,7 +1818,8 @@
    BuildMI(machineKernelBB, V9::NOP, 0);
 
    //Add unconditional branch to first epilogue
-   BuildMI(machineKernelBB, V9::BA, 1).addReg(llvm_epilogues[0]);
+   BuildMI(machineKernelBB, V9::BA, 1).addPCDisp(llvm_epilogues[0]);
+
 
    //Add kernel noop
    BuildMI(machineKernelBB, V9::NOP, 0);
@@ -1703,7 +1829,7 @@
      
     //Now since I don't trust fall throughs, add a unconditional branch to the next prologue
      if(I != epilogues.size()-1) {
-       BuildMI(epilogues[I], V9::BA, 1).addReg(llvm_epilogues[I+1]);
+       BuildMI(epilogues[I], V9::BA, 1).addPCDisp(llvm_epilogues[I+1]);
        //Add unconditional branch to end of epilogue
        TerminatorInst *newBranch = new BranchInst(llvm_epilogues[I+1], 
 						  llvm_epilogues[I]);
@@ -1715,7 +1841,7 @@
 	MachineOpCode OC = inst->getOpcode();
 	if(TMI->isBranch(OC)) {
 	  branch = &*inst;
-	  DEBUG(std::cerr << *inst << "\n");
+	  DEBUG(std::cerr << "Exit branch from loop" << *inst << "\n");
 	  break;
 	
 	}
@@ -1724,7 +1850,7 @@
 	  MachineOperand &mOp = branch->getOperand(opNum);
 	  
 	  if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
-	    BuildMI(epilogues[I], V9::BA, 1).addReg(mOp.getVRegValue());
+	    BuildMI(epilogues[I], V9::BA, 1).addPCDisp(mOp.getVRegValue());
 	    break;
 	  }
 	}
@@ -1835,7 +1961,7 @@
   DEBUG(std::cerr << "New Machine Function" << "\n");
   DEBUG(std::cerr << BB->getParent() << "\n");
 
-  BB->getParent()->getBasicBlockList().erase(BB);
+  //BB->getParent()->getBasicBlockList().erase(BB);
 
 }
 


Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h
diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.15 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.16
--- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.15	Fri Jul 30 18:36:10 2004
+++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h	Sun Oct 10 17:44:35 2004
@@ -41,19 +41,19 @@
 
     //Map that holds node to node attribute information
     std::map<MSchedGraphNode*, MSNodeAttributes> nodeToAttributesMap;
-
+    
     //Map to hold all reccurrences
     std::set<std::pair<int, std::vector<MSchedGraphNode*> > > recurrenceList;
-
+    
     //Set of edges to ignore, stored as src node and index into vector of successors
     std::set<std::pair<MSchedGraphNode*, unsigned> > edgesToIgnore;
     
     //Vector containing the partial order
     std::vector<std::vector<MSchedGraphNode*> > partialOrder;
-
+    
     //Vector containing the final node order
     std::vector<MSchedGraphNode*> FinalNodeOrder;
-
+    
     //Schedule table, key is the cycle number and the vector is resource, node pairs
     MSSchedule schedule;
 
@@ -68,7 +68,6 @@
 
     bool ignoreEdge(MSchedGraphNode *srcNode, MSchedGraphNode *destNode);
 
-
     int calculateASAP(MSchedGraphNode *node, int MII,MSchedGraphNode *destNode);
     int calculateALAP(MSchedGraphNode *node, int MII, int maxASAP, MSchedGraphNode *srcNode);
 
@@ -93,12 +92,12 @@
     
     //void saveValue(const MachineInstr*, const std::set<Value*>&, std::vector<Value*>*);
 
-    void writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, std::vector<Value*> > > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation);
+    void writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation);
 
-    void writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave,std::map<Value*, std::map<int, std::vector<Value*> > > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation);
+    void writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave,std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation,  std::map<Value*, std::map<int, Value*> > &kernelPHIs);
   
     
-    void writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, std::vector<Value*> > > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation);
+    void writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs);
 
     void removePHIs(const MachineBasicBlock *origBB, std::vector<MachineBasicBlock *> &prologues, std::vector<MachineBasicBlock *> &epilogues, MachineBasicBlock *kernelBB, std::map<Value*, MachineBasicBlock*> &newValLocation);
   






More information about the llvm-commits mailing list