mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
Reworked branch adding in prologue. Added check for infinite loops which are not modulo scheduled.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18419 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fa07e4fc30
commit
ad7654f7c4
@ -164,8 +164,6 @@ bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MSSchedule::constructKernel(int II) {
|
bool MSSchedule::constructKernel(int II) {
|
||||||
MSchedGraphNode *branchNode = 0;
|
|
||||||
MSchedGraphNode *branchANode = 0;
|
|
||||||
|
|
||||||
int stageNum = (schedule.rbegin()->first)/ II;
|
int stageNum = (schedule.rbegin()->first)/ II;
|
||||||
DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
|
DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
|
||||||
@ -178,11 +176,8 @@ bool MSSchedule::constructKernel(int II) {
|
|||||||
E = schedule[i].end(); I != E; ++I) {
|
E = schedule[i].end(); I != E; ++I) {
|
||||||
//Check if its a branch
|
//Check if its a branch
|
||||||
if((*I)->isBranch()) {
|
if((*I)->isBranch()) {
|
||||||
if((*I)->getInst()->getOpcode() == V9::BA)
|
|
||||||
branchANode = *I;
|
|
||||||
else
|
|
||||||
branchNode = *I;
|
|
||||||
assert(count == 0 && "Branch can not be from a previous iteration");
|
assert(count == 0 && "Branch can not be from a previous iteration");
|
||||||
|
kernel.push_back(std::make_pair(*I, count));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
//FIXME: Check if the instructions in the earlier stage conflict
|
//FIXME: Check if the instructions in the earlier stage conflict
|
||||||
@ -193,13 +188,6 @@ bool MSSchedule::constructKernel(int II) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add Branch to the end
|
|
||||||
kernel.push_back(std::make_pair(branchNode, 0));
|
|
||||||
|
|
||||||
//Add Branch Always to the end
|
|
||||||
kernel.push_back(std::make_pair(branchANode, 0));
|
|
||||||
|
|
||||||
|
|
||||||
if(stageNum > 0)
|
if(stageNum > 0)
|
||||||
maxStage = stageNum;
|
maxStage = stageNum;
|
||||||
else
|
else
|
||||||
|
@ -213,20 +213,20 @@ bool ModuloSchedulingPass::runOnFunction(Function &F) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Finally schedule nodes
|
//Finally schedule nodes
|
||||||
computeSchedule();
|
bool haveSched = computeSchedule();
|
||||||
|
|
||||||
//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 && haveSched) {
|
||||||
reconstructLoop(*BI);
|
reconstructLoop(*BI);
|
||||||
++MSLoops;
|
++MSLoops;
|
||||||
Changed = true;
|
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 or reached cap\n");
|
||||||
|
|
||||||
//Clear out our maps for the next basic block that is processed
|
//Clear out our maps for the next basic block that is processed
|
||||||
nodeToAttributesMap.clear();
|
nodeToAttributesMap.clear();
|
||||||
@ -293,6 +293,11 @@ bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
|
|||||||
if(!isLoop)
|
if(!isLoop)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
//Check that we have a conditional branch (avoiding MS infinite loops)
|
||||||
|
if(BranchInst *b = dyn_cast<BranchInst>(((BasicBlock*) BI->getBasicBlock())->getTerminator()))
|
||||||
|
if(b->isUnconditional())
|
||||||
|
return false;
|
||||||
|
|
||||||
//Check size of our basic block.. make sure we have more then just the terminator in it
|
//Check size of our basic block.. make sure we have more then just the terminator in it
|
||||||
if(BI->getBasicBlock()->size() == 1)
|
if(BI->getBasicBlock()->size() == 1)
|
||||||
return false;
|
return false;
|
||||||
@ -1139,13 +1144,13 @@ void ModuloSchedulingPass::orderNodes() {
|
|||||||
//return FinalNodeOrder;
|
//return FinalNodeOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuloSchedulingPass::computeSchedule() {
|
bool ModuloSchedulingPass::computeSchedule() {
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
//FIXME: Should be set to max II of the original loop
|
//FIXME: Should be set to max II of the original loop
|
||||||
//Cap II in order to prevent infinite loop
|
//Cap II in order to prevent infinite loop
|
||||||
int capII = 30;
|
int capII = 100;
|
||||||
|
|
||||||
while(!success) {
|
while(!success) {
|
||||||
|
|
||||||
@ -1252,8 +1257,12 @@ void ModuloSchedulingPass::computeSchedule() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(II >= capII)
|
||||||
|
return false;
|
||||||
|
|
||||||
assert(II < capII && "The II should not exceed the original loop number of cycles");
|
assert(II < capII && "The II should not exceed the original loop number of cycles");
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1312,21 +1321,22 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
|
|||||||
std::map<int, std::set<const MachineInstr*> > inKernel;
|
std::map<int, std::set<const MachineInstr*> > inKernel;
|
||||||
int maxStageCount = 0;
|
int maxStageCount = 0;
|
||||||
|
|
||||||
|
//Keep a map of new values we consumed in case they need to be added back
|
||||||
|
std::map<Value*, std::map<int, Value*> > consumedValues;
|
||||||
|
|
||||||
MSchedGraphNode *branch = 0;
|
MSchedGraphNode *branch = 0;
|
||||||
MSchedGraphNode *BAbranch = 0;
|
MSchedGraphNode *BAbranch = 0;
|
||||||
|
|
||||||
schedule.print(std::cerr);
|
schedule.print(std::cerr);
|
||||||
|
|
||||||
|
std::vector<MSchedGraphNode*> branches;
|
||||||
|
|
||||||
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)
|
branches.push_back(I->first);
|
||||||
branch = I->first;
|
|
||||||
else
|
|
||||||
BAbranch = I->first;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1357,7 +1367,7 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
|
|||||||
//After cloning, we may need to save the value that this instruction defines
|
//After cloning, we may need to save the value that this instruction defines
|
||||||
for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) {
|
for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) {
|
||||||
//get machine operand
|
//get machine operand
|
||||||
const MachineOperand &mOp = instClone->getOperand(opNum);
|
MachineOperand &mOp = instClone->getOperand(opNum);
|
||||||
if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
|
if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
|
||||||
|
|
||||||
//Check if this is a value we should save
|
//Check if this is a value we should save
|
||||||
@ -1386,13 +1396,24 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
|
|||||||
//We may also need to update the value that we use if its from an earlier prologue
|
//We may also need to update the value that we use if its from an earlier prologue
|
||||||
if(j != 0) {
|
if(j != 0) {
|
||||||
if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
|
if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
|
||||||
if(newValues.count(mOp.getVRegValue()))
|
if(newValues.count(mOp.getVRegValue())) {
|
||||||
if(newValues[mOp.getVRegValue()].count(j-1)) {
|
if(newValues[mOp.getVRegValue()].count(i-1)) {
|
||||||
|
Value *oldV = mOp.getVRegValue();
|
||||||
DEBUG(std::cerr << "Replaced this value: " << mOp.getVRegValue() << " With:" << (newValues[mOp.getVRegValue()][i-1]) << "\n");
|
DEBUG(std::cerr << "Replaced this value: " << mOp.getVRegValue() << " With:" << (newValues[mOp.getVRegValue()][i-1]) << "\n");
|
||||||
//Update the operand with the right value
|
//Update the operand with the right value
|
||||||
instClone->getOperand(opNum).setValueReg(newValues[mOp.getVRegValue()][i-1]);
|
mOp.setValueReg(newValues[mOp.getVRegValue()][i-1]);
|
||||||
|
|
||||||
|
//Remove this value since we have consumed it
|
||||||
|
//NOTE: Should this only be done if j != maxStage?
|
||||||
|
consumedValues[oldV][i-1] = (newValues[oldV][i-1]);
|
||||||
|
DEBUG(std::cerr << "Deleted value: " << consumedValues[oldV][i-1] << "\n");
|
||||||
|
newValues[oldV].erase(i-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if(consumedValues.count(mOp.getVRegValue()))
|
||||||
|
assert(!consumedValues[mOp.getVRegValue()].count(i-1) && "Found a case where we need the value");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1400,17 +1421,15 @@ void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prol
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for(std::vector<MSchedGraphNode*>::iterator BR = branches.begin(), BE = branches.end(); BR != BE; ++BR) {
|
||||||
|
|
||||||
//Stick in branch at the end
|
//Stick in branch at the end
|
||||||
machineBB->push_back(branch->getInst()->clone());
|
machineBB->push_back((*BR)->getInst()->clone());
|
||||||
|
|
||||||
//Add nop
|
//Add nop
|
||||||
BuildMI(machineBB, V9::NOP, 0);
|
BuildMI(machineBB, V9::NOP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
//Stick in branch at the end
|
|
||||||
machineBB->push_back(BAbranch->getInst()->clone());
|
|
||||||
|
|
||||||
//Add nop
|
|
||||||
BuildMI(machineBB, V9::NOP, 0);
|
|
||||||
|
|
||||||
(((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
|
(((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
|
||||||
prologues.push_back(machineBB);
|
prologues.push_back(machineBB);
|
||||||
|
@ -88,7 +88,7 @@ namespace llvm {
|
|||||||
void addReccurrence(std::vector<MSchedGraphNode*> &recurrence, int II, MSchedGraphNode*, MSchedGraphNode*);
|
void addReccurrence(std::vector<MSchedGraphNode*> &recurrence, int II, MSchedGraphNode*, MSchedGraphNode*);
|
||||||
|
|
||||||
void computePartialOrder();
|
void computePartialOrder();
|
||||||
void computeSchedule();
|
bool computeSchedule();
|
||||||
bool scheduleNode(MSchedGraphNode *node,
|
bool scheduleNode(MSchedGraphNode *node,
|
||||||
int start, int end);
|
int start, int end);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user