aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-08-24 06:59:16 +0000
committerChris Lattner <sabre@nondot.org>2003-08-24 06:59:16 +0000
commit80a38d245359cb0a3be8f78f5d7d911232886b9a (patch)
tree05213fc3a5ea32167b17fc56f8c4dd80df4a3aa1 /lib
parent9d3a1b2d972baf72b7da371a1ae72126bc5c6c04 (diff)
downloadexternal_llvm-80a38d245359cb0a3be8f78f5d7d911232886b9a.zip
external_llvm-80a38d245359cb0a3be8f78f5d7d911232886b9a.tar.gz
external_llvm-80a38d245359cb0a3be8f78f5d7d911232886b9a.tar.bz2
*** Implement inlining of Invoke instructions!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8106 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp189
1 files changed, 138 insertions, 51 deletions
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 2fafef3..fade863 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -9,14 +9,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Constant.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
-#include "llvm/iTerminators.h"
-#include "llvm/iPHINode.h"
-#include "llvm/iMemory.h"
-#include "llvm/iOther.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Transforms/Utils/Local.h"
+bool InlineFunction(CallInst *CI) { return InlineFunction(CallSite(CI)); }
+bool InlineFunction(InvokeInst *II) { return InlineFunction(CallSite(II)); }
+
// InlineFunction - This function inlines the called function into the basic
// block of the caller. This returns false if it is not possible to inline this
// call. The program is still in a well defined state if this occurs though.
@@ -26,46 +29,60 @@
// exists in the instruction stream. Similiarly this will inline a recursive
// function by one level.
//
-bool InlineFunction(CallInst *CI) {
- assert(isa<CallInst>(CI) && "InlineFunction only works on CallInst nodes");
- assert(CI->getParent() && "Instruction not embedded in basic block!");
- assert(CI->getParent()->getParent() && "Instruction not in function!");
+bool InlineFunction(CallSite CS) {
+ Instruction *TheCall = CS.getInstruction();
+ assert(TheCall->getParent() && TheCall->getParent()->getParent() &&
+ "Instruction not in function!");
- const Function *CalledFunc = CI->getCalledFunction();
+ const Function *CalledFunc = CS.getCalledFunction();
if (CalledFunc == 0 || // Can't inline external function or indirect
CalledFunc->isExternal() || // call, or call to a vararg function!
CalledFunc->getFunctionType()->isVarArg()) return false;
- BasicBlock *OrigBB = CI->getParent();
+ BasicBlock *OrigBB = TheCall->getParent();
Function *Caller = OrigBB->getParent();
- // Call splitBasicBlock - The original basic block now ends at the instruction
- // immediately before the call. The original basic block now ends with an
- // unconditional branch to NewBB, and NewBB starts with the call instruction.
- //
- BasicBlock *NewBB = OrigBB->splitBasicBlock(CI,
- CalledFunc->getName()+".entry");
- NewBB->setName(OrigBB->getName()+".split");
+ // We want to clone the entire callee function into the whole 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
+ BasicBlock *AfterCallBB;
+ if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
+ AfterCallBB = II->getNormalDest();
+ InvokeDest = II->getExceptionalDest();
- // Remove (unlink) the CallInst from the start of the new basic block.
- NewBB->getInstList().remove(CI);
+ // Add an unconditional branch to make this look like the CallInst case...
+ new BranchInst(AfterCallBB, TheCall);
+
+ // 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.
//
PHINode *PHI = 0;
- if (!CI->use_empty()) {
+ if (!TheCall->use_empty()) {
// The PHI node should go at the front of the new basic block to merge all
// possible incoming values.
//
- PHI = new PHINode(CalledFunc->getReturnType(), CI->getName(),
- NewBB->begin());
+ 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.
//
- CI->replaceAllUsesWith(PHI);
+ TheCall->replaceAllUsesWith(PHI);
}
// Get an iterator to the last basic block in the function, which will have
@@ -75,21 +92,23 @@ bool InlineFunction(CallInst *CI) {
// Calculate the vector of arguments to pass into the function cloner...
std::map<const Value*, Value*> ValueMap;
- assert((unsigned)std::distance(CalledFunc->abegin(), CalledFunc->aend()) ==
- CI->getNumOperands()-1 && "No varargs calls can be inlined yet!");
+ assert(std::distance(CalledFunc->abegin(), CalledFunc->aend()) ==
+ std::distance(CS.arg_begin(), CS.arg_end()) &&
+ "No varargs calls can be inlined!");
- unsigned i = 1;
+ CallSite::arg_iterator AI = CS.arg_begin();
for (Function::const_aiterator I = CalledFunc->abegin(), E=CalledFunc->aend();
- I != E; ++I, ++i)
- ValueMap[I] = CI->getOperand(i);
+ I != E; ++I, ++AI)
+ ValueMap[I] = *AI;
- // Since we are now done with the CallInst, we can delete it.
- delete CI;
+ // Since we are now done with the Call/Invoke, we can delete it.
+ delete TheCall;
// Make a vector to capture the return instructions in the cloned function...
std::vector<ReturnInst*> Returns;
// Populate the value map with all of the globals in the program.
+ // FIXME: This should be the default for CloneFunctionInto!
Module &M = *Caller->getParent();
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
ValueMap[I] = I;
@@ -105,8 +124,8 @@ bool InlineFunction(CallInst *CI) {
ReturnInst *RI = Returns[i];
BasicBlock *BB = RI->getParent();
- // Add a branch to the merge point where the PHI node would live...
- new BranchInst(NewBB, RI);
+ // Add a branch to the merge point where the PHI node lives if it exists.
+ new BranchInst(AfterCallBB, RI);
if (PHI) { // The PHI node should include this value!
assert(RI->getReturnValue() && "Ret should have value!");
@@ -128,8 +147,8 @@ bool InlineFunction(CallInst *CI) {
PHI->getParent()->getInstList().erase(PHI);
}
- // Change the branch that used to go to NewBB to branch to the first basic
- // block of the inlined function.
+ // 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 &&
@@ -141,25 +160,93 @@ bool InlineFunction(CallInst *CI) {
// calculate which instruction they should be inserted before. We insert the
// instructions at the end of the current alloca list.
//
- BasicBlock::iterator InsertPoint = Caller->begin()->begin();
- while (isa<AllocaInst>(InsertPoint)) ++InsertPoint;
-
- for (BasicBlock::iterator I = LastBlock->begin(), E = LastBlock->end();
- I != E; )
- if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
- ++I; // Move to the next instruction
- LastBlock->getInstList().remove(AI);
- Caller->front().getInstList().insert(InsertPoint, AI);
-
- } else {
- ++I;
- }
+ if (isa<AllocaInst>(LastBlock->begin())) {
+ BasicBlock::iterator InsertPoint = Caller->begin()->begin();
+ while (isa<AllocaInst>(InsertPoint)) ++InsertPoint;
+
+ for (BasicBlock::iterator I = LastBlock->begin(), E = LastBlock->end();
+ I != E; )
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
+ ++I; // Move to the next instruction
+ LastBlock->getInstList().remove(AI);
+ Caller->front().getInstList().insert(InsertPoint, AI);
+ } else {
+ ++I;
+ }
+ }
+
+ // 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 llvm.exc.rethrow()'s which should be turned into
+ // branches.
+ if (InvokeDest)
+ for (Function::iterator BB = LastBlock, 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...
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ // FIXME: this should use annotations of the LLVM functions themselves
+ // to determine whether or not the function can throw.
+ bool ShouldInvokify = true;
+
+ if (Function *F = CI->getCalledFunction())
+ if (unsigned ID = F->getIntrinsicID())
+ if (ID == LLVMIntrinsic::exc_rethrow) {
+ // llvm.exc.rethrow requires special handling when it gets
+ // inlined into an invoke site. Once this happens, we know that
+ // the rethrow would cause a control transfer to the invoke
+ // exception destination, so we can transform it into a direct
+ // branch to the exception destination.
+ BranchInst *BI = new BranchInst(InvokeDest, CI);
+
+ // Note that since any instructions after the rethrow/branch are
+ // dead, we must delete them now (otherwise the terminator we
+ // just inserted wouldn't be at the end of the basic block!)
+ BasicBlock *CurBB = BB;
+ while (&CurBB->back() != BI) {
+ Instruction *I = &CurBB->back();
+ if (!I->use_empty())
+ I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
+ CurBB->getInstList().pop_back();
+ }
+
+ break; // Done with this basic block!
+ } else if (ID == LLVMIntrinsic::exc_throw ||
+ ID == LLVMIntrinsic::exc_getcurrent) {
+ ShouldInvokify = false; // Not correct to invokify exc.throw!
+ }
+
+ // If we should convert this function into an invoke instruction, do
+ // so now.
+ if (ShouldInvokify) {
+ // First, split the basic block...
+ BasicBlock *Split = BB->splitBasicBlock(CI, CI->getName()+".noexc");
+
+ // Next, create the new invoke instruction, inserting it at the end
+ // of the old basic block.
+ new InvokeInst(CI->getCalledValue(), Split, InvokeDest,
+ std::vector<Value*>(CI->op_begin()+1, CI->op_end()),
+ CI->getName(), BB->getTerminator());
+
+ // Delete the unconditional branch inserted by splitBasicBlock
+ BB->getInstList().pop_back();
+ Split->getInstList().pop_front(); // Delete the original call
+
+ // This basic block is now complete, start scanning the next one.
+ break;
+ } else {
+ ++I;
+ }
+ } else {
+ ++I;
+ }
+ }
// 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(NewBB, Caller->getBasicBlockList(),
+ Caller->getBasicBlockList().splice(AfterCallBB, Caller->getBasicBlockList(),
LastBlock, Caller->end());
// We should always be able to fold the entry block of the function into the
@@ -170,8 +257,8 @@ bool InlineFunction(CallInst *CI) {
// Okay, continue the CFG cleanup. It's often the case that there is only a
// single return instruction in the callee function. If this is the case,
- // then we have an unconditional branch from the return block to the 'NewBB'.
- // Check for this case, and eliminate the branch is possible.
- SimplifyCFG(NewBB);
+ // then we have an unconditional branch from the return block to the
+ // 'AfterCallBB'. Check for this case, and eliminate the branch is possible.
+ SimplifyCFG(AfterCallBB);
return true;
}