diff options
author | Chris Lattner <sabre@nondot.org> | 2003-08-24 06:59:16 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-08-24 06:59:16 +0000 |
commit | 80a38d245359cb0a3be8f78f5d7d911232886b9a (patch) | |
tree | 05213fc3a5ea32167b17fc56f8c4dd80df4a3aa1 /lib | |
parent | 9d3a1b2d972baf72b7da371a1ae72126bc5c6c04 (diff) | |
download | external_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.cpp | 189 |
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; } |