mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-19 19:29:31 +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,
|
||||
Values &outputs,
|
||||
void CodeExtractor::findInputsOutputs(Values &inputs, Values &outputs,
|
||||
BasicBlock *newHeader,
|
||||
BasicBlock *newRootNode)
|
||||
{
|
||||
BasicBlock *newRootNode) {
|
||||
for (std::set<BasicBlock*>::const_iterator ci = BlocksToExtract.begin(),
|
||||
ce = BlocksToExtract.end(); ci != ce; ++ci) {
|
||||
BasicBlock *BB = *ci;
|
||||
for (BasicBlock::iterator BBi = BB->begin(), BBe = BB->end();
|
||||
BBi != BBe; ++BBi) {
|
||||
// If a use is defined outside the region, it's an input.
|
||||
// If a def is used outside the region, it's an output.
|
||||
if (Instruction *I = dyn_cast<Instruction>(&*BBi)) {
|
||||
// If it's a phi node
|
||||
if (PHINode *Phi = dyn_cast<PHINode>(I)) {
|
||||
processPhiNodeInputs(Phi, inputs, newHeader, newRootNode);
|
||||
} else {
|
||||
// All other instructions go through the generic input finder
|
||||
// Loop over the operands of each instruction (inputs)
|
||||
for (User::op_iterator op = I->op_begin(), opE = I->op_end();
|
||||
op != opE; ++op) {
|
||||
if (Instruction *opI = dyn_cast<Instruction>(op->get())) {
|
||||
// Check if definition of this operand is within the loop
|
||||
if (!BlocksToExtract.count(opI->getParent())) {
|
||||
// add this operand to the inputs
|
||||
inputs.push_back(opI);
|
||||
}
|
||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||
// If a used value is defined outside the region, it's an input. If an
|
||||
// instruction is used outside the region, it's an output.
|
||||
if (PHINode *Phi = dyn_cast<PHINode>(I)) {
|
||||
processPhiNodeInputs(Phi, inputs, newHeader, newRootNode);
|
||||
} else {
|
||||
// All other instructions go through the generic input finder
|
||||
// Loop over the operands of each instruction (inputs)
|
||||
for (User::op_iterator op = I->op_begin(), opE = I->op_end();
|
||||
op != opE; ++op)
|
||||
if (Instruction *opI = dyn_cast<Instruction>(*op)) {
|
||||
// Check if definition of this operand is within the loop
|
||||
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)
|
||||
for (Value::use_iterator use = I->use_begin(), useE = I->use_end();
|
||||
use != useE; ++use) {
|
||||
if (Instruction* inst = dyn_cast<Instruction>(*use)) {
|
||||
if (!BlocksToExtract.count(inst->getParent())) {
|
||||
// add this op to the outputs
|
||||
outputs.push_back(I);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* if */
|
||||
} /* for: insts */
|
||||
} /* for: basic blocks */
|
||||
}
|
||||
|
||||
// Consider uses of this instruction (outputs)
|
||||
for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
|
||||
UI != E; ++UI)
|
||||
if (!BlocksToExtract.count(cast<Instruction>(*UI)->getParent()))
|
||||
outputs.push_back(*UI);
|
||||
} // for: insts
|
||||
} // for: basic blocks
|
||||
}
|
||||
|
||||
void CodeExtractor::rewritePhiNodes(Function *F,
|
||||
@ -470,11 +460,16 @@ Function *CodeExtractor::ExtractCodeRegion(const std::vector<BasicBlock*> &code)
|
||||
Values inputs, outputs;
|
||||
|
||||
// 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
|
||||
// natural function?
|
||||
// block in the region.
|
||||
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();
|
||||
Module *module = oldFunction->getParent();
|
||||
|
||||
// This takes place of the original loop
|
||||
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,
|
||||
// Add allocas for all defs
|
||||
Function *newFunction = constructFunction(inputs, outputs, newFuncRoot,
|
||||
codeReplacer, oldFunction, module);
|
||||
codeReplacer, oldFunction,
|
||||
oldFunction->getParent());
|
||||
|
||||
rewritePhiNodes(newFunction, newFuncRoot);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user