Checking in code that works on my simple test case. However, there is still a bug with branches that I need to fix.

llvm-svn: 16979
This commit is contained in:
Tanya Lattner 2004-10-14 06:04:28 +00:00
parent 189f3dc8d2
commit d38a7605d8
1 changed files with 205 additions and 104 deletions

View File

@ -1192,16 +1192,14 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
int maxStageCount = 0; int maxStageCount = 0;
MSchedGraphNode *branch = 0; MSchedGraphNode *branch = 0;
MSchedGraphNode *BAbranch = 0;
for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) { for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
maxStageCount = std::max(maxStageCount, I->second); maxStageCount = std::max(maxStageCount, I->second);
//Ignore the branch, we will handle this separately //Ignore the branch, we will handle this separately
if(I->first->isBranch()) { if(I->first->isBranch()) {
if (I->first->getInst()->getOpcode() == V9::BA) if (I->first->getInst()->getOpcode() != V9::BA)
BAbranch = I->first;
else
branch = I->first; branch = I->first;
continue; continue;
} }
@ -1241,6 +1239,10 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
//Save copy in tmpInstruction //Save copy in tmpInstruction
tmp = new TmpInstruction(mOp.getVRegValue()); tmp = new TmpInstruction(mOp.getVRegValue());
//Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get((Instruction*) mOp.getVRegValue());
tempMvec.addTemp((Value*) tmp);
DEBUG(std::cerr << "Value: " << *(mOp.getVRegValue()) << " New Value: " << *tmp << " Stage: " << i << "\n"); DEBUG(std::cerr << "Value: " << *(mOp.getVRegValue()) << " New Value: " << *tmp << " Stage: " << i << "\n");
newValues[mOp.getVRegValue()][i]= tmp; newValues[mOp.getVRegValue()][i]= tmp;
@ -1275,8 +1277,6 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
//Stick in branch at the end //Stick in branch at the end
machineBB->push_back(branch->getInst()->clone()); 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); (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
prologues.push_back(machineBB); prologues.push_back(machineBB);
@ -1322,7 +1322,7 @@ void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epil
DEBUG(std::cerr << " Epilogue #: " << i << "\n"); DEBUG(std::cerr << " Epilogue #: " << i << "\n");
std::map<Value*, int> inEpilogue;
for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) { for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
for(int j=schedule.getMaxStage(); j > i; --j) { for(int j=schedule.getMaxStage(); j > i; --j) {
@ -1334,19 +1334,25 @@ void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epil
for(unsigned opNum=0; opNum < clone->getNumOperands(); ++opNum) { for(unsigned opNum=0; opNum < clone->getNumOperands(); ++opNum) {
//get machine operand //get machine operand
const MachineOperand &mOp = clone->getOperand(opNum); 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())) { if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse())) {
DEBUG(std::cerr << "Writing PHI for " << *(mOp.getVRegValue()) << "\n"); DEBUG(std::cerr << "Writing PHI for " << *(mOp.getVRegValue()) << "\n");
//If this is the last instructions for the max iterations ago, don't update operands
if(inEpilogue.count(mOp.getVRegValue()))
if(inEpilogue[mOp.getVRegValue()] == i)
continue;
//Quickly write appropriate phis for this operand //Quickly write appropriate phis for this operand
if(newValues.count(mOp.getVRegValue())) { if(newValues.count(mOp.getVRegValue())) {
if(newValues[mOp.getVRegValue()].count(i)) { if(newValues[mOp.getVRegValue()].count(i)) {
Instruction *tmp = new TmpInstruction(newValues[mOp.getVRegValue()][i]); Instruction *tmp = new TmpInstruction(newValues[mOp.getVRegValue()][i]);
//Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get((Instruction*) mOp.getVRegValue());
tempMvec.addTemp((Value*) tmp);
MachineInstr *saveValue = BuildMI(machineBB, V9::PHI, 3).addReg(newValues[mOp.getVRegValue()][i]).addReg(kernelPHIs[mOp.getVRegValue()][i]).addRegDef(tmp); 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"); DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
valPHIs[mOp.getVRegValue()] = tmp; valPHIs[mOp.getVRegValue()] = tmp;
@ -1358,6 +1364,9 @@ void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epil
clone->getOperand(opNum).setValueReg(valPHIs[mOp.getVRegValue()]); clone->getOperand(opNum).setValueReg(valPHIs[mOp.getVRegValue()]);
} }
} }
else if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef())) {
inEpilogue[mOp.getVRegValue()] = i;
}
} }
machineBB->push_back(clone); machineBB->push_back(clone);
} }
@ -1392,6 +1401,10 @@ 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);
if(I->first->isBranch()) {
//Add kernel noop
BuildMI(machineBB, V9::NOP, 0);
}
//Loop over Machine Operands //Loop over Machine Operands
for(unsigned i=0; i < inst->getNumOperands(); ++i) { for(unsigned i=0; i < inst->getNumOperands(); ++i) {
@ -1409,6 +1422,10 @@ 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()); TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
//Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get((Instruction*) mOp.getVRegValue());
tempMvec.addTemp((Value*) tmp);
//Update the operand in the cloned instruction //Update the operand in the cloned instruction
instClone->getOperand(i).setValueReg(tmp); instClone->getOperand(i).setValueReg(tmp);
@ -1425,6 +1442,10 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue()); TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
//Get machine code for this instruction
MachineCodeForInstruction & tempVec = MachineCodeForInstruction::get((Instruction*) mOp.getVRegValue());
tempVec.addTemp((Value*) tmp);
//Create new machine instr and put in MBB //Create new machine instr and put in MBB
MachineInstr *saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp); MachineInstr *saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
@ -1476,12 +1497,23 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
if(count < (V->second).size()) { if(count < (V->second).size()) {
if(lastPhi == 0) { if(lastPhi == 0) {
lastPhi = new TmpInstruction(I->second); lastPhi = new TmpInstruction(I->second);
//Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get((Instruction*) V->first);
tempMvec.addTemp((Value*) lastPhi);
MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(kernelValue[V->first]).addReg(I->second).addRegDef(lastPhi); 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"); DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
newValLocation[lastPhi] = machineBB; newValLocation[lastPhi] = machineBB;
} }
else { else {
Instruction *tmp = new TmpInstruction(I->second); Instruction *tmp = new TmpInstruction(I->second);
//Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get((Instruction*) V->first);
tempMvec.addTemp((Value*) tmp);
MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(tmp); MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(tmp);
DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n"); DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
lastPhi = tmp; lastPhi = tmp;
@ -1513,60 +1545,97 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
//Worklist to delete things //Worklist to delete things
std::vector<std::pair<MachineBasicBlock*, MachineBasicBlock::iterator> > worklist; std::vector<std::pair<MachineBasicBlock*, MachineBasicBlock::iterator> > worklist;
//Worklist of TmpInstructions that need to be added to a MCFI
std::vector<Instruction*> addToMCFI;
//Worklist to add OR instructions to end of kernel so not to invalidate the iterator
//std::vector<std::pair<Instruction*, Value*> > newORs;
const TargetInstrInfo *TMI = target.getInstrInfo(); const TargetInstrInfo *TMI = target.getInstrInfo();
//Start with the kernel and for each phi insert a copy for the phi def and for each arg //Start with the kernel and for each phi insert a copy for the phi def and for each arg
for(MachineBasicBlock::iterator I = kernelBB->begin(), E = kernelBB->end(); I != E; ++I) { for(MachineBasicBlock::iterator I = kernelBB->begin(), E = kernelBB->end(); I != E; ++I) {
//Get op code and check if its a phi //Get op code and check if its a phi
if(I->getOpcode() == V9::PHI) { if(I->getOpcode() == V9::PHI) {
Instruction *tmp = 0;
for(unsigned i = 0; i < I->getNumOperands(); ++i) { DEBUG(std::cerr << "Replacing PHI: " << *I << "\n");
//Get Operand Instruction *tmp = 0;
const MachineOperand &mOp = I->getOperand(i);
assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
if(!tmp) {
tmp = new TmpInstruction(mOp.getVRegValue());
}
//Now for all our arguments we read, OR to the new TmpInstruction that we created for(unsigned i = 0; i < I->getNumOperands(); ++i) {
if(mOp.isUse()) { //Get Operand
DEBUG(std::cerr << "Use: " << mOp << "\n"); const MachineOperand &mOp = I->getOperand(i);
//Place a copy at the end of its BB but before the branches assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
assert(newValLocation.count(mOp.getVRegValue()) && "We must know where this value is located\n");
//Reverse iterate to find the branches, we can safely assume no instructions have been if(!tmp) {
//put in the nop positions tmp = new TmpInstruction(mOp.getVRegValue());
for(MachineBasicBlock::iterator inst = --(newValLocation[mOp.getVRegValue()])->end(), endBB = (newValLocation[mOp.getVRegValue()])->begin(); inst != endBB; --inst) { addToMCFI.push_back(tmp);
MachineOpCode opc = inst->getOpcode(); }
if(TMI->isBranch(opc) || TMI->isNop(opc))
continue;
else {
BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
break;
}
}
} //Now for all our arguments we read, OR to the new TmpInstruction that we created
else { if(mOp.isUse()) {
//Remove the phi and replace it with an OR DEBUG(std::cerr << "Use: " << mOp << "\n");
DEBUG(std::cerr << "Def: " << mOp << "\n"); //Place a copy at the end of its BB but before the branches
BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue()); assert(newValLocation.count(mOp.getVRegValue()) && "We must know where this value is located\n");
worklist.push_back(std::make_pair(kernelBB, I)); //Reverse iterate to find the branches, we can safely assume no instructions have been
} //put in the nop positions
for(MachineBasicBlock::iterator inst = --(newValLocation[mOp.getVRegValue()])->end(), endBB = (newValLocation[mOp.getVRegValue()])->begin(); inst != endBB; --inst) {
MachineOpCode opc = inst->getOpcode();
if(TMI->isBranch(opc) || TMI->isNop(opc))
continue;
else {
BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
break;
}
}
} }
} else {
//Remove the phi and replace it with an OR
DEBUG(std::cerr << "Def: " << mOp << "\n");
//newORs.push_back(std::make_pair(tmp, mOp.getVRegValue()));
BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue());
worklist.push_back(std::make_pair(kernelBB, I));
}
}
}
else {
//We found an instruction that we can add to its mcfi
if(addToMCFI.size() > 0) {
for(unsigned i = 0; i < I->getNumOperands(); ++i) {
const MachineOperand &mOp = I->getOperand(i);
if(mOp.getType() == MachineOperand::MO_VirtualRegister) {
if(!isa<TmpInstruction>(mOp.getVRegValue()) && !isa<PHINode>(mOp.getVRegValue())) {
//Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get((Instruction*) mOp.getVRegValue());
for(unsigned x = 0; x < addToMCFI.size(); ++x) {
tempMvec.addTemp(addToMCFI[x]);
}
addToMCFI.clear();
break;
}
}
}
}
}
} }
//for(std::vector<std::pair<Instruction*, Value*> >::reverse_iterator I = newORs.rbegin(), IE = newORs.rend(); I != IE; ++I)
//BuildMI(*kernelBB, kernelBB->begin(), V9::ORr, 3).addReg(I->first).addImm(0).addRegDef(I->second);
//Remove phis from epilogue //Remove phis from epilogue
for(std::vector<MachineBasicBlock*>::iterator MB = epilogues.begin(), ME = epilogues.end(); MB != ME; ++MB) { for(std::vector<MachineBasicBlock*>::iterator MB = epilogues.begin(), ME = epilogues.end(); MB != ME; ++MB) {
for(MachineBasicBlock::iterator I = (*MB)->begin(), E = (*MB)->end(); I != E; ++I) { for(MachineBasicBlock::iterator I = (*MB)->begin(), E = (*MB)->end(); I != E; ++I) {
//Get op code and check if its a phi //Get op code and check if its a phi
if(I->getOpcode() == V9::PHI) { if(I->getOpcode() == V9::PHI) {
Instruction *tmp = 0; Instruction *tmp = 0;
for(unsigned i = 0; i < I->getNumOperands(); ++i) { for(unsigned i = 0; i < I->getNumOperands(); ++i) {
//Get Operand //Get Operand
const MachineOperand &mOp = I->getOperand(i); const MachineOperand &mOp = I->getOperand(i);
@ -1574,6 +1643,7 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
if(!tmp) { if(!tmp) {
tmp = new TmpInstruction(mOp.getVRegValue()); tmp = new TmpInstruction(mOp.getVRegValue());
addToMCFI.push_back(tmp);
} }
//Now for all our arguments we read, OR to the new TmpInstruction that we created //Now for all our arguments we read, OR to the new TmpInstruction that we created
@ -1593,7 +1663,7 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
} }
} }
} }
else { else {
//Remove the phi and replace it with an OR //Remove the phi and replace it with an OR
@ -1604,16 +1674,40 @@ void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vect
} }
} }
else {
//We found an instruction that we can add to its mcfi
if(addToMCFI.size() > 0) {
for(unsigned i = 0; i < I->getNumOperands(); ++i) {
const MachineOperand &mOp = I->getOperand(i);
if(mOp.getType() == MachineOperand::MO_VirtualRegister) {
if(!isa<TmpInstruction>(mOp.getVRegValue()) && !isa<PHINode>(mOp.getVRegValue())) {
//Get machine code for this instruction
MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get((Instruction*) mOp.getVRegValue());
for(unsigned x = 0; x < addToMCFI.size(); ++x) {
tempMvec.addTemp(addToMCFI[x]);
}
addToMCFI.clear();
break;
}
}
}
}
}
} }
} }
//Delete the phis //Delete the phis
for(std::vector<std::pair<MachineBasicBlock*, MachineBasicBlock::iterator> >::iterator I = worklist.begin(), E = worklist.end(); I != E; ++I) { 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");
DEBUG(std::cerr << "Deleting PHI " << *I->second << "\n");
I->first->erase(I->second); I->first->erase(I->second);
} }
assert((addToMCFI.size() == 0) && "We should have added all TmpInstructions to some MachineCodeForInstruction");
} }
@ -1744,30 +1838,34 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
} }
} }
//Update branch //Update branch
for(unsigned opNum = 0; opNum < branch->getNumOperands(); ++opNum) { for(unsigned opNum = 0; opNum < branch->getNumOperands(); ++opNum) {
MachineOperand &mOp = branch->getOperand(opNum); MachineOperand &mOp = branch->getOperand(opNum);
if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) { if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
mOp.setValueReg(llvm_epilogues[(llvm_epilogues.size()-1-I)]); mOp.setValueReg(llvm_epilogues[(llvm_epilogues.size()-1-I)]);
} }
} }
//Update llvm basic block with our new branch instr //Update llvm basic block with our new branch instr
DEBUG(std::cerr << BB->getBasicBlock()->getTerminator() << "\n"); DEBUG(std::cerr << BB->getBasicBlock()->getTerminator() << "\n");
const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator()); const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
TmpInstruction *tmp = new TmpInstruction(branchVal->getCondition()); //TmpInstruction *tmp = new TmpInstruction(branchVal->getCondition());
//Add TmpInstruction to original branches MCFI
//MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(branchVal);
//tempMvec.addTemp((Value*) tmp);
if(I == prologues.size()-1) { if(I == prologues.size()-1) {
TerminatorInst *newBranch = new BranchInst(llvmKernelBB, TerminatorInst *newBranch = new BranchInst(llvmKernelBB,
llvm_epilogues[(llvm_epilogues.size()-1-I)], llvm_epilogues[(llvm_epilogues.size()-1-I)],
tmp, branchVal->getCondition(),
llvm_prologues[I]); llvm_prologues[I]);
} }
else else
TerminatorInst *newBranch = new BranchInst(llvm_prologues[I+1], TerminatorInst *newBranch = new BranchInst(llvm_prologues[I+1],
llvm_epilogues[(llvm_epilogues.size()-1-I)], llvm_epilogues[(llvm_epilogues.size()-1-I)],
tmp, branchVal->getCondition(),
llvm_prologues[I]); llvm_prologues[I]);
assert(branch != 0 && "There must be a terminator for this machine basic block!\n"); assert(branch != 0 && "There must be a terminator for this machine basic block!\n");
@ -1776,8 +1874,9 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
BuildMI(prologues[I], V9::NOP, 0); BuildMI(prologues[I], V9::NOP, 0);
//Add a unconditional branch to the next prologue //Add a unconditional branch to the next prologue
if(I != prologues.size()-1) if(I != prologues.size()-1) {
BuildMI(prologues[I], V9::BA, 1).addPCDisp(llvm_prologues[I+1]); BuildMI(prologues[I], V9::BA, 1).addPCDisp(llvm_prologues[I+1]);
}
else else
BuildMI(prologues[I], V9::BA, 1).addPCDisp(llvmKernelBB); BuildMI(prologues[I], V9::BA, 1).addPCDisp(llvmKernelBB);
@ -1787,12 +1886,18 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
//Fix up kernel machine branches //Fix up kernel machine branches
MachineInstr *branch = 0; MachineInstr *branch = 0;
MachineInstr *BAbranch = 0;
for(MachineBasicBlock::reverse_iterator mInst = machineKernelBB->rbegin(), mInstEnd = machineKernelBB->rend(); mInst != mInstEnd; ++mInst) { for(MachineBasicBlock::reverse_iterator mInst = machineKernelBB->rbegin(), mInstEnd = machineKernelBB->rend(); mInst != mInstEnd; ++mInst) {
MachineOpCode OC = mInst->getOpcode(); MachineOpCode OC = mInst->getOpcode();
if(TMI->isBranch(OC)) { if(TMI->isBranch(OC)) {
branch = &*mInst; if(mInst->getOpcode() == V9::BA) {
DEBUG(std::cerr << *mInst << "\n"); BAbranch = &*mInst;
break; }
else {
branch = &*mInst;
break;
}
} }
} }
@ -1807,27 +1912,39 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
} }
} }
Value *origBAVal = 0;
//Update kernel BA branch
for(unsigned opNum = 0; opNum < BAbranch->getNumOperands(); ++opNum) {
MachineOperand &mOp = BAbranch->getOperand(opNum);
if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
origBAVal = mOp.getVRegValue();
if(llvm_epilogues.size() > 0)
mOp.setValueReg(llvm_epilogues[0]);
}
}
assert((origBAVal != 0) && "Could not find original branch always value");
//Update kernelLLVM branches //Update kernelLLVM branches
const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator()); const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
//TmpInstruction *tmp = new TmpInstruction(branchVal->getCondition());
//Add TmpInstruction to original branches MCFI
//MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(branchVal);
//tempMvec.addTemp((Value*) tmp);
TerminatorInst *newBranch = new BranchInst(llvmKernelBB, TerminatorInst *newBranch = new BranchInst(llvmKernelBB,
llvm_epilogues[0], llvm_epilogues[0],
new TmpInstruction(branchVal->getCondition()), branchVal->getCondition(),
llvmKernelBB); llvmKernelBB);
//Add kernel noop
BuildMI(machineKernelBB, V9::NOP, 0);
//Add unconditional branch to first epilogue
BuildMI(machineKernelBB, V9::BA, 1).addPCDisp(llvm_epilogues[0]);
//Add kernel noop
BuildMI(machineKernelBB, V9::NOP, 0);
//Lastly add unconditional branches for the epilogues //Lastly add unconditional branches for the epilogues
for(unsigned I = 0; I < epilogues.size(); ++I) { for(unsigned I = 0; I < epilogues.size(); ++I) {
//Now since I don't trust fall throughs, add a unconditional branch to the next prologue //Now since we don't have fall throughs, add a unconditional branch to the next prologue
if(I != epilogues.size()-1) { if(I != epilogues.size()-1) {
BuildMI(epilogues[I], V9::BA, 1).addPCDisp(llvm_epilogues[I+1]); BuildMI(epilogues[I], V9::BA, 1).addPCDisp(llvm_epilogues[I+1]);
//Add unconditional branch to end of epilogue //Add unconditional branch to end of epilogue
@ -1835,41 +1952,25 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
llvm_epilogues[I]); llvm_epilogues[I]);
} }
else { else {
MachineBasicBlock *origBlock = (MachineBasicBlock*) BB; BuildMI(epilogues[I], V9::BA, 1).addPCDisp(origBAVal);
for(MachineBasicBlock::reverse_iterator inst = origBlock->rbegin(), instEnd = origBlock->rend(); inst != instEnd; ++inst) {
MachineOpCode OC = inst->getOpcode();
if(TMI->isBranch(OC)) {
branch = &*inst;
DEBUG(std::cerr << "Exit branch from loop" << *inst << "\n");
break;
}
for(unsigned opNum = 0; opNum < branch->getNumOperands(); ++opNum) {
MachineOperand &mOp = branch->getOperand(opNum);
if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
BuildMI(epilogues[I], V9::BA, 1).addPCDisp(mOp.getVRegValue());
break;
}
}
}
//Update last epilogue exit branch //Update last epilogue exit branch
BranchInst *branchVal = (BranchInst*) dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator()); BranchInst *branchVal = (BranchInst*) dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
//Find where we are supposed to branch to //Find where we are supposed to branch to
BasicBlock *nextBlock = 0; BasicBlock *nextBlock = 0;
for(unsigned j=0; j <branchVal->getNumSuccessors(); ++j) { for(unsigned j=0; j <branchVal->getNumSuccessors(); ++j) {
if(branchVal->getSuccessor(j) != BB->getBasicBlock()) if(branchVal->getSuccessor(j) != BB->getBasicBlock())
nextBlock = branchVal->getSuccessor(j); nextBlock = branchVal->getSuccessor(j);
} }
TerminatorInst *newBranch = new BranchInst(nextBlock, llvm_epilogues[I]);
} assert((nextBlock != 0) && "Next block should not be null!");
//Add one more nop! TerminatorInst *newBranch = new BranchInst(nextBlock, llvm_epilogues[I]);
BuildMI(epilogues[I], V9::NOP, 0); }
//Add one more nop!
BuildMI(epilogues[I], V9::NOP, 0);
} }
//FIX UP Machine BB entry!! //FIX UP Machine BB entry!!