forked from OSchip/llvm-project
				
			Added my own defMap. Only saving values that are not loop invariant. Fixed a couple of assertions that were triggered due to registers not being allocated. These both had to do with PHINodes.
llvm-svn: 17907
This commit is contained in:
		
							parent
							
								
									6d7c8d6801
								
							
						
					
					
						commit
						7beb51cd29
					
				| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//===-- ModuloScheduling.cpp - ModuloScheduling  ----------------*- C++ -*-===//
 | 
					//===-- ModuloScheduling.cpp - ModuloScheduling  ----------------*- C++ -*-===//
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//                     The LLVM Compiler Infrastructure
 | 
					//                     The LLVM Compiler Infrastructure
 | 
				
			||||||
| 
						 | 
					@ -122,6 +123,7 @@ namespace llvm {
 | 
				
			||||||
bool ModuloSchedulingPass::runOnFunction(Function &F) {
 | 
					bool ModuloSchedulingPass::runOnFunction(Function &F) {
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  bool Changed = false;
 | 
					  bool Changed = false;
 | 
				
			||||||
 | 
					  int numMS = 0;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  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");
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
| 
						 | 
					@ -139,37 +141,14 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  defaultInst = 0;
 | 
					  defaultInst = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //If we have a basic block to schedule, create our def map
 | 
					 | 
				
			||||||
  if(Worklist.size() > 0) {
 | 
					 | 
				
			||||||
    for(MachineFunction::iterator BI = MF.begin(); BI != MF.end(); ++BI) {
 | 
					 | 
				
			||||||
      for(MachineBasicBlock::iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
 | 
					 | 
				
			||||||
	for(unsigned opNum = 0; opNum < I->getNumOperands(); ++opNum) {
 | 
					 | 
				
			||||||
	  const MachineOperand &mOp = I->getOperand(opNum);
 | 
					 | 
				
			||||||
	  if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
 | 
					 | 
				
			||||||
	    defMap[mOp.getVRegValue()] = &*I;
 | 
					 | 
				
			||||||
	  }
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	    //See if we can use this Value* as our defaultInst
 | 
					 | 
				
			||||||
	  if(!defaultInst && mOp.getType() == MachineOperand::MO_VirtualRegister) {
 | 
					 | 
				
			||||||
	    Value *V = mOp.getVRegValue();
 | 
					 | 
				
			||||||
	    if(!isa<TmpInstruction>(V) && !isa<Argument>(V) && !isa<Constant>(V))
 | 
					 | 
				
			||||||
	      defaultInst = (Instruction*) V;
 | 
					 | 
				
			||||||
	  }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  assert(defaultInst && "We must have a default instruction to use as our main point to add to machine code for instruction\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DEBUG(std::cerr << "Default Instruction: " << *defaultInst << "\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DEBUG(if(Worklist.size() == 0) std::cerr << "No single basic block loops in function to ModuloSchedule\n");
 | 
					  DEBUG(if(Worklist.size() == 0) std::cerr << "No single basic block loops in function to ModuloSchedule\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //Iterate over the worklist and perform scheduling
 | 
					  //Iterate over the worklist and perform scheduling
 | 
				
			||||||
  for(std::vector<MachineBasicBlock*>::iterator BI = Worklist.begin(),  
 | 
					  for(std::vector<MachineBasicBlock*>::iterator BI = Worklist.begin(),  
 | 
				
			||||||
	BE = Worklist.end(); BI != BE; ++BI) {
 | 
						BE = Worklist.end(); BI != BE; ++BI) {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    CreateDefMap(*BI);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MSchedGraph *MSG = new MSchedGraph(*BI, target);
 | 
					    MSchedGraph *MSG = new MSchedGraph(*BI, target);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    //Write Graph out to file
 | 
					    //Write Graph out to file
 | 
				
			||||||
| 
						 | 
					@ -234,11 +213,13 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
 | 
				
			||||||
    //Print out final schedule
 | 
					    //Print out final schedule
 | 
				
			||||||
    DEBUG(schedule.print(std::cerr));
 | 
					    DEBUG(schedule.print(std::cerr));
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					 | 
				
			||||||
    //Final scheduling step is to reconstruct the loop only if we actual have
 | 
					    //Final scheduling step is to reconstruct the loop only if we actual have
 | 
				
			||||||
    //stage > 0
 | 
					    //stage > 0
 | 
				
			||||||
    if(schedule.getMaxStage() != 0)
 | 
					    if(schedule.getMaxStage() != 0) {
 | 
				
			||||||
      reconstructLoop(*BI);
 | 
					      reconstructLoop(*BI);
 | 
				
			||||||
 | 
					      numMS++;
 | 
				
			||||||
 | 
					      Changed = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    else
 | 
					    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\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -248,7 +229,7 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
 | 
				
			||||||
    recurrenceList.clear();
 | 
					    recurrenceList.clear();
 | 
				
			||||||
    FinalNodeOrder.clear();
 | 
					    FinalNodeOrder.clear();
 | 
				
			||||||
    schedule.clear();
 | 
					    schedule.clear();
 | 
				
			||||||
 | 
					    defMap.clear();
 | 
				
			||||||
    //Clean up. Nuke old MachineBB and llvmBB
 | 
					    //Clean up. Nuke old MachineBB and llvmBB
 | 
				
			||||||
    //BasicBlock *llvmBB = (BasicBlock*) (*BI)->getBasicBlock();
 | 
					    //BasicBlock *llvmBB = (BasicBlock*) (*BI)->getBasicBlock();
 | 
				
			||||||
    //Function *parent = (Function*) llvmBB->getParent();
 | 
					    //Function *parent = (Function*) llvmBB->getParent();
 | 
				
			||||||
| 
						 | 
					@ -261,10 +242,32 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 | 
					  DEBUG(std::cerr << "Number of Loop Candidates: " << Worklist.size() << "\n Number ModuloScheduled: " << numMS << "\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return Changed;
 | 
					  return Changed;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ModuloSchedulingPass::CreateDefMap(MachineBasicBlock *BI) {
 | 
				
			||||||
 | 
					  defaultInst = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for(MachineBasicBlock::iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
 | 
				
			||||||
 | 
					    for(unsigned opNum = 0; opNum < I->getNumOperands(); ++opNum) {
 | 
				
			||||||
 | 
					      const MachineOperand &mOp = I->getOperand(opNum);
 | 
				
			||||||
 | 
					      if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
 | 
				
			||||||
 | 
						defMap[mOp.getVRegValue()] = &*I;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      //See if we can use this Value* as our defaultInst
 | 
				
			||||||
 | 
					      if(!defaultInst && mOp.getType() == MachineOperand::MO_VirtualRegister) {
 | 
				
			||||||
 | 
						Value *V = mOp.getVRegValue();
 | 
				
			||||||
 | 
						if(!isa<TmpInstruction>(V) && !isa<Argument>(V) && !isa<Constant>(V) && !isa<PHINode>(V))
 | 
				
			||||||
 | 
						  defaultInst = (Instruction*) V;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  assert(defaultInst && "We must have a default instruction to use as our main point to add to machine code for instruction\n");
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
/// This function checks if a Machine Basic Block is valid for modulo
 | 
					/// This function checks if a Machine Basic Block is valid for modulo
 | 
				
			||||||
/// scheduling. This means that it has no control flow (if/else or
 | 
					/// scheduling. This means that it has no control flow (if/else or
 | 
				
			||||||
/// calls) in the block.  Currently ModuloScheduling only works on
 | 
					/// calls) in the block.  Currently ModuloScheduling only works on
 | 
				
			||||||
| 
						 | 
					@ -1482,6 +1485,8 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
 | 
				
			||||||
   //Insert into machine basic block
 | 
					   //Insert into machine basic block
 | 
				
			||||||
   machineBB->push_back(instClone);
 | 
					   machineBB->push_back(instClone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   DEBUG(std::cerr <<  "Cloned Inst: " << *instClone << "\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   if(I->first->isBranch()) {
 | 
					   if(I->first->isBranch()) {
 | 
				
			||||||
     //Add kernel noop
 | 
					     //Add kernel noop
 | 
				
			||||||
     BuildMI(machineBB, V9::NOP, 0);
 | 
					     BuildMI(machineBB, V9::NOP, 0);
 | 
				
			||||||
| 
						 | 
					@ -1502,18 +1507,26 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	 //If its in the value saved, we need to create a temp instruction and use that instead
 | 
						 //If its in the value saved, we need to create a temp instruction and use that instead
 | 
				
			||||||
	 if(valuesToSave.count(mOp.getVRegValue())) {
 | 
						 if(valuesToSave.count(mOp.getVRegValue())) {
 | 
				
			||||||
	   TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	   //Get machine code for this instruction
 | 
						   //Check if we already have a final PHI value for this
 | 
				
			||||||
	   MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
 | 
						   if(!finalPHIValue.count(mOp.getVRegValue())) {
 | 
				
			||||||
	   tempMvec.addTemp((Value*) tmp);
 | 
						     TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
 | 
				
			||||||
	     
 | 
						     
 | 
				
			||||||
	   //Update the operand in the cloned instruction
 | 
						     //Get machine code for this instruction
 | 
				
			||||||
	   instClone->getOperand(i).setValueReg(tmp);
 | 
						     MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
 | 
				
			||||||
 | 
						     tempMvec.addTemp((Value*) tmp);
 | 
				
			||||||
	     
 | 
						     
 | 
				
			||||||
	   //save this as our final phi
 | 
						     //Update the operand in the cloned instruction
 | 
				
			||||||
	   finalPHIValue[mOp.getVRegValue()] = tmp;
 | 
						     instClone->getOperand(i).setValueReg(tmp);
 | 
				
			||||||
	   newValLocation[tmp] = machineBB;
 | 
						     
 | 
				
			||||||
 | 
						     //save this as our final phi
 | 
				
			||||||
 | 
						     finalPHIValue[mOp.getVRegValue()] = tmp;
 | 
				
			||||||
 | 
						     newValLocation[tmp] = machineBB;
 | 
				
			||||||
 | 
						   }
 | 
				
			||||||
 | 
						   else {
 | 
				
			||||||
 | 
						     //Use the previous final phi value
 | 
				
			||||||
 | 
						     instClone->getOperand(i).setValueReg(finalPHIValue[mOp.getVRegValue()]); 
 | 
				
			||||||
 | 
						   }
 | 
				
			||||||
	 }
 | 
						 }
 | 
				
			||||||
       }
 | 
					       }
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
| 
						 | 
					@ -1802,7 +1815,7 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
 | 
				
			||||||
	  //find the value in the map
 | 
						  //find the value in the map
 | 
				
			||||||
	  if (const Value* srcI = mOp.getVRegValue()) {
 | 
						  if (const Value* srcI = mOp.getVRegValue()) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    if(isa<Constant>(srcI) || isa<Argument>(srcI))
 | 
						    if(isa<Constant>(srcI) || isa<Argument>(srcI) || isa<PHINode>(srcI))
 | 
				
			||||||
	      continue;
 | 
						      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    //Before we declare this Value* one that we should save
 | 
						    //Before we declare this Value* one that we should save
 | 
				
			||||||
| 
						 | 
					@ -1813,13 +1826,18 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
 | 
				
			||||||
	    //Should we save this value?
 | 
						    //Should we save this value?
 | 
				
			||||||
	    bool save = true;
 | 
						    bool save = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    //Assert if not in the def map
 | 
						    //Continue if not in the def map, loop invariant code does not need to be saved
 | 
				
			||||||
	    assert(defMap.count(srcI) && "No entry for this Value* definition in our map"); 
 | 
						    if(!defMap.count(srcI))
 | 
				
			||||||
 | 
						      continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    MachineInstr *defInstr = defMap[srcI];
 | 
						    MachineInstr *defInstr = defMap[srcI];
 | 
				
			||||||
	    
 | 
						    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    if(lastInstrs.count(defInstr)) {
 | 
						    if(lastInstrs.count(defInstr)) {
 | 
				
			||||||
	      if(lastInstrs[defInstr] == I->second) 
 | 
						      if(lastInstrs[defInstr] == I->second) {
 | 
				
			||||||
		save = false;
 | 
							save = false;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						      }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    
 | 
						    
 | 
				
			||||||
	    if(save)
 | 
						    if(save)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +67,7 @@ namespace llvm {
 | 
				
			||||||
    int II;
 | 
					    int II;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Internal functions
 | 
					    //Internal functions
 | 
				
			||||||
 | 
					    void CreateDefMap(MachineBasicBlock *BI);
 | 
				
			||||||
    bool MachineBBisValid(const MachineBasicBlock *BI);
 | 
					    bool MachineBBisValid(const MachineBasicBlock *BI);
 | 
				
			||||||
    int calculateResMII(const MachineBasicBlock *BI);
 | 
					    int calculateResMII(const MachineBasicBlock *BI);
 | 
				
			||||||
    int calculateRecMII(MSchedGraph *graph, int MII);
 | 
					    int calculateRecMII(MSchedGraph *graph, int MII);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue