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:
parent
189f3dc8d2
commit
d38a7605d8
|
|
@ -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) {
|
||||||
|
|
@ -1335,18 +1335,24 @@ void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epil
|
||||||
//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) {
|
||||||
|
|
@ -1410,6 +1423,10 @@ void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *ma
|
||||||
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;
|
||||||
|
|
@ -1514,13 +1546,23 @@ 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) {
|
||||||
|
|
||||||
|
DEBUG(std::cerr << "Replacing PHI: " << *I << "\n");
|
||||||
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);
|
||||||
|
|
@ -1528,6 +1570,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
|
||||||
|
|
@ -1552,21 +1595,47 @@ 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
|
||||||
DEBUG(std::cerr << "Def: " << mOp << "\n");
|
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());
|
BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue());
|
||||||
worklist.push_back(std::make_pair(kernelBB, I));
|
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
|
||||||
|
|
@ -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,14 +1886,20 @@ 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)) {
|
||||||
|
if(mInst->getOpcode() == V9::BA) {
|
||||||
|
BAbranch = &*mInst;
|
||||||
|
}
|
||||||
|
else {
|
||||||
branch = &*mInst;
|
branch = &*mInst;
|
||||||
DEBUG(std::cerr << *mInst << "\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(branch != 0 && "There must be a terminator for the kernel machine basic block!\n");
|
assert(branch != 0 && "There must be a terminator for the kernel machine basic block!\n");
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1836,26 +1953,8 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
|
||||||
|
|
||||||
}
|
}
|
||||||
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());
|
||||||
|
|
@ -1865,6 +1964,8 @@ void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
|
||||||
if(branchVal->getSuccessor(j) != BB->getBasicBlock())
|
if(branchVal->getSuccessor(j) != BB->getBasicBlock())
|
||||||
nextBlock = branchVal->getSuccessor(j);
|
nextBlock = branchVal->getSuccessor(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert((nextBlock != 0) && "Next block should not be null!");
|
||||||
TerminatorInst *newBranch = new BranchInst(nextBlock, llvm_epilogues[I]);
|
TerminatorInst *newBranch = new BranchInst(nextBlock, llvm_epilogues[I]);
|
||||||
}
|
}
|
||||||
//Add one more nop!
|
//Add one more nop!
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue