X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FUtils%2FInlineFunction.cpp;h=0a9aa7a8d751fc2fe35590852b950e729ff6412f;hp=b61a85be9d992ee31c205f3e9d3439cf7eb79962;hb=0e13821c96937830ec817f08095c3cef1fdcac8d;hpb=33bb3c8be355d179ece8e751f6e0f0978d0dd038 diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index b61a85be9d9..0a9aa7a8d75 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -19,14 +19,15 @@ #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/CallSite.h" using namespace llvm; -bool llvm::InlineFunction(CallInst *CI, CallGraph *CG) { - return InlineFunction(CallSite(CI), CG); +bool llvm::InlineFunction(CallInst *CI, CallGraph *CG, const TargetData *TD) { + return InlineFunction(CallSite(CI), CG, TD); } -bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG) { - return InlineFunction(CallSite(II), CG); +bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD) { + return InlineFunction(CallSite(II), CG, TD); } /// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls @@ -68,23 +69,23 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, if (!isa(I)) continue; CallInst *CI = cast(I); - // If this is an intrinsic function call, don't convert it to an - // invoke. - if (CI->getCalledFunction() && - CI->getCalledFunction()->getIntrinsicID()) + // If this call cannot unwind, don't convert it to an invoke. + if (CI->doesNotThrow()) continue; - + // Convert this function call into an invoke instruction. // 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. + SmallVector InvokeArgs(CI->op_begin()+1, CI->op_end()); InvokeInst *II = new InvokeInst(CI->getCalledValue(), Split, InvokeDest, - std::vector(CI->op_begin()+1, CI->op_end()), + InvokeArgs.begin(), InvokeArgs.end(), CI->getName(), BB->getTerminator()); II->setCallingConv(CI->getCallingConv()); + II->setParamAttrs(CI->getParamAttrs()); // Make sure that anything using the call now uses the invoke! CI->replaceAllUsesWith(II); @@ -143,7 +144,7 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, static void UpdateCallGraphAfterInlining(const Function *Caller, const Function *Callee, Function::iterator FirstNewBlock, - std::map &ValueMap, + DenseMap &ValueMap, CallGraph &CG) { // Update the call graph by deleting the edge from Callee to Caller CallGraphNode *CalleeNode = CG[Callee]; @@ -156,7 +157,7 @@ static void UpdateCallGraphAfterInlining(const Function *Caller, E = CalleeNode->end(); I != E; ++I) { const Instruction *OrigCall = I->first.getInstruction(); - std::map::iterator VMI = ValueMap.find(OrigCall); + DenseMap::iterator VMI = ValueMap.find(OrigCall); // Only copy the edge if the call was inlined! if (VMI != ValueMap.end() && VMI->second) { // If the call was inlined, but then constant folded, there is no edge to @@ -177,14 +178,14 @@ static void UpdateCallGraphAfterInlining(const Function *Caller, // exists in the instruction stream. Similiarly this will inline a recursive // function by one level. // -bool llvm::InlineFunction(CallSite CS, CallGraph *CG) { +bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) { Instruction *TheCall = CS.getInstruction(); assert(TheCall->getParent() && TheCall->getParent()->getParent() && "Instruction not in function!"); 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->isDeclaration() || // call, or call to a vararg function! CalledFunc->getFunctionType()->isVarArg()) return false; @@ -193,9 +194,26 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG) { bool MustClearTailCallFlags = isa(TheCall) && !cast(TheCall)->isTailCall(); + // If the call to the callee cannot throw, set the 'nounwind' flag on any + // calls that we inline. + bool MarkNoUnwind = CS.doesNotThrow(); + BasicBlock *OrigBB = TheCall->getParent(); Function *Caller = OrigBB->getParent(); + + // GC poses two hazards to inlining, which only occur when the callee has GC: + // 1. If the caller has no GC, then the callee's GC must be propagated to the + // caller. + // 2. If the caller has a differing GC, it is invalid to inline. + if (CalledFunc->hasCollector()) { + if (!Caller->hasCollector()) + Caller->setCollector(CalledFunc->getCollector()); + else if (CalledFunc->getCollector() != Caller->getCollector()) + return false; + } + + // Get an iterator to the last basic block in the function, which will have // the new function inlined after it. // @@ -206,9 +224,9 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG) { std::vector Returns; ClonedCodeInfo InlinedFunctionInfo; Function::iterator FirstNewBlock; - + { // Scope to destroy ValueMap after cloning. - std::map ValueMap; + DenseMap ValueMap; // Calculate the vector of arguments to pass into the function cloner, which // matches up the formal to the actual argument values. @@ -225,7 +243,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG) { // (which can happen, e.g., because an argument was constant), but we'll be // happy with whatever the cloner can do. CloneAndPruneFunctionInto(Caller, CalledFunc, ValueMap, Returns, ".i", - &InlinedFunctionInfo); + &InlinedFunctionInfo, TD); // Remember the first block that is newly cloned over. FirstNewBlock = LastBlock; ++FirstNewBlock; @@ -261,11 +279,12 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG) { ++I; // Transfer all of the allocas over in a block. Using splice means - // that they instructions aren't removed from the symbol table, then + // that the instructions aren't removed from the symbol table, then // reinserted. - Caller->front().getInstList().splice(InsertPoint, - FirstNewBlock->getInstList(), - AI, I); + Caller->getEntryBlock().getInstList().splice( + InsertPoint, + FirstNewBlock->getInstList(), + AI, I); } } } @@ -274,19 +293,21 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG) { // code with llvm.stacksave/llvm.stackrestore intrinsics. if (InlinedFunctionInfo.ContainsDynamicAllocas) { Module *M = Caller->getParent(); - const Type *SBytePtr = PointerType::get(Type::SByteTy); + const Type *BytePtr = PointerType::getUnqual(Type::Int8Ty); // Get the two intrinsics we care about. - Function *StackSave, *StackRestore; - StackSave = M->getOrInsertFunction("llvm.stacksave", SBytePtr, NULL); + Constant *StackSave, *StackRestore; + StackSave = M->getOrInsertFunction("llvm.stacksave", BytePtr, NULL); StackRestore = M->getOrInsertFunction("llvm.stackrestore", Type::VoidTy, - SBytePtr, NULL); + BytePtr, NULL); // If we are preserving the callgraph, add edges to the stacksave/restore // functions for the calls we insert. CallGraphNode *StackSaveCGN = 0, *StackRestoreCGN = 0, *CallerNode = 0; if (CG) { - StackSaveCGN = CG->getOrInsertFunction(StackSave); - StackRestoreCGN = CG->getOrInsertFunction(StackRestore); + // We know that StackSave/StackRestore are Function*'s, because they are + // intrinsics which must have the right types. + StackSaveCGN = CG->getOrInsertFunction(cast(StackSave)); + StackRestoreCGN = CG->getOrInsertFunction(cast(StackRestore)); CallerNode = (*CG)[Caller]; } @@ -319,15 +340,33 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG) { // If we are inlining tail call instruction through a call site that isn't // marked 'tail', we must remove the tail marker for any calls in the inlined - // code. - if (MustClearTailCallFlags && InlinedFunctionInfo.ContainsCalls) { + // code. Also, calls inlined through a 'nounwind' call site should be marked + // 'nounwind'. + if (InlinedFunctionInfo.ContainsCalls && + (MustClearTailCallFlags || MarkNoUnwind)) { for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (CallInst *CI = dyn_cast(I)) - CI->setTailCall(false); + if (CallInst *CI = dyn_cast(I)) { + if (MustClearTailCallFlags) + CI->setTailCall(false); + if (MarkNoUnwind) + CI->setDoesNotThrow(); + } } + // If we are inlining through a 'nounwind' call site then any inlined 'unwind' + // instructions are unreachable. + if (InlinedFunctionInfo.ContainsUnwinds && MarkNoUnwind) + for (Function::iterator BB = FirstNewBlock, E = Caller->end(); + BB != E; ++BB) { + TerminatorInst *Term = BB->getTerminator(); + if (isa(Term)) { + new UnreachableInst(Term); + BB->getInstList().erase(Term); + } + } + // 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.