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