X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FTransforms%2FUtils%2FCloning.h;h=7fac6615d97e54f910b5100f14db910c3a779c84;hp=be15d6cd02509c9cd2c372f6a8be766b0ef9b9b3;hb=c94da20917cb4dfa750903b366c920210c5265ee;hpb=7ed47a13356daed2a34cd2209a31f92552e3bdd8 diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index be15d6cd025..7fac6615d97 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -18,14 +18,17 @@ #ifndef LLVM_TRANSFORMS_UTILS_CLONING_H #define LLVM_TRANSFORMS_UTILS_CLONING_H -#include -#include "llvm/ADT/DenseMap.h" -#include "llvm/Analysis/LoopInfo.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Twine.h" +#include "llvm/IR/ValueHandle.h" +#include "llvm/IR/ValueMap.h" +#include "llvm/Transforms/Utils/ValueMapper.h" namespace llvm { class Module; class Function; +class Instruction; class Pass; class LPPassManager; class BasicBlock; @@ -36,12 +39,17 @@ class ReturnInst; class CallSite; class Trace; class CallGraph; -class TargetData; +class DataLayout; +class Loop; +class LoopInfo; +class AllocaInst; +class AliasAnalysis; +class AssumptionCacheTracker; /// CloneModule - Return an exact copy of the specified module /// Module *CloneModule(const Module *M); -Module *CloneModule(const Module *M, DenseMap &ValueMap); +Module *CloneModule(const Module *M, ValueToValueMapTy &VMap); /// ClonedCodeInfo - This struct can be used to capture information about code /// being cloned, while it is being cloned. @@ -49,24 +57,15 @@ struct ClonedCodeInfo { /// ContainsCalls - This is set to true if the cloned code contains a normal /// call instruction. bool ContainsCalls; - - /// ContainsUnwinds - This is set to true if the cloned code contains an - /// unwind instruction. - bool ContainsUnwinds; - + /// ContainsDynamicAllocas - This is set to true if the cloned code contains /// a 'dynamic' alloca. Dynamic allocas are allocas that are either not in /// the entry block or they are in the entry block but are not a constant /// size. bool ContainsDynamicAllocas; - - ClonedCodeInfo() { - ContainsCalls = false; - ContainsUnwinds = false; - ContainsDynamicAllocas = false; - } -}; + ClonedCodeInfo() : ContainsCalls(false), ContainsDynamicAllocas(false) {} +}; /// CloneBasicBlock - Return a copy of the specified basic block, but without /// embedding the block into a particular function. The block returned is an @@ -84,7 +83,7 @@ struct ClonedCodeInfo { /// incoming edges. /// /// The correlation between instructions in the source and result basic blocks -/// is recorded in the ValueMap map. +/// is recorded in the VMap map. /// /// If you have a particular suffix you'd like to use to add to any cloned /// names, specify it as the optional third parameter. @@ -96,48 +95,78 @@ struct ClonedCodeInfo { /// function, you can specify a ClonedCodeInfo object with the optional fifth /// parameter. /// -BasicBlock *CloneBasicBlock(const BasicBlock *BB, - DenseMap &ValueMap, - const char *NameSuffix = "", Function *F = 0, - ClonedCodeInfo *CodeInfo = 0); - - -/// CloneLoop - Clone Loop. Clone dominator info for loop insiders. Populate ValueMap -/// using old blocks to new blocks mapping. -Loop *CloneLoop(Loop *L, LPPassManager *LPM, LoopInfo *LI, - DenseMap &ValueMap, Pass *P); +BasicBlock *CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, + const Twine &NameSuffix = "", Function *F = nullptr, + ClonedCodeInfo *CodeInfo = nullptr); /// CloneFunction - Return a copy of the specified function, but without /// embedding the function into another module. Also, any references specified -/// in the ValueMap are changed to refer to their mapped value instead of the -/// original one. If any of the arguments to the function are in the ValueMap, -/// the arguments are deleted from the resultant function. The ValueMap is +/// in the VMap are changed to refer to their mapped value instead of the +/// original one. If any of the arguments to the function are in the VMap, +/// the arguments are deleted from the resultant function. The VMap is /// updated to include mappings from all of the instructions and basicblocks in /// the function from their old to new values. The final argument captures /// information about the cloned code if non-null. /// -Function *CloneFunction(const Function *F, - DenseMap &ValueMap, - ClonedCodeInfo *CodeInfo = 0); - -/// CloneFunction - Version of the function that doesn't need the ValueMap. +/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue +/// mappings, and debug info metadata will not be cloned. /// -inline Function *CloneFunction(const Function *F, ClonedCodeInfo *CodeInfo = 0){ - DenseMap ValueMap; - return CloneFunction(F, ValueMap, CodeInfo); -} +Function *CloneFunction(const Function *F, ValueToValueMapTy &VMap, + bool ModuleLevelChanges, + ClonedCodeInfo *CodeInfo = nullptr); /// Clone OldFunc into NewFunc, transforming the old arguments into references -/// to ArgMap values. Note that if NewFunc already has basic blocks, the ones +/// to VMap values. Note that if NewFunc already has basic blocks, the ones /// cloned into it will be added to the end of the function. This function -/// fills in a list of return instructions, and can optionally append the -/// specified suffix to all values cloned. +/// fills in a list of return instructions, and can optionally remap types +/// and/or append the specified suffix to all values cloned. +/// +/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue +/// mappings. /// void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, - DenseMap &ValueMap, - std::vector &Returns, - const char *NameSuffix = "", - ClonedCodeInfo *CodeInfo = 0); + ValueToValueMapTy &VMap, bool ModuleLevelChanges, + SmallVectorImpl &Returns, + const char *NameSuffix = "", + ClonedCodeInfo *CodeInfo = nullptr, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr); + +/// A helper class used with CloneAndPruneIntoFromInst to change the default +/// behavior while instructions are being cloned. +class CloningDirector { +public: + /// This enumeration describes the way CloneAndPruneIntoFromInst should + /// proceed after the CloningDirector has examined an instruction. + enum CloningAction { + ///< Continue cloning the instruction (default behavior). + CloneInstruction, + ///< Skip this instruction but continue cloning the current basic block. + SkipInstruction, + ///< Skip this instruction and stop cloning the current basic block. + StopCloningBB + }; + + virtual ~CloningDirector() {} + + /// Subclasses must override this function to customize cloning behavior. + virtual CloningAction handleInstruction(ValueToValueMapTy &VMap, + const Instruction *Inst, + BasicBlock *NewBB) = 0; + + virtual ValueMapTypeRemapper *getTypeRemapper() { return nullptr; } + virtual ValueMaterializer *getValueMaterializer() { return nullptr; } +}; + +void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, + const Instruction *StartingInst, + ValueToValueMapTy &VMap, bool ModuleLevelChanges, + SmallVectorImpl &Returns, + const char *NameSuffix = "", + ClonedCodeInfo *CodeInfo = nullptr, + const DataLayout *DL = nullptr, + CloningDirector *Director = nullptr); + /// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto, /// except that it does some simple constant prop and DCE on the fly. The @@ -146,26 +175,46 @@ void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, /// constant arguments cause a significant amount of code in the callee to be /// dead. Since this doesn't produce an exactly copy of the input, it can't be /// used for things like CloneFunction or CloneModule. -void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, - DenseMap &ValueMap, - std::vector &Returns, - const char *NameSuffix = "", - ClonedCodeInfo *CodeInfo = 0, - const TargetData *TD = 0); - - -/// CloneTraceInto - Clone T into NewFunc. Original<->clone mapping is -/// saved in ValueMap. /// -void CloneTraceInto(Function *NewFunc, Trace &T, - DenseMap &ValueMap, - const char *NameSuffix); - -/// CloneTrace - Returns a copy of the specified trace. -/// It takes a vector of basic blocks clones the basic blocks, removes internal -/// phi nodes, adds it to the same function as the original (although there is -/// no jump to it) and returns the new vector of basic blocks. -std::vector CloneTrace(const std::vector &origTrace); +/// If ModuleLevelChanges is false, VMap contains no non-identity GlobalValue +/// mappings. +/// +void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, + ValueToValueMapTy &VMap, bool ModuleLevelChanges, + SmallVectorImpl &Returns, + const char *NameSuffix = "", + ClonedCodeInfo *CodeInfo = nullptr, + const DataLayout *DL = nullptr, + Instruction *TheCall = nullptr); + +/// 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 = nullptr, + AliasAnalysis *AA = nullptr, + AssumptionCacheTracker *ACT = nullptr) + : CG(cg), AA(AA), ACT(ACT) {} + + /// CG - If non-null, InlineFunction will update the callgraph to reflect the + /// changes it makes. + CallGraph *CG; + AliasAnalysis *AA; + AssumptionCacheTracker *ACT; + + /// StaticAllocas - InlineFunction fills this in with all static allocas that + /// get copied into the caller. + SmallVector StaticAllocas; + + /// InlinedCalls - InlineFunction fills this in with callsites that were + /// inlined from the callee. This is only filled in if CG is non-null. + SmallVector InlinedCalls; + + void reset() { + StaticAllocas.clear(); + InlinedCalls.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 @@ -174,15 +223,15 @@ std::vector CloneTrace(const std::vector &origTrace); /// /// Note that this only does one level of inlining. For example, if the /// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now -/// exists in the instruction stream. Similiarly this will inline a recursive +/// exists in the instruction stream. Similarly 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. -/// -bool InlineFunction(CallInst *C, CallGraph *CG = 0, const TargetData *TD = 0); -bool InlineFunction(InvokeInst *II, CallGraph *CG = 0, const TargetData *TD =0); -bool InlineFunction(CallSite CS, CallGraph *CG = 0, const TargetData *TD = 0); +bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, + bool InsertLifetime = true); +bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, + bool InsertLifetime = true); +bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, + bool InsertLifetime = true); } // End llvm namespace