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:
Chris Lattner 2004-03-15 01:18:23 +00:00
parent e94fd1963d
commit 0de632bfae

View File

@ -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);