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

Tanya Brethour tbrethou at cs.uiuc.edu
Wed May 26 01:29:13 PDT 2004


Changes in directory llvm/lib/CodeGen/ModuloScheduling:

MSchedGraph.cpp updated: 1.2 -> 1.3
MSchedGraph.h updated: 1.2 -> 1.3
ModuloScheduling.cpp updated: 1.17 -> 1.18
ModuloScheduling.h updated: 1.12 -> 1.13

---
Log message:

Updating my cvs versions. THis is still in progress and much will be changed.


---
Diffs of the changes:  (+299 -157)

Index: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp
diff -u llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.2 llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.3
--- llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp:1.2	Sat May  8 11:12:10 2004
+++ llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp	Wed May 26 01:27:18 2004
@@ -1,4 +1,4 @@
-//===-- MSchedGraph.h - Scheduling Graph ------------------------*- C++ -*-===//
+//===-- MSchedGraph.cpp - Scheduling Graph ------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -13,6 +13,7 @@
 #define DEBUG_TYPE "ModuloSched"
 
 #include "MSchedGraph.h"
+#include "../../Target/SparcV9/SparcV9RegisterInfo.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "Support/Debug.h"
@@ -21,8 +22,8 @@
 
 MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst, 
 				 MSchedGraph *graph, 
-				 unsigned late) 
-  : Inst(inst), Parent(graph), latency(late) {
+				 unsigned late, bool isBranch) 
+  : Inst(inst), Parent(graph), latency(late), isBranchInstr(isBranch) {
 
   //Add to the graph
   graph->addNode(inst, this);
@@ -118,7 +119,7 @@
     //using the op code, create a new node for it, and add to the
     //graph.
     
-    MachineOpCode MIopCode = MI->getOpcode();
+    MachineOpCode opCode = MI->getOpcode();
     int delay;
 
 #if 0  // FIXME: LOOK INTO THIS
@@ -128,26 +129,30 @@
       delay = MTI.minLatency(MIopCode);
     else
 #endif
-      /// FIxME: get this from the sched class.
-      delay = 7; //MTI.maxLatency(MIopCode);
+      //Get delay
+      delay = MTI.maxLatency(opCode);
     
     //Create new node for this machine instruction and add to the graph.
     //Create only if not a nop
-    if(MTI.isNop(MIopCode))
+    if(MTI.isNop(opCode))
       continue;
     
     //Add PHI to phi instruction list to be processed later
-    if (MIopCode == TargetInstrInfo::PHI)
+    if (opCode == TargetInstrInfo::PHI)
       phiInstrs.push_back(MI);
 
+    bool isBranch = false;
+
+    //We want to flag the branch node to treat it special
+    if(MTI.isBranch(opCode))
+      isBranch = true;
+
     //Node is created and added to the graph automatically
-    MSchedGraphNode *node =  new MSchedGraphNode(MI, this, delay);
+    MSchedGraphNode *node =  new MSchedGraphNode(MI, this, delay, isBranch);
 
     DEBUG(std::cerr << "Created Node: " << *node << "\n"); 
-    
-    //Check OpCode to keep track of memory operations to add memory dependencies later.
-    MachineOpCode opCode = MI->getOpcode();
 
+    //Check OpCode to keep track of memory operations to add memory dependencies later.    
     if(MTI.isLoad(opCode) || MTI.isStore(opCode))
       memInstructions.push_back(node);
 
@@ -158,14 +163,14 @@
       //Get Operand
       const MachineOperand &mOp = MI->getOperand(i);
       
-      //Check if it has an allocated register (Note: this means it
-      //is greater then zero because zero is a special register for
-      //Sparc that holds the constant zero
+      //Check if it has an allocated register 
       if(mOp.hasAllocatedReg()) {
 	int regNum = mOp.getReg();
-	
+
+	if(regNum != SparcV9::g0) {
 	//Put into our map
 	regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
+	}
 	continue;
       }
       
@@ -179,7 +184,7 @@
 	assert((mOp.getVRegValue() != NULL) && "Null value is defined");
 
 	//Check if this is a read operation in a phi node, if so DO NOT PROCESS
-	if(mOp.isUse() && (MIopCode == TargetInstrInfo::PHI))
+	if(mOp.isUse() && (opCode == TargetInstrInfo::PHI))
 	  continue;
 
       
@@ -334,24 +339,24 @@
 	              //Src only uses the register (read)
             if(srcIsUse)
 	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
-				  MSchedGraphEdge::AntiDep, 1);
+	      		  MSchedGraphEdge::AntiDep, 1);
 	    
             else if(srcIsUseandDef) {
 	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
-				  MSchedGraphEdge::AntiDep, 1);
+	      		  MSchedGraphEdge::AntiDep, 1);
 	      
 	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
-				  MSchedGraphEdge::OutputDep, 1);
+	      		  MSchedGraphEdge::OutputDep, 1);
 	    }
             else
 	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
-				  MSchedGraphEdge::OutputDep, 1);
+	      		  MSchedGraphEdge::OutputDep, 1);
 	}
 	//Dest node is a read
 	else {
 	  if(!srcIsUse || srcIsUseandDef)
 	    srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
-				MSchedGraphEdge::TrueDep,1 );
+	    		MSchedGraphEdge::TrueDep,1 );
 	}
 	
 


Index: llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h
diff -u llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h:1.2 llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h:1.3
--- llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h:1.2	Sat May  8 11:12:10 2004
+++ llvm/lib/CodeGen/ModuloScheduling/MSchedGraph.h	Wed May 26 01:27:18 2004
@@ -58,13 +58,14 @@
     const MachineInstr* Inst; //Machine Instruction
     MSchedGraph* Parent; //Graph this node belongs to
     unsigned latency; //Latency of Instruction
-    
+    bool isBranchInstr; //Is this node the branch instr or not
+
     std::vector<MSchedGraphNode*> Predecessors; //Predecessor Nodes
     std::vector<MSchedGraphEdge> Successors;
 
   public:
     MSchedGraphNode(const MachineInstr *inst, MSchedGraph *graph, 
-		    unsigned late=0);
+		    unsigned late=0, bool isBranch=false);
 
     //Iterators
     typedef std::vector<MSchedGraphNode*>::iterator pred_iterator;
@@ -85,6 +86,7 @@
 				    MSchedGraphNode> succ_iterator;
     succ_iterator succ_begin();
     succ_iterator succ_end();
+
     
 
     void addOutEdge(MSchedGraphNode *destination, 
@@ -103,7 +105,7 @@
 
     bool isSuccessor(MSchedGraphNode *);
     bool isPredecessor(MSchedGraphNode *);
-
+    bool isBranch() { return isBranchInstr; }
     //Debug support
     void print(std::ostream &os) const;
 
@@ -200,7 +202,7 @@
     iterator begin() { return GraphMap.begin(); }
     reverse_iterator rbegin() { return GraphMap.rbegin(); }
     reverse_iterator rend() { return GraphMap.rend(); }
-    
+    const TargetMachine* getTarget() { return &Target; }
   };
 
   


Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp
diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.17 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.18
--- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp:1.17	Sat May  8 11:12:10 2004
+++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp	Wed May 26 01:27:18 2004
@@ -135,7 +135,8 @@
 
       II = std::max(RecMII, ResMII);
 
-      DEBUG(std::cerr << "II starts out as " << II << "\n");
+      
+      DEBUG(std::cerr << "II starts out as " << II << " ( RecMII=" << RecMII << "and ResMII=" << ResMII << "\n");
 
       //Calculate Node Properties
       calculateNodeAttributes(MSG, ResMII);
@@ -165,20 +166,9 @@
       //Finally schedule nodes
       computeSchedule();
 
-
-      //Dump out final schedule
-      //std::cerr << "FINALSCHEDULE\n";
-  //Dump out current schedule
-  /*for(std::map<unsigned, std::vector<std::pair<unsigned, MSchedGraphNode*> > >::iterator J = schedule.begin(), 
-	JE = schedule.end(); J != JE; ++J) {
-    std::cerr << "Cycle " << J->first << ":\n";
-    for(std::vector<std::pair<unsigned, MSchedGraphNode*> >::iterator VI = J->second.begin(), VE = J->second.end(); VI != VE; ++VI)
-      std::cerr << "Resource ID: " << VI->first << " by node " << *(VI->second) << "\n";
-  }
-  std::cerr << "END FINAL SCHEDULE\n";
-
-      DEBUG(std::cerr << "II ends up as " << II << "\n");
-  */  
+      DEBUG(schedule.print(std::cerr));
+   
+      reconstructLoop(BI);
 
 
       nodeToAttributesMap.clear();
@@ -265,11 +255,12 @@
   //Find maximum usage count
   
   //Get max number of instructions that can be issued at once. (FIXME)
-  int issueSlots = 1; // msi.maxNumIssueTotal;
+  int issueSlots = msi.maxNumIssueTotal;
 
   for(std::map<unsigned,unsigned>::iterator RB = resourceUsageCount.begin(), RE = resourceUsageCount.end(); RB != RE; ++RB) {
+    
     //Get the total number of the resources in our cpu
-    //int resourceNum = msi.getCPUResourceNum(RB->first);
+    int resourceNum = CPUResource::getCPUResource(RB->first)->maxNumUsers;
     
     //Get total usage count for this resources
     unsigned usageCount = RB->second;
@@ -277,9 +268,9 @@
     //Divide the usage count by either the max number we can issue or the number of
     //resources (whichever is its upper bound)
     double finalUsageCount;
-    //if( resourceNum <= issueSlots)
-    //finalUsageCount = ceil(1.0 * usageCount / resourceNum);
-    //else
+    if( resourceNum <= issueSlots)
+      finalUsageCount = ceil(1.0 * usageCount / resourceNum);
+    else
       finalUsageCount = ceil(1.0 * usageCount / issueSlots);
     
     
@@ -363,7 +354,7 @@
     return false;
 
   bool findEdge = edgesToIgnore.count(std::make_pair(srcNode, destNode->getInEdgeNum(srcNode)));
-  DEBUG(std::cerr << "Ignore Edge from " << *srcNode << " to " << *destNode << "? " << findEdge << "\n");
+  
   return findEdge;
 }
 
@@ -561,10 +552,23 @@
   }
   
   if(!same) {
-    //if(srcBENode == 0 || destBENode == 0) {
-      srcBENode = recurrence.back();
-      destBENode = recurrence.front();
-      //}
+    srcBENode = recurrence.back();
+    destBENode = recurrence.front();
+    
+    //FIXME
+    if(destBENode->getInEdge(srcBENode).getIteDiff() == 0) {
+      //DEBUG(std::cerr << "NOT A BACKEDGE\n");
+      //find actual backedge HACK HACK 
+      for(unsigned i=0; i< recurrence.size()-1; ++i) {
+	if(recurrence[i+1]->getInEdge(recurrence[i]).getIteDiff() == 1) {
+	  srcBENode = recurrence[i];
+	  destBENode = recurrence[i+1];
+	  break;
+	}
+	  
+      }
+      
+    }
     DEBUG(std::cerr << "Back Edge to Remove: " << *srcBENode << " to " << *destBENode << "\n");
     edgesToIgnore.insert(std::make_pair(srcBENode, destBENode->getInEdgeNum(srcBENode)));
     recurrenceList.insert(std::make_pair(II, recurrence));
@@ -996,42 +1000,47 @@
       int LateStart = 99999; //Set to something higher then we would ever expect (FIXME)
       bool hasSucc = false;
       bool hasPred = false;
-      std::set<MSchedGraphNode*> seenNodes;
-
-      for(std::map<unsigned, std::vector<std::pair<unsigned, std::vector<MSchedGraphNode*> > > >::iterator J = schedule.begin(), 
-	    JE = schedule.end(); J != JE; ++J) {
-	
-	//For each resource with nodes scheduled, loop over the nodes and see if they
-	//are a predecessor or successor of this current node we are trying
-	//to schedule.
-	for(std::vector<std::pair<unsigned, std::vector<MSchedGraphNode*> > >::iterator schedNodeVec = J->second.begin(), SNE = J->second.end(); schedNodeVec != SNE; ++schedNodeVec) {
+      
+      if(!(*I)->isBranch()) {
+	//Loop over nodes in the schedule and determine if they are predecessors
+	//or successors of the node we are trying to schedule
+	for(MSSchedule::schedule_iterator nodesByCycle = schedule.begin(), nodesByCycleEnd = schedule.end(); 
+	    nodesByCycle != nodesByCycleEnd; ++nodesByCycle) {
 	  
-	  for(std::vector<MSchedGraphNode*>::iterator schedNode = schedNodeVec->second.begin(), schedNodeEnd = schedNodeVec->second.end(); schedNode != schedNodeEnd; ++schedNode) {
-	    if((*I)->isPredecessor(*schedNode) && !seenNodes.count(*schedNode)) {
+	  //For this cycle, get the vector of nodes schedule and loop over it
+	  for(std::vector<MSchedGraphNode*>::iterator schedNode = nodesByCycle->second.begin(), SNE = nodesByCycle->second.end(); schedNode != SNE; ++schedNode) {
+	    
+	    if((*I)->isPredecessor(*schedNode)) {
 	      if(!ignoreEdge(*schedNode, *I)) {
 		int diff = (*I)->getInEdge(*schedNode).getIteDiff();
-		int ES_Temp = J->first + (*schedNode)->getLatency() - diff * II;
-		DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << J->first << "\n");
+		int ES_Temp = nodesByCycle->first + (*schedNode)->getLatency() - diff * II;
+		DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n");
 		DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n");
 		EarlyStart = std::max(EarlyStart, ES_Temp);
 		hasPred = true;
 	      }
 	    }
-	    if((*I)->isSuccessor(*schedNode) && !seenNodes.count(*schedNode)) {
+	    if((*I)->isSuccessor(*schedNode)) {
 	      if(!ignoreEdge(*I,*schedNode)) {
 		int diff = (*schedNode)->getInEdge(*I).getIteDiff();
-		int LS_Temp = J->first - (*I)->getLatency() + diff * II;
-		DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << J->first << "\n");
+		int LS_Temp = nodesByCycle->first - (*I)->getLatency() + diff * II;
+		DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n");
 		DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n");
 		LateStart = std::min(LateStart, LS_Temp);
 		hasSucc = true;
 	      }
 	    }
-	    seenNodes.insert(*schedNode);
 	  }
 	}
       }
-      seenNodes.clear();
+      else {
+	//WARNING: HACK! FIXME!!!!
+	EarlyStart = II-1;
+	LateStart = II-1;
+	hasPred = 1;
+	hasSucc = 1;
+      }
+ 
       
       DEBUG(std::cerr << "Has Successors: " << hasSucc << ", Has Pred: " << hasPred << "\n");
       DEBUG(std::cerr << "EarlyStart: " << EarlyStart << ", LateStart: " << LateStart << "\n");
@@ -1058,6 +1067,13 @@
       }
      
     }
+
+    DEBUG(std::cerr << "Constructing Kernel\n");
+    success = schedule.constructKernel(II);
+    if(!success) {
+      ++II;
+      schedule.clear();
+    }
   } 
 }
 
@@ -1068,17 +1084,6 @@
 
   DEBUG(std::cerr << *node << " (Start Cycle: " << start << ", End Cycle: " << end << ")\n");
 
-  /*std::cerr << "CURRENT SCHEDULE\n";
-  //Dump out current schedule
-  for(std::map<unsigned, std::vector<std::pair<unsigned, MSchedGraphNode*> > >::iterator J = schedule.begin(), 
-	JE = schedule.end(); J != JE; ++J) {
-    std::cerr << "Cycle " << J->first << ":\n";
-    for(std::vector<std::pair<unsigned, MSchedGraphNode*> >::iterator VI = J->second.begin(), VE = J->second.end(); VI != VE; ++VI)
-      std::cerr << "Resource ID: " << VI->first << " by node " << *(VI->second) << "\n";
-  }
-  std::cerr << "END CURRENT SCHEDULE\n";
-  */
-
   //Make sure start and end are not negative
   if(start < 0)
     start = 0;
@@ -1089,10 +1094,7 @@
   if(start > end)
     forward = false;
 
-  const TargetSchedInfo & msi = target.getSchedInfo();
-
   bool increaseSC = true;
- 
   int cycle = start ;
 
 
@@ -1100,79 +1102,8 @@
     
     increaseSC = false;
 
-    //Get the resource used by this instruction
-    //Get resource usage for this instruction
-    InstrRUsage rUsage = msi.getInstrRUsage(node->getInst()->getOpcode());
-    std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
-
-    //Loop over each resource and see if we can put it into the schedule
-    for(unsigned r=0; r < resources.size(); ++r) {
-      unsigned intermediateCycle = cycle + r;
-      
-      for(unsigned j=0; j < resources[r].size(); ++j) {
-	//Put it into the schedule
-	DEBUG(std::cerr << "Attempting to put resource " << resources[r][j] << " in schedule at cycle: " << intermediateCycle << "\n");
-	
-	//Check if resource is free at this cycle
-	std::vector<std::pair<unsigned, std::vector<MSchedGraphNode*> > > resourceForCycle = schedule[intermediateCycle]; 
-      
-	//Vector of nodes using this resource
-	std::vector<MSchedGraphNode*> *nodesUsingResource;
-
-	for(std::vector<std::pair<unsigned, std::vector<MSchedGraphNode*> > >::iterator I = resourceForCycle.begin(), E= resourceForCycle.end(); I != E; ++I) {
-	
-	  if(I->first == resources[r][j]) {
-	    //Get the number of available for this resource
-	    unsigned numResource = CPUResource::getCPUResource(resources[r][j])->maxNumUsers;
-	    nodesUsingResource = &(I->second);
-
-	    //Check that there are enough of this resource, otherwise
-	    //we need to increase/decrease the cycle
-	    if(I->second.size() >= numResource) {
-	      DEBUG(std::cerr << "No open spot for this resource in this cycle\n");
-	      increaseSC = true;
-	    }
-	    break;
-		
-	  }
-	  //safe to put into schedule
-	}
-
-	if(increaseSC)
-	  break;
-
-	else {
-	  DEBUG(std::cerr << "Found spot in schedule\n");
-	  //Add node to resource vector
-	  if(nodesUsingResource == 0) {
-	    nodesUsingResource = new std::vector<MSchedGraphNode*>;
-	    resourceForCycle.push_back(std::make_pair(resources[r][j], *nodesUsingResource));
-	  }
-	  
-	  nodesUsingResource->push_back(node);
-	  
-	  schedule[intermediateCycle] = resourceForCycle;
-	}
-      }
-      if(increaseSC) {
-	/*for(unsigned x = 0; x < r; ++x) {
-	  unsigned removeCycle = x + start;
-	  for(unsigned j=0; j < resources[x].size(); ++j) {
-	    std::vector<std::pair<unsigned, MSchedGraphNode*> > resourceForCycle = schedule[removeCycle]; 
-	    for(std::vector<std::pair<unsigned,MSchedGraphNode*> >::iterator I = resourceForCycle.begin(), E= resourceForCycle.end(); I != E; ++I) {
-	      if(I->first == resources[x][j]) {
-		//remove it
-		resourceForCycle.erase(I);
-	      }
-	    }
-	    //Put vector back
-	    schedule[removeCycle] = resourceForCycle;
-	  }
-	  }*/
-	
-	break;
-      }
-    }
+    increaseSC = schedule.insert(node, cycle);
+    
     if(!increaseSC) 
       return true;
 
@@ -1190,5 +1121,202 @@
 	return false;
     }
   }
+
   return success;
 }
+
+/*void ModuloSchedulingPass::saveValue(const MachineInstr *inst, std::set<const Value*> &valuestoSave, std::vector<Value*> *valuesForNode) {
+  int numFound = 0;
+  Instruction *tmp;
+
+  //For each value* in this inst that is a def, we want to save a copy
+  //Target info
+  const TargetInstrInfo & mii = target.getInstrInfo();
+  for(unsigned i=0; i < inst->getNumOperands(); ++i) {
+    //get machine operand
+    const MachineOperand &mOp = inst->getOperand(i);
+    if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
+      //Save copy in tmpInstruction
+      numFound++;
+      tmp = TmpInstruction(mii.getMachineCodeFor(mOp.getVRegValue()),
+                 mOp.getVRegValue());
+      valuesForNode->push_back(tmp);
+    }
+  }
+
+  assert(numFound == 1 && "We should have only found one def to this virtual register!"); 
+}*/
+
+void ModuloSchedulingPass::writePrologue(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues) {
+  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())
+      continue;
+
+    //Put int the map so we know what instructions in each stage are in the kernel
+    if(I->second > 0)
+      inKernel[I->second].insert(I->first->getInst());
+  }
+
+  //Now write the prologues
+  for(std::map<int, std::set<const MachineInstr*> >::iterator I = inKernel.begin(), E = inKernel.end();
+      I != E; ++I) {
+    BasicBlock *llvmBB = new BasicBlock();
+    MachineBasicBlock *machineBB = new MachineBasicBlock(llvmBB);
+  
+    //Loop over original machine basic block. If we see an instruction from this
+    //stage that is NOT in the kernel, then it needs to be added into the prologue
+    //We go in order to preserve dependencies
+    for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
+      if(I->second.count(&*MI))
+	continue;
+      else
+	machineBB->push_back(MI->clone());
+    }
+
+    prologues.push_back(machineBB);
+    llvm_prologues.push_back(llvmBB);
+  }
+}
+
+
+void ModuloSchedulingPass::reconstructLoop(const MachineBasicBlock *BB) {
+
+  //The new loop will consist of an prologue, the kernel, and one or more epilogues.
+
+  std::vector<MachineBasicBlock*> prologues;
+  std::vector<BasicBlock*> llvm_prologues;
+
+
+
+  //create a vector of epilogues corresponding to each stage
+  /*std::vector<MachineBasicBlock*> epilogues;
+
+    //Create kernel
+  MachineBasicBlock *kernel = new MachineBasicBlock();
+
+  //keep track of stage count
+  int stageCount = 0;
+  
+  //Target info
+  const TargetInstrInfo & mii = target.getInstrInfo();
+
+  //Map for creating MachinePhis
+  std::map<MSchedGraphNode *, std::vector<Value*> > nodeAndValueMap; 
+  
+
+  //Loop through the kernel and clone instructions that need to be put into the prologue
+  for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
+    //For each pair see if the stage is greater then 0
+    //if so, then ALL instructions before this in the original loop, need to be
+    //copied into the prologue
+    MachineBasicBlock::const_iterator actualInst;
+
+
+    //ignore branch
+    if(I->first->isBranch())
+      continue;
+
+    if(I->second > 0) {
+
+      assert(I->second >= stageCount && "Visiting instruction from previous stage count.\n");
+
+      
+      //Make a set that has all the Value*'s that we read
+      std::set<const Value*> valuesToSave;
+
+      //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();
+      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.insert(srcI);
+	}
+	
+	if(mOp.getType() != MachineOperand::MO_VirtualRegister && mOp.isUse()) {
+	  assert("Our assumption is wrong. We have another type of register that needs to be saved\n");
+	}
+      }
+
+      //Check if we skipped a stage count, we need to add that stuff here
+      if(I->second - stageCount > 1) {
+	int temp = stageCount;
+	while(I->second - temp > 1) {
+	  for(MachineBasicBlock::const_iterator MI = BB->begin(), ME = BB->end(); ME != MI; ++MI) {
+	    //Check that MI is not a branch before adding, we add branches separately
+	    if(!mii.isBranch(MI->getOpcode()) && !mii.isNop(MI->getOpcode())) {
+	      prologue->push_back(MI->clone());
+	      saveValue(&*MI, valuesToSave);
+	    }
+	  }
+	  ++temp;
+	}
+      }
+
+      if(I->second == stageCount)
+	continue;
+
+      stageCount = I->second;
+      DEBUG(std::cerr << "Found Instruction from Stage > 0\n");
+      //Loop over instructions in original basic block and clone them. Add to the prologue
+      for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); MI != e; ++MI) {
+	if(&*MI == I->first->getInst()) {
+	  actualInst = MI;
+	  break;
+	}
+	else {
+	  //Check that MI is not a branch before adding, we add branches separately
+	  if(!mii.isBranch(MI->getOpcode()) && !mii.isNop(MI->getOpcode()))
+	    prologue->push_back(MI->clone());
+	}
+      }
+      
+      //Now add in all instructions from this one on to its corresponding epilogue
+      MachineBasicBlock *epi = new MachineBasicBlock();
+      epilogues.push_back(epi);
+
+      for(MachineBasicBlock::const_iterator MI = actualInst, ME = BB->end(); ME != MI; ++MI) {
+	//Check that MI is not a branch before adding, we add branches separately
+	if(!mii.isBranch(MI->getOpcode()) && !mii.isNop(MI->getOpcode()))
+	  epi->push_back(MI->clone());
+      }
+    }
+  }
+
+  //Create kernel
+   for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), 
+	 E = schedule.kernel_end(); I != E; ++I) {
+     kernel->push_back(I->first->getInst()->clone());
+     
+     }
+
+  //Debug stuff
+  ((MachineBasicBlock*)BB)->getParent()->getBasicBlockList().push_back(prologue);
+  std::cerr << "PROLOGUE:\n";
+  prologue->print(std::cerr);
+
+  ((MachineBasicBlock*)BB)->getParent()->getBasicBlockList().push_back(kernel);
+  std::cerr << "KERNEL: \n";
+  kernel->print(std::cerr);
+
+  for(std::vector<MachineBasicBlock*>::iterator MBB = epilogues.begin(), ME = epilogues.end();
+      MBB != ME; ++MBB) {
+    std::cerr << "EPILOGUE:\n";
+    ((MachineBasicBlock*)BB)->getParent()->getBasicBlockList().push_back(*MBB);
+    (*MBB)->print(std::cerr);
+    }*/
+
+
+
+}
+


Index: llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h
diff -u llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.12 llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.13
--- llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h:1.12	Sat May  8 11:12:10 2004
+++ llvm/lib/CodeGen/ModuloScheduling/ModuloScheduling.h	Wed May 26 01:27:18 2004
@@ -14,6 +14,7 @@
 #define LLVM_MODULOSCHEDULING_H
 
 #include "MSchedGraph.h"
+#include "MSSchedule.h"
 #include "llvm/Function.h"
 #include "llvm/Pass.h"
 #include <set>
@@ -54,7 +55,7 @@
     std::vector<MSchedGraphNode*> FinalNodeOrder;
 
     //Schedule table, key is the cycle number and the vector is resource, node pairs
-    std::map<unsigned, std::vector<std::pair<unsigned, std::vector<MSchedGraphNode*> > > > schedule;
+    MSSchedule schedule;
 
     //Current initiation interval
     int II;
@@ -87,6 +88,12 @@
 
     void predIntersect(std::vector<MSchedGraphNode*> &CurrentSet, std::vector<MSchedGraphNode*> &IntersectResult);
     void succIntersect(std::vector<MSchedGraphNode*> &CurrentSet, std::vector<MSchedGraphNode*> &IntersectResult);
+    
+    void reconstructLoop(const MachineBasicBlock*);
+    
+    //void saveValue(const MachineInstr*, const std::set<Value*>&, std::vector<Value*>*);
+
+    void writePrologue(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues);
 
   public:
     ModuloSchedulingPass(TargetMachine &targ) : target(targ) {}





More information about the llvm-commits mailing list