mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-10 04:33:40 +00:00
Assert that input blocks meet the invariants we expect
Simplify the input/output finder. All elements of a basic block are instructions. Any used arguments are also inputs. An instruction can only be used by another instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12405 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e94fd1963d
commit
0de632bfae
@ -172,50 +172,40 @@ void CodeExtractor::processPhiNodeInputs(PHINode *Phi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CodeExtractor::findInputsOutputs(Values &inputs,
|
void CodeExtractor::findInputsOutputs(Values &inputs, Values &outputs,
|
||||||
Values &outputs,
|
|
||||||
BasicBlock *newHeader,
|
BasicBlock *newHeader,
|
||||||
BasicBlock *newRootNode)
|
BasicBlock *newRootNode) {
|
||||||
{
|
|
||||||
for (std::set<BasicBlock*>::const_iterator ci = BlocksToExtract.begin(),
|
for (std::set<BasicBlock*>::const_iterator ci = BlocksToExtract.begin(),
|
||||||
ce = BlocksToExtract.end(); ci != ce; ++ci) {
|
ce = BlocksToExtract.end(); ci != ce; ++ci) {
|
||||||
BasicBlock *BB = *ci;
|
BasicBlock *BB = *ci;
|
||||||
for (BasicBlock::iterator BBi = BB->begin(), BBe = BB->end();
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||||
BBi != BBe; ++BBi) {
|
// If a used value is defined outside the region, it's an input. If an
|
||||||
// If a use is defined outside the region, it's an input.
|
// instruction is used outside the region, it's an output.
|
||||||
// If a def is used outside the region, it's an output.
|
if (PHINode *Phi = dyn_cast<PHINode>(I)) {
|
||||||
if (Instruction *I = dyn_cast<Instruction>(&*BBi)) {
|
processPhiNodeInputs(Phi, inputs, newHeader, newRootNode);
|
||||||
// If it's a phi node
|
} else {
|
||||||
if (PHINode *Phi = dyn_cast<PHINode>(I)) {
|
// All other instructions go through the generic input finder
|
||||||
processPhiNodeInputs(Phi, inputs, newHeader, newRootNode);
|
// Loop over the operands of each instruction (inputs)
|
||||||
} else {
|
for (User::op_iterator op = I->op_begin(), opE = I->op_end();
|
||||||
// All other instructions go through the generic input finder
|
op != opE; ++op)
|
||||||
// Loop over the operands of each instruction (inputs)
|
if (Instruction *opI = dyn_cast<Instruction>(*op)) {
|
||||||
for (User::op_iterator op = I->op_begin(), opE = I->op_end();
|
// Check if definition of this operand is within the loop
|
||||||
op != opE; ++op) {
|
if (!BlocksToExtract.count(opI->getParent())) {
|
||||||
if (Instruction *opI = dyn_cast<Instruction>(op->get())) {
|
// add this operand to the inputs
|
||||||
// Check if definition of this operand is within the loop
|
inputs.push_back(opI);
|
||||||
if (!BlocksToExtract.count(opI->getParent())) {
|
|
||||||
// add this operand to the inputs
|
|
||||||
inputs.push_back(opI);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else if (isa<Argument>(*op)) {
|
||||||
|
inputs.push_back(*op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consider uses of this instruction (outputs)
|
// Consider uses of this instruction (outputs)
|
||||||
for (Value::use_iterator use = I->use_begin(), useE = I->use_end();
|
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
|
||||||
use != useE; ++use) {
|
UI != E; ++UI)
|
||||||
if (Instruction* inst = dyn_cast<Instruction>(*use)) {
|
if (!BlocksToExtract.count(cast<Instruction>(*UI)->getParent()))
|
||||||
if (!BlocksToExtract.count(inst->getParent())) {
|
outputs.push_back(*UI);
|
||||||
// add this op to the outputs
|
} // for: insts
|
||||||
outputs.push_back(I);
|
} // for: basic blocks
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* if */
|
|
||||||
} /* for: insts */
|
|
||||||
} /* for: basic blocks */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeExtractor::rewritePhiNodes(Function *F,
|
void CodeExtractor::rewritePhiNodes(Function *F,
|
||||||
@ -470,11 +460,16 @@ Function *CodeExtractor::ExtractCodeRegion(const std::vector<BasicBlock*> &code)
|
|||||||
Values inputs, outputs;
|
Values inputs, outputs;
|
||||||
|
|
||||||
// Assumption: this is a single-entry code region, and the header is the first
|
// Assumption: this is a single-entry code region, and the header is the first
|
||||||
// block in the region. FIXME: is this true for a list of blocks from a
|
// block in the region.
|
||||||
// natural function?
|
|
||||||
BasicBlock *header = code[0];
|
BasicBlock *header = code[0];
|
||||||
|
for (unsigned i = 1, e = code.size(); i != e; ++i)
|
||||||
|
for (pred_iterator PI = pred_begin(code[i]), E = pred_end(code[i]);
|
||||||
|
PI != E; ++PI)
|
||||||
|
assert(BlocksToExtract.count(*PI) &&
|
||||||
|
"No blocks in this region may have entries from outside the region"
|
||||||
|
" except for the first block!");
|
||||||
|
|
||||||
Function *oldFunction = header->getParent();
|
Function *oldFunction = header->getParent();
|
||||||
Module *module = oldFunction->getParent();
|
|
||||||
|
|
||||||
// This takes place of the original loop
|
// This takes place of the original loop
|
||||||
BasicBlock *codeReplacer = new BasicBlock("codeRepl", oldFunction);
|
BasicBlock *codeReplacer = new BasicBlock("codeRepl", oldFunction);
|
||||||
@ -504,7 +499,8 @@ Function *CodeExtractor::ExtractCodeRegion(const std::vector<BasicBlock*> &code)
|
|||||||
// Step 2: Construct new function based on inputs/outputs,
|
// Step 2: Construct new function based on inputs/outputs,
|
||||||
// Add allocas for all defs
|
// Add allocas for all defs
|
||||||
Function *newFunction = constructFunction(inputs, outputs, newFuncRoot,
|
Function *newFunction = constructFunction(inputs, outputs, newFuncRoot,
|
||||||
codeReplacer, oldFunction, module);
|
codeReplacer, oldFunction,
|
||||||
|
oldFunction->getParent());
|
||||||
|
|
||||||
rewritePhiNodes(newFunction, newFuncRoot);
|
rewritePhiNodes(newFunction, newFuncRoot);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user