From 4ba01ec869a82800490747646b8b02cab203484f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Apr 2010 23:07:58 +0000 Subject: [PATCH] refactor the interface to InlineFunction so that most of the in/out arguments are handled with a new InlineFunctionInfo class. This makes it easier to extend InlineFunction to return more info in the future. llvm-svn: 102137 --- llvm/include/llvm/Transforms/Utils/Cloning.h | 40 ++++++++++++------ llvm/lib/Transforms/IPO/Inliner.cpp | 13 +++--- llvm/lib/Transforms/IPO/PartialInlining.cpp | 10 +++-- .../Scalar/SimplifyHalfPowrLibCalls.cpp | 3 +- llvm/lib/Transforms/Utils/BasicInliner.cpp | 3 +- llvm/lib/Transforms/Utils/InlineFunction.cpp | 42 +++++++++---------- 6 files changed, 64 insertions(+), 47 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h index 5f494fb50d39..4b6025b6be72 100644 --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -19,6 +19,7 @@ #define LLVM_TRANSFORMS_UTILS_CLONING_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" namespace llvm { @@ -40,7 +41,6 @@ class TargetData; class Loop; class LoopInfo; class AllocaInst; -template class SmallVectorImpl; /// CloneModule - Return an exact copy of the specified module /// @@ -158,6 +158,29 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, const TargetData *TD = 0, Instruction *TheCall = 0); + +/// InlineFunctionInfo - This class captures the data input to the +/// InlineFunction call, and records the auxiliary results produced by it. +class InlineFunctionInfo { +public: + explicit InlineFunctionInfo(CallGraph *cg = 0, const TargetData *td = 0) + : CG(cg), TD(td) {} + + /// CG - If non-null, InlineFunction will update the callgraph to reflect the + /// changes it makes. + CallGraph *CG; + const TargetData *TD; + + /// StaticAllocas - InlineFunction fills this in with all static allocas that + /// get copied into the caller. + SmallVector StaticAllocas; + + + void reset() { + StaticAllocas.clear(); + } +}; + /// 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 @@ -168,18 +191,9 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, /// exists in the instruction stream. Similiarly this will inline a recursive /// function by one level. /// -/// If a non-null callgraph pointer is provided, these functions update the -/// CallGraph to represent the program after inlining. -/// -/// If StaticAllocas is non-null, InlineFunction populates it with all of the -/// static allocas that it inlines into the caller. -/// -bool InlineFunction(CallInst *C, CallGraph *CG = 0, const TargetData *TD = 0, - SmallVectorImpl *StaticAllocas = 0); -bool InlineFunction(InvokeInst *II, CallGraph *CG = 0, const TargetData *TD = 0, - SmallVectorImpl *StaticAllocas = 0); -bool InlineFunction(CallSite CS, CallGraph *CG = 0, const TargetData *TD = 0, - SmallVectorImpl *StaticAllocas = 0); +bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI); +bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI); +bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI); } // End llvm namespace diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 6c732d21f28d..19b65e8e1f96 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -73,16 +73,14 @@ InlinedArrayAllocasTy; /// available from other functions inlined into the caller. If we are able to /// inline this call site we attempt to reuse already available allocas or add /// any new allocas to the set if not possible. -static bool InlineCallIfPossible(CallSite CS, CallGraph &CG, - const TargetData *TD, +static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI, InlinedArrayAllocasTy &InlinedArrayAllocas) { Function *Callee = CS.getCalledFunction(); Function *Caller = CS.getCaller(); // Try to inline the function. Get the list of static allocas that were // inlined. - SmallVector StaticAllocas; - if (!InlineFunction(CS, &CG, TD, &StaticAllocas)) + if (!InlineFunction(CS, IFI)) return false; // If the inlined function had a higher stack protection level than the @@ -119,9 +117,9 @@ static bool InlineCallIfPossible(CallSite CS, CallGraph &CG, // Loop over all the allocas we have so far and see if they can be merged with // a previously inlined alloca. If not, remember that we had it. - for (unsigned AllocaNo = 0, e = StaticAllocas.size(); + for (unsigned AllocaNo = 0, e = IFI.StaticAllocas.size(); AllocaNo != e; ++AllocaNo) { - AllocaInst *AI = StaticAllocas[AllocaNo]; + AllocaInst *AI = IFI.StaticAllocas[AllocaNo]; // Don't bother trying to merge array allocations (they will usually be // canonicalized to be an allocation *of* an array), or allocations whose @@ -347,6 +345,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { InlinedArrayAllocasTy InlinedArrayAllocas; + InlineFunctionInfo InlineInfo(&CG, TD); // Now that we have all of the call sites, loop over them and inline them if // it looks profitable to do so. @@ -385,7 +384,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { continue; // Attempt to inline the function... - if (!InlineCallIfPossible(CS, CG, TD, InlinedArrayAllocas)) + if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas)) continue; ++NumInlined; diff --git a/llvm/lib/Transforms/IPO/PartialInlining.cpp b/llvm/lib/Transforms/IPO/PartialInlining.cpp index f8ec72227380..07525eaada5e 100644 --- a/llvm/lib/Transforms/IPO/PartialInlining.cpp +++ b/llvm/lib/Transforms/IPO/PartialInlining.cpp @@ -120,15 +120,17 @@ Function* PartialInliner::unswitchFunction(Function* F) { // Extract the body of the if. Function* extractedFunction = ExtractCodeRegion(DT, toExtract); + InlineFunctionInfo IFI; + // Inline the top-level if test into all callers. std::vector Users(duplicateFunction->use_begin(), duplicateFunction->use_end()); for (std::vector::iterator UI = Users.begin(), UE = Users.end(); UI != UE; ++UI) - if (CallInst* CI = dyn_cast(*UI)) - InlineFunction(CI); - else if (InvokeInst* II = dyn_cast(*UI)) - InlineFunction(II); + if (CallInst *CI = dyn_cast(*UI)) + InlineFunction(CI, IFI); + else if (InvokeInst *II = dyn_cast(*UI)) + InlineFunction(II, IFI); // Ditch the duplicate, since we're done with it, and rewrite all remaining // users (function pointers, etc.) back to the original function. diff --git a/llvm/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp b/llvm/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp index 4464961a0799..c3408e77807f 100644 --- a/llvm/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp +++ b/llvm/lib/Transforms/Scalar/SimplifyHalfPowrLibCalls.cpp @@ -93,7 +93,8 @@ InlineHalfPowrs(const std::vector &HalfPowrs, // Inline the call, taking care of what code ends up where. NewBlock = SplitBlock(NextInst->getParent(), NextInst, this); - bool B = InlineFunction(Call, 0, TD); + InlineFunctionInfo IFI(0, TD); + bool B = InlineFunction(Call, IFI); assert(B && "half_powr didn't inline?"); B=B; BasicBlock *NewBody = NewBlock->getSinglePredecessor(); diff --git a/llvm/lib/Transforms/Utils/BasicInliner.cpp b/llvm/lib/Transforms/Utils/BasicInliner.cpp index c580b8fed98c..f0e31efa30c4 100644 --- a/llvm/lib/Transforms/Utils/BasicInliner.cpp +++ b/llvm/lib/Transforms/Utils/BasicInliner.cpp @@ -129,7 +129,8 @@ void BasicInlinerImpl::inlineFunctions() { } // Inline - if (InlineFunction(CS, NULL, TD)) { + InlineFunctionInfo IFI(0, TD); + if (InlineFunction(CS, IFI)) { if (Callee->use_empty() && (Callee->hasLocalLinkage() || Callee->hasAvailableExternallyLinkage())) DeadFunctions.insert(Callee); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 9425821ce051..5629a38709b4 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -28,13 +28,11 @@ #include "llvm/Support/CallSite.h" using namespace llvm; -bool llvm::InlineFunction(CallInst *CI, CallGraph *CG, const TargetData *TD, - SmallVectorImpl *StaticAllocas) { - return InlineFunction(CallSite(CI), CG, TD, StaticAllocas); +bool llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI) { + return InlineFunction(CallSite(CI), IFI); } -bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD, - SmallVectorImpl *StaticAllocas) { - return InlineFunction(CallSite(II), CG, TD, StaticAllocas); +bool llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI) { + return InlineFunction(CallSite(II), IFI); } @@ -232,13 +230,15 @@ static void UpdateCallGraphAfterInlining(CallSite CS, // exists in the instruction stream. Similiarly this will inline a recursive // function by one level. // -bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, - SmallVectorImpl *StaticAllocas) { +bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) { Instruction *TheCall = CS.getInstruction(); LLVMContext &Context = TheCall->getContext(); assert(TheCall->getParent() && TheCall->getParent()->getParent() && "Instruction not in function!"); + // If IFI has any state in it, zap it before we fill it in. + IFI.reset(); + const Function *CalledFunc = CS.getCalledFunction(); if (CalledFunc == 0 || // Can't inline external function or indirect CalledFunc->isDeclaration() || // call, or call to a vararg function! @@ -305,7 +305,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, // Create the alloca. If we have TargetData, use nice alignment. unsigned Align = 1; - if (TD) Align = TD->getPrefTypeAlignment(AggTy); + if (IFI.TD) Align = IFI.TD->getPrefTypeAlignment(AggTy); Value *NewAlloca = new AllocaInst(AggTy, 0, Align, I->getName(), &*Caller->begin()->begin()); @@ -318,11 +318,11 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, Value *SrcCast = new BitCastInst(*AI, VoidPtrTy, "tmp", TheCall); Value *Size; - if (TD == 0) + if (IFI.TD == 0) Size = ConstantExpr::getSizeOf(AggTy); else Size = ConstantInt::get(Type::getInt64Ty(Context), - TD->getTypeStoreSize(AggTy)); + IFI.TD->getTypeStoreSize(AggTy)); // Always generate a memcpy of alignment 1 here because we don't know // the alignment of the src pointer. Other optimizations can infer @@ -336,7 +336,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, CallInst::Create(MemCpyFn, CallArgs, CallArgs+5, "", TheCall); // If we have a call graph, update it. - if (CG) { + if (CallGraph *CG = IFI.CG) { CallGraphNode *MemCpyCGN = CG->getOrInsertFunction(MemCpyFn); CallGraphNode *CallerNode = (*CG)[Caller]; CallerNode->addCalledFunction(TheMemCpy, MemCpyCGN); @@ -355,14 +355,14 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, // (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, TD, TheCall); + &InlinedFunctionInfo, IFI.TD, TheCall); // Remember the first block that is newly cloned over. FirstNewBlock = LastBlock; ++FirstNewBlock; // Update the callgraph if requested. - if (CG) - UpdateCallGraphAfterInlining(CS, FirstNewBlock, ValueMap, *CG); + if (IFI.CG) + UpdateCallGraphAfterInlining(CS, FirstNewBlock, ValueMap, *IFI.CG); } // If there are any alloca instructions in the block that used to be the entry @@ -389,13 +389,13 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, // Keep track of the static allocas that we inline into the caller if the // StaticAllocas pointer is non-null. - if (StaticAllocas) StaticAllocas->push_back(AI); + IFI.StaticAllocas.push_back(AI); // Scan for the block of allocas that we can move over, and move them // all at once. while (isa(I) && isa(cast(I)->getArraySize())) { - if (StaticAllocas) StaticAllocas->push_back(cast(I)); + IFI.StaticAllocas.push_back(cast(I)); ++I; } @@ -419,7 +419,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, // 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) { + if (CallGraph *CG = IFI.CG) { StackSaveCGN = CG->getOrInsertFunction(StackSave); StackRestoreCGN = CG->getOrInsertFunction(StackRestore); CallerNode = (*CG)[Caller]; @@ -428,13 +428,13 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, // Insert the llvm.stacksave. CallInst *SavedPtr = CallInst::Create(StackSave, "savedstack", FirstNewBlock->begin()); - if (CG) CallerNode->addCalledFunction(SavedPtr, StackSaveCGN); + if (IFI.CG) CallerNode->addCalledFunction(SavedPtr, StackSaveCGN); // Insert a call to llvm.stackrestore before any return instructions in the // inlined function. for (unsigned i = 0, e = Returns.size(); i != e; ++i) { CallInst *CI = CallInst::Create(StackRestore, SavedPtr, "", Returns[i]); - if (CG) CallerNode->addCalledFunction(CI, StackRestoreCGN); + if (IFI.CG) CallerNode->addCalledFunction(CI, StackRestoreCGN); } // Count the number of StackRestore calls we insert. @@ -447,7 +447,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD, BB != E; ++BB) if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { CallInst *CI = CallInst::Create(StackRestore, SavedPtr, "", UI); - if (CG) CallerNode->addCalledFunction(CI, StackRestoreCGN); + if (IFI.CG) CallerNode->addCalledFunction(CI, StackRestoreCGN); ++NumStackRestores; } }