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:
Tanya Lattner 2004-11-16 21:31:37 +00:00
parent 6d7c8d6801
commit 7beb51cd29
2 changed files with 63 additions and 44 deletions

View File

@ -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)

View File

@ -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);