aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-02-04 02:51:48 +0000
committerChris Lattner <sabre@nondot.org>2004-02-04 02:51:48 +0000
commit5e923dee6024248f58fa83a7c7299437f44f0d1a (patch)
treeb08d519fcb8ff0dc01e85144eb8da3592ee263e8
parent5052c911ec1be51ecb36e7f025c26412e9f1bfac (diff)
More refactoring. Move alloca instructions and handle invoke instructions
before we delete the original call site, allowing slight simplifications of code, but nothing exciting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11109 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp261
1 files changed, 132 insertions, 129 deletions
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index b60742a69b..107c6cd063 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -50,153 +50,68 @@ bool llvm::InlineFunction(CallSite CS) {
BasicBlock *OrigBB = TheCall->getParent();
Function *Caller = OrigBB->getParent();
- // Calculate the vector of arguments to pass into the function cloner...
- std::map<const Value*, Value*> ValueMap;
- assert(std::distance(CalledFunc->abegin(), CalledFunc->aend()) ==
- std::distance(CS.arg_begin(), CS.arg_end()) &&
- "No varargs calls can be inlined!");
-
- CallSite::arg_iterator AI = CS.arg_begin();
- for (Function::const_aiterator I = CalledFunc->abegin(), E=CalledFunc->aend();
- I != E; ++I, ++AI)
- ValueMap[I] = *AI;
-
// Get an iterator to the last basic block in the function, which will have
// the new function inlined after it.
//
Function::iterator LastBlock = &Caller->back();
- // Clone the entire body of the callee into the caller. Make sure to capture
- // all of the return instructions from the cloned function.
+ // Make sure to capture all of the return instructions from the cloned
+ // function.
std::vector<ReturnInst*> Returns;
- CloneFunctionInto(Caller, CalledFunc, ValueMap, Returns, ".i");
-
+ { // Scope to destroy ValueMap after cloning.
+ // Calculate the vector of arguments to pass into the function cloner...
+ std::map<const Value*, Value*> ValueMap;
+ assert(std::distance(CalledFunc->abegin(), CalledFunc->aend()) ==
+ std::distance(CS.arg_begin(), CS.arg_end()) &&
+ "No varargs calls can be inlined!");
+
+ CallSite::arg_iterator AI = CS.arg_begin();
+ for (Function::const_aiterator I = CalledFunc->abegin(),
+ E = CalledFunc->aend(); I != E; ++I, ++AI)
+ ValueMap[I] = *AI;
+
+ // Clone the entire body of the callee into the caller.
+ CloneFunctionInto(Caller, CalledFunc, ValueMap, Returns, ".i");
+ }
-
-
- // We want to clone the entire callee function into the hole between the
- // "starter" and "ender" blocks. How we accomplish this depends on whether
- // this is an invoke instruction or a call instruction.
-
- BasicBlock *InvokeDest = 0; // Exception handling destination
- std::vector<Value*> InvokeDestPHIValues; // Values for PHI nodes in InvokeDest
- BasicBlock *AfterCallBB;
-
- if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
- InvokeDest = II->getExceptionalDest();
-
- // If there are PHI nodes in the exceptional destination block, we need to
- // keep track of which values came into them from this invoke, then remove
- // the entry for this block.
- for (BasicBlock::iterator I = InvokeDest->begin();
- PHINode *PN = dyn_cast<PHINode>(I); ++I) {
- // Save the value to use for this edge...
- InvokeDestPHIValues.push_back(PN->getIncomingValueForBlock(OrigBB));
- }
-
- // Add an unconditional branch to make this look like the CallInst case...
- BranchInst *NewBr = new BranchInst(II->getNormalDest(), TheCall);
-
- // Split the basic block. This guarantees that no PHI nodes will have to be
- // updated due to new incoming edges, and make the invoke case more
- // symmetric to the call case.
- AfterCallBB = OrigBB->splitBasicBlock(NewBr,
- CalledFunc->getName()+".entry");
-
- // Remove (unlink) the InvokeInst from the function...
- OrigBB->getInstList().remove(TheCall);
-
- } else { // It's a call
- // If this is a call instruction, we need to split the basic block that the
- // call lives in.
- //
- AfterCallBB = OrigBB->splitBasicBlock(TheCall,
- CalledFunc->getName()+".entry");
- // Remove (unlink) the CallInst from the function...
- AfterCallBB->getInstList().remove(TheCall);
- }
-
- // If we have a return value generated by this call, convert it into a PHI
- // node that gets values from each of the old RET instructions in the original
- // function.
- //
- if (!TheCall->use_empty()) {
- // We only need to make the PHI if there is more than one return instruction
- if (Returns.size() > 1) {
- // The PHI node should go at the front of the new basic block to merge all
- // possible incoming values.
- //
- PHINode *PHI = new PHINode(CalledFunc->getReturnType(),
- TheCall->getName(), AfterCallBB->begin());
-
- // Anything that used the result of the function call should now use the
- // PHI node as their operand.
- //
- TheCall->replaceAllUsesWith(PHI);
-
- // Add all of the return instructions as entries in the PHI node.
- for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
- ReturnInst *RI = Returns[i];
-
- assert(RI->getReturnValue() && "Ret should have value!");
- assert(RI->getReturnValue()->getType() == PHI->getType() &&
- "Ret value not consistent in function!");
- PHI->addIncoming(RI->getReturnValue(), RI->getParent());
- }
-
- } else if (!Returns.empty()) {
- // Otherwise, if there is exactly one return value, just replace anything
- // using the return value of the call with the computed value.
- TheCall->replaceAllUsesWith(Returns[0]->getReturnValue());
- }
- }
-
- // Since we are now done with the Call/Invoke, we can delete it.
- delete TheCall;
-
- // Loop over all of the return instructions, turning them into unconditional
- // branches to the merge point now...
- for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
- ReturnInst *RI = Returns[i];
-
- // Add a branch to the merge point where the PHI node lives if it exists.
- new BranchInst(AfterCallBB, RI);
-
- // Delete the return instruction now
- RI->getParent()->getInstList().erase(RI);
- }
-
- // Change the branch that used to go to AfterCallBB to branch to the first
- // basic block of the inlined function.
- //
- TerminatorInst *Br = OrigBB->getTerminator();
- assert(Br && Br->getOpcode() == Instruction::Br &&
- "splitBasicBlock broken!");
- Br->setOperand(0, ++LastBlock);
+ // Remember the first block that is newly cloned over.
+ Function::iterator FirstNewBlock = LastBlock; ++FirstNewBlock;
// If there are any alloca instructions in the block that used to be the entry
// block for the callee, move them to the entry block of the caller. First
// calculate which instruction they should be inserted before. We insert the
// instructions at the end of the current alloca list.
//
- if (isa<AllocaInst>(LastBlock->begin())) {
+ if (isa<AllocaInst>(FirstNewBlock->begin())) {
BasicBlock::iterator InsertPoint = Caller->begin()->begin();
while (isa<AllocaInst>(InsertPoint)) ++InsertPoint;
- for (BasicBlock::iterator I = LastBlock->begin(), E = LastBlock->end();
- I != E; )
+ for (BasicBlock::iterator I = FirstNewBlock->begin(),
+ E = FirstNewBlock->end(); I != E; )
if (AllocaInst *AI = dyn_cast<AllocaInst>(I++))
if (isa<Constant>(AI->getArraySize())) {
- LastBlock->getInstList().remove(AI);
+ FirstNewBlock->getInstList().remove(AI);
Caller->front().getInstList().insert(InsertPoint, AI);
}
}
- // If we just inlined a call due to an invoke instruction, scan the inlined
- // function checking for function calls that should now be made into invoke
- // instructions, and for unwind's which should be turned into branches.
- if (InvokeDest) {
- for (Function::iterator BB = LastBlock, E = Caller->end(); BB != E; ++BB) {
+ // If we are inlining for an invoke instruction, we must make sure to rewrite
+ // any inlined 'unwind' instructions into branches to the invoke exception
+ // destination, and call instructions into invoke instructions.
+ if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
+ BasicBlock *InvokeDest = II->getExceptionalDest();
+ std::vector<Value*> InvokeDestPHIValues;
+
+ // If there are PHI nodes in the exceptional destination block, we need to
+ // keep track of which values came into them from this invoke, then remove
+ // the entry for this block.
+ for (BasicBlock::iterator I = InvokeDest->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I)
+ // Save the value to use for this edge...
+ InvokeDestPHIValues.push_back(PN->getIncomingValueForBlock(OrigBB));
+
+ for (Function::iterator BB = FirstNewBlock, E = Caller->end();
+ BB != E; ++BB) {
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
// We only need to check for function calls: inlined invoke instructions
// require no special handling...
@@ -257,16 +172,104 @@ bool llvm::InlineFunction(CallSite CS) {
// the exception destination block still have entries due to the original
// invoke instruction. Eliminate these entries (which might even delete the
// PHI node) now.
- for (BasicBlock::iterator I = InvokeDest->begin();
- PHINode *PN = dyn_cast<PHINode>(I); ++I)
- PN->removeIncomingValue(AfterCallBB);
+ InvokeDest->removePredecessor(II->getParent());
}
+
+ // We want to clone the entire callee function into the hole between the
+ // "starter" and "ender" blocks. How we accomplish this depends on whether
+ // this is an invoke instruction or a call instruction.
+ BasicBlock *AfterCallBB;
+ if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
+
+ // Add an unconditional branch to make this look like the CallInst case...
+ BranchInst *NewBr = new BranchInst(II->getNormalDest(), TheCall);
+
+ // Split the basic block. This guarantees that no PHI nodes will have to be
+ // updated due to new incoming edges, and make the invoke case more
+ // symmetric to the call case.
+ AfterCallBB = OrigBB->splitBasicBlock(NewBr,
+ CalledFunc->getName()+".entry");
+
+ // Remove (unlink) the InvokeInst from the function...
+ OrigBB->getInstList().remove(TheCall);
+
+ } else { // It's a call
+ // If this is a call instruction, we need to split the basic block that the
+ // call lives in.
+ //
+ AfterCallBB = OrigBB->splitBasicBlock(TheCall,
+ CalledFunc->getName()+".entry");
+ // Remove (unlink) the CallInst from the function...
+ AfterCallBB->getInstList().remove(TheCall);
+ }
+
+ // Handle all of the return instructions that we just cloned in, and eliminate
+ // any users of the original call/invoke instruction.
+ if (Returns.size() > 1) {
+ // The PHI node should go at the front of the new basic block to merge all
+ // possible incoming values.
+ //
+ PHINode *PHI = 0;
+ if (!TheCall->use_empty()) {
+ PHI = new PHINode(CalledFunc->getReturnType(),
+ TheCall->getName(), AfterCallBB->begin());
+
+ // Anything that used the result of the function call should now use the
+ // PHI node as their operand.
+ //
+ TheCall->replaceAllUsesWith(PHI);
+ }
+
+ // Loop over all of the return instructions, turning them into unconditional
+ // branches to the merge point now, and adding entries to the PHI node as
+ // appropriate.
+ for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
+ ReturnInst *RI = Returns[i];
+
+ if (PHI) {
+ assert(RI->getReturnValue() && "Ret should have value!");
+ assert(RI->getReturnValue()->getType() == PHI->getType() &&
+ "Ret value not consistent in function!");
+ PHI->addIncoming(RI->getReturnValue(), RI->getParent());
+ }
+
+ // Add a branch to the merge point where the PHI node lives if it exists.
+ new BranchInst(AfterCallBB, RI);
+
+ // Delete the return instruction now
+ RI->getParent()->getInstList().erase(RI);
+ }
+
+ } else if (!Returns.empty()) {
+ // Otherwise, if there is exactly one return value, just replace anything
+ // using the return value of the call with the computed value.
+ if (!TheCall->use_empty())
+ TheCall->replaceAllUsesWith(Returns[0]->getReturnValue());
+
+ // Add a branch to the merge point where the PHI node lives if it exists.
+ new BranchInst(AfterCallBB, Returns[0]);
+
+ // Delete the return instruction now
+ Returns[0]->getParent()->getInstList().erase(Returns[0]);
+ }
+
+ // Since we are now done with the Call/Invoke, we can delete it.
+ delete TheCall;
+
+ // Change the branch that used to go to AfterCallBB to branch to the first
+ // basic block of the inlined function.
+ //
+ TerminatorInst *Br = OrigBB->getTerminator();
+ assert(Br && Br->getOpcode() == Instruction::Br &&
+ "splitBasicBlock broken!");
+ Br->setOperand(0, FirstNewBlock);
+
// Now that the function is correct, make it a little bit nicer. In
// particular, move the basic blocks inserted from the end of the function
// into the space made by splitting the source basic block.
//
Caller->getBasicBlockList().splice(AfterCallBB, Caller->getBasicBlockList(),
- LastBlock, Caller->end());
+ FirstNewBlock, Caller->end());
// We should always be able to fold the entry block of the function into the
// single predecessor of the block...