diff options
Diffstat (limited to 'include/llvm/Analysis')
56 files changed, 4539 insertions, 1773 deletions
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 36f8199a03224..5cc840a64a627 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -41,10 +41,11 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Metadata.h" +#include "llvm/IR/PassManager.h" #include "llvm/Analysis/MemoryLocation.h" namespace llvm { - +class BasicAAResult; class LoadInst; class StoreInst; class VAArgInst; @@ -55,6 +56,7 @@ class AnalysisUsage; class MemTransferInst; class MemIntrinsic; class DominatorTree; +class OrderedBasicBlock; /// The possible results of an alias query. /// @@ -84,462 +86,871 @@ enum AliasResult { MustAlias, }; -class AliasAnalysis { -protected: - const DataLayout *DL; - const TargetLibraryInfo *TLI; +/// Flags indicating whether a memory access modifies or references memory. +/// +/// This is no access at all, a modification, a reference, or both +/// a modification and a reference. These are specifically structured such that +/// they form a two bit matrix and bit-tests for 'mod' or 'ref' work with any +/// of the possible values. +enum ModRefInfo { + /// The access neither references nor modifies the value stored in memory. + MRI_NoModRef = 0, + /// The access references the value stored in memory. + MRI_Ref = 1, + /// The access modifies the value stored in memory. + MRI_Mod = 2, + /// The access both references and modifies the value stored in memory. + MRI_ModRef = MRI_Ref | MRI_Mod +}; -private: - AliasAnalysis *AA; // Previous Alias Analysis to chain to. +/// The locations at which a function might access memory. +/// +/// These are primarily used in conjunction with the \c AccessKind bits to +/// describe both the nature of access and the locations of access for a +/// function call. +enum FunctionModRefLocation { + /// Base case is no access to memory. + FMRL_Nowhere = 0, + /// Access to memory via argument pointers. + FMRL_ArgumentPointees = 4, + /// Access to any memory. + FMRL_Anywhere = 8 | FMRL_ArgumentPointees +}; -protected: - /// InitializeAliasAnalysis - Subclasses must call this method to initialize - /// the AliasAnalysis interface before any other methods are called. This is - /// typically called by the run* methods of these subclasses. This may be - /// called multiple times. +/// Summary of how a function affects memory in the program. +/// +/// Loads from constant globals are not considered memory accesses for this +/// interface. Also, functions may freely modify stack space local to their +/// invocation without having to report it through these interfaces. +enum FunctionModRefBehavior { + /// This function does not perform any non-local loads or stores to memory. /// - void InitializeAliasAnalysis(Pass *P, const DataLayout *DL); - - /// getAnalysisUsage - All alias analysis implementations should invoke this - /// directly (using AliasAnalysis::getAnalysisUsage(AU)). - virtual void getAnalysisUsage(AnalysisUsage &AU) const; + /// This property corresponds to the GCC 'const' attribute. + /// This property corresponds to the LLVM IR 'readnone' attribute. + /// This property corresponds to the IntrNoMem LLVM intrinsic flag. + FMRB_DoesNotAccessMemory = FMRL_Nowhere | MRI_NoModRef, -public: - static char ID; // Class identification, replacement for typeinfo - AliasAnalysis() : DL(nullptr), TLI(nullptr), AA(nullptr) {} - virtual ~AliasAnalysis(); // We want to be subclassed + /// The only memory references in this function (if it has any) are + /// non-volatile loads from objects pointed to by its pointer-typed + /// arguments, with arbitrary offsets. + /// + /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag. + FMRB_OnlyReadsArgumentPointees = FMRL_ArgumentPointees | MRI_Ref, - /// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo - /// object, or null if no TargetLibraryInfo object is available. + /// The only memory references in this function (if it has any) are + /// non-volatile loads and stores from objects pointed to by its + /// pointer-typed arguments, with arbitrary offsets. /// - const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; } + /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag. + FMRB_OnlyAccessesArgumentPointees = FMRL_ArgumentPointees | MRI_ModRef, - /// getTypeStoreSize - Return the DataLayout store size for the given type, - /// if known, or a conservative value otherwise. + /// This function does not perform any non-local stores or volatile loads, + /// but may read from any memory location. /// - uint64_t getTypeStoreSize(Type *Ty); + /// This property corresponds to the GCC 'pure' attribute. + /// This property corresponds to the LLVM IR 'readonly' attribute. + /// This property corresponds to the IntrReadMem LLVM intrinsic flag. + FMRB_OnlyReadsMemory = FMRL_Anywhere | MRI_Ref, + + /// This indicates that the function could not be classified into one of the + /// behaviors above. + FMRB_UnknownModRefBehavior = FMRL_Anywhere | MRI_ModRef +}; + +class AAResults { +public: + // Make these results default constructable and movable. We have to spell + // these out because MSVC won't synthesize them. + AAResults() {} + AAResults(AAResults &&Arg); + AAResults &operator=(AAResults &&Arg); + ~AAResults(); + + /// Register a specific AA result. + template <typename AAResultT> void addAAResult(AAResultT &AAResult) { + // FIXME: We should use a much lighter weight system than the usual + // polymorphic pattern because we don't own AAResult. It should + // ideally involve two pointers and no separate allocation. + AAs.emplace_back(new Model<AAResultT>(AAResult, *this)); + } //===--------------------------------------------------------------------===// - /// Alias Queries... - /// + /// \name Alias Queries + /// @{ - /// alias - The main low level interface to the alias analysis implementation. + /// The main low level interface to the alias analysis implementation. /// Returns an AliasResult indicating whether the two pointers are aliased to - /// each other. This is the interface that must be implemented by specific + /// each other. This is the interface that must be implemented by specific /// alias analysis implementations. - virtual AliasResult alias(const MemoryLocation &LocA, - const MemoryLocation &LocB); + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); - /// alias - A convenience wrapper. - AliasResult alias(const Value *V1, uint64_t V1Size, - const Value *V2, uint64_t V2Size) { + /// A convenience wrapper around the primary \c alias interface. + AliasResult alias(const Value *V1, uint64_t V1Size, const Value *V2, + uint64_t V2Size) { return alias(MemoryLocation(V1, V1Size), MemoryLocation(V2, V2Size)); } - /// alias - A convenience wrapper. + /// A convenience wrapper around the primary \c alias interface. AliasResult alias(const Value *V1, const Value *V2) { return alias(V1, MemoryLocation::UnknownSize, V2, MemoryLocation::UnknownSize); } - /// isNoAlias - A trivial helper function to check to see if the specified - /// pointers are no-alias. + /// A trivial helper function to check to see if the specified pointers are + /// no-alias. bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) { return alias(LocA, LocB) == NoAlias; } - /// isNoAlias - A convenience wrapper. - bool isNoAlias(const Value *V1, uint64_t V1Size, - const Value *V2, uint64_t V2Size) { + /// A convenience wrapper around the \c isNoAlias helper interface. + bool isNoAlias(const Value *V1, uint64_t V1Size, const Value *V2, + uint64_t V2Size) { return isNoAlias(MemoryLocation(V1, V1Size), MemoryLocation(V2, V2Size)); } - - /// isNoAlias - A convenience wrapper. + + /// A convenience wrapper around the \c isNoAlias helper interface. bool isNoAlias(const Value *V1, const Value *V2) { return isNoAlias(MemoryLocation(V1), MemoryLocation(V2)); } - - /// isMustAlias - A convenience wrapper. + + /// A trivial helper function to check to see if the specified pointers are + /// must-alias. bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB) { return alias(LocA, LocB) == MustAlias; } - /// isMustAlias - A convenience wrapper. + /// A convenience wrapper around the \c isMustAlias helper interface. bool isMustAlias(const Value *V1, const Value *V2) { return alias(V1, 1, V2, 1) == MustAlias; } - - /// pointsToConstantMemory - If the specified memory location is - /// known to be constant, return true. If OrLocal is true and the - /// specified memory location is known to be "local" (derived from - /// an alloca), return true. Otherwise return false. - virtual bool pointsToConstantMemory(const MemoryLocation &Loc, - bool OrLocal = false); - /// pointsToConstantMemory - A convenient wrapper. + /// Checks whether the given location points to constant memory, or if + /// \p OrLocal is true whether it points to a local alloca. + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false); + + /// A convenience wrapper around the primary \c pointsToConstantMemory + /// interface. bool pointsToConstantMemory(const Value *P, bool OrLocal = false) { return pointsToConstantMemory(MemoryLocation(P), OrLocal); } + /// @} //===--------------------------------------------------------------------===// - /// Simple mod/ref information... - /// - - /// ModRefResult - Represent the result of a mod/ref query. Mod and Ref are - /// bits which may be or'd together. - /// - enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 }; - - /// These values define additional bits used to define the - /// ModRefBehavior values. - enum { Nowhere = 0, ArgumentPointees = 4, Anywhere = 8 | ArgumentPointees }; - - /// ModRefBehavior - Summary of how a function affects memory in the program. - /// Loads from constant globals are not considered memory accesses for this - /// interface. Also, functions may freely modify stack space local to their - /// invocation without having to report it through these interfaces. - enum ModRefBehavior { - /// DoesNotAccessMemory - This function does not perform any non-local loads - /// or stores to memory. - /// - /// This property corresponds to the GCC 'const' attribute. - /// This property corresponds to the LLVM IR 'readnone' attribute. - /// This property corresponds to the IntrNoMem LLVM intrinsic flag. - DoesNotAccessMemory = Nowhere | NoModRef, - - /// OnlyReadsArgumentPointees - The only memory references in this function - /// (if it has any) are non-volatile loads from objects pointed to by its - /// pointer-typed arguments, with arbitrary offsets. - /// - /// This property corresponds to the LLVM IR 'argmemonly' attribute combined - /// with 'readonly' attribute. - /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag. - OnlyReadsArgumentPointees = ArgumentPointees | Ref, - - /// OnlyAccessesArgumentPointees - The only memory references in this - /// function (if it has any) are non-volatile loads and stores from objects - /// pointed to by its pointer-typed arguments, with arbitrary offsets. - /// - /// This property corresponds to the LLVM IR 'argmemonly' attribute. - /// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag. - OnlyAccessesArgumentPointees = ArgumentPointees | ModRef, - - /// OnlyReadsMemory - This function does not perform any non-local stores or - /// volatile loads, but may read from any memory location. - /// - /// This property corresponds to the GCC 'pure' attribute. - /// This property corresponds to the LLVM IR 'readonly' attribute. - /// This property corresponds to the IntrReadMem LLVM intrinsic flag. - OnlyReadsMemory = Anywhere | Ref, - - /// UnknownModRefBehavior - This indicates that the function could not be - /// classified into one of the behaviors above. - UnknownModRefBehavior = Anywhere | ModRef - }; + /// \name Simple mod/ref information + /// @{ /// Get the ModRef info associated with a pointer argument of a callsite. The /// result's bits are set to indicate the allowed aliasing ModRef kinds. Note /// that these bits do not necessarily account for the overall behavior of /// the function, but rather only provide additional per-argument /// information. - virtual ModRefResult getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); - /// getModRefBehavior - Return the behavior when calling the given call site. - virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS); + /// Return the behavior of the given call site. + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); - /// getModRefBehavior - Return the behavior when calling the given function. - /// For use when the call site is not known. - virtual ModRefBehavior getModRefBehavior(const Function *F); + /// Return the behavior when calling the given function. + FunctionModRefBehavior getModRefBehavior(const Function *F); - /// doesNotAccessMemory - If the specified call is known to never read or - /// write memory, return true. If the call only reads from known-constant - /// memory, it is also legal to return true. Calls that unwind the stack - /// are legal for this predicate. + /// Checks if the specified call is known to never read or write memory. + /// + /// Note that if the call only reads from known-constant memory, it is also + /// legal to return true. Also, calls that unwind the stack are legal for + /// this predicate. /// /// Many optimizations (such as CSE and LICM) can be performed on such calls /// without worrying about aliasing properties, and many calls have this /// property (e.g. calls to 'sin' and 'cos'). /// /// This property corresponds to the GCC 'const' attribute. - /// bool doesNotAccessMemory(ImmutableCallSite CS) { - return getModRefBehavior(CS) == DoesNotAccessMemory; + return getModRefBehavior(CS) == FMRB_DoesNotAccessMemory; } - /// doesNotAccessMemory - If the specified function is known to never read or - /// write memory, return true. For use when the call site is not known. + /// Checks if the specified function is known to never read or write memory. + /// + /// Note that if the function only reads from known-constant memory, it is + /// also legal to return true. Also, function that unwind the stack are legal + /// for this predicate. /// + /// Many optimizations (such as CSE and LICM) can be performed on such calls + /// to such functions without worrying about aliasing properties, and many + /// functions have this property (e.g. 'sin' and 'cos'). + /// + /// This property corresponds to the GCC 'const' attribute. bool doesNotAccessMemory(const Function *F) { - return getModRefBehavior(F) == DoesNotAccessMemory; + return getModRefBehavior(F) == FMRB_DoesNotAccessMemory; } - /// onlyReadsMemory - If the specified call is known to only read from - /// non-volatile memory (or not access memory at all), return true. Calls - /// that unwind the stack are legal for this predicate. + /// Checks if the specified call is known to only read from non-volatile + /// memory (or not access memory at all). + /// + /// Calls that unwind the stack are legal for this predicate. /// /// This property allows many common optimizations to be performed in the /// absence of interfering store instructions, such as CSE of strlen calls. /// /// This property corresponds to the GCC 'pure' attribute. - /// bool onlyReadsMemory(ImmutableCallSite CS) { return onlyReadsMemory(getModRefBehavior(CS)); } - /// onlyReadsMemory - If the specified function is known to only read from - /// non-volatile memory (or not access memory at all), return true. For use - /// when the call site is not known. + /// Checks if the specified function is known to only read from non-volatile + /// memory (or not access memory at all). + /// + /// Functions that unwind the stack are legal for this predicate. + /// + /// This property allows many common optimizations to be performed in the + /// absence of interfering store instructions, such as CSE of strlen calls. /// + /// This property corresponds to the GCC 'pure' attribute. bool onlyReadsMemory(const Function *F) { return onlyReadsMemory(getModRefBehavior(F)); } - /// onlyReadsMemory - Return true if functions with the specified behavior are - /// known to only read from non-volatile memory (or not access memory at all). - /// - static bool onlyReadsMemory(ModRefBehavior MRB) { - return !(MRB & Mod); + /// Checks if functions with the specified behavior are known to only read + /// from non-volatile memory (or not access memory at all). + static bool onlyReadsMemory(FunctionModRefBehavior MRB) { + return !(MRB & MRI_Mod); } - /// onlyAccessesArgPointees - Return true if functions with the specified - /// behavior are known to read and write at most from objects pointed to by - /// their pointer-typed arguments (with arbitrary offsets). - /// - static bool onlyAccessesArgPointees(ModRefBehavior MRB) { - return !(MRB & Anywhere & ~ArgumentPointees); + /// Checks if functions with the specified behavior are known to read and + /// write at most from objects pointed to by their pointer-typed arguments + /// (with arbitrary offsets). + static bool onlyAccessesArgPointees(FunctionModRefBehavior MRB) { + return !(MRB & FMRL_Anywhere & ~FMRL_ArgumentPointees); } - /// doesAccessArgPointees - Return true if functions with the specified - /// behavior are known to potentially read or write from objects pointed - /// to be their pointer-typed arguments (with arbitrary offsets). - /// - static bool doesAccessArgPointees(ModRefBehavior MRB) { - return (MRB & ModRef) && (MRB & ArgumentPointees); - } - - /// getModRefInfo - Return information about whether or not an - /// instruction may read or write memory (without regard to a - /// specific location) - ModRefResult getModRefInfo(const Instruction *I) { - if (auto CS = ImmutableCallSite(I)) { - auto MRB = getModRefBehavior(CS); - if (MRB & ModRef) - return ModRef; - else if (MRB & Ref) - return Ref; - else if (MRB & Mod) - return Mod; - return NoModRef; - } - - return getModRefInfo(I, MemoryLocation()); - } - - /// getModRefInfo - Return information about whether or not an instruction may - /// read or write the specified memory location. An instruction - /// that doesn't read or write memory may be trivially LICM'd for example. - ModRefResult getModRefInfo(const Instruction *I, const MemoryLocation &Loc) { - switch (I->getOpcode()) { - case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc); - case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc); - case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc); - case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc); - case Instruction::AtomicCmpXchg: - return getModRefInfo((const AtomicCmpXchgInst*)I, Loc); - case Instruction::AtomicRMW: - return getModRefInfo((const AtomicRMWInst*)I, Loc); - case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc); - case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc); - default: return NoModRef; - } - } - - /// getModRefInfo - A convenience wrapper. - ModRefResult getModRefInfo(const Instruction *I, - const Value *P, uint64_t Size) { - return getModRefInfo(I, MemoryLocation(P, Size)); + /// Checks if functions with the specified behavior are known to potentially + /// read or write from objects pointed to be their pointer-typed arguments + /// (with arbitrary offsets). + static bool doesAccessArgPointees(FunctionModRefBehavior MRB) { + return (MRB & MRI_ModRef) && (MRB & FMRL_ArgumentPointees); } /// getModRefInfo (for call sites) - Return information about whether /// a particular call site modifies or reads the specified memory location. - virtual ModRefResult getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc); + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); /// getModRefInfo (for call sites) - A convenience wrapper. - ModRefResult getModRefInfo(ImmutableCallSite CS, - const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(ImmutableCallSite CS, const Value *P, + uint64_t Size) { return getModRefInfo(CS, MemoryLocation(P, Size)); } /// getModRefInfo (for calls) - Return information about whether /// a particular call modifies or reads the specified memory location. - ModRefResult getModRefInfo(const CallInst *C, const MemoryLocation &Loc) { + ModRefInfo getModRefInfo(const CallInst *C, const MemoryLocation &Loc) { return getModRefInfo(ImmutableCallSite(C), Loc); } /// getModRefInfo (for calls) - A convenience wrapper. - ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) { return getModRefInfo(C, MemoryLocation(P, Size)); } /// getModRefInfo (for invokes) - Return information about whether /// a particular invoke modifies or reads the specified memory location. - ModRefResult getModRefInfo(const InvokeInst *I, const MemoryLocation &Loc) { + ModRefInfo getModRefInfo(const InvokeInst *I, const MemoryLocation &Loc) { return getModRefInfo(ImmutableCallSite(I), Loc); } /// getModRefInfo (for invokes) - A convenience wrapper. - ModRefResult getModRefInfo(const InvokeInst *I, - const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const InvokeInst *I, const Value *P, uint64_t Size) { return getModRefInfo(I, MemoryLocation(P, Size)); } /// getModRefInfo (for loads) - Return information about whether /// a particular load modifies or reads the specified memory location. - ModRefResult getModRefInfo(const LoadInst *L, const MemoryLocation &Loc); + ModRefInfo getModRefInfo(const LoadInst *L, const MemoryLocation &Loc); /// getModRefInfo (for loads) - A convenience wrapper. - ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) { + ModRefInfo getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) { return getModRefInfo(L, MemoryLocation(P, Size)); } /// getModRefInfo (for stores) - Return information about whether /// a particular store modifies or reads the specified memory location. - ModRefResult getModRefInfo(const StoreInst *S, const MemoryLocation &Loc); + ModRefInfo getModRefInfo(const StoreInst *S, const MemoryLocation &Loc); /// getModRefInfo (for stores) - A convenience wrapper. - ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){ + ModRefInfo getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size) { return getModRefInfo(S, MemoryLocation(P, Size)); } /// getModRefInfo (for fences) - Return information about whether /// a particular store modifies or reads the specified memory location. - ModRefResult getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) { + ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc) { // Conservatively correct. (We could possibly be a bit smarter if // Loc is a alloca that doesn't escape.) - return ModRef; + return MRI_ModRef; } /// getModRefInfo (for fences) - A convenience wrapper. - ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){ + ModRefInfo getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size) { return getModRefInfo(S, MemoryLocation(P, Size)); } /// getModRefInfo (for cmpxchges) - Return information about whether /// a particular cmpxchg modifies or reads the specified memory location. - ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, - const MemoryLocation &Loc); + ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX, + const MemoryLocation &Loc); /// getModRefInfo (for cmpxchges) - A convenience wrapper. - ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, - const Value *P, unsigned Size) { + ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX, const Value *P, + unsigned Size) { return getModRefInfo(CX, MemoryLocation(P, Size)); } /// getModRefInfo (for atomicrmws) - Return information about whether /// a particular atomicrmw modifies or reads the specified memory location. - ModRefResult getModRefInfo(const AtomicRMWInst *RMW, - const MemoryLocation &Loc); + ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc); /// getModRefInfo (for atomicrmws) - A convenience wrapper. - ModRefResult getModRefInfo(const AtomicRMWInst *RMW, - const Value *P, unsigned Size) { + ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const Value *P, + unsigned Size) { return getModRefInfo(RMW, MemoryLocation(P, Size)); } /// getModRefInfo (for va_args) - Return information about whether /// a particular va_arg modifies or reads the specified memory location. - ModRefResult getModRefInfo(const VAArgInst *I, const MemoryLocation &Loc); + ModRefInfo getModRefInfo(const VAArgInst *I, const MemoryLocation &Loc); /// getModRefInfo (for va_args) - A convenience wrapper. - ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){ + ModRefInfo getModRefInfo(const VAArgInst *I, const Value *P, uint64_t Size) { + return getModRefInfo(I, MemoryLocation(P, Size)); + } + + /// getModRefInfo (for catchpads) - Return information about whether + /// a particular catchpad modifies or reads the specified memory location. + ModRefInfo getModRefInfo(const CatchPadInst *I, const MemoryLocation &Loc); + + /// getModRefInfo (for catchpads) - A convenience wrapper. + ModRefInfo getModRefInfo(const CatchPadInst *I, const Value *P, + uint64_t Size) { + return getModRefInfo(I, MemoryLocation(P, Size)); + } + + /// getModRefInfo (for catchrets) - Return information about whether + /// a particular catchret modifies or reads the specified memory location. + ModRefInfo getModRefInfo(const CatchReturnInst *I, const MemoryLocation &Loc); + + /// getModRefInfo (for catchrets) - A convenience wrapper. + ModRefInfo getModRefInfo(const CatchReturnInst *I, const Value *P, + uint64_t Size) { + return getModRefInfo(I, MemoryLocation(P, Size)); + } + + /// Check whether or not an instruction may read or write memory (without + /// regard to a specific location). + /// + /// For function calls, this delegates to the alias-analysis specific + /// call-site mod-ref behavior queries. Otherwise it delegates to the generic + /// mod ref information query without a location. + ModRefInfo getModRefInfo(const Instruction *I) { + if (auto CS = ImmutableCallSite(I)) { + auto MRB = getModRefBehavior(CS); + if (MRB & MRI_ModRef) + return MRI_ModRef; + else if (MRB & MRI_Ref) + return MRI_Ref; + else if (MRB & MRI_Mod) + return MRI_Mod; + return MRI_NoModRef; + } + + return getModRefInfo(I, MemoryLocation()); + } + + /// Check whether or not an instruction may read or write the specified + /// memory location. + /// + /// An instruction that doesn't read or write memory may be trivially LICM'd + /// for example. + /// + /// This primarily delegates to specific helpers above. + ModRefInfo getModRefInfo(const Instruction *I, const MemoryLocation &Loc) { + switch (I->getOpcode()) { + case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc); + case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc); + case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc); + case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc); + case Instruction::AtomicCmpXchg: + return getModRefInfo((const AtomicCmpXchgInst*)I, Loc); + case Instruction::AtomicRMW: + return getModRefInfo((const AtomicRMWInst*)I, Loc); + case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc); + case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc); + case Instruction::CatchPad: + return getModRefInfo((const CatchPadInst *)I, Loc); + case Instruction::CatchRet: + return getModRefInfo((const CatchReturnInst *)I, Loc); + default: + return MRI_NoModRef; + } + } + + /// A convenience wrapper for constructing the memory location. + ModRefInfo getModRefInfo(const Instruction *I, const Value *P, + uint64_t Size) { return getModRefInfo(I, MemoryLocation(P, Size)); } - /// getModRefInfo - Return information about whether a call and an instruction - /// may refer to the same memory locations. - ModRefResult getModRefInfo(Instruction *I, - ImmutableCallSite Call); - /// getModRefInfo - Return information about whether two call sites may refer - /// to the same set of memory locations. See + /// Return information about whether a call and an instruction may refer to + /// the same memory locations. + ModRefInfo getModRefInfo(Instruction *I, ImmutableCallSite Call); + + /// Return information about whether two call sites may refer to the same set + /// of memory locations. See the AA documentation for details: /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo - /// for details. - virtual ModRefResult getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2); + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); - /// callCapturesBefore - Return information about whether a particular call - /// site modifies or reads the specified memory location. - ModRefResult callCapturesBefore(const Instruction *I, - const MemoryLocation &MemLoc, - DominatorTree *DT); + /// \brief Return information about whether a particular call site modifies + /// or reads the specified memory location \p MemLoc before instruction \p I + /// in a BasicBlock. A ordered basic block \p OBB can be used to speed up + /// instruction ordering queries inside the BasicBlock containing \p I. + ModRefInfo callCapturesBefore(const Instruction *I, + const MemoryLocation &MemLoc, DominatorTree *DT, + OrderedBasicBlock *OBB = nullptr); - /// callCapturesBefore - A convenience wrapper. - ModRefResult callCapturesBefore(const Instruction *I, const Value *P, - uint64_t Size, DominatorTree *DT) { - return callCapturesBefore(I, MemoryLocation(P, Size), DT); + /// \brief A convenience wrapper to synthesize a memory location. + ModRefInfo callCapturesBefore(const Instruction *I, const Value *P, + uint64_t Size, DominatorTree *DT, + OrderedBasicBlock *OBB = nullptr) { + return callCapturesBefore(I, MemoryLocation(P, Size), DT, OBB); } + /// @} //===--------------------------------------------------------------------===// - /// Higher level methods for querying mod/ref information. - /// + /// \name Higher level methods for querying mod/ref information. + /// @{ - /// canBasicBlockModify - Return true if it is possible for execution of the - /// specified basic block to modify the location Loc. + /// Check if it is possible for execution of the specified basic block to + /// modify the location Loc. bool canBasicBlockModify(const BasicBlock &BB, const MemoryLocation &Loc); - /// canBasicBlockModify - A convenience wrapper. - bool canBasicBlockModify(const BasicBlock &BB, const Value *P, uint64_t Size){ + /// A convenience wrapper synthesizing a memory location. + bool canBasicBlockModify(const BasicBlock &BB, const Value *P, + uint64_t Size) { return canBasicBlockModify(BB, MemoryLocation(P, Size)); } - /// canInstructionRangeModRef - Return true if it is possible for the - /// execution of the specified instructions to mod\ref (according to the - /// mode) the location Loc. The instructions to consider are all - /// of the instructions in the range of [I1,I2] INCLUSIVE. - /// I1 and I2 must be in the same basic block. + /// Check if it is possible for the execution of the specified instructions + /// to mod\ref (according to the mode) the location Loc. + /// + /// The instructions to consider are all of the instructions in the range of + /// [I1,I2] INCLUSIVE. I1 and I2 must be in the same basic block. bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2, const MemoryLocation &Loc, - const ModRefResult Mode); + const ModRefInfo Mode); - /// canInstructionRangeModRef - A convenience wrapper. - bool canInstructionRangeModRef(const Instruction &I1, - const Instruction &I2, const Value *Ptr, - uint64_t Size, const ModRefResult Mode) { + /// A convenience wrapper synthesizing a memory location. + bool canInstructionRangeModRef(const Instruction &I1, const Instruction &I2, + const Value *Ptr, uint64_t Size, + const ModRefInfo Mode) { return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode); } +private: + class Concept; + template <typename T> class Model; + + template <typename T> friend class AAResultBase; + + std::vector<std::unique_ptr<Concept>> AAs; +}; + +/// Temporary typedef for legacy code that uses a generic \c AliasAnalysis +/// pointer or reference. +typedef AAResults AliasAnalysis; + +/// A private abstract base class describing the concept of an individual alias +/// analysis implementation. +/// +/// This interface is implemented by any \c Model instantiation. It is also the +/// interface which a type used to instantiate the model must provide. +/// +/// All of these methods model methods by the same name in the \c +/// AAResults class. Only differences and specifics to how the +/// implementations are called are documented here. +class AAResults::Concept { +public: + virtual ~Concept() = 0; + + /// An update API used internally by the AAResults to provide + /// a handle back to the top level aggregation. + virtual void setAAResults(AAResults *NewAAR) = 0; + //===--------------------------------------------------------------------===// - /// Methods that clients should call when they transform the program to allow - /// alias analyses to update their internal data structures. Note that these - /// methods may be called on any instruction, regardless of whether or not - /// they have pointer-analysis implications. - /// + /// \name Alias Queries + /// @{ - /// deleteValue - This method should be called whenever an LLVM Value is - /// deleted from the program, for example when an instruction is found to be - /// redundant and is eliminated. - /// - virtual void deleteValue(Value *V); + /// The main low level interface to the alias analysis implementation. + /// Returns an AliasResult indicating whether the two pointers are aliased to + /// each other. This is the interface that must be implemented by specific + /// alias analysis implementations. + virtual AliasResult alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) = 0; - /// addEscapingUse - This method should be used whenever an escaping use is - /// added to a pointer value. Analysis implementations may either return - /// conservative responses for that value in the future, or may recompute - /// some or all internal state to continue providing precise responses. - /// - /// Escaping uses are considered by anything _except_ the following: - /// - GEPs or bitcasts of the pointer - /// - Loads through the pointer - /// - Stores through (but not of) the pointer - virtual void addEscapingUse(Use &U); + /// Checks whether the given location points to constant memory, or if + /// \p OrLocal is true whether it points to a local alloca. + virtual bool pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) = 0; - /// replaceWithNewValue - This method is the obvious combination of the two - /// above, and it provided as a helper to simplify client code. + /// @} + //===--------------------------------------------------------------------===// + /// \name Simple mod/ref information + /// @{ + + /// Get the ModRef info associated with a pointer argument of a callsite. The + /// result's bits are set to indicate the allowed aliasing ModRef kinds. Note + /// that these bits do not necessarily account for the overall behavior of + /// the function, but rather only provide additional per-argument + /// information. + virtual ModRefInfo getArgModRefInfo(ImmutableCallSite CS, + unsigned ArgIdx) = 0; + + /// Return the behavior of the given call site. + virtual FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) = 0; + + /// Return the behavior when calling the given function. + virtual FunctionModRefBehavior getModRefBehavior(const Function *F) = 0; + + /// getModRefInfo (for call sites) - Return information about whether + /// a particular call site modifies or reads the specified memory location. + virtual ModRefInfo getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) = 0; + + /// Return information about whether two call sites may refer to the same set + /// of memory locations. See the AA documentation for details: + /// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo + virtual ModRefInfo getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) = 0; + + /// @} +}; + +/// A private class template which derives from \c Concept and wraps some other +/// type. +/// +/// This models the concept by directly forwarding each interface point to the +/// wrapped type which must implement a compatible interface. This provides +/// a type erased binding. +template <typename AAResultT> class AAResults::Model final : public Concept { + AAResultT &Result; + +public: + explicit Model(AAResultT &Result, AAResults &AAR) : Result(Result) { + Result.setAAResults(&AAR); + } + ~Model() override {} + + void setAAResults(AAResults *NewAAR) override { Result.setAAResults(NewAAR); } + + AliasResult alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) override { + return Result.alias(LocA, LocB); + } + + bool pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) override { + return Result.pointsToConstantMemory(Loc, OrLocal); + } + + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) override { + return Result.getArgModRefInfo(CS, ArgIdx); + } + + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override { + return Result.getModRefBehavior(CS); + } + + FunctionModRefBehavior getModRefBehavior(const Function *F) override { + return Result.getModRefBehavior(F); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) override { + return Result.getModRefInfo(CS, Loc); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) override { + return Result.getModRefInfo(CS1, CS2); + } +}; + +/// A CRTP-driven "mixin" base class to help implement the function alias +/// analysis results concept. +/// +/// Because of the nature of many alias analysis implementations, they often +/// only implement a subset of the interface. This base class will attempt to +/// implement the remaining portions of the interface in terms of simpler forms +/// of the interface where possible, and otherwise provide conservatively +/// correct fallback implementations. +/// +/// Implementors of an alias analysis should derive from this CRTP, and then +/// override specific methods that they wish to customize. There is no need to +/// use virtual anywhere, the CRTP base class does static dispatch to the +/// derived type passed into it. +template <typename DerivedT> class AAResultBase { + // Expose some parts of the interface only to the AAResults::Model + // for wrapping. Specifically, this allows the model to call our + // setAAResults method without exposing it as a fully public API. + friend class AAResults::Model<DerivedT>; + + /// A pointer to the AAResults object that this AAResult is + /// aggregated within. May be null if not aggregated. + AAResults *AAR; + + /// Helper to dispatch calls back through the derived type. + DerivedT &derived() { return static_cast<DerivedT &>(*this); } + + /// A setter for the AAResults pointer, which is used to satisfy the + /// AAResults::Model contract. + void setAAResults(AAResults *NewAAR) { AAR = NewAAR; } + +protected: + /// This proxy class models a common pattern where we delegate to either the + /// top-level \c AAResults aggregation if one is registered, or to the + /// current result if none are registered. + class AAResultsProxy { + AAResults *AAR; + DerivedT &CurrentResult; + + public: + AAResultsProxy(AAResults *AAR, DerivedT &CurrentResult) + : AAR(AAR), CurrentResult(CurrentResult) {} + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { + return AAR ? AAR->alias(LocA, LocB) : CurrentResult.alias(LocA, LocB); + } + + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) { + return AAR ? AAR->pointsToConstantMemory(Loc, OrLocal) + : CurrentResult.pointsToConstantMemory(Loc, OrLocal); + } + + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { + return AAR ? AAR->getArgModRefInfo(CS, ArgIdx) : CurrentResult.getArgModRefInfo(CS, ArgIdx); + } + + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) { + return AAR ? AAR->getModRefBehavior(CS) : CurrentResult.getModRefBehavior(CS); + } + + FunctionModRefBehavior getModRefBehavior(const Function *F) { + return AAR ? AAR->getModRefBehavior(F) : CurrentResult.getModRefBehavior(F); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc) { + return AAR ? AAR->getModRefInfo(CS, Loc) + : CurrentResult.getModRefInfo(CS, Loc); + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) { + return AAR ? AAR->getModRefInfo(CS1, CS2) : CurrentResult.getModRefInfo(CS1, CS2); + } + }; + + const TargetLibraryInfo &TLI; + + explicit AAResultBase(const TargetLibraryInfo &TLI) : TLI(TLI) {} + + // Provide all the copy and move constructors so that derived types aren't + // constrained. + AAResultBase(const AAResultBase &Arg) : TLI(Arg.TLI) {} + AAResultBase(AAResultBase &&Arg) : TLI(Arg.TLI) {} + + /// Get a proxy for the best AA result set to query at this time. /// - void replaceWithNewValue(Value *Old, Value *New) { - deleteValue(Old); + /// When this result is part of a larger aggregation, this will proxy to that + /// aggregation. When this result is used in isolation, it will just delegate + /// back to the derived class's implementation. + AAResultsProxy getBestAAResults() { return AAResultsProxy(AAR, derived()); } + +public: + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { + return MayAlias; } + + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) { + return false; + } + + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx) { + return MRI_ModRef; + } + + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) { + if (!CS.hasOperandBundles()) + // If CS has operand bundles then aliasing attributes from the function it + // calls do not directly apply to the CallSite. This can be made more + // precise in the future. + if (const Function *F = CS.getCalledFunction()) + return getBestAAResults().getModRefBehavior(F); + + return FMRB_UnknownModRefBehavior; + } + + FunctionModRefBehavior getModRefBehavior(const Function *F) { + return FMRB_UnknownModRefBehavior; + } + + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); + + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); }; +/// Synthesize \c ModRefInfo for a call site and memory location by examining +/// the general behavior of the call site and any specific information for its +/// arguments. +/// +/// This essentially, delegates across the alias analysis interface to collect +/// information which may be enough to (conservatively) fulfill the query. +template <typename DerivedT> +ModRefInfo AAResultBase<DerivedT>::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { + auto MRB = getBestAAResults().getModRefBehavior(CS); + if (MRB == FMRB_DoesNotAccessMemory) + return MRI_NoModRef; + + ModRefInfo Mask = MRI_ModRef; + if (AAResults::onlyReadsMemory(MRB)) + Mask = MRI_Ref; + + if (AAResults::onlyAccessesArgPointees(MRB)) { + bool DoesAlias = false; + ModRefInfo AllArgsMask = MRI_NoModRef; + if (AAResults::doesAccessArgPointees(MRB)) { + for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), + AE = CS.arg_end(); + AI != AE; ++AI) { + const Value *Arg = *AI; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned ArgIdx = std::distance(CS.arg_begin(), AI); + MemoryLocation ArgLoc = MemoryLocation::getForArgument(CS, ArgIdx, TLI); + AliasResult ArgAlias = getBestAAResults().alias(ArgLoc, Loc); + if (ArgAlias != NoAlias) { + ModRefInfo ArgMask = getBestAAResults().getArgModRefInfo(CS, ArgIdx); + DoesAlias = true; + AllArgsMask = ModRefInfo(AllArgsMask | ArgMask); + } + } + } + if (!DoesAlias) + return MRI_NoModRef; + Mask = ModRefInfo(Mask & AllArgsMask); + } + + // If Loc is a constant memory location, the call definitely could not + // modify the memory location. + if ((Mask & MRI_Mod) && + getBestAAResults().pointsToConstantMemory(Loc, /*OrLocal*/ false)) + Mask = ModRefInfo(Mask & ~MRI_Mod); + + return Mask; +} + +/// Synthesize \c ModRefInfo for two call sites by examining the general +/// behavior of the call site and any specific information for its arguments. +/// +/// This essentially, delegates across the alias analysis interface to collect +/// information which may be enough to (conservatively) fulfill the query. +template <typename DerivedT> +ModRefInfo AAResultBase<DerivedT>::getModRefInfo(ImmutableCallSite CS1, + ImmutableCallSite CS2) { + // If CS1 or CS2 are readnone, they don't interact. + auto CS1B = getBestAAResults().getModRefBehavior(CS1); + if (CS1B == FMRB_DoesNotAccessMemory) + return MRI_NoModRef; + + auto CS2B = getBestAAResults().getModRefBehavior(CS2); + if (CS2B == FMRB_DoesNotAccessMemory) + return MRI_NoModRef; + + // If they both only read from memory, there is no dependence. + if (AAResults::onlyReadsMemory(CS1B) && AAResults::onlyReadsMemory(CS2B)) + return MRI_NoModRef; + + ModRefInfo Mask = MRI_ModRef; + + // If CS1 only reads memory, the only dependence on CS2 can be + // from CS1 reading memory written by CS2. + if (AAResults::onlyReadsMemory(CS1B)) + Mask = ModRefInfo(Mask & MRI_Ref); + + // If CS2 only access memory through arguments, accumulate the mod/ref + // information from CS1's references to the memory referenced by + // CS2's arguments. + if (AAResults::onlyAccessesArgPointees(CS2B)) { + ModRefInfo R = MRI_NoModRef; + if (AAResults::doesAccessArgPointees(CS2B)) { + for (ImmutableCallSite::arg_iterator I = CS2.arg_begin(), + E = CS2.arg_end(); + I != E; ++I) { + const Value *Arg = *I; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); + auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); + + // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence + // of CS1 on that location is the inverse. + ModRefInfo ArgMask = + getBestAAResults().getArgModRefInfo(CS2, CS2ArgIdx); + if (ArgMask == MRI_Mod) + ArgMask = MRI_ModRef; + else if (ArgMask == MRI_Ref) + ArgMask = MRI_Mod; + + ArgMask = ModRefInfo(ArgMask & + getBestAAResults().getModRefInfo(CS1, CS2ArgLoc)); + + R = ModRefInfo((R | ArgMask) & Mask); + if (R == Mask) + break; + } + } + return R; + } + + // If CS1 only accesses memory through arguments, check if CS2 references + // any of the memory referenced by CS1's arguments. If not, return NoModRef. + if (AAResults::onlyAccessesArgPointees(CS1B)) { + ModRefInfo R = MRI_NoModRef; + if (AAResults::doesAccessArgPointees(CS1B)) { + for (ImmutableCallSite::arg_iterator I = CS1.arg_begin(), + E = CS1.arg_end(); + I != E; ++I) { + const Value *Arg = *I; + if (!Arg->getType()->isPointerTy()) + continue; + unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); + auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); + + // ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod + // CS1ArgLoc, then we care about either a Mod or a Ref by CS2. If CS1 + // might Ref, then we care only about a Mod by CS2. + ModRefInfo ArgMask = getBestAAResults().getArgModRefInfo(CS1, CS1ArgIdx); + ModRefInfo ArgR = getBestAAResults().getModRefInfo(CS2, CS1ArgLoc); + if (((ArgMask & MRI_Mod) != MRI_NoModRef && + (ArgR & MRI_ModRef) != MRI_NoModRef) || + ((ArgMask & MRI_Ref) != MRI_NoModRef && + (ArgR & MRI_Mod) != MRI_NoModRef)) + R = ModRefInfo((R | ArgMask) & Mask); + + if (R == Mask) + break; + } + } + return R; + } + + return Mask; +} + /// isNoAliasCall - Return true if this pointer is returned by a noalias /// function. bool isNoAliasCall(const Value *V); @@ -564,6 +975,98 @@ bool isIdentifiedObject(const Value *V); /// IdentifiedObjects. bool isIdentifiedFunctionLocal(const Value *V); +/// A manager for alias analyses. +/// +/// This class can have analyses registered with it and when run, it will run +/// all of them and aggregate their results into single AA results interface +/// that dispatches across all of the alias analysis results available. +/// +/// Note that the order in which analyses are registered is very significant. +/// That is the order in which the results will be aggregated and queried. +/// +/// This manager effectively wraps the AnalysisManager for registering alias +/// analyses. When you register your alias analysis with this manager, it will +/// ensure the analysis itself is registered with its AnalysisManager. +class AAManager { +public: + typedef AAResults Result; + + // This type hase value semantics. We have to spell these out because MSVC + // won't synthesize them. + AAManager() {} + AAManager(AAManager &&Arg) + : FunctionResultGetters(std::move(Arg.FunctionResultGetters)) {} + AAManager(const AAManager &Arg) + : FunctionResultGetters(Arg.FunctionResultGetters) {} + AAManager &operator=(AAManager &&RHS) { + FunctionResultGetters = std::move(RHS.FunctionResultGetters); + return *this; + } + AAManager &operator=(const AAManager &RHS) { + FunctionResultGetters = RHS.FunctionResultGetters; + return *this; + } + + /// Register a specific AA result. + template <typename AnalysisT> void registerFunctionAnalysis() { + FunctionResultGetters.push_back(&getFunctionAAResultImpl<AnalysisT>); + } + + Result run(Function &F, AnalysisManager<Function> &AM) { + Result R; + for (auto &Getter : FunctionResultGetters) + (*Getter)(F, AM, R); + return R; + } + +private: + SmallVector<void (*)(Function &F, AnalysisManager<Function> &AM, + AAResults &AAResults), + 4> FunctionResultGetters; + + template <typename AnalysisT> + static void getFunctionAAResultImpl(Function &F, + AnalysisManager<Function> &AM, + AAResults &AAResults) { + AAResults.addAAResult(AM.template getResult<AnalysisT>(F)); + } +}; + +/// A wrapper pass to provide the legacy pass manager access to a suitably +/// prepared AAResults object. +class AAResultsWrapperPass : public FunctionPass { + std::unique_ptr<AAResults> AAR; + +public: + static char ID; + + AAResultsWrapperPass(); + + AAResults &getAAResults() { return *AAR; } + const AAResults &getAAResults() const { return *AAR; } + + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +FunctionPass *createAAResultsWrapperPass(); + +/// A wrapper pass around a callback which can be used to populate the +/// AAResults in the AAResultsWrapperPass from an external AA. +/// +/// The callback provided here will be used each time we prepare an AAResults +/// object, and will receive a reference to the function wrapper pass, the +/// function, and the AAResults object to populate. This should be used when +/// setting up a custom pass pipeline to inject a hook into the AA results. +ImmutablePass *createExternalAAWrapperPass( + std::function<void(Pass &, Function &, AAResults &)> Callback); + +/// A helper for the legacy pass manager to create a \c AAResults +/// object populated to the best of our ability for a particular function when +/// inside of a \c ModulePass or a \c CallGraphSCCPass. +AAResults createLegacyPMAAResults(Pass &P, Function &F, BasicAAResult &BAR); + } // End llvm namespace #endif diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 881699d09225a..37fd69b081ccb 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -20,13 +20,13 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/ValueHandle.h" #include <vector> namespace llvm { -class AliasAnalysis; class LoadInst; class StoreInst; class VAArgInst; @@ -42,13 +42,14 @@ class AliasSet : public ilist_node<AliasSet> { AliasSet *AS; uint64_t Size; AAMDNodes AAInfo; + public: PointerRec(Value *V) : Val(V), PrevInList(nullptr), NextInList(nullptr), AS(nullptr), Size(0), AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {} Value *getValue() const { return Val; } - + PointerRec *getNext() const { return NextInList; } bool hasAliasSet() const { return AS != nullptr; } @@ -156,7 +157,7 @@ class AliasSet : public ilist_node<AliasSet> { assert(i < UnknownInsts.size()); return UnknownInsts[i]; } - + public: /// Accessors... bool isRef() const { return Access & RefAccess; } @@ -190,6 +191,7 @@ public: class iterator : public std::iterator<std::forward_iterator_tag, PointerRec, ptrdiff_t> { PointerRec *CurNode; + public: explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {} @@ -282,14 +284,14 @@ inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) { return OS; } - class AliasSetTracker { /// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be /// notified whenever a Value is deleted. - class ASTCallbackVH : public CallbackVH { + class ASTCallbackVH final : public CallbackVH { AliasSetTracker *AST; void deleted() override; void allUsesReplacedWith(Value *) override; + public: ASTCallbackVH(Value *V, AliasSetTracker *AST = nullptr); ASTCallbackVH &operator=(Value *V); @@ -347,7 +349,7 @@ public: bool remove(Instruction *I); void remove(AliasSet &AS); bool removeUnknown(Instruction *I); - + void clear(); /// getAliasSets - Return the alias sets that are active. @@ -398,7 +400,6 @@ public: /// void copyValue(Value *From, Value *To); - typedef ilist<AliasSet>::iterator iterator; typedef ilist<AliasSet>::const_iterator const_iterator; diff --git a/include/llvm/Analysis/AssumptionCache.h b/include/llvm/Analysis/AssumptionCache.h index 1f00b691b3052..b903f96d55b21 100644 --- a/include/llvm/Analysis/AssumptionCache.h +++ b/include/llvm/Analysis/AssumptionCache.h @@ -66,7 +66,7 @@ public: /// \brief Add an @llvm.assume intrinsic to this function's cache. /// - /// The call passed in must be an instruction within this fuction and must + /// The call passed in must be an instruction within this function and must /// not already be in the cache. void registerAssumption(CallInst *CI); @@ -79,7 +79,7 @@ public: } /// \brief Access the list of assumption handles currently tracked for this - /// fuction. + /// function. /// /// Note that these produce weak handles that may be null. The caller must /// handle that case. @@ -140,7 +140,7 @@ public: class AssumptionCacheTracker : public ImmutablePass { /// A callback value handle applied to function objects, which we use to /// delete our cache of intrinsics for a function when it is deleted. - class FunctionCallbackVH : public CallbackVH { + class FunctionCallbackVH final : public CallbackVH { AssumptionCacheTracker *ACT; void deleted() override; diff --git a/include/llvm/Analysis/BasicAliasAnalysis.h b/include/llvm/Analysis/BasicAliasAnalysis.h new file mode 100644 index 0000000000000..181a9327024c2 --- /dev/null +++ b/include/llvm/Analysis/BasicAliasAnalysis.h @@ -0,0 +1,223 @@ +//===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the interface for LLVM's primary stateless and local alias analysis. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_BASICALIASANALYSIS_H +#define LLVM_ANALYSIS_BASICALIASANALYSIS_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Support/ErrorHandling.h" + +namespace llvm { +class AssumptionCache; +class DominatorTree; +class LoopInfo; + +/// This is the AA result object for the basic, local, and stateless alias +/// analysis. It implements the AA query interface in an entirely stateless +/// manner. As one consequence, it is never invalidated. While it does retain +/// some storage, that is used as an optimization and not to preserve +/// information from query to query. +class BasicAAResult : public AAResultBase<BasicAAResult> { + friend AAResultBase<BasicAAResult>; + + const DataLayout &DL; + AssumptionCache &AC; + DominatorTree *DT; + LoopInfo *LI; + +public: + BasicAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI, + AssumptionCache &AC, DominatorTree *DT = nullptr, + LoopInfo *LI = nullptr) + : AAResultBase(TLI), DL(DL), AC(AC), DT(DT), LI(LI) {} + + BasicAAResult(const BasicAAResult &Arg) + : AAResultBase(Arg), DL(Arg.DL), AC(Arg.AC), DT(Arg.DT), LI(Arg.LI) {} + BasicAAResult(BasicAAResult &&Arg) + : AAResultBase(std::move(Arg)), DL(Arg.DL), AC(Arg.AC), DT(Arg.DT), + LI(Arg.LI) {} + + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); + + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); + + /// Chases pointers until we find a (constant global) or not. + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal); + + /// Get the location associated with a pointer argument of a callsite. + ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); + + /// Returns the behavior when calling the given call site. + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); + + /// Returns the behavior when calling the given function. For use when the + /// call site is not known. + FunctionModRefBehavior getModRefBehavior(const Function *F); + +private: + // A linear transformation of a Value; this class represents ZExt(SExt(V, + // SExtBits), ZExtBits) * Scale + Offset. + struct VariableGEPIndex { + + // An opaque Value - we can't decompose this further. + const Value *V; + + // We need to track what extensions we've done as we consider the same Value + // with different extensions as different variables in a GEP's linear + // expression; + // e.g.: if V == -1, then sext(x) != zext(x). + unsigned ZExtBits; + unsigned SExtBits; + + int64_t Scale; + + bool operator==(const VariableGEPIndex &Other) const { + return V == Other.V && ZExtBits == Other.ZExtBits && + SExtBits == Other.SExtBits && Scale == Other.Scale; + } + + bool operator!=(const VariableGEPIndex &Other) const { + return !operator==(Other); + } + }; + + /// Track alias queries to guard against recursion. + typedef std::pair<MemoryLocation, MemoryLocation> LocPair; + typedef SmallDenseMap<LocPair, AliasResult, 8> AliasCacheTy; + AliasCacheTy AliasCache; + + /// Tracks phi nodes we have visited. + /// + /// When interpret "Value" pointer equality as value equality we need to make + /// sure that the "Value" is not part of a cycle. Otherwise, two uses could + /// come from different "iterations" of a cycle and see different values for + /// the same "Value" pointer. + /// + /// The following example shows the problem: + /// %p = phi(%alloca1, %addr2) + /// %l = load %ptr + /// %addr1 = gep, %alloca2, 0, %l + /// %addr2 = gep %alloca2, 0, (%l + 1) + /// alias(%p, %addr1) -> MayAlias ! + /// store %l, ... + SmallPtrSet<const BasicBlock *, 8> VisitedPhiBBs; + + /// Tracks instructions visited by pointsToConstantMemory. + SmallPtrSet<const Value *, 16> Visited; + + static const Value * + GetLinearExpression(const Value *V, APInt &Scale, APInt &Offset, + unsigned &ZExtBits, unsigned &SExtBits, + const DataLayout &DL, unsigned Depth, AssumptionCache *AC, + DominatorTree *DT, bool &NSW, bool &NUW); + + static const Value * + DecomposeGEPExpression(const Value *V, int64_t &BaseOffs, + SmallVectorImpl<VariableGEPIndex> &VarIndices, + bool &MaxLookupReached, const DataLayout &DL, + AssumptionCache *AC, DominatorTree *DT); + /// \brief A Heuristic for aliasGEP that searches for a constant offset + /// between the variables. + /// + /// GetLinearExpression has some limitations, as generally zext(%x + 1) + /// != zext(%x) + zext(1) if the arithmetic overflows. GetLinearExpression + /// will therefore conservatively refuse to decompose these expressions. + /// However, we know that, for all %x, zext(%x) != zext(%x + 1), even if + /// the addition overflows. + bool + constantOffsetHeuristic(const SmallVectorImpl<VariableGEPIndex> &VarIndices, + uint64_t V1Size, uint64_t V2Size, int64_t BaseOffset, + AssumptionCache *AC, DominatorTree *DT); + + bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2); + + void GetIndexDifference(SmallVectorImpl<VariableGEPIndex> &Dest, + const SmallVectorImpl<VariableGEPIndex> &Src); + + AliasResult aliasGEP(const GEPOperator *V1, uint64_t V1Size, + const AAMDNodes &V1AAInfo, const Value *V2, + uint64_t V2Size, const AAMDNodes &V2AAInfo, + const Value *UnderlyingV1, const Value *UnderlyingV2); + + AliasResult aliasPHI(const PHINode *PN, uint64_t PNSize, + const AAMDNodes &PNAAInfo, const Value *V2, + uint64_t V2Size, const AAMDNodes &V2AAInfo); + + AliasResult aliasSelect(const SelectInst *SI, uint64_t SISize, + const AAMDNodes &SIAAInfo, const Value *V2, + uint64_t V2Size, const AAMDNodes &V2AAInfo); + + AliasResult aliasCheck(const Value *V1, uint64_t V1Size, AAMDNodes V1AATag, + const Value *V2, uint64_t V2Size, AAMDNodes V2AATag); +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class BasicAA { +public: + typedef BasicAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + BasicAAResult run(Function &F, AnalysisManager<Function> *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "BasicAliasAnalysis"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the BasicAAResult object. +class BasicAAWrapperPass : public FunctionPass { + std::unique_ptr<BasicAAResult> Result; + + virtual void anchor(); + +public: + static char ID; + + BasicAAWrapperPass(); + + BasicAAResult &getResult() { return *Result; } + const BasicAAResult &getResult() const { return *Result; } + + bool runOnFunction(Function &F) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +FunctionPass *createBasicAAWrapperPass(); + +/// A helper for the legacy pass manager to create a \c BasicAAResult object +/// populated to the best of our ability for a particular function when inside +/// of a \c ModulePass or a \c CallGraphSCCPass. +BasicAAResult createLegacyPMBasicAAResult(Pass &P, Function &F); +} + +#endif diff --git a/include/llvm/Analysis/BlockFrequencyInfo.h b/include/llvm/Analysis/BlockFrequencyInfo.h index f27c32df92836..6f2a2b5227696 100644 --- a/include/llvm/Analysis/BlockFrequencyInfo.h +++ b/include/llvm/Analysis/BlockFrequencyInfo.h @@ -21,26 +21,20 @@ namespace llvm { class BranchProbabilityInfo; +class LoopInfo; template <class BlockT> class BlockFrequencyInfoImpl; /// BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to /// estimate IR basic block frequencies. -class BlockFrequencyInfo : public FunctionPass { +class BlockFrequencyInfo { typedef BlockFrequencyInfoImpl<BasicBlock> ImplType; std::unique_ptr<ImplType> BFI; public: - static char ID; - BlockFrequencyInfo(); + BlockFrequencyInfo(const Function &F, const BranchProbabilityInfo &BPI, + const LoopInfo &LI); - ~BlockFrequencyInfo() override; - - void getAnalysisUsage(AnalysisUsage &AU) const override; - - bool runOnFunction(Function &F) override; - void releaseMemory() override; - void print(raw_ostream &O, const Module *M) const override; const Function *getFunction() const; void view() const; @@ -51,6 +45,13 @@ public: /// floating points. BlockFrequency getBlockFreq(const BasicBlock *BB) const; + // Set the frequency of the given basic block. + void setBlockFreq(const BasicBlock *BB, uint64_t Freq); + + /// calculate - compute block frequency info for the given function. + void calculate(const Function &F, const BranchProbabilityInfo &BPI, + const LoopInfo &LI); + // Print the block frequency Freq to OS using the current functions entry // frequency to convert freq into a relative decimal form. raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency Freq) const; @@ -60,7 +61,28 @@ public: raw_ostream &printBlockFreq(raw_ostream &OS, const BasicBlock *BB) const; uint64_t getEntryFreq() const; + void releaseMemory(); + void print(raw_ostream &OS) const; +}; +/// \brief Legacy analysis pass which computes \c BlockFrequencyInfo. +class BlockFrequencyInfoWrapperPass : public FunctionPass { + BlockFrequencyInfo BFI; + +public: + static char ID; + + BlockFrequencyInfoWrapperPass(); + ~BlockFrequencyInfoWrapperPass() override; + + BlockFrequencyInfo &getBFI() { return BFI; } + const BlockFrequencyInfo &getBFI() const { return BFI; } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + bool runOnFunction(Function &F) override; + void releaseMemory() override; + void print(raw_ostream &OS, const Module *M) const override; }; } diff --git a/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/include/llvm/Analysis/BlockFrequencyInfoImpl.h index 32d96090f4569..387e9a887d93c 100644 --- a/include/llvm/Analysis/BlockFrequencyInfoImpl.h +++ b/include/llvm/Analysis/BlockFrequencyInfoImpl.h @@ -84,7 +84,7 @@ public: /// \brief Add another mass. /// /// Adds another mass, saturating at \a isFull() rather than overflowing. - BlockMass &operator+=(const BlockMass &X) { + BlockMass &operator+=(BlockMass X) { uint64_t Sum = Mass + X.Mass; Mass = Sum < Mass ? UINT64_MAX : Sum; return *this; @@ -94,23 +94,23 @@ public: /// /// Subtracts another mass, saturating at \a isEmpty() rather than /// undeflowing. - BlockMass &operator-=(const BlockMass &X) { + BlockMass &operator-=(BlockMass X) { uint64_t Diff = Mass - X.Mass; Mass = Diff > Mass ? 0 : Diff; return *this; } - BlockMass &operator*=(const BranchProbability &P) { + BlockMass &operator*=(BranchProbability P) { Mass = P.scale(Mass); return *this; } - bool operator==(const BlockMass &X) const { return Mass == X.Mass; } - bool operator!=(const BlockMass &X) const { return Mass != X.Mass; } - bool operator<=(const BlockMass &X) const { return Mass <= X.Mass; } - bool operator>=(const BlockMass &X) const { return Mass >= X.Mass; } - bool operator<(const BlockMass &X) const { return Mass < X.Mass; } - bool operator>(const BlockMass &X) const { return Mass > X.Mass; } + bool operator==(BlockMass X) const { return Mass == X.Mass; } + bool operator!=(BlockMass X) const { return Mass != X.Mass; } + bool operator<=(BlockMass X) const { return Mass <= X.Mass; } + bool operator>=(BlockMass X) const { return Mass >= X.Mass; } + bool operator<(BlockMass X) const { return Mass < X.Mass; } + bool operator>(BlockMass X) const { return Mass > X.Mass; } /// \brief Convert to scaled number. /// @@ -122,20 +122,20 @@ public: raw_ostream &print(raw_ostream &OS) const; }; -inline BlockMass operator+(const BlockMass &L, const BlockMass &R) { +inline BlockMass operator+(BlockMass L, BlockMass R) { return BlockMass(L) += R; } -inline BlockMass operator-(const BlockMass &L, const BlockMass &R) { +inline BlockMass operator-(BlockMass L, BlockMass R) { return BlockMass(L) -= R; } -inline BlockMass operator*(const BlockMass &L, const BranchProbability &R) { +inline BlockMass operator*(BlockMass L, BranchProbability R) { return BlockMass(L) *= R; } -inline BlockMass operator*(const BranchProbability &L, const BlockMass &R) { +inline BlockMass operator*(BranchProbability L, BlockMass R) { return BlockMass(R) *= L; } -inline raw_ostream &operator<<(raw_ostream &OS, const BlockMass &X) { +inline raw_ostream &operator<<(raw_ostream &OS, BlockMass X) { return X.print(OS); } @@ -477,6 +477,8 @@ public: BlockFrequency getBlockFreq(const BlockNode &Node) const; + void setBlockFreq(const BlockNode &Node, uint64_t Freq); + raw_ostream &printBlockFreq(raw_ostream &OS, const BlockNode &Node) const; raw_ostream &printBlockFreq(raw_ostream &OS, const BlockFrequency &Freq) const; @@ -905,14 +907,15 @@ template <class BT> class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase { public: const FunctionT *getFunction() const { return F; } - void doFunction(const FunctionT *F, const BranchProbabilityInfoT *BPI, - const LoopInfoT *LI); + void calculate(const FunctionT &F, const BranchProbabilityInfoT &BPI, + const LoopInfoT &LI); BlockFrequencyInfoImpl() : BPI(nullptr), LI(nullptr), F(nullptr) {} using BlockFrequencyInfoImplBase::getEntryFreq; BlockFrequency getBlockFreq(const BlockT *BB) const { return BlockFrequencyInfoImplBase::getBlockFreq(getNode(BB)); } + void setBlockFreq(const BlockT *BB, uint64_t Freq); Scaled64 getFloatingBlockFreq(const BlockT *BB) const { return BlockFrequencyInfoImplBase::getFloatingBlockFreq(getNode(BB)); } @@ -938,13 +941,13 @@ public: }; template <class BT> -void BlockFrequencyInfoImpl<BT>::doFunction(const FunctionT *F, - const BranchProbabilityInfoT *BPI, - const LoopInfoT *LI) { +void BlockFrequencyInfoImpl<BT>::calculate(const FunctionT &F, + const BranchProbabilityInfoT &BPI, + const LoopInfoT &LI) { // Save the parameters. - this->BPI = BPI; - this->LI = LI; - this->F = F; + this->BPI = &BPI; + this->LI = &LI; + this->F = &F; // Clean up left-over data structures. BlockFrequencyInfoImplBase::clear(); @@ -952,8 +955,8 @@ void BlockFrequencyInfoImpl<BT>::doFunction(const FunctionT *F, Nodes.clear(); // Initialize. - DEBUG(dbgs() << "\nblock-frequency: " << F->getName() << "\n=================" - << std::string(F->getName().size(), '=') << "\n"); + DEBUG(dbgs() << "\nblock-frequency: " << F.getName() << "\n=================" + << std::string(F.getName().size(), '=') << "\n"); initializeRPOT(); initializeLoops(); @@ -965,8 +968,23 @@ void BlockFrequencyInfoImpl<BT>::doFunction(const FunctionT *F, finalizeMetrics(); } +template <class BT> +void BlockFrequencyInfoImpl<BT>::setBlockFreq(const BlockT *BB, uint64_t Freq) { + if (Nodes.count(BB)) + BlockFrequencyInfoImplBase::setBlockFreq(getNode(BB), Freq); + else { + // If BB is a newly added block after BFI is done, we need to create a new + // BlockNode for it assigned with a new index. The index can be determined + // by the size of Freqs. + BlockNode NewNode(Freqs.size()); + Nodes[BB] = NewNode; + Freqs.emplace_back(); + BlockFrequencyInfoImplBase::setBlockFreq(NewNode, Freq); + } +} + template <class BT> void BlockFrequencyInfoImpl<BT>::initializeRPOT() { - const BlockT *Entry = F->begin(); + const BlockT *Entry = &F->front(); RPOT.reserve(F->size()); std::copy(po_begin(Entry), po_end(Entry), std::back_inserter(RPOT)); std::reverse(RPOT.begin(), RPOT.end()); @@ -1155,6 +1173,13 @@ void BlockFrequencyInfoImpl<BT>::computeIrreducibleMass( updateLoopWithIrreducible(*OuterLoop); } +namespace { +// A helper function that converts a branch probability into weight. +inline uint32_t getWeightFromBranchProb(const BranchProbability Prob) { + return Prob.getNumerator(); +} +} // namespace + template <class BT> bool BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop, @@ -1171,10 +1196,8 @@ BlockFrequencyInfoImpl<BT>::propagateMassToSuccessors(LoopData *OuterLoop, const BlockT *BB = getBlock(Node); for (auto SI = Successor::child_begin(BB), SE = Successor::child_end(BB); SI != SE; ++SI) - // Do not dereference SI, or getEdgeWeight() is linear in the number of - // successors. if (!addToDist(Dist, OuterLoop, Node, getNode(*SI), - BPI->getEdgeWeight(BB, SI))) + getWeightFromBranchProb(BPI->getEdgeProbability(BB, SI)))) // Irreducible backedge. return false; } @@ -1190,10 +1213,11 @@ raw_ostream &BlockFrequencyInfoImpl<BT>::print(raw_ostream &OS) const { if (!F) return OS; OS << "block-frequency-info: " << F->getName() << "\n"; - for (const BlockT &BB : *F) - OS << " - " << bfi_detail::getBlockName(&BB) - << ": float = " << getFloatingBlockFreq(&BB) - << ", int = " << getBlockFreq(&BB).getFrequency() << "\n"; + for (const BlockT &BB : *F) { + OS << " - " << bfi_detail::getBlockName(&BB) << ": float = "; + getFloatingBlockFreq(&BB).print(OS, 5) + << ", int = " << getBlockFreq(&BB).getFrequency() << "\n"; + } // Add an extra newline for readability. OS << "\n"; diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 9d867567ba294..cfdf218491bdb 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -25,9 +25,9 @@ namespace llvm { class LoopInfo; class raw_ostream; -/// \brief Analysis pass providing branch probability information. +/// \brief Analysis providing branch probability information. /// -/// This is a function analysis pass which provides information on the relative +/// This is a function analysis which provides information on the relative /// probabilities of each "edge" in the function's CFG where such an edge is /// defined by a pair (PredBlock and an index in the successors). The /// probability of an edge from one block is always relative to the @@ -37,20 +37,14 @@ class raw_ostream; /// identify an edge, since we can have multiple edges from Src to Dst. /// As an example, we can have a switch which jumps to Dst with value 0 and /// value 10. -class BranchProbabilityInfo : public FunctionPass { +class BranchProbabilityInfo { public: - static char ID; - - BranchProbabilityInfo() : FunctionPass(ID) { - initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry()); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnFunction(Function &F) override; + BranchProbabilityInfo() {} + BranchProbabilityInfo(Function &F, const LoopInfo &LI) { calculate(F, LI); } - void releaseMemory() override; + void releaseMemory(); - void print(raw_ostream &OS, const Module *M = nullptr) const override; + void print(raw_ostream &OS) const; /// \brief Get an edge's probability, relative to other out-edges of the Src. /// @@ -67,6 +61,9 @@ public: BranchProbability getEdgeProbability(const BasicBlock *Src, const BasicBlock *Dst) const; + BranchProbability getEdgeProbability(const BasicBlock *Src, + succ_const_iterator Dst) const; + /// \brief Test if an edge is hot relative to other out-edges of the Src. /// /// Check whether this edge out of the source block is 'hot'. We define hot @@ -87,37 +84,22 @@ public: raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src, const BasicBlock *Dst) const; - /// \brief Get the raw edge weight calculated for the edge. - /// - /// This returns the raw edge weight. It is guaranteed to fall between 1 and - /// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation. - /// This interface should be very carefully, and primarily by routines that - /// are updating the analysis by later calling setEdgeWeight. - uint32_t getEdgeWeight(const BasicBlock *Src, - unsigned IndexInSuccessors) const; - - /// \brief Get the raw edge weight calculated for the block pair. + /// \brief Set the raw edge probability for the given edge. /// - /// This returns the sum of all raw edge weights from Src to Dst. - /// It is guaranteed to fall between 1 and UINT32_MAX. - uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const; - - uint32_t getEdgeWeight(const BasicBlock *Src, - succ_const_iterator Dst) const; - - /// \brief Set the raw edge weight for a given edge. - /// - /// This allows a pass to explicitly set the edge weight for an edge. It can - /// be used when updating the CFG to update and preserve the branch + /// This allows a pass to explicitly set the edge probability for an edge. It + /// can be used when updating the CFG to update and preserve the branch /// probability information. Read the implementation of how these edge - /// weights are calculated carefully before using! - void setEdgeWeight(const BasicBlock *Src, unsigned IndexInSuccessors, - uint32_t Weight); + /// probabilities are calculated carefully before using! + void setEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors, + BranchProbability Prob); - static uint32_t getBranchWeightStackProtector(bool IsLikely) { - return IsLikely ? (1u << 20) - 1 : 1; + static BranchProbability getBranchProbStackProtector(bool IsLikely) { + static const BranchProbability LikelyProb((1u << 20) - 1, 1u << 20); + return IsLikely ? LikelyProb : LikelyProb.getCompl(); } + void calculate(Function &F, const LoopInfo& LI); + private: // Since we allow duplicate edges from one basic block to another, we use // a pair (PredBlock and an index in the successors) to specify an edge. @@ -131,10 +113,7 @@ private: // weight to just "inherit" the non-zero weight of an adjacent successor. static const uint32_t DEFAULT_WEIGHT = 16; - DenseMap<Edge, uint32_t> Weights; - - /// \brief Handle to the LoopInfo analysis. - LoopInfo *LI; + DenseMap<Edge, BranchProbability> Probs; /// \brief Track the last function we run over for printing. Function *LastF; @@ -145,19 +124,37 @@ private: /// \brief Track the set of blocks that always lead to a cold call. SmallPtrSet<BasicBlock *, 16> PostDominatedByColdCall; - /// \brief Get sum of the block successors' weights. - uint32_t getSumForBlock(const BasicBlock *BB) const; - bool calcUnreachableHeuristics(BasicBlock *BB); bool calcMetadataWeights(BasicBlock *BB); bool calcColdCallHeuristics(BasicBlock *BB); bool calcPointerHeuristics(BasicBlock *BB); - bool calcLoopBranchHeuristics(BasicBlock *BB); + bool calcLoopBranchHeuristics(BasicBlock *BB, const LoopInfo &LI); bool calcZeroHeuristics(BasicBlock *BB); bool calcFloatingPointHeuristics(BasicBlock *BB); bool calcInvokeHeuristics(BasicBlock *BB); }; +/// \brief Legacy analysis pass which computes \c BranchProbabilityInfo. +class BranchProbabilityInfoWrapperPass : public FunctionPass { + BranchProbabilityInfo BPI; + +public: + static char ID; + + BranchProbabilityInfoWrapperPass() : FunctionPass(ID) { + initializeBranchProbabilityInfoWrapperPassPass( + *PassRegistry::getPassRegistry()); + } + + BranchProbabilityInfo &getBPI() { return BPI; } + const BranchProbabilityInfo &getBPI() const { return BPI; } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + bool runOnFunction(Function &F) override; + void releaseMemory() override; + void print(raw_ostream &OS, const Module *M = nullptr) const override; +}; + } #endif diff --git a/include/llvm/Analysis/CFG.h b/include/llvm/Analysis/CFG.h index 7c4df780198cb..35165f4061f1e 100644 --- a/include/llvm/Analysis/CFG.h +++ b/include/llvm/Analysis/CFG.h @@ -40,7 +40,7 @@ void FindFunctionBackedges( /// Search for the specified successor of basic block BB and return its position /// in the terminator instruction's list of successors. It is an error to call /// this with a block that is not a successor. -unsigned GetSuccessorNumber(BasicBlock *BB, BasicBlock *Succ); +unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ); /// Return true if the specified edge is a critical edge. Critical edges are /// edges from a block with multiple successors to a block with multiple diff --git a/include/llvm/Analysis/CFLAliasAnalysis.h b/include/llvm/Analysis/CFLAliasAnalysis.h new file mode 100644 index 0000000000000..7473a454ab303 --- /dev/null +++ b/include/llvm/Analysis/CFLAliasAnalysis.h @@ -0,0 +1,158 @@ +//===- CFLAliasAnalysis.h - CFL-Based Alias Analysis Interface ---*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the interface for LLVM's primary stateless and local alias analysis. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_CFLALIASANALYSIS_H +#define LLVM_ANALYSIS_CFLALIASANALYSIS_H + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/ValueHandle.h" +#include "llvm/Pass.h" +#include <forward_list> + +namespace llvm { + +class CFLAAResult : public AAResultBase<CFLAAResult> { + friend AAResultBase<CFLAAResult>; + + struct FunctionInfo; + +public: + explicit CFLAAResult(const TargetLibraryInfo &TLI); + CFLAAResult(CFLAAResult &&Arg); + + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } + + /// \brief Inserts the given Function into the cache. + void scan(Function *Fn); + + void evict(Function *Fn); + + /// \brief Ensures that the given function is available in the cache. + /// Returns the appropriate entry from the cache. + const Optional<FunctionInfo> &ensureCached(Function *Fn); + + AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB); + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) { + if (LocA.Ptr == LocB.Ptr) { + if (LocA.Size == LocB.Size) { + return MustAlias; + } else { + return PartialAlias; + } + } + + // Comparisons between global variables and other constants should be + // handled by BasicAA. + // TODO: ConstantExpr handling -- CFLAA may report NoAlias when comparing + // a GlobalValue and ConstantExpr, but every query needs to have at least + // one Value tied to a Function, and neither GlobalValues nor ConstantExprs + // are. + if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr)) { + return AAResultBase::alias(LocA, LocB); + } + + AliasResult QueryResult = query(LocA, LocB); + if (QueryResult == MayAlias) + return AAResultBase::alias(LocA, LocB); + + return QueryResult; + } + +private: + struct FunctionHandle final : public CallbackVH { + FunctionHandle(Function *Fn, CFLAAResult *Result) + : CallbackVH(Fn), Result(Result) { + assert(Fn != nullptr); + assert(Result != nullptr); + } + + void deleted() override { removeSelfFromCache(); } + void allUsesReplacedWith(Value *) override { removeSelfFromCache(); } + + private: + CFLAAResult *Result; + + void removeSelfFromCache() { + assert(Result != nullptr); + auto *Val = getValPtr(); + Result->evict(cast<Function>(Val)); + setValPtr(nullptr); + } + }; + + /// \brief Cached mapping of Functions to their StratifiedSets. + /// If a function's sets are currently being built, it is marked + /// in the cache as an Optional without a value. This way, if we + /// have any kind of recursion, it is discernable from a function + /// that simply has empty sets. + DenseMap<Function *, Optional<FunctionInfo>> Cache; + std::forward_list<FunctionHandle> Handles; + + FunctionInfo buildSetsFrom(Function *F); +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +/// +/// FIXME: We really should refactor CFL to use the analysis more heavily, and +/// in particular to leverage invalidation to trigger re-computation of sets. +class CFLAA { +public: + typedef CFLAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + CFLAAResult run(Function &F, AnalysisManager<Function> *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "CFLAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the CFLAAResult object. +class CFLAAWrapperPass : public ImmutablePass { + std::unique_ptr<CFLAAResult> Result; + +public: + static char ID; + + CFLAAWrapperPass(); + + CFLAAResult &getResult() { return *Result; } + const CFLAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +//===--------------------------------------------------------------------===// +// +// createCFLAAWrapperPass - This pass implements a set-based approach to +// alias analysis. +// +ImmutablePass *createCFLAAWrapperPass(); +} + +#endif diff --git a/include/llvm/Analysis/CGSCCPassManager.h b/include/llvm/Analysis/CGSCCPassManager.h index 6a406cd244026..e7635eb1ab678 100644 --- a/include/llvm/Analysis/CGSCCPassManager.h +++ b/include/llvm/Analysis/CGSCCPassManager.h @@ -358,7 +358,7 @@ private: /// returned PreservedAnalysis set. class CGSCCAnalysisManagerFunctionProxy { public: - /// \brief Result proxy object for \c ModuleAnalysisManagerFunctionProxy. + /// \brief Result proxy object for \c CGSCCAnalysisManagerFunctionProxy. class Result { public: explicit Result(const CGSCCAnalysisManager &CGAM) : CGAM(&CGAM) {} diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 662ae0e6363ce..5562e9b9465f8 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -75,7 +75,8 @@ class CallGraphNode; class CallGraph { Module &M; - typedef std::map<const Function *, CallGraphNode *> FunctionMapTy; + typedef std::map<const Function *, std::unique_ptr<CallGraphNode>> + FunctionMapTy; /// \brief A map from \c Function* to \c CallGraphNode*. FunctionMapTy FunctionMap; @@ -90,7 +91,7 @@ class CallGraph { /// \brief This node has edges to it from all functions making indirect calls /// or calling an external function. - CallGraphNode *CallsExternalNode; + std::unique_ptr<CallGraphNode> CallsExternalNode; /// \brief Replace the function represented by this node by another. /// @@ -104,7 +105,8 @@ class CallGraph { void addToCallGraph(Function *F); public: - CallGraph(Module &M); + explicit CallGraph(Module &M); + CallGraph(CallGraph &&Arg); ~CallGraph(); void print(raw_ostream &OS) const; @@ -125,21 +127,23 @@ public: inline const CallGraphNode *operator[](const Function *F) const { const_iterator I = FunctionMap.find(F); assert(I != FunctionMap.end() && "Function not in callgraph!"); - return I->second; + return I->second.get(); } /// \brief Returns the call graph node for the provided function. inline CallGraphNode *operator[](const Function *F) { const_iterator I = FunctionMap.find(F); assert(I != FunctionMap.end() && "Function not in callgraph!"); - return I->second; + return I->second.get(); } /// \brief Returns the \c CallGraphNode which is used to represent /// undetermined calls into the callgraph. CallGraphNode *getExternalCallingNode() const { return ExternalCallingNode; } - CallGraphNode *getCallsExternalNode() const { return CallsExternalNode; } + CallGraphNode *getCallsExternalNode() const { + return CallsExternalNode.get(); + } //===--------------------------------------------------------------------- // Functions to keep a call graph up to date with a function that has been @@ -444,8 +448,10 @@ struct GraphTraits<CallGraph *> : public GraphTraits<CallGraphNode *> { static NodeType *getEntryNode(CallGraph *CGN) { return CGN->getExternalCallingNode(); // Start at the external node! } - typedef std::pair<const Function *, CallGraphNode *> PairTy; - typedef std::pointer_to_unary_function<PairTy, CallGraphNode &> DerefFun; + typedef std::pair<const Function *const, std::unique_ptr<CallGraphNode>> + PairTy; + typedef std::pointer_to_unary_function<const PairTy &, CallGraphNode &> + DerefFun; // nodes_iterator/begin/end - Allow iteration over all nodes in the graph typedef mapped_iterator<CallGraph::iterator, DerefFun> nodes_iterator; @@ -456,7 +462,7 @@ struct GraphTraits<CallGraph *> : public GraphTraits<CallGraphNode *> { return map_iterator(CG->end(), DerefFun(CGdereference)); } - static CallGraphNode &CGdereference(PairTy P) { return *P.second; } + static CallGraphNode &CGdereference(const PairTy &P) { return *P.second; } }; template <> @@ -465,8 +471,9 @@ struct GraphTraits<const CallGraph *> : public GraphTraits< static NodeType *getEntryNode(const CallGraph *CGN) { return CGN->getExternalCallingNode(); // Start at the external node! } - typedef std::pair<const Function *, const CallGraphNode *> PairTy; - typedef std::pointer_to_unary_function<PairTy, const CallGraphNode &> + typedef std::pair<const Function *const, std::unique_ptr<CallGraphNode>> + PairTy; + typedef std::pointer_to_unary_function<const PairTy &, const CallGraphNode &> DerefFun; // nodes_iterator/begin/end - Allow iteration over all nodes in the graph @@ -478,7 +485,9 @@ struct GraphTraits<const CallGraph *> : public GraphTraits< return map_iterator(CG->end(), DerefFun(CGdereference)); } - static const CallGraphNode &CGdereference(PairTy P) { return *P.second; } + static const CallGraphNode &CGdereference(const PairTy &P) { + return *P.second; + } }; } // End llvm namespace diff --git a/include/llvm/Analysis/CallGraphSCCPass.h b/include/llvm/Analysis/CallGraphSCCPass.h index 667e1715775fa..9c7f7bd34cceb 100644 --- a/include/llvm/Analysis/CallGraphSCCPass.h +++ b/include/llvm/Analysis/CallGraphSCCPass.h @@ -30,7 +30,7 @@ class CallGraphNode; class CallGraph; class PMStack; class CallGraphSCC; - + class CallGraphSCCPass : public Pass { public: explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {} @@ -79,25 +79,26 @@ public: void getAnalysisUsage(AnalysisUsage &Info) const override; }; -/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on. +/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on. class CallGraphSCC { void *Context; // The CGPassManager object that is vending this. std::vector<CallGraphNode*> Nodes; + public: CallGraphSCC(void *context) : Context(context) {} - - void initialize(CallGraphNode*const*I, CallGraphNode*const*E) { + + void initialize(CallGraphNode *const *I, CallGraphNode *const *E) { Nodes.assign(I, E); } - + bool isSingular() const { return Nodes.size() == 1; } unsigned size() const { return Nodes.size(); } - + /// ReplaceNode - This informs the SCC and the pass manager that the specified /// Old node has been deleted, and New is to be used in its place. void ReplaceNode(CallGraphNode *Old, CallGraphNode *New); - - typedef std::vector<CallGraphNode*>::const_iterator iterator; + + typedef std::vector<CallGraphNode *>::const_iterator iterator; iterator begin() const { return Nodes.begin(); } iterator end() const { return Nodes.end(); } }; diff --git a/include/llvm/Analysis/CaptureTracking.h b/include/llvm/Analysis/CaptureTracking.h index 8b7c7a90f7c0c..8d2c095d8585f 100644 --- a/include/llvm/Analysis/CaptureTracking.h +++ b/include/llvm/Analysis/CaptureTracking.h @@ -20,6 +20,7 @@ namespace llvm { class Use; class Instruction; class DominatorTree; + class OrderedBasicBlock; /// PointerMayBeCaptured - Return true if this pointer value may be captured /// by the enclosing function (which is required to exist). This routine can @@ -41,10 +42,12 @@ namespace llvm { /// it or not. The boolean StoreCaptures specified whether storing the value /// (or part of it) into memory anywhere automatically counts as capturing it /// or not. Captures by the provided instruction are considered if the - /// final parameter is true. + /// final parameter is true. An ordered basic block in \p OBB could be used + /// to speed up capture-tracker queries. bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures, bool StoreCaptures, const Instruction *I, - DominatorTree *DT, bool IncludeI = false); + DominatorTree *DT, bool IncludeI = false, + OrderedBasicBlock *OBB = nullptr); /// This callback is used in conjunction with PointerMayBeCaptured. In /// addition to the interface here, you'll need to provide your own getters diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h index cb74e9f32d3da..ca50ee2f829a5 100644 --- a/include/llvm/Analysis/DOTGraphTraitsPass.h +++ b/include/llvm/Analysis/DOTGraphTraitsPass.h @@ -36,8 +36,23 @@ public: DOTGraphTraitsViewer(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} + /// @brief Return true if this function should be processed. + /// + /// An implementation of this class my override this function to indicate that + /// only certain functions should be viewed. + /// + /// @param Analysis The current analysis result for this function. + virtual bool processFunction(Function &F, AnalysisT &Analysis) { + return true; + } + bool runOnFunction(Function &F) override { - GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); + auto &Analysis = getAnalysis<AnalysisT>(); + + if (!processFunction(F, Analysis)) + return false; + + GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis); std::string GraphName = DOTGraphTraits<GraphT>::getGraphName(Graph); std::string Title = GraphName + " for '" + F.getName().str() + "' function"; @@ -63,8 +78,23 @@ public: DOTGraphTraitsPrinter(StringRef GraphName, char &ID) : FunctionPass(ID), Name(GraphName) {} + /// @brief Return true if this function should be processed. + /// + /// An implementation of this class my override this function to indicate that + /// only certain functions should be printed. + /// + /// @param Analysis The current analysis result for this function. + virtual bool processFunction(Function &F, AnalysisT &Analysis) { + return true; + } + bool runOnFunction(Function &F) override { - GraphT Graph = AnalysisGraphTraitsT::getGraph(&getAnalysis<AnalysisT>()); + auto &Analysis = getAnalysis<AnalysisT>(); + + if (!processFunction(F, Analysis)) + return false; + + GraphT Graph = AnalysisGraphTraitsT::getGraph(&Analysis); std::string Filename = Name + "." + F.getName().str() + ".dot"; std::error_code EC; diff --git a/include/llvm/Analysis/DemandedBits.h b/include/llvm/Analysis/DemandedBits.h new file mode 100644 index 0000000000000..42932bfd3491d --- /dev/null +++ b/include/llvm/Analysis/DemandedBits.h @@ -0,0 +1,75 @@ +//===-- llvm/Analysis/DemandedBits.h - Determine demanded bits --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass implements a demanded bits analysis. A demanded bit is one that +// contributes to a result; bits that are not demanded can be either zero or +// one without affecting control or data flow. For example in this sequence: +// +// %1 = add i32 %x, %y +// %2 = trunc i32 %1 to i16 +// +// Only the lowest 16 bits of %1 are demanded; the rest are removed by the +// trunc. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DEMANDED_BITS_H +#define LLVM_ANALYSIS_DEMANDED_BITS_H + +#include "llvm/Pass.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" + +namespace llvm { + +class FunctionPass; +class Function; +class Instruction; +class DominatorTree; +class AssumptionCache; + +struct DemandedBits : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + DemandedBits(); + + bool runOnFunction(Function& F) override; + void getAnalysisUsage(AnalysisUsage& AU) const override; + void print(raw_ostream &OS, const Module *M) const override; + + /// Return the bits demanded from instruction I. + APInt getDemandedBits(Instruction *I); + + /// Return true if, during analysis, I could not be reached. + bool isInstructionDead(Instruction *I); + +private: + void performAnalysis(); + void determineLiveOperandBits(const Instruction *UserI, + const Instruction *I, unsigned OperandNo, + const APInt &AOut, APInt &AB, + APInt &KnownZero, APInt &KnownOne, + APInt &KnownZero2, APInt &KnownOne2); + + AssumptionCache *AC; + DominatorTree *DT; + Function *F; + bool Analyzed; + + // The set of visited instructions (non-integer-typed only). + SmallPtrSet<Instruction*, 128> Visited; + DenseMap<Instruction *, APInt> AliveBits; +}; + +/// Create a demanded bits analysis pass. +FunctionPass *createDemandedBitsPass(); + +} // End llvm namespace + +#endif diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h index a08ce574ea565..5290552b41dc9 100644 --- a/include/llvm/Analysis/DependenceAnalysis.h +++ b/include/llvm/Analysis/DependenceAnalysis.h @@ -42,11 +42,11 @@ #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/Instructions.h" #include "llvm/Pass.h" namespace llvm { - class AliasAnalysis; class Loop; class LoopInfo; class ScalarEvolution; @@ -69,6 +69,15 @@ namespace llvm { /// as singly-linked lists, with the "next" fields stored in the dependence /// itelf. class Dependence { + protected: + Dependence(const Dependence &) = default; + + // FIXME: When we move to MSVC 2015 as the base compiler for Visual Studio + // support, uncomment this line to allow a defaulted move constructor for + // Dependence. Currently, FullDependence relies on the copy constructor, but + // that is acceptable given the triviality of the class. + // Dependence(Dependence &&) = default; + public: Dependence(Instruction *Source, Instruction *Destination) : @@ -176,38 +185,30 @@ namespace llvm { /// getNextPredecessor - Returns the value of the NextPredecessor /// field. - const Dependence *getNextPredecessor() const { - return NextPredecessor; - } - + const Dependence *getNextPredecessor() const { return NextPredecessor; } + /// getNextSuccessor - Returns the value of the NextSuccessor /// field. - const Dependence *getNextSuccessor() const { - return NextSuccessor; - } - + const Dependence *getNextSuccessor() const { return NextSuccessor; } + /// setNextPredecessor - Sets the value of the NextPredecessor /// field. - void setNextPredecessor(const Dependence *pred) { - NextPredecessor = pred; - } - + void setNextPredecessor(const Dependence *pred) { NextPredecessor = pred; } + /// setNextSuccessor - Sets the value of the NextSuccessor /// field. - void setNextSuccessor(const Dependence *succ) { - NextSuccessor = succ; - } - + void setNextSuccessor(const Dependence *succ) { NextSuccessor = succ; } + /// dump - For debugging purposes, dumps a dependence to OS. /// void dump(raw_ostream &OS) const; + private: Instruction *Src, *Dst; const Dependence *NextPredecessor, *NextSuccessor; friend class DependenceAnalysis; }; - /// FullDependence - This class represents a dependence between two memory /// references in a function. It contains detailed information about the /// dependence (direction vectors, etc.) and is used when the compiler is @@ -216,11 +217,15 @@ namespace llvm { /// (for output, flow, and anti dependences), the dependence implies an /// ordering, where the source must precede the destination; in contrast, /// input dependences are unordered. - class FullDependence : public Dependence { + class FullDependence final : public Dependence { public: FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent, unsigned Levels); - ~FullDependence() override { delete[] DV; } + + FullDependence(FullDependence &&RHS) + : Dependence(std::move(RHS)), Levels(RHS.Levels), + LoopIndependent(RHS.LoopIndependent), Consistent(RHS.Consistent), + DV(std::move(RHS.DV)) {} /// isLoopIndependent - Returns true if this is a loop-independent /// dependence. @@ -268,16 +273,16 @@ namespace llvm { unsigned short Levels; bool LoopIndependent; bool Consistent; // Init to true, then refine. - DVEntry *DV; + std::unique_ptr<DVEntry[]> DV; friend class DependenceAnalysis; }; - /// DependenceAnalysis - This class is the main dependence-analysis driver. /// class DependenceAnalysis : public FunctionPass { void operator=(const DependenceAnalysis &) = delete; DependenceAnalysis(const DependenceAnalysis &) = delete; + public: /// depends - Tests for a dependence between the Src and Dst instructions. /// Returns NULL if no dependence; otherwise, returns a Dependence (or a @@ -387,6 +392,7 @@ namespace llvm { const SCEV *B; const SCEV *C; const Loop *AssociatedLoop; + public: /// isEmpty - Return true if the constraint is of kind Empty. bool isEmpty() const { return Kind == Empty; } @@ -453,7 +459,6 @@ namespace llvm { void dump(raw_ostream &OS) const; }; - /// establishNestingLevels - Examines the loop nesting of the Src and Dst /// instructions and establishes their shared loops. Sets the variables /// CommonLevels, SrcLevels, and MaxLevels. @@ -521,10 +526,10 @@ namespace llvm { /// in LoopNest. bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const; - /// Makes sure all subscript pairs share the same integer type by + /// Makes sure all subscript pairs share the same integer type by /// sign-extending as necessary. /// Sign-extending a subscript is safe because getelementptr assumes the - /// array subscripts are signed. + /// array subscripts are signed. void unifySubscriptType(ArrayRef<Subscript *> Pairs); /// removeMatchingExtensions - Examines a subscript pair. @@ -806,7 +811,6 @@ namespace llvm { const SCEV *Delta) const; /// testBounds - Returns true iff the current bounds are plausible. - /// bool testBounds(unsigned char DirKind, unsigned Level, BoundInfo *Bound, @@ -913,9 +917,8 @@ namespace llvm { void updateDirection(Dependence::DVEntry &Level, const Constraint &CurConstraint) const; - bool tryDelinearize(const SCEV *SrcSCEV, const SCEV *DstSCEV, - SmallVectorImpl<Subscript> &Pair, - const SCEV *ElementSize); + bool tryDelinearize(Instruction *Src, Instruction *Dst, + SmallVectorImpl<Subscript> &Pair); public: static char ID; // Class identification, replacement for typeinfo diff --git a/include/llvm/Analysis/DivergenceAnalysis.h b/include/llvm/Analysis/DivergenceAnalysis.h new file mode 100644 index 0000000000000..aa2de571ba1bc --- /dev/null +++ b/include/llvm/Analysis/DivergenceAnalysis.h @@ -0,0 +1,48 @@ +//===- llvm/Analysis/DivergenceAnalysis.h - Divergence Analysis -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The divergence analysis is an LLVM pass which can be used to find out +// if a branch instruction in a GPU program is divergent or not. It can help +// branch optimizations such as jump threading and loop unswitching to make +// better decisions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/DenseSet.h" +#include "llvm/IR/Function.h" +#include "llvm/Pass.h" + +namespace llvm { +class Value; +class DivergenceAnalysis : public FunctionPass { +public: + static char ID; + + DivergenceAnalysis() : FunctionPass(ID) { + initializeDivergenceAnalysisPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override; + + bool runOnFunction(Function &F) override; + + // Print all divergent branches in the function. + void print(raw_ostream &OS, const Module *) const override; + + // Returns true if V is divergent. + bool isDivergent(const Value *V) const { return DivergentValues.count(V); } + + // Returns true if V is uniform/non-divergent. + bool isUniform(const Value *V) const { return !isDivergent(V); } + +private: + // Stores all divergent values. + DenseSet<const Value *> DivergentValues; +}; +} // End llvm namespace diff --git a/include/llvm/Analysis/EHPersonalities.h b/include/llvm/Analysis/EHPersonalities.h new file mode 100644 index 0000000000000..59e9672b88e59 --- /dev/null +++ b/include/llvm/Analysis/EHPersonalities.h @@ -0,0 +1,94 @@ +//===- EHPersonalities.h - Compute EH-related information -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_EHPERSONALITIES_H +#define LLVM_ANALYSIS_EHPERSONALITIES_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/Support/ErrorHandling.h" + +namespace llvm { +class BasicBlock; +class Function; +class Value; + +enum class EHPersonality { + Unknown, + GNU_Ada, + GNU_C, + GNU_CXX, + GNU_ObjC, + MSVC_X86SEH, + MSVC_Win64SEH, + MSVC_CXX, + CoreCLR +}; + +/// \brief See if the given exception handling personality function is one +/// that we understand. If so, return a description of it; otherwise return +/// Unknown. +EHPersonality classifyEHPersonality(const Value *Pers); + +/// \brief Returns true if this personality function catches asynchronous +/// exceptions. +inline bool isAsynchronousEHPersonality(EHPersonality Pers) { + // The two SEH personality functions can catch asynch exceptions. We assume + // unknown personalities don't catch asynch exceptions. + switch (Pers) { + case EHPersonality::MSVC_X86SEH: + case EHPersonality::MSVC_Win64SEH: + return true; + default: + return false; + } + llvm_unreachable("invalid enum"); +} + +/// \brief Returns true if this is a personality function that invokes +/// handler funclets (which must return to it). +inline bool isFuncletEHPersonality(EHPersonality Pers) { + switch (Pers) { + case EHPersonality::MSVC_CXX: + case EHPersonality::MSVC_X86SEH: + case EHPersonality::MSVC_Win64SEH: + case EHPersonality::CoreCLR: + return true; + default: + return false; + } + llvm_unreachable("invalid enum"); +} + +/// \brief Return true if this personality may be safely removed if there +/// are no invoke instructions remaining in the current function. +inline bool isNoOpWithoutInvoke(EHPersonality Pers) { + switch (Pers) { + case EHPersonality::Unknown: + return false; + // All known personalities currently have this behavior + default: + return true; + } + llvm_unreachable("invalid enum"); +} + +bool canSimplifyInvokeNoUnwind(const Function *F); + +typedef TinyPtrVector<BasicBlock *> ColorVector; + +/// \brief If an EH funclet personality is in use (see isFuncletEHPersonality), +/// this will recompute which blocks are in which funclet. It is possible that +/// some blocks are in multiple funclets. Consider this analysis to be +/// expensive. +DenseMap<BasicBlock *, ColorVector> colorEHFunclets(Function &F); + +} // end namespace llvm + +#endif diff --git a/include/llvm/Analysis/GlobalsModRef.h b/include/llvm/Analysis/GlobalsModRef.h new file mode 100644 index 0000000000000..bcd102e7ded2a --- /dev/null +++ b/include/llvm/Analysis/GlobalsModRef.h @@ -0,0 +1,160 @@ +//===- GlobalsModRef.h - Simple Mod/Ref AA for Globals ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the interface for a simple mod/ref and alias analysis over globals. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_GLOBALSMODREF_H +#define LLVM_ANALYSIS_GLOBALSMODREF_H + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/ValueHandle.h" +#include "llvm/Pass.h" +#include <list> + +namespace llvm { + +/// An alias analysis result set for globals. +/// +/// This focuses on handling aliasing properties of globals and interprocedural +/// function call mod/ref information. +class GlobalsAAResult : public AAResultBase<GlobalsAAResult> { + friend AAResultBase<GlobalsAAResult>; + + class FunctionInfo; + + const DataLayout &DL; + + /// The globals that do not have their addresses taken. + SmallPtrSet<const GlobalValue *, 8> NonAddressTakenGlobals; + + /// IndirectGlobals - The memory pointed to by this global is known to be + /// 'owned' by the global. + SmallPtrSet<const GlobalValue *, 8> IndirectGlobals; + + /// AllocsForIndirectGlobals - If an instruction allocates memory for an + /// indirect global, this map indicates which one. + DenseMap<const Value *, const GlobalValue *> AllocsForIndirectGlobals; + + /// For each function, keep track of what globals are modified or read. + DenseMap<const Function *, FunctionInfo> FunctionInfos; + + /// A map of functions to SCC. The SCCs are described by a simple integer + /// ID that is only useful for comparing for equality (are two functions + /// in the same SCC or not?) + DenseMap<const Function *, unsigned> FunctionToSCCMap; + + /// Handle to clear this analysis on deletion of values. + struct DeletionCallbackHandle final : CallbackVH { + GlobalsAAResult *GAR; + std::list<DeletionCallbackHandle>::iterator I; + + DeletionCallbackHandle(GlobalsAAResult &GAR, Value *V) + : CallbackVH(V), GAR(&GAR) {} + + void deleted() override; + }; + + /// List of callbacks for globals being tracked by this analysis. Note that + /// these objects are quite large, but we only anticipate having one per + /// global tracked by this analysis. There are numerous optimizations we + /// could perform to the memory utilization here if this becomes a problem. + std::list<DeletionCallbackHandle> Handles; + + explicit GlobalsAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI); + +public: + GlobalsAAResult(GlobalsAAResult &&Arg); + + static GlobalsAAResult analyzeModule(Module &M, const TargetLibraryInfo &TLI, + CallGraph &CG); + + //------------------------------------------------ + // Implement the AliasAnalysis API + // + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + + using AAResultBase::getModRefInfo; + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); + + /// getModRefBehavior - Return the behavior of the specified function if + /// called from the specified call site. The call site may be null in which + /// case the most generic behavior of this function should be returned. + FunctionModRefBehavior getModRefBehavior(const Function *F); + + /// getModRefBehavior - Return the behavior of the specified function if + /// called from the specified call site. The call site may be null in which + /// case the most generic behavior of this function should be returned. + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); + +private: + FunctionInfo *getFunctionInfo(const Function *F); + + void AnalyzeGlobals(Module &M); + void AnalyzeCallGraph(CallGraph &CG, Module &M); + bool AnalyzeUsesOfPointer(Value *V, + SmallPtrSetImpl<Function *> *Readers = nullptr, + SmallPtrSetImpl<Function *> *Writers = nullptr, + GlobalValue *OkayStoreDest = nullptr); + bool AnalyzeIndirectGlobalMemory(GlobalVariable *GV); + void CollectSCCMembership(CallGraph &CG); + + bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V); + ModRefInfo getModRefInfoForArgument(ImmutableCallSite CS, + const GlobalValue *GV); +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class GlobalsAA { +public: + typedef GlobalsAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + GlobalsAAResult run(Module &M, AnalysisManager<Module> *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "GlobalsAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the GlobalsAAResult object. +class GlobalsAAWrapperPass : public ModulePass { + std::unique_ptr<GlobalsAAResult> Result; + +public: + static char ID; + + GlobalsAAWrapperPass(); + + GlobalsAAResult &getResult() { return *Result; } + const GlobalsAAResult &getResult() const { return *Result; } + + bool runOnModule(Module &M) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +//===--------------------------------------------------------------------===// +// +// createGlobalsAAWrapperPass - This pass provides alias and mod/ref info for +// global values that do not have their addresses taken. +// +ModulePass *createGlobalsAAWrapperPass(); +} + +#endif diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 00dbcbdd78063..37d01490dac6a 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -34,7 +34,7 @@ class DataLayout; /// The Expr member keeps track of the expression, User is the actual user /// instruction of the operand, and 'OperandValToReplace' is the operand of /// the User that is the use. -class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> { +class IVStrideUse final : public CallbackVH, public ilist_node<IVStrideUse> { friend class IVUsers; public: IVStrideUse(IVUsers *P, Instruction* U, Value *O) diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 79ed74d824111..35f991cb3f674 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -23,7 +23,7 @@ class AssumptionCacheTracker; class CallSite; class DataLayout; class Function; -class TargetTransformInfoWrapperPass; +class TargetTransformInfo; namespace InlineConstants { // Various magic constants used to adjust heuristics. @@ -98,46 +98,31 @@ public: int getCostDelta() const { return Threshold - getCost(); } }; -/// \brief Cost analyzer used by inliner. -class InlineCostAnalysis : public CallGraphSCCPass { - TargetTransformInfoWrapperPass *TTIWP; - AssumptionCacheTracker *ACT; - -public: - static char ID; - - InlineCostAnalysis(); - ~InlineCostAnalysis() override; - - // Pass interface implementation. - void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnSCC(CallGraphSCC &SCC) override; - - /// \brief Get an InlineCost object representing the cost of inlining this - /// callsite. - /// - /// Note that threshold is passed into this function. Only costs below the - /// threshold are computed with any accuracy. The threshold can be used to - /// bound the computation necessary to determine whether the cost is - /// sufficiently low to warrant inlining. - /// - /// Also note that calling this function *dynamically* computes the cost of - /// inlining the callsite. It is an expensive, heavyweight call. - InlineCost getInlineCost(CallSite CS, int Threshold); - - /// \brief Get an InlineCost with the callee explicitly specified. - /// This allows you to calculate the cost of inlining a function via a - /// pointer. This behaves exactly as the version with no explicit callee - /// parameter in all other respects. - // - // Note: This is used by out-of-tree passes, please do not remove without - // adding a replacement API. - InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold); +/// \brief Get an InlineCost object representing the cost of inlining this +/// callsite. +/// +/// Note that threshold is passed into this function. Only costs below the +/// threshold are computed with any accuracy. The threshold can be used to +/// bound the computation necessary to determine whether the cost is +/// sufficiently low to warrant inlining. +/// +/// Also note that calling this function *dynamically* computes the cost of +/// inlining the callsite. It is an expensive, heavyweight call. +InlineCost getInlineCost(CallSite CS, int Threshold, + TargetTransformInfo &CalleeTTI, + AssumptionCacheTracker *ACT); - /// \brief Minimal filter to detect invalid constructs for inlining. - bool isInlineViable(Function &Callee); -}; +/// \brief Get an InlineCost with the callee explicitly specified. +/// This allows you to calculate the cost of inlining a function via a +/// pointer. This behaves exactly as the version with no explicit callee +/// parameter in all other respects. +// +InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold, + TargetTransformInfo &CalleeTTI, + AssumptionCacheTracker *ACT); +/// \brief Minimal filter to detect invalid constructs for inlining. +bool isInlineViable(Function &Callee); } #endif diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index d44c5ff4078d1..ed313dae9ab13 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -207,7 +207,7 @@ namespace llvm { const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, - Instruction *CxtI = nullptr); + const Instruction *CxtI = nullptr); /// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can /// fold the result. If not, this returns null. diff --git a/include/llvm/Analysis/IteratedDominanceFrontier.h b/include/llvm/Analysis/IteratedDominanceFrontier.h index 5a339f10f50fd..a1ded2554d44b 100644 --- a/include/llvm/Analysis/IteratedDominanceFrontier.h +++ b/include/llvm/Analysis/IteratedDominanceFrontier.h @@ -34,7 +34,7 @@ namespace llvm { class BasicBlock; template <class T> class DomTreeNodeBase; typedef DomTreeNodeBase<BasicBlock> DomTreeNode; -class DominatorTree; +template <class T> class DominatorTreeBase; /// \brief Determine the iterated dominance frontier, given a set of defining /// blocks, and optionally, a set of live-in blocks. @@ -47,7 +47,7 @@ class DominatorTree; class IDFCalculator { public: - IDFCalculator(DominatorTree &DT) : DT(DT), useLiveIn(false) {} + IDFCalculator(DominatorTreeBase<BasicBlock> &DT) : DT(DT), useLiveIn(false) {} /// \brief Give the IDF calculator the set of blocks in which the value is /// defined. This is equivalent to the set of starting blocks it should be @@ -85,7 +85,7 @@ public: void calculate(SmallVectorImpl<BasicBlock *> &IDFBlocks); private: - DominatorTree &DT; + DominatorTreeBase<BasicBlock> &DT; bool useLiveIn; DenseMap<DomTreeNode *, unsigned> DomLevels; const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks; diff --git a/include/llvm/Analysis/LazyCallGraph.h b/include/llvm/Analysis/LazyCallGraph.h index b0b9068de34bf..ef3d5e8fe3df1 100644 --- a/include/llvm/Analysis/LazyCallGraph.h +++ b/include/llvm/Analysis/LazyCallGraph.h @@ -54,7 +54,7 @@ namespace llvm { class PreservedAnalyses; class raw_ostream; -/// \brief A lazily constructed view of the call graph of a module. +/// A lazily constructed view of the call graph of a module. /// /// With the edges of this graph, the motivating constraint that we are /// attempting to maintain is that function-local optimization, CGSCC-local @@ -107,7 +107,7 @@ public: typedef SmallVector<PointerUnion<Function *, Node *>, 4> NodeVectorT; typedef SmallVectorImpl<PointerUnion<Function *, Node *>> NodeVectorImplT; - /// \brief A lazy iterator used for both the entry nodes and child nodes. + /// A lazy iterator used for both the entry nodes and child nodes. /// /// When this iterator is dereferenced, if not yet available, a function will /// be scanned for "calls" or uses of functions and its child information @@ -152,7 +152,7 @@ public: } }; - /// \brief A node in the call graph. + /// A node in the call graph. /// /// This represents a single node. It's primary roles are to cache the list of /// callees, de-duplicate and provide fast testing of whether a function is @@ -172,25 +172,23 @@ public: mutable NodeVectorT Callees; DenseMap<Function *, size_t> CalleeIndexMap; - /// \brief Basic constructor implements the scanning of F into Callees and + /// Basic constructor implements the scanning of F into Callees and /// CalleeIndexMap. Node(LazyCallGraph &G, Function &F); - /// \brief Internal helper to insert a callee. + /// Internal helper to insert a callee. void insertEdgeInternal(Function &Callee); - /// \brief Internal helper to insert a callee. + /// Internal helper to insert a callee. void insertEdgeInternal(Node &CalleeN); - /// \brief Internal helper to remove a callee from this node. + /// Internal helper to remove a callee from this node. void removeEdgeInternal(Function &Callee); public: typedef LazyCallGraph::iterator iterator; - Function &getFunction() const { - return F; - }; + Function &getFunction() const { return F; } iterator begin() const { return iterator(*G, Callees.begin(), Callees.end()); @@ -202,7 +200,7 @@ public: bool operator!=(const Node &N) const { return !operator==(N); } }; - /// \brief An SCC of the call graph. + /// An SCC of the call graph. /// /// This represents a Strongly Connected Component of the call graph as /// a collection of call graph nodes. While the order of nodes in the SCC is @@ -226,7 +224,8 @@ public: public: typedef SmallVectorImpl<Node *>::const_iterator iterator; - typedef pointee_iterator<SmallPtrSet<SCC *, 1>::const_iterator> parent_iterator; + typedef pointee_iterator<SmallPtrSet<SCC *, 1>::const_iterator> + parent_iterator; iterator begin() const { return Nodes.begin(); } iterator end() const { return Nodes.end(); } @@ -235,24 +234,24 @@ public: parent_iterator parent_end() const { return ParentSCCs.end(); } iterator_range<parent_iterator> parents() const { - return iterator_range<parent_iterator>(parent_begin(), parent_end()); + return make_range(parent_begin(), parent_end()); } - /// \brief Test if this SCC is a parent of \a C. + /// Test if this SCC is a parent of \a C. bool isParentOf(const SCC &C) const { return C.isChildOf(*this); } - /// \brief Test if this SCC is an ancestor of \a C. + /// Test if this SCC is an ancestor of \a C. bool isAncestorOf(const SCC &C) const { return C.isDescendantOf(*this); } - /// \brief Test if this SCC is a child of \a C. + /// Test if this SCC is a child of \a C. bool isChildOf(const SCC &C) const { return ParentSCCs.count(const_cast<SCC *>(&C)); } - /// \brief Test if this SCC is a descendant of \a C. + /// Test if this SCC is a descendant of \a C. bool isDescendantOf(const SCC &C) const; - /// \brief Short name useful for debugging or logging. + /// Short name useful for debugging or logging. /// /// We use the name of the first function in the SCC to name the SCC for /// the purposes of debugging and logging. @@ -267,22 +266,21 @@ public: /// Note that these methods sometimes have complex runtimes, so be careful /// how you call them. - /// \brief Insert an edge from one node in this SCC to another in this SCC. + /// Insert an edge from one node in this SCC to another in this SCC. /// /// By the definition of an SCC, this does not change the nature or make-up /// of any SCCs. void insertIntraSCCEdge(Node &CallerN, Node &CalleeN); - /// \brief Insert an edge whose tail is in this SCC and head is in some - /// child SCC. + /// Insert an edge whose tail is in this SCC and head is in some child SCC. /// /// There must be an existing path from the caller to the callee. This /// operation is inexpensive and does not change the set of SCCs in the /// graph. void insertOutgoingEdge(Node &CallerN, Node &CalleeN); - /// \brief Insert an edge whose tail is in a descendant SCC and head is in - /// this SCC. + /// Insert an edge whose tail is in a descendant SCC and head is in this + /// SCC. /// /// There must be an existing path from the callee to the caller in this /// case. NB! This is has the potential to be a very expensive function. It @@ -297,7 +295,7 @@ public: /// implementation for details, but that use case might impact users. SmallVector<SCC *, 1> insertIncomingEdge(Node &CallerN, Node &CalleeN); - /// \brief Remove an edge whose source is in this SCC and target is *not*. + /// Remove an edge whose source is in this SCC and target is *not*. /// /// This removes an inter-SCC edge. All inter-SCC edges originating from /// this SCC have been fully explored by any in-flight DFS SCC formation, @@ -309,7 +307,7 @@ public: /// them. void removeInterSCCEdge(Node &CallerN, Node &CalleeN); - /// \brief Remove an edge which is entirely within this SCC. + /// Remove an edge which is entirely within this SCC. /// /// Both the \a Caller and the \a Callee must be within this SCC. Removing /// such an edge make break cycles that form this SCC and thus this @@ -346,7 +344,7 @@ public: ///@} }; - /// \brief A post-order depth-first SCC iterator over the call graph. + /// A post-order depth-first SCC iterator over the call graph. /// /// This iterator triggers the Tarjan DFS-based formation of the SCC DAG for /// the call graph, walking it lazily in depth-first post-order. That is, it @@ -358,7 +356,7 @@ public: friend class LazyCallGraph; friend class LazyCallGraph::Node; - /// \brief Nonce type to select the constructor for the end iterator. + /// Nonce type to select the constructor for the end iterator. struct IsAtEndT {}; LazyCallGraph *G; @@ -387,7 +385,7 @@ public: } }; - /// \brief Construct a graph for the given module. + /// Construct a graph for the given module. /// /// This sets up the graph and computes all of the entry points of the graph. /// No function definitions are scanned until their nodes in the graph are @@ -410,22 +408,20 @@ public: } iterator_range<postorder_scc_iterator> postorder_sccs() { - return iterator_range<postorder_scc_iterator>(postorder_scc_begin(), - postorder_scc_end()); + return make_range(postorder_scc_begin(), postorder_scc_end()); } - /// \brief Lookup a function in the graph which has already been scanned and - /// added. + /// Lookup a function in the graph which has already been scanned and added. Node *lookup(const Function &F) const { return NodeMap.lookup(&F); } - /// \brief Lookup a function's SCC in the graph. + /// Lookup a function's SCC in the graph. /// /// \returns null if the function hasn't been assigned an SCC via the SCC /// iterator walk. SCC *lookupSCC(Node &N) const { return SCCMap.lookup(&N); } - /// \brief Get a graph node for a given function, scanning it to populate the - /// graph data as necessary. + /// Get a graph node for a given function, scanning it to populate the graph + /// data as necessary. Node &get(Function &F) { Node *&N = NodeMap[&F]; if (N) @@ -444,18 +440,18 @@ public: /// Once you begin manipulating a call graph's SCCs, you must perform all /// mutation of the graph via the SCC methods. - /// \brief Update the call graph after inserting a new edge. + /// Update the call graph after inserting a new edge. void insertEdge(Node &Caller, Function &Callee); - /// \brief Update the call graph after inserting a new edge. + /// Update the call graph after inserting a new edge. void insertEdge(Function &Caller, Function &Callee) { return insertEdge(get(Caller), Callee); } - /// \brief Update the call graph after deleting an edge. + /// Update the call graph after deleting an edge. void removeEdge(Node &Caller, Function &Callee); - /// \brief Update the call graph after deleting an edge. + /// Update the call graph after deleting an edge. void removeEdge(Function &Caller, Function &Callee) { return removeEdge(get(Caller), Callee); } @@ -463,57 +459,56 @@ public: ///@} private: - /// \brief Allocator that holds all the call graph nodes. + /// Allocator that holds all the call graph nodes. SpecificBumpPtrAllocator<Node> BPA; - /// \brief Maps function->node for fast lookup. + /// Maps function->node for fast lookup. DenseMap<const Function *, Node *> NodeMap; - /// \brief The entry nodes to the graph. + /// The entry nodes to the graph. /// /// These nodes are reachable through "external" means. Put another way, they /// escape at the module scope. NodeVectorT EntryNodes; - /// \brief Map of the entry nodes in the graph to their indices in - /// \c EntryNodes. + /// Map of the entry nodes in the graph to their indices in \c EntryNodes. DenseMap<Function *, size_t> EntryIndexMap; - /// \brief Allocator that holds all the call graph SCCs. + /// Allocator that holds all the call graph SCCs. SpecificBumpPtrAllocator<SCC> SCCBPA; - /// \brief Maps Function -> SCC for fast lookup. + /// Maps Function -> SCC for fast lookup. DenseMap<Node *, SCC *> SCCMap; - /// \brief The leaf SCCs of the graph. + /// The leaf SCCs of the graph. /// /// These are all of the SCCs which have no children. SmallVector<SCC *, 4> LeafSCCs; - /// \brief Stack of nodes in the DFS walk. + /// Stack of nodes in the DFS walk. SmallVector<std::pair<Node *, iterator>, 4> DFSStack; - /// \brief Set of entry nodes not-yet-processed into SCCs. + /// Set of entry nodes not-yet-processed into SCCs. SmallVector<Function *, 4> SCCEntryNodes; - /// \brief Stack of nodes the DFS has walked but not yet put into a SCC. + /// Stack of nodes the DFS has walked but not yet put into a SCC. SmallVector<Node *, 4> PendingSCCStack; - /// \brief Counter for the next DFS number to assign. + /// Counter for the next DFS number to assign. int NextDFSNumber; - /// \brief Helper to insert a new function, with an already looked-up entry in + /// Helper to insert a new function, with an already looked-up entry in /// the NodeMap. Node &insertInto(Function &F, Node *&MappedN); - /// \brief Helper to update pointers back to the graph object during moves. + /// Helper to update pointers back to the graph object during moves. void updateGraphPtrs(); - /// \brief Helper to form a new SCC out of the top of a DFSStack-like + /// Helper to form a new SCC out of the top of a DFSStack-like /// structure. SCC *formSCC(Node *RootN, SmallVectorImpl<Node *> &NodeStack); - /// \brief Retrieve the next node in the post-order SCC walk of the call graph. + /// Retrieve the next node in the post-order SCC walk of the call graph. SCC *getNextSCCInPostOrder(); }; @@ -535,17 +530,17 @@ template <> struct GraphTraits<LazyCallGraph *> { static ChildIteratorType child_end(NodeType *N) { return N->end(); } }; -/// \brief An analysis pass which computes the call graph for a module. +/// An analysis pass which computes the call graph for a module. class LazyCallGraphAnalysis { public: - /// \brief Inform generic clients of the result type. + /// Inform generic clients of the result type. typedef LazyCallGraph Result; static void *ID() { return (void *)&PassID; } static StringRef name() { return "Lazy CallGraph Analysis"; } - /// \brief Compute the \c LazyCallGraph for the module \c M. + /// Compute the \c LazyCallGraph for the module \c M. /// /// This just builds the set of entry points to the call graph. The rest is /// built lazily as it is walked. @@ -555,7 +550,7 @@ private: static char PassID; }; -/// \brief A pass which prints the call graph to a \c raw_ostream. +/// A pass which prints the call graph to a \c raw_ostream. /// /// This is primarily useful for testing the analysis. class LazyCallGraphPrinterPass { diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h index 1051cff5efb70..42002062dca21 100644 --- a/include/llvm/Analysis/LazyValueInfo.h +++ b/include/llvm/Analysis/LazyValueInfo.h @@ -25,7 +25,7 @@ namespace llvm { class Instruction; class TargetLibraryInfo; class Value; - + /// This pass computes, caches, and vends lazy value constraint information. class LazyValueInfo : public FunctionPass { AssumptionCache *AC; @@ -45,23 +45,22 @@ public: enum Tristate { Unknown = -1, False = 0, True = 1 }; - - + // Public query interface. - + /// Determine whether the specified value comparison with a constant is known /// to be true or false on the specified CFG edge. /// Pred is a CmpInst predicate. Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI = nullptr); - + /// Determine whether the specified value comparison with a constant is known /// to be true or false at the specified instruction /// (from an assume intrinsic). Pred is a CmpInst predicate. Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C, Instruction *CxtI); - + /// Determine whether the specified value is known to be a /// constant at the end of the specified block. Return null if not. Constant *getConstant(Value *V, BasicBlock *BB, Instruction *CxtI = nullptr); @@ -70,14 +69,14 @@ public: /// constant on the specified edge. Return null if not. Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI = nullptr); - + /// Inform the analysis cache that we have threaded an edge from /// PredBB to OldSucc to be from PredBB to NewSucc instead. void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc); - + /// Inform the analysis cache that we have erased a block. void eraseBlock(BasicBlock *BB); - + // Implementation boilerplate. void getAnalysisUsage(AnalysisUsage &AU) const override; diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h deleted file mode 100644 index 6589ac13c746f..0000000000000 --- a/include/llvm/Analysis/LibCallAliasAnalysis.h +++ /dev/null @@ -1,71 +0,0 @@ -//===- LibCallAliasAnalysis.h - Implement AliasAnalysis for libcalls ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the LibCallAliasAnalysis class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H -#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H - -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/IR/Module.h" -#include "llvm/Pass.h" - -namespace llvm { - class LibCallInfo; - struct LibCallFunctionInfo; - - /// LibCallAliasAnalysis - Alias analysis driven from LibCallInfo. - struct LibCallAliasAnalysis : public FunctionPass, public AliasAnalysis { - static char ID; // Class identification - - LibCallInfo *LCI; - - explicit LibCallAliasAnalysis(LibCallInfo *LC = nullptr) - : FunctionPass(ID), LCI(LC) { - initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry()); - } - explicit LibCallAliasAnalysis(char &ID, LibCallInfo *LC) - : FunctionPass(ID), LCI(LC) { - initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry()); - } - ~LibCallAliasAnalysis() override; - - ModRefResult getModRefInfo(ImmutableCallSite CS, - const MemoryLocation &Loc) override; - - ModRefResult getModRefInfo(ImmutableCallSite CS1, - ImmutableCallSite CS2) override { - // TODO: Could compare two direct calls against each other if we cared to. - return AliasAnalysis::getModRefInfo(CS1, CS2); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override; - - bool runOnFunction(Function &F) override; - - /// getAdjustedAnalysisPointer - This method is used when a pass implements - /// an analysis interface through multiple inheritance. If needed, it - /// should override this to adjust the this pointer as needed for the - /// specified pass info. - void *getAdjustedAnalysisPointer(const void *PI) override { - if (PI == &AliasAnalysis::ID) - return (AliasAnalysis*)this; - return this; - } - - private: - ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI, - ImmutableCallSite CS, - const MemoryLocation &Loc); - }; -} // End of llvm namespace - -#endif diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h deleted file mode 100644 index b4bef310e5909..0000000000000 --- a/include/llvm/Analysis/LibCallSemantics.h +++ /dev/null @@ -1,225 +0,0 @@ -//===- LibCallSemantics.h - Describe library semantics --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines interfaces that can be used to describe language specific -// runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H -#define LLVM_ANALYSIS_LIBCALLSEMANTICS_H - -#include "llvm/Analysis/AliasAnalysis.h" - -namespace llvm { -class InvokeInst; - - /// LibCallLocationInfo - This struct describes a set of memory locations that - /// are accessed by libcalls. Identification of a location is doing with a - /// simple callback function. - /// - /// For example, the LibCallInfo may be set up to model the behavior of - /// standard libm functions. The location that they may be interested in is - /// an abstract location that represents errno for the current target. In - /// this case, a location for errno is anything such that the predicate - /// returns true. On Mac OS X, this predicate would return true if the - /// pointer is the result of a call to "__error()". - /// - /// Locations can also be defined in a constant-sensitive way. For example, - /// it is possible to define a location that returns true iff it is passed - /// into the call as a specific argument. This is useful for modeling things - /// like "printf", which can store to memory, but only through pointers passed - /// with a '%n' constraint. - /// - struct LibCallLocationInfo { - // TODO: Flags: isContextSensitive etc. - - /// isLocation - Return a LocResult if the specified pointer refers to this - /// location for the specified call site. This returns "Yes" if we can tell - /// that the pointer *does definitely* refer to the location, "No" if we can - /// tell that the location *definitely does not* refer to the location, and - /// returns "Unknown" if we cannot tell for certain. - enum LocResult { - Yes, No, Unknown - }; - LocResult (*isLocation)(ImmutableCallSite CS, const MemoryLocation &Loc); - }; - - /// LibCallFunctionInfo - Each record in the array of FunctionInfo structs - /// records the behavior of one libcall that is known by the optimizer. This - /// captures things like the side effects of the call. Side effects are - /// modeled both universally (in the readnone/readonly) sense, but also - /// potentially against a set of abstract locations defined by the optimizer. - /// This allows an optimizer to define that some libcall (e.g. sqrt) is - /// side-effect free except that it might modify errno (thus, the call is - /// *not* universally readonly). Or it might say that the side effects - /// are unknown other than to say that errno is not modified. - /// - struct LibCallFunctionInfo { - /// Name - This is the name of the libcall this describes. - const char *Name; - - /// TODO: Constant folding function: Constant* vector -> Constant*. - - /// UniversalBehavior - This captures the absolute mod/ref behavior without - /// any specific context knowledge. For example, if the function is known - /// to be readonly, this would be set to 'ref'. If known to be readnone, - /// this is set to NoModRef. - AliasAnalysis::ModRefResult UniversalBehavior; - - /// LocationMRInfo - This pair captures info about whether a specific - /// location is modified or referenced by a libcall. - struct LocationMRInfo { - /// LocationID - ID # of the accessed location or ~0U for array end. - unsigned LocationID; - /// MRInfo - Mod/Ref info for this location. - AliasAnalysis::ModRefResult MRInfo; - }; - - /// DetailsType - Indicate the sense of the LocationDetails array. This - /// controls how the LocationDetails array is interpreted. - enum { - /// DoesOnly - If DetailsType is set to DoesOnly, then we know that the - /// *only* mod/ref behavior of this function is captured by the - /// LocationDetails array. If we are trying to say that 'sqrt' can only - /// modify errno, we'd have the {errnoloc,mod} in the LocationDetails - /// array and have DetailsType set to DoesOnly. - DoesOnly, - - /// DoesNot - If DetailsType is set to DoesNot, then the sense of the - /// LocationDetails array is completely inverted. This means that we *do - /// not* know everything about the side effects of this libcall, but we do - /// know things that the libcall cannot do. This is useful for complex - /// functions like 'ctime' which have crazy mod/ref behavior, but are - /// known to never read or write errno. In this case, we'd have - /// {errnoloc,modref} in the LocationDetails array and DetailsType would - /// be set to DoesNot, indicating that ctime does not read or write the - /// errno location. - DoesNot - } DetailsType; - - /// LocationDetails - This is a pointer to an array of LocationMRInfo - /// structs which indicates the behavior of the libcall w.r.t. specific - /// locations. For example, if this libcall is known to only modify - /// 'errno', it would have a LocationDetails array with the errno ID and - /// 'mod' in it. See the DetailsType field for how this is interpreted. - /// - /// In the "DoesOnly" case, this information is 'may' information for: there - /// is no guarantee that the specified side effect actually does happen, - /// just that it could. In the "DoesNot" case, this is 'must not' info. - /// - /// If this pointer is null, no details are known. - /// - const LocationMRInfo *LocationDetails; - }; - - - /// LibCallInfo - Abstract interface to query about library call information. - /// Instances of this class return known information about some set of - /// libcalls. - /// - class LibCallInfo { - // Implementation details of this object, private. - mutable void *Impl; - mutable const LibCallLocationInfo *Locations; - mutable unsigned NumLocations; - public: - LibCallInfo() : Impl(nullptr), Locations(nullptr), NumLocations(0) {} - virtual ~LibCallInfo(); - - //===------------------------------------------------------------------===// - // Accessor Methods: Efficient access to contained data. - //===------------------------------------------------------------------===// - - /// getLocationInfo - Return information about the specified LocationID. - const LibCallLocationInfo &getLocationInfo(unsigned LocID) const; - - - /// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to - /// the specified function if we have it. If not, return null. - const LibCallFunctionInfo *getFunctionInfo(const Function *F) const; - - - //===------------------------------------------------------------------===// - // Implementation Methods: Subclasses should implement these. - //===------------------------------------------------------------------===// - - /// getLocationInfo - Return descriptors for the locations referenced by - /// this set of libcalls. - virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const { - return 0; - } - - /// getFunctionInfoArray - Return an array of descriptors that describe the - /// set of libcalls represented by this LibCallInfo object. This array is - /// terminated by an entry with a NULL name. - virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0; - }; - - enum class EHPersonality { - Unknown, - GNU_Ada, - GNU_C, - GNU_CXX, - GNU_ObjC, - MSVC_X86SEH, - MSVC_Win64SEH, - MSVC_CXX, - }; - - /// \brief See if the given exception handling personality function is one - /// that we understand. If so, return a description of it; otherwise return - /// Unknown. - EHPersonality classifyEHPersonality(const Value *Pers); - - /// \brief Returns true if this personality function catches asynchronous - /// exceptions. - inline bool isAsynchronousEHPersonality(EHPersonality Pers) { - // The two SEH personality functions can catch asynch exceptions. We assume - // unknown personalities don't catch asynch exceptions. - switch (Pers) { - case EHPersonality::MSVC_X86SEH: - case EHPersonality::MSVC_Win64SEH: - return true; - default: return false; - } - llvm_unreachable("invalid enum"); - } - - /// \brief Returns true if this is an MSVC personality function. - inline bool isMSVCEHPersonality(EHPersonality Pers) { - // The two SEH personality functions can catch asynch exceptions. We assume - // unknown personalities don't catch asynch exceptions. - switch (Pers) { - case EHPersonality::MSVC_CXX: - case EHPersonality::MSVC_X86SEH: - case EHPersonality::MSVC_Win64SEH: - return true; - default: return false; - } - llvm_unreachable("invalid enum"); - } - - /// \brief Return true if this personality may be safely removed if there - /// are no invoke instructions remaining in the current function. - inline bool isNoOpWithoutInvoke(EHPersonality Pers) { - switch (Pers) { - case EHPersonality::Unknown: - return false; - // All known personalities currently have this behavior - default: return true; - } - llvm_unreachable("invalid enum"); - } - - bool canSimplifyInvokeNoUnwind(const Function *F); - -} // end namespace llvm - -#endif diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h index 42667d2af14a6..939663b0def14 100644 --- a/include/llvm/Analysis/Loads.h +++ b/include/llvm/Analysis/Loads.h @@ -14,11 +14,12 @@ #ifndef LLVM_ANALYSIS_LOADS_H #define LLVM_ANALYSIS_LOADS_H +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/Support/CommandLine.h" namespace llvm { -class AliasAnalysis; class DataLayout; class MDNode; @@ -29,15 +30,19 @@ class MDNode; bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, unsigned Align); +/// DefMaxInstsToScan - the default number of maximum instructions +/// to scan in the block, used by FindAvailableLoadedValue(). +extern cl::opt<unsigned> DefMaxInstsToScan; + /// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at /// the instruction before ScanFrom) checking to see if we have the value at /// the memory address *Ptr locally available within a small number of /// instructions. If the value is available, return it. /// -/// If not, return the iterator for the last validated instruction that the +/// If not, return the iterator for the last validated instruction that the /// value would be live through. If we scanned the entire block and didn't /// find something that invalidates *Ptr or provides it, ScanFrom would be -/// left at begin() and this returns null. ScanFrom could also be left +/// left at begin() and this returns null. ScanFrom could also be left /// /// MaxInstsToScan specifies the maximum instructions to scan in the block. /// If it is set to 0, it will scan the whole block. You can also optionally @@ -48,7 +53,7 @@ bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, /// is found, it is left unmodified. Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, - unsigned MaxInstsToScan = 6, + unsigned MaxInstsToScan = DefMaxInstsToScan, AliasAnalysis *AA = nullptr, AAMDNodes *AATags = nullptr); diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 476e4b6686bb5..871d35e99b748 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -29,10 +29,11 @@ namespace llvm { class Value; class DataLayout; -class AliasAnalysis; class ScalarEvolution; class Loop; class SCEV; +class SCEVUnionPredicate; +class LoopAccessInfo; /// Optimization analysis message produced during vectorization. Messages inform /// the user why vectorization did not occur. @@ -136,6 +137,14 @@ public: // We couldn't determine the direction or the distance. Unknown, // Lexically forward. + // + // FIXME: If we only have loop-independent forward dependences (e.g. a + // read and write of A[i]), LAA will locally deem the dependence "safe" + // without querying the MemoryDepChecker. Therefore we can miss + // enumerating loop-independent forward dependences in + // getDependences. Note that as soon as there are different + // indices used to access the same array, the MemoryDepChecker *is* + // queried and the dependence list is complete. Forward, // Forward, but if vectorized, is likely to prevent store-to-load // forwarding. @@ -162,13 +171,20 @@ public: Dependence(unsigned Source, unsigned Destination, DepType Type) : Source(Source), Destination(Destination), Type(Type) {} + /// \brief Return the source instruction of the dependence. + Instruction *getSource(const LoopAccessInfo &LAI) const; + /// \brief Return the destination instruction of the dependence. + Instruction *getDestination(const LoopAccessInfo &LAI) const; + /// \brief Dependence types that don't prevent vectorization. static bool isSafeForVectorization(DepType Type); - /// \brief Dependence types that can be queried from the analysis. - static bool isInterestingDependence(DepType Type); + /// \brief Lexically forward dependence. + bool isForward() const; + /// \brief Lexically backward dependence. + bool isBackward() const; - /// \brief Lexically backward dependence types. + /// \brief May be a lexically backward dependence type (includes Unknown). bool isPossiblyBackward() const; /// \brief Print the dependence. \p Instr is used to map the instruction @@ -177,10 +193,10 @@ public: const SmallVectorImpl<Instruction *> &Instrs) const; }; - MemoryDepChecker(ScalarEvolution *Se, const Loop *L) - : SE(Se), InnermostLoop(L), AccessIdx(0), + MemoryDepChecker(PredicatedScalarEvolution &PSE, const Loop *L) + : PSE(PSE), InnermostLoop(L), AccessIdx(0), ShouldRetryWithRuntimeCheck(false), SafeForVectorization(true), - RecordInterestingDependences(true) {} + RecordDependences(true) {} /// \brief Register the location (instructions are given increasing numbers) /// of a write access. @@ -218,14 +234,14 @@ public: /// vectorize the loop with a dynamic array access check. bool shouldRetryWithRuntimeCheck() { return ShouldRetryWithRuntimeCheck; } - /// \brief Returns the interesting dependences. If null is returned we - /// exceeded the MaxInterestingDependence threshold and this information is - /// not available. - const SmallVectorImpl<Dependence> *getInterestingDependences() const { - return RecordInterestingDependences ? &InterestingDependences : nullptr; + /// \brief Returns the memory dependences. If null is returned we exceeded + /// the MaxDependences threshold and this information is not + /// available. + const SmallVectorImpl<Dependence> *getDependences() const { + return RecordDependences ? &Dependences : nullptr; } - void clearInterestingDependences() { InterestingDependences.clear(); } + void clearDependences() { Dependences.clear(); } /// \brief The vector of memory access instructions. The indices are used as /// instruction identifiers in the Dependence class. @@ -233,12 +249,29 @@ public: return InstMap; } + /// \brief Generate a mapping between the memory instructions and their + /// indices according to program order. + DenseMap<Instruction *, unsigned> generateInstructionOrderMap() const { + DenseMap<Instruction *, unsigned> OrderMap; + + for (unsigned I = 0; I < InstMap.size(); ++I) + OrderMap[InstMap[I]] = I; + + return OrderMap; + } + /// \brief Find the set of instructions that read or write via \p Ptr. SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr, bool isWrite) const; private: - ScalarEvolution *SE; + /// A wrapper around ScalarEvolution, used to add runtime SCEV checks, and + /// applies dynamic knowledge to simplify SCEV expressions and convert them + /// to a more usable form. We need this in case assumptions about SCEV + /// expressions need to be made in order to avoid unknown dependences. For + /// example we might assume a unit stride for a pointer in order to prove + /// that a memory access is strided and doesn't wrap. + PredicatedScalarEvolution &PSE; const Loop *InnermostLoop; /// \brief Maps access locations (ptr, read/write) to program order. @@ -261,15 +294,14 @@ private: /// vectorization. bool SafeForVectorization; - //// \brief True if InterestingDependences reflects the dependences in the - //// loop. If false we exceeded MaxInterestingDependence and - //// InterestingDependences is invalid. - bool RecordInterestingDependences; + //// \brief True if Dependences reflects the dependences in the + //// loop. If false we exceeded MaxDependences and + //// Dependences is invalid. + bool RecordDependences; - /// \brief Interesting memory dependences collected during the analysis as - /// defined by isInterestingDependence. Only valid if - /// RecordInterestingDependences is true. - SmallVector<Dependence, 8> InterestingDependences; + /// \brief Memory dependences collected during the analysis. Only valid if + /// RecordDependences is true. + SmallVector<Dependence, 8> Dependences; /// \brief Check whether there is a plausible dependence between the two /// accesses. @@ -327,11 +359,17 @@ public: void reset() { Need = false; Pointers.clear(); + Checks.clear(); } /// Insert a pointer and calculate the start and end SCEVs. + /// \p We need Preds in order to compute the SCEV expression of the pointer + /// according to the assumptions that we've made during the analysis. + /// The method might also version the pointer stride according to \p Strides, + /// and change \p Preds. void insert(Loop *Lp, Value *Ptr, bool WritePtr, unsigned DepSetId, - unsigned ASId, const ValueToValueMap &Strides); + unsigned ASId, const ValueToValueMap &Strides, + PredicatedScalarEvolution &PSE); /// \brief No run-time memory checking is necessary. bool empty() const { return Pointers.empty(); } @@ -368,33 +406,38 @@ public: SmallVector<unsigned, 2> Members; }; - /// \brief Groups pointers such that a single memcheck is required - /// between two different groups. This will clear the CheckingGroups vector - /// and re-compute it. We will only group dependecies if \p UseDependencies - /// is true, otherwise we will create a separate group for each pointer. - void groupChecks(MemoryDepChecker::DepCandidates &DepCands, - bool UseDependencies); + /// \brief A memcheck which made up of a pair of grouped pointers. + /// + /// These *have* to be const for now, since checks are generated from + /// CheckingPtrGroups in LAI::addRuntimeChecks which is a const member + /// function. FIXME: once check-generation is moved inside this class (after + /// the PtrPartition hack is removed), we could drop const. + typedef std::pair<const CheckingPtrGroup *, const CheckingPtrGroup *> + PointerCheck; + + /// \brief Generate the checks and store it. This also performs the grouping + /// of pointers to reduce the number of memchecks necessary. + void generateChecks(MemoryDepChecker::DepCandidates &DepCands, + bool UseDependencies); + + /// \brief Returns the checks that generateChecks created. + const SmallVector<PointerCheck, 4> &getChecks() const { return Checks; } /// \brief Decide if we need to add a check between two groups of pointers, /// according to needsChecking. - bool needsChecking(const CheckingPtrGroup &M, const CheckingPtrGroup &N, - const SmallVectorImpl<int> *PtrPartition) const; - - /// \brief Return true if any pointer requires run-time checking according - /// to needsChecking. - bool needsAnyChecking(const SmallVectorImpl<int> *PtrPartition) const; + bool needsChecking(const CheckingPtrGroup &M, + const CheckingPtrGroup &N) const; /// \brief Returns the number of run-time checks required according to /// needsChecking. - unsigned getNumberOfChecks(const SmallVectorImpl<int> *PtrPartition) const; + unsigned getNumberOfChecks() const { return Checks.size(); } /// \brief Print the list run-time memory checks necessary. - /// - /// If \p PtrPartition is set, it contains the partition number for - /// pointers (-1 if the pointer belongs to multiple partitions). In this - /// case omit checks between pointers belonging to the same partition. - void print(raw_ostream &OS, unsigned Depth = 0, - const SmallVectorImpl<int> *PtrPartition = nullptr) const; + void print(raw_ostream &OS, unsigned Depth = 0) const; + + /// Print \p Checks. + void printChecks(raw_ostream &OS, const SmallVectorImpl<PointerCheck> &Checks, + unsigned Depth = 0) const; /// This flag indicates if we need to add the runtime check. bool Need; @@ -405,18 +448,41 @@ public: /// Holds a partitioning of pointers into "check groups". SmallVector<CheckingPtrGroup, 2> CheckingGroups; -private: + /// \brief Check if pointers are in the same partition + /// + /// \p PtrToPartition contains the partition number for pointers (-1 if the + /// pointer belongs to multiple partitions). + static bool + arePointersInSamePartition(const SmallVectorImpl<int> &PtrToPartition, + unsigned PtrIdx1, unsigned PtrIdx2); + /// \brief Decide whether we need to issue a run-time check for pointer at /// index \p I and \p J to prove their independence. - /// - /// If \p PtrPartition is set, it contains the partition number for - /// pointers (-1 if the pointer belongs to multiple partitions). In this - /// case omit checks between pointers belonging to the same partition. - bool needsChecking(unsigned I, unsigned J, - const SmallVectorImpl<int> *PtrPartition) const; + bool needsChecking(unsigned I, unsigned J) const; + + /// \brief Return PointerInfo for pointer at index \p PtrIdx. + const PointerInfo &getPointerInfo(unsigned PtrIdx) const { + return Pointers[PtrIdx]; + } + +private: + /// \brief Groups pointers such that a single memcheck is required + /// between two different groups. This will clear the CheckingGroups vector + /// and re-compute it. We will only group dependecies if \p UseDependencies + /// is true, otherwise we will create a separate group for each pointer. + void groupChecks(MemoryDepChecker::DepCandidates &DepCands, + bool UseDependencies); + + /// Generate the checks and return them. + SmallVector<PointerCheck, 4> + generateChecks() const; /// Holds a pointer to the ScalarEvolution analysis. ScalarEvolution *SE; + + /// \brief Set of run-time checks required to establish independence of + /// otherwise may-aliasing pointers in the loop. + SmallVector<PointerCheck, 4> Checks; }; /// \brief Drive the analysis of memory accesses in the loop @@ -433,6 +499,13 @@ private: /// generates run-time checks to prove independence. This is done by /// AccessAnalysis::canCheckPtrAtRT and the checks are maintained by the /// RuntimePointerCheck class. +/// +/// If pointers can wrap or can't be expressed as affine AddRec expressions by +/// ScalarEvolution, we will generate run-time checks by emitting a +/// SCEVUnionPredicate. +/// +/// Checks for both memory dependences and the SCEV predicates contained in the +/// PSE must be emitted in order for the results of this analysis to be valid. class LoopAccessInfo { public: LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout &DL, @@ -450,9 +523,8 @@ public: /// \brief Number of memchecks required to prove independence of otherwise /// may-alias pointers. - unsigned getNumRuntimePointerChecks( - const SmallVectorImpl<int> *PtrPartition = nullptr) const { - return PtrRtChecking.getNumberOfChecks(PtrPartition); + unsigned getNumRuntimePointerChecks() const { + return PtrRtChecking.getNumberOfChecks(); } /// Return true if the block BB needs to be predicated in order for the loop @@ -472,13 +544,18 @@ public: /// Returns a pair of instructions where the first element is the first /// instruction generated in possibly a sequence of instructions and the /// second value is the final comparator value or NULL if no check is needed. + std::pair<Instruction *, Instruction *> + addRuntimeChecks(Instruction *Loc) const; + + /// \brief Generete the instructions for the checks in \p PointerChecks. /// - /// If \p PtrPartition is set, it contains the partition number for pointers - /// (-1 if the pointer belongs to multiple partitions). In this case omit - /// checks between pointers belonging to the same partition. + /// Returns a pair of instructions where the first element is the first + /// instruction generated in possibly a sequence of instructions and the + /// second value is the final comparator value or NULL if no check is needed. std::pair<Instruction *, Instruction *> - addRuntimeCheck(Instruction *Loc, - const SmallVectorImpl<int> *PtrPartition = nullptr) const; + addRuntimeChecks(Instruction *Loc, + const SmallVectorImpl<RuntimePointerChecking::PointerCheck> + &PointerChecks) const; /// \brief The diagnostics report generated for the analysis. E.g. why we /// couldn't analyze the loop. @@ -510,6 +587,13 @@ public: return StoreToLoopInvariantAddress; } + /// Used to add runtime SCEV checks. Simplifies SCEV expressions and converts + /// them to a more usable form. All SCEV expressions during the analysis + /// should be re-written (and therefore simplified) according to PSE. + /// A user of LoopAccessAnalysis will need to emit the runtime checks + /// associated with this predicate. + PredicatedScalarEvolution PSE; + private: /// \brief Analyze the loop. Substitute symbolic strides using Strides. void analyzeLoop(const ValueToValueMap &Strides); @@ -529,7 +613,6 @@ private: MemoryDepChecker DepChecker; Loop *TheLoop; - ScalarEvolution *SE; const DataLayout &DL; const TargetLibraryInfo *TLI; AliasAnalysis *AA; @@ -556,18 +639,24 @@ private: Value *stripIntegerCast(Value *V); ///\brief Return the SCEV corresponding to a pointer with the symbolic stride -///replaced with constant one. +/// replaced with constant one, assuming \p Preds is true. +/// +/// If necessary this method will version the stride of the pointer according +/// to \p PtrToStride and therefore add a new predicate to \p Preds. /// /// If \p OrigPtr is not null, use it to look up the stride value instead of \p /// Ptr. \p PtrToStride provides the mapping between the pointer value and its /// stride as collected by LoopVectorizationLegality::collectStridedAccess. -const SCEV *replaceSymbolicStrideSCEV(ScalarEvolution *SE, +const SCEV *replaceSymbolicStrideSCEV(PredicatedScalarEvolution &PSE, const ValueToValueMap &PtrToStride, Value *Ptr, Value *OrigPtr = nullptr); /// \brief Check the stride of the pointer and ensure that it does not wrap in -/// the address space. -int isStridedPtr(ScalarEvolution *SE, Value *Ptr, const Loop *Lp, +/// the address space, assuming \p Preds is true. +/// +/// If necessary this method will version the stride of the pointer according +/// to \p PtrToStride and therefore add a new predicate to \p Preds. +int isStridedPtr(PredicatedScalarEvolution &PSE, Value *Ptr, const Loop *Lp, const ValueToValueMap &StridesMap); /// \brief This analysis provides dependence information for the memory accesses @@ -616,6 +705,17 @@ private: DominatorTree *DT; LoopInfo *LI; }; + +inline Instruction *MemoryDepChecker::Dependence::getSource( + const LoopAccessInfo &LAI) const { + return LAI.getDepChecker().getMemoryInstructions()[Source]; +} + +inline Instruction *MemoryDepChecker::Dependence::getDestination( + const LoopAccessInfo &LAI) const { + return LAI.getDepChecker().getMemoryInstructions()[Destination]; +} + } // End llvm namespace #endif diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 3ec83f2c21fdf..c219bd85a48ab 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -37,6 +37,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/Pass.h" #include <algorithm> @@ -72,6 +73,10 @@ class LoopBase { SmallPtrSet<const BlockT*, 8> DenseBlockSet; + /// Indicator that this loops has been "unlooped", so there's no loop here + /// anymore. + bool IsUnloop = false; + LoopBase(const LoopBase<BlockT, LoopT> &) = delete; const LoopBase<BlockT, LoopT>& operator=(const LoopBase<BlockT, LoopT> &) = delete; @@ -140,12 +145,22 @@ public: typedef typename std::vector<BlockT*>::const_iterator block_iterator; block_iterator block_begin() const { return Blocks.begin(); } block_iterator block_end() const { return Blocks.end(); } + inline iterator_range<block_iterator> blocks() const { + return make_range(block_begin(), block_end()); + } /// getNumBlocks - Get the number of blocks in this loop in constant time. unsigned getNumBlocks() const { return Blocks.size(); } + /// Mark this loop as having been unlooped - the last backedge was removed and + /// we no longer have a loop. + void markUnlooped() { IsUnloop = true; } + + /// Return true if this no longer represents a loop. + bool isUnloop() const { return IsUnloop; } + /// isLoopExiting - True if terminator in the block can branch to another /// block that is outside of the current loop. /// @@ -398,6 +413,9 @@ public: /// isLCSSAForm - Return true if the Loop is in LCSSA form bool isLCSSAForm(DominatorTree &DT) const; + /// \brief Return true if this Loop and all inner subloops are in LCSSA form. + bool isRecursivelyLCSSAForm(DominatorTree &DT) const; + /// isLoopSimplifyForm - Return true if the Loop is in the form that /// the LoopSimplify form transforms loops to, which is sometimes called /// normal form. @@ -622,7 +640,7 @@ public: } /// Create the loop forest using a stable algorithm. - void Analyze(DominatorTreeBase<BlockT> &DomTree); + void analyze(const DominatorTreeBase<BlockT> &DomTree); // Debugging void print(raw_ostream &OS) const; @@ -642,6 +660,7 @@ class LoopInfo : public LoopInfoBase<BasicBlock, Loop> { LoopInfo(const LoopInfo &) = delete; public: LoopInfo() {} + explicit LoopInfo(const DominatorTreeBase<BasicBlock> &DomTree); LoopInfo(LoopInfo &&Arg) : BaseT(std::move(static_cast<BaseT &>(Arg))) {} LoopInfo &operator=(LoopInfo &&RHS) { @@ -653,8 +672,9 @@ public: /// updateUnloop - Update LoopInfo after removing the last backedge from a /// loop--now the "unloop". This updates the loop forest and parent loops for - /// each block so that Unloop is no longer referenced, but the caller must - /// actually delete the Unloop object. + /// each block so that Unloop is no longer referenced, but does not actually + /// delete the Unloop object. Generally, the loop pass manager should manage + /// deleting the Unloop. void updateUnloop(Loop *Unloop); /// replacementPreservesLCSSAForm - Returns true if replacing From with To @@ -677,6 +697,78 @@ public: // it as a replacement will not break LCSSA form. return ToLoop->contains(getLoopFor(From->getParent())); } + + /// \brief Checks if moving a specific instruction can break LCSSA in any + /// loop. + /// + /// Return true if moving \p Inst to before \p NewLoc will break LCSSA, + /// assuming that the function containing \p Inst and \p NewLoc is currently + /// in LCSSA form. + bool movementPreservesLCSSAForm(Instruction *Inst, Instruction *NewLoc) { + assert(Inst->getFunction() == NewLoc->getFunction() && + "Can't reason about IPO!"); + + auto *OldBB = Inst->getParent(); + auto *NewBB = NewLoc->getParent(); + + // Movement within the same loop does not break LCSSA (the equality check is + // to avoid doing a hashtable lookup in case of intra-block movement). + if (OldBB == NewBB) + return true; + + auto *OldLoop = getLoopFor(OldBB); + auto *NewLoop = getLoopFor(NewBB); + + if (OldLoop == NewLoop) + return true; + + // Check if Outer contains Inner; with the null loop counting as the + // "outermost" loop. + auto Contains = [](const Loop *Outer, const Loop *Inner) { + return !Outer || Outer->contains(Inner); + }; + + // To check that the movement of Inst to before NewLoc does not break LCSSA, + // we need to check two sets of uses for possible LCSSA violations at + // NewLoc: the users of NewInst, and the operands of NewInst. + + // If we know we're hoisting Inst out of an inner loop to an outer loop, + // then the uses *of* Inst don't need to be checked. + + if (!Contains(NewLoop, OldLoop)) { + for (Use &U : Inst->uses()) { + auto *UI = cast<Instruction>(U.getUser()); + auto *UBB = isa<PHINode>(UI) ? cast<PHINode>(UI)->getIncomingBlock(U) + : UI->getParent(); + if (UBB != NewBB && getLoopFor(UBB) != NewLoop) + return false; + } + } + + // If we know we're sinking Inst from an outer loop into an inner loop, then + // the *operands* of Inst don't need to be checked. + + if (!Contains(OldLoop, NewLoop)) { + // See below on why we can't handle phi nodes here. + if (isa<PHINode>(Inst)) + return false; + + for (Use &U : Inst->operands()) { + auto *DefI = dyn_cast<Instruction>(U.get()); + if (!DefI) + return false; + + // This would need adjustment if we allow Inst to be a phi node -- the + // new use block won't simply be NewBB. + + auto *DefBlock = DefI->getParent(); + if (DefBlock != NewBB && getLoopFor(DefBlock) != NewLoop) + return false; + } + } + + return true; + } }; // Allow clients to walk the list of nested loops... @@ -759,6 +851,19 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; }; +/// \brief Pass for printing a loop's contents as LLVM's text IR assembly. +class PrintLoopPass { + raw_ostream &OS; + std::string Banner; + +public: + PrintLoopPass(); + PrintLoopPass(raw_ostream &OS, const std::string &Banner = ""); + + PreservedAnalyses run(Loop &L); + static StringRef name() { return "PrintLoopPass"; } +}; + } // End llvm namespace #endif diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index f5cc856f62476..824fc7e8f1559 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -269,7 +269,7 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const { // A non-header loop shouldn't be reachable from outside the loop, // though it is permitted if the predecessor is not itself actually // reachable. - BlockT *EntryBB = BB->getParent()->begin(); + BlockT *EntryBB = &BB->getParent()->front(); for (BlockT *CB : depth_first(EntryBB)) for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i) assert(CB != OutsideLoopPreds[i] && @@ -345,7 +345,7 @@ void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth) const { template<class BlockT, class LoopT> static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges, LoopInfoBase<BlockT, LoopT> *LI, - DominatorTreeBase<BlockT> &DomTree) { + const DominatorTreeBase<BlockT> &DomTree) { typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits; unsigned NumBlocks = 0; @@ -468,10 +468,10 @@ void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) { /// insertions per block. template<class BlockT, class LoopT> void LoopInfoBase<BlockT, LoopT>:: -Analyze(DominatorTreeBase<BlockT> &DomTree) { +analyze(const DominatorTreeBase<BlockT> &DomTree) { // Postorder traversal of the dominator tree. - DomTreeNodeBase<BlockT>* DomRoot = DomTree.getRootNode(); + const DomTreeNodeBase<BlockT> *DomRoot = DomTree.getRootNode(); for (auto DomNode : post_order(DomRoot)) { BlockT *Header = DomNode->getBlock(); diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index 8650000fcfb6e..2cf734e53bb43 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -127,20 +127,9 @@ public: } public: - // Delete loop from the loop queue and loop nest (LoopInfo). - void deleteLoopFromQueue(Loop *L); - - // Insert loop into the loop queue and add it as a child of the - // given parent. - void insertLoop(Loop *L, Loop *ParentLoop); - - // Insert a loop into the loop queue. - void insertLoopIntoQueue(Loop *L); - - // Reoptimize this loop. LPPassManager will re-insert this loop into the - // queue. This allows LoopPass to change loop nest for the loop. This - // utility may send LPPassManager into infinite loops so use caution. - void redoLoop(Loop *L); + // Add a new loop into the loop queue as a child of the given parent, or at + // the top level if \c ParentLoop is null. + Loop &addLoop(Loop *ParentLoop); //===--------------------------------------------------------------------===// /// SimpleAnalysis - Provides simple interface to update analysis info @@ -163,8 +152,6 @@ public: private: std::deque<Loop *> LQ; - bool skipThisLoop; - bool redoThisLoop; LoopInfo *LI; Loop *CurrentLoop; }; diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index 805a43dfb0705..87fb3efaf50e3 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -60,11 +60,6 @@ bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); /// \brief Tests if a value is a call or invoke to a library function that -/// reallocates memory (such as realloc). -bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, - bool LookThroughBitCast = false); - -/// \brief Tests if a value is a call or invoke to a library function that /// allocates memory and never returns null (such as operator new). bool isOperatorNewLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast = false); diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 511898071c22c..daa1ba91c0710 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -28,7 +28,6 @@ namespace llvm { class FunctionPass; class Instruction; class CallSite; - class AliasAnalysis; class AssumptionCache; class MemoryDependenceAnalysis; class PredIteratorCache; @@ -97,6 +96,7 @@ namespace llvm { typedef PointerIntPair<Instruction*, 2, DepType> PairTy; PairTy Value; explicit MemDepResult(PairTy V) : Value(V) {} + public: MemDepResult() : Value(nullptr, Invalid) {} @@ -164,6 +164,7 @@ namespace llvm { bool operator!=(const MemDepResult &M) const { return Value != M.Value; } bool operator<(const MemDepResult &M) const { return Value < M.Value; } bool operator>(const MemDepResult &M) const { return Value > M.Value; } + private: friend class MemoryDependenceAnalysis; /// Dirty - Entries with this marker occur in a LocalDeps map or @@ -190,6 +191,7 @@ namespace llvm { class NonLocalDepEntry { BasicBlock *BB; MemDepResult Result; + public: NonLocalDepEntry(BasicBlock *bb, MemDepResult result) : BB(bb), Result(result) {} @@ -215,6 +217,7 @@ namespace llvm { class NonLocalDepResult { NonLocalDepEntry Entry; Value *Address; + public: NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address) : Entry(bb, result), Address(address) {} @@ -261,6 +264,7 @@ namespace llvm { public: typedef std::vector<NonLocalDepEntry> NonLocalDepInfo; + private: /// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if /// the dependence is a read only dependence, false if read/write. @@ -302,7 +306,6 @@ namespace llvm { SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy; ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps; - /// PerInstNLInfo - This is the instruction we keep for each cached access /// that we have for an instruction. The pointer is an owning pointer and /// the bool indicates whether we have any dirty bits in the set. @@ -326,6 +329,7 @@ namespace llvm { AliasAnalysis *AA; DominatorTree *DT; AssumptionCache *AC; + const TargetLibraryInfo *TLI; PredIteratorCache PredCache; public: @@ -363,14 +367,13 @@ namespace llvm { /// that. const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS); - /// getNonLocalPointerDependency - Perform a full dependency query for an /// access to the QueryInst's specified memory location, returning the set /// of instructions that either define or clobber the value. /// /// Warning: For a volatile query instruction, the dependencies will be /// accurate, and thus usable for reordering, but it is never legal to - /// remove the query instruction. + /// remove the query instruction. /// /// This method assumes the pointer has a "NonLocal" dependency within /// QueryInst's parent basic block. @@ -394,12 +397,12 @@ namespace llvm { /// critical edges. void invalidateCachedPredecessors(); - /// getPointerDependencyFrom - Return the instruction on which a memory - /// location depends. If isLoad is true, this routine ignores may-aliases - /// with read-only operations. If isLoad is false, this routine ignores - /// may-aliases with reads from read-only locations. If possible, pass - /// the query instruction as well; this function may take advantage of - /// the metadata annotated to the query instruction to refine the result. + /// \brief Return the instruction on which a memory location depends. + /// If isLoad is true, this routine ignores may-aliases with read-only + /// operations. If isLoad is false, this routine ignores may-aliases + /// with reads from read-only locations. If possible, pass the query + /// instruction as well; this function may take advantage of the metadata + /// annotated to the query instruction to refine the result. /// /// Note that this is an uncached query, and thus may be inefficient. /// @@ -409,6 +412,21 @@ namespace llvm { BasicBlock *BB, Instruction *QueryInst = nullptr); + MemDepResult getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, + bool isLoad, + BasicBlock::iterator ScanIt, + BasicBlock *BB, + Instruction *QueryInst); + + /// This analysis looks for other loads and stores with invariant.group + /// metadata and the same pointer operand. Returns Unknown if it does not + /// find anything, and Def if it can be assumed that 2 instructions load or + /// store the same value. + /// FIXME: This analysis works only on single block because of restrictions + /// at the call site. + MemDepResult getInvariantGroupPointerDependency(LoadInst *LI, + BasicBlock *BB); + /// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that /// looks at a memory location for a load (specified by MemLocBase, Offs, /// and Size) and compares it against a load. If the specified load could @@ -442,7 +460,6 @@ namespace llvm { /// verifyRemoved - Verify that the specified instruction does not occur /// in our internal data structures. void verifyRemoved(Instruction *Inst) const; - }; } // End llvm namespace diff --git a/include/llvm/Analysis/ObjCARCAliasAnalysis.h b/include/llvm/Analysis/ObjCARCAliasAnalysis.h new file mode 100644 index 0000000000000..ac01154bac6c2 --- /dev/null +++ b/include/llvm/Analysis/ObjCARCAliasAnalysis.h @@ -0,0 +1,102 @@ +//===- ObjCARCAliasAnalysis.h - ObjC ARC Alias Analysis ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares a simple ARC-aware AliasAnalysis using special knowledge +/// of Objective C to enhance other optimization passes which rely on the Alias +/// Analysis infrastructure. +/// +/// WARNING: This file knows about certain library functions. It recognizes them +/// by name, and hardwires knowledge of their semantics. +/// +/// WARNING: This file knows about how certain Objective-C library functions are +/// used. Naive LLVM IR transformations which would otherwise be +/// behavior-preserving may break these assumptions. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H +#define LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Pass.h" + +namespace llvm { +namespace objcarc { + +/// \brief This is a simple alias analysis implementation that uses knowledge +/// of ARC constructs to answer queries. +/// +/// TODO: This class could be generalized to know about other ObjC-specific +/// tricks. Such as knowing that ivars in the non-fragile ABI are non-aliasing +/// even though their offsets are dynamic. +class ObjCARCAAResult : public AAResultBase<ObjCARCAAResult> { + friend AAResultBase<ObjCARCAAResult>; + + const DataLayout &DL; + +public: + explicit ObjCARCAAResult(const DataLayout &DL, const TargetLibraryInfo &TLI) + : AAResultBase(TLI), DL(DL) {} + ObjCARCAAResult(ObjCARCAAResult &&Arg) + : AAResultBase(std::move(Arg)), DL(Arg.DL) {} + + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal); + + using AAResultBase::getModRefBehavior; + FunctionModRefBehavior getModRefBehavior(const Function *F); + + using AAResultBase::getModRefInfo; + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class ObjCARCAA { +public: + typedef ObjCARCAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + ObjCARCAAResult run(Function &F, AnalysisManager<Function> *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "ObjCARCAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the ObjCARCAAResult object. +class ObjCARCAAWrapperPass : public ImmutablePass { + std::unique_ptr<ObjCARCAAResult> Result; + +public: + static char ID; + + ObjCARCAAWrapperPass(); + + ObjCARCAAResult &getResult() { return *Result; } + const ObjCARCAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +} // namespace objcarc +} // namespace llvm + +#endif diff --git a/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/include/llvm/Analysis/ObjCARCAnalysisUtils.h new file mode 100644 index 0000000000000..29d99c9d316d4 --- /dev/null +++ b/include/llvm/Analysis/ObjCARCAnalysisUtils.h @@ -0,0 +1,287 @@ +//===- ObjCARCAnalysisUtils.h - ObjC ARC Analysis Utilities -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file defines common analysis utilities used by the ObjC ARC Optimizer. +/// ARC stands for Automatic Reference Counting and is a system for managing +/// reference counts for objects in Objective C. +/// +/// WARNING: This file knows about certain library functions. It recognizes them +/// by name, and hardwires knowledge of their semantics. +/// +/// WARNING: This file knows about how certain Objective-C library functions are +/// used. Naive LLVM IR transformations which would otherwise be +/// behavior-preserving may break these assumptions. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H +#define LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H + +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/ObjCARCInstKind.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" + +namespace llvm { +class raw_ostream; +} + +namespace llvm { +namespace objcarc { + +/// \brief A handy option to enable/disable all ARC Optimizations. +extern bool EnableARCOpts; + +/// \brief Test if the given module looks interesting to run ARC optimization +/// on. +inline bool ModuleHasARC(const Module &M) { + return + M.getNamedValue("objc_retain") || + M.getNamedValue("objc_release") || + M.getNamedValue("objc_autorelease") || + M.getNamedValue("objc_retainAutoreleasedReturnValue") || + M.getNamedValue("objc_retainBlock") || + M.getNamedValue("objc_autoreleaseReturnValue") || + M.getNamedValue("objc_autoreleasePoolPush") || + M.getNamedValue("objc_loadWeakRetained") || + M.getNamedValue("objc_loadWeak") || + M.getNamedValue("objc_destroyWeak") || + M.getNamedValue("objc_storeWeak") || + M.getNamedValue("objc_initWeak") || + M.getNamedValue("objc_moveWeak") || + M.getNamedValue("objc_copyWeak") || + M.getNamedValue("objc_retainedObject") || + M.getNamedValue("objc_unretainedObject") || + M.getNamedValue("objc_unretainedPointer") || + M.getNamedValue("clang.arc.use"); +} + +/// \brief This is a wrapper around getUnderlyingObject which also knows how to +/// look through objc_retain and objc_autorelease calls, which we know to return +/// their argument verbatim. +inline const Value *GetUnderlyingObjCPtr(const Value *V, + const DataLayout &DL) { + for (;;) { + V = GetUnderlyingObject(V, DL); + if (!IsForwarding(GetBasicARCInstKind(V))) + break; + V = cast<CallInst>(V)->getArgOperand(0); + } + + return V; +} + +/// The RCIdentity root of a value \p V is a dominating value U for which +/// retaining or releasing U is equivalent to retaining or releasing V. In other +/// words, ARC operations on \p V are equivalent to ARC operations on \p U. +/// +/// We use this in the ARC optimizer to make it easier to match up ARC +/// operations by always mapping ARC operations to RCIdentityRoots instead of +/// pointers themselves. +/// +/// The two ways that we see RCIdentical values in ObjC are via: +/// +/// 1. PointerCasts +/// 2. Forwarding Calls that return their argument verbatim. +/// +/// Thus this function strips off pointer casts and forwarding calls. *NOTE* +/// This implies that two RCIdentical values must alias. +inline const Value *GetRCIdentityRoot(const Value *V) { + for (;;) { + V = V->stripPointerCasts(); + if (!IsForwarding(GetBasicARCInstKind(V))) + break; + V = cast<CallInst>(V)->getArgOperand(0); + } + return V; +} + +/// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just +/// casts away the const of the result. For documentation about what an +/// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that +/// function. +inline Value *GetRCIdentityRoot(Value *V) { + return const_cast<Value *>(GetRCIdentityRoot((const Value *)V)); +} + +/// \brief Assuming the given instruction is one of the special calls such as +/// objc_retain or objc_release, return the RCIdentity root of the argument of +/// the call. +inline Value *GetArgRCIdentityRoot(Value *Inst) { + return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0)); +} + +inline bool IsNullOrUndef(const Value *V) { + return isa<ConstantPointerNull>(V) || isa<UndefValue>(V); +} + +inline bool IsNoopInstruction(const Instruction *I) { + return isa<BitCastInst>(I) || + (isa<GetElementPtrInst>(I) && + cast<GetElementPtrInst>(I)->hasAllZeroIndices()); +} + +/// \brief Test whether the given value is possible a retainable object pointer. +inline bool IsPotentialRetainableObjPtr(const Value *Op) { + // Pointers to static or stack storage are not valid retainable object + // pointers. + if (isa<Constant>(Op) || isa<AllocaInst>(Op)) + return false; + // Special arguments can not be a valid retainable object pointer. + if (const Argument *Arg = dyn_cast<Argument>(Op)) + if (Arg->hasByValAttr() || + Arg->hasInAllocaAttr() || + Arg->hasNestAttr() || + Arg->hasStructRetAttr()) + return false; + // Only consider values with pointer types. + // + // It seemes intuitive to exclude function pointer types as well, since + // functions are never retainable object pointers, however clang occasionally + // bitcasts retainable object pointers to function-pointer type temporarily. + PointerType *Ty = dyn_cast<PointerType>(Op->getType()); + if (!Ty) + return false; + // Conservatively assume anything else is a potential retainable object + // pointer. + return true; +} + +inline bool IsPotentialRetainableObjPtr(const Value *Op, + AliasAnalysis &AA) { + // First make the rudimentary check. + if (!IsPotentialRetainableObjPtr(Op)) + return false; + + // Objects in constant memory are not reference-counted. + if (AA.pointsToConstantMemory(Op)) + return false; + + // Pointers in constant memory are not pointing to reference-counted objects. + if (const LoadInst *LI = dyn_cast<LoadInst>(Op)) + if (AA.pointsToConstantMemory(LI->getPointerOperand())) + return false; + + // Otherwise assume the worst. + return true; +} + +/// \brief Helper for GetARCInstKind. Determines what kind of construct CS +/// is. +inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) { + for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); + I != E; ++I) + if (IsPotentialRetainableObjPtr(*I)) + return CS.onlyReadsMemory() ? ARCInstKind::User : ARCInstKind::CallOrUser; + + return CS.onlyReadsMemory() ? ARCInstKind::None : ARCInstKind::Call; +} + +/// \brief Return true if this value refers to a distinct and identifiable +/// object. +/// +/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses +/// special knowledge of ObjC conventions. +inline bool IsObjCIdentifiedObject(const Value *V) { + // Assume that call results and arguments have their own "provenance". + // Constants (including GlobalVariables) and Allocas are never + // reference-counted. + if (isa<CallInst>(V) || isa<InvokeInst>(V) || + isa<Argument>(V) || isa<Constant>(V) || + isa<AllocaInst>(V)) + return true; + + if (const LoadInst *LI = dyn_cast<LoadInst>(V)) { + const Value *Pointer = + GetRCIdentityRoot(LI->getPointerOperand()); + if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) { + // A constant pointer can't be pointing to an object on the heap. It may + // be reference-counted, but it won't be deleted. + if (GV->isConstant()) + return true; + StringRef Name = GV->getName(); + // These special variables are known to hold values which are not + // reference-counted pointers. + if (Name.startswith("\01l_objc_msgSend_fixup_")) + return true; + + StringRef Section = GV->getSection(); + if (Section.find("__message_refs") != StringRef::npos || + Section.find("__objc_classrefs") != StringRef::npos || + Section.find("__objc_superrefs") != StringRef::npos || + Section.find("__objc_methname") != StringRef::npos || + Section.find("__cstring") != StringRef::npos) + return true; + } + } + + return false; +} + +enum class ARCMDKindID { + ImpreciseRelease, + CopyOnEscape, + NoObjCARCExceptions, +}; + +/// A cache of MDKinds used by various ARC optimizations. +class ARCMDKindCache { + Module *M; + + /// The Metadata Kind for clang.imprecise_release metadata. + llvm::Optional<unsigned> ImpreciseReleaseMDKind; + + /// The Metadata Kind for clang.arc.copy_on_escape metadata. + llvm::Optional<unsigned> CopyOnEscapeMDKind; + + /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata. + llvm::Optional<unsigned> NoObjCARCExceptionsMDKind; + +public: + void init(Module *Mod) { + M = Mod; + ImpreciseReleaseMDKind = NoneType::None; + CopyOnEscapeMDKind = NoneType::None; + NoObjCARCExceptionsMDKind = NoneType::None; + } + + unsigned get(ARCMDKindID ID) { + switch (ID) { + case ARCMDKindID::ImpreciseRelease: + if (!ImpreciseReleaseMDKind) + ImpreciseReleaseMDKind = + M->getContext().getMDKindID("clang.imprecise_release"); + return *ImpreciseReleaseMDKind; + case ARCMDKindID::CopyOnEscape: + if (!CopyOnEscapeMDKind) + CopyOnEscapeMDKind = + M->getContext().getMDKindID("clang.arc.copy_on_escape"); + return *CopyOnEscapeMDKind; + case ARCMDKindID::NoObjCARCExceptions: + if (!NoObjCARCExceptionsMDKind) + NoObjCARCExceptionsMDKind = + M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions"); + return *NoObjCARCExceptionsMDKind; + } + llvm_unreachable("Covered switch isn't covered?!"); + } +}; + +} // end namespace objcarc +} // end namespace llvm + +#endif diff --git a/include/llvm/Analysis/ObjCARCInstKind.h b/include/llvm/Analysis/ObjCARCInstKind.h new file mode 100644 index 0000000000000..13efb4b160bef --- /dev/null +++ b/include/llvm/Analysis/ObjCARCInstKind.h @@ -0,0 +1,123 @@ +//===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H +#define LLVM_ANALYSIS_OBJCARCINSTKIND_H + +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Function.h" + +namespace llvm { +namespace objcarc { + +/// \enum ARCInstKind +/// +/// \brief Equivalence classes of instructions in the ARC Model. +/// +/// Since we do not have "instructions" to represent ARC concepts in LLVM IR, +/// we instead operate on equivalence classes of instructions. +/// +/// TODO: This should be split into two enums: a runtime entry point enum +/// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals +/// with effects of instructions in the ARC model (which would handle the notion +/// of a User or CallOrUser). +enum class ARCInstKind { + Retain, ///< objc_retain + RetainRV, ///< objc_retainAutoreleasedReturnValue + RetainBlock, ///< objc_retainBlock + Release, ///< objc_release + Autorelease, ///< objc_autorelease + AutoreleaseRV, ///< objc_autoreleaseReturnValue + AutoreleasepoolPush, ///< objc_autoreleasePoolPush + AutoreleasepoolPop, ///< objc_autoreleasePoolPop + NoopCast, ///< objc_retainedObject, etc. + FusedRetainAutorelease, ///< objc_retainAutorelease + FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue + LoadWeakRetained, ///< objc_loadWeakRetained (primitive) + StoreWeak, ///< objc_storeWeak (primitive) + InitWeak, ///< objc_initWeak (derived) + LoadWeak, ///< objc_loadWeak (derived) + MoveWeak, ///< objc_moveWeak (derived) + CopyWeak, ///< objc_copyWeak (derived) + DestroyWeak, ///< objc_destroyWeak (derived) + StoreStrong, ///< objc_storeStrong (derived) + IntrinsicUser, ///< clang.arc.use + CallOrUser, ///< could call objc_release and/or "use" pointers + Call, ///< could call objc_release + User, ///< could "use" a pointer + None ///< anything that is inert from an ARC perspective. +}; + +raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class); + +/// \brief Test if the given class is a kind of user. +bool IsUser(ARCInstKind Class); + +/// \brief Test if the given class is objc_retain or equivalent. +bool IsRetain(ARCInstKind Class); + +/// \brief Test if the given class is objc_autorelease or equivalent. +bool IsAutorelease(ARCInstKind Class); + +/// \brief Test if the given class represents instructions which return their +/// argument verbatim. +bool IsForwarding(ARCInstKind Class); + +/// \brief Test if the given class represents instructions which do nothing if +/// passed a null pointer. +bool IsNoopOnNull(ARCInstKind Class); + +/// \brief Test if the given class represents instructions which are always safe +/// to mark with the "tail" keyword. +bool IsAlwaysTail(ARCInstKind Class); + +/// \brief Test if the given class represents instructions which are never safe +/// to mark with the "tail" keyword. +bool IsNeverTail(ARCInstKind Class); + +/// \brief Test if the given class represents instructions which are always safe +/// to mark with the nounwind attribute. +bool IsNoThrow(ARCInstKind Class); + +/// Test whether the given instruction can autorelease any pointer or cause an +/// autoreleasepool pop. +bool CanInterruptRV(ARCInstKind Class); + +/// \brief Determine if F is one of the special known Functions. If it isn't, +/// return ARCInstKind::CallOrUser. +ARCInstKind GetFunctionClass(const Function *F); + +/// \brief Determine which objc runtime call instruction class V belongs to. +/// +/// This is similar to GetARCInstKind except that it only detects objc +/// runtime calls. This allows it to be faster. +/// +inline ARCInstKind GetBasicARCInstKind(const Value *V) { + if (const CallInst *CI = dyn_cast<CallInst>(V)) { + if (const Function *F = CI->getCalledFunction()) + return GetFunctionClass(F); + // Otherwise, be conservative. + return ARCInstKind::CallOrUser; + } + + // Otherwise, be conservative. + return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User; +} + +/// Map V to its ARCInstKind equivalence class. +ARCInstKind GetARCInstKind(const Value *V); + +/// Returns false if conservatively we can prove that any instruction mapped to +/// this kind can not decrement ref counts. Returns true otherwise. +bool CanDecrementRefCount(ARCInstKind Kind); + +} // end namespace objcarc +} // end namespace llvm + +#endif diff --git a/include/llvm/Analysis/OrderedBasicBlock.h b/include/llvm/Analysis/OrderedBasicBlock.h new file mode 100644 index 0000000000000..5aa813eb48324 --- /dev/null +++ b/include/llvm/Analysis/OrderedBasicBlock.h @@ -0,0 +1,66 @@ +//===- llvm/Analysis/OrderedBasicBlock.h --------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the OrderedBasicBlock class. OrderedBasicBlock maintains +// an interface where clients can query if one instruction comes before another +// in a BasicBlock. Since BasicBlock currently lacks a reliable way to query +// relative position between instructions one can use OrderedBasicBlock to do +// such queries. OrderedBasicBlock is lazily built on a source BasicBlock and +// maintains an internal Instruction -> Position map. A OrderedBasicBlock +// instance should be discarded whenever the source BasicBlock changes. +// +// It's currently used by the CaptureTracker in order to find relative +// positions of a pair of instructions inside a BasicBlock. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_ORDEREDBASICBLOCK_H +#define LLVM_ANALYSIS_ORDEREDBASICBLOCK_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/IR/BasicBlock.h" + +namespace llvm { + +class Instruction; +class BasicBlock; + +class OrderedBasicBlock { +private: + /// \brief Map a instruction to its position in a BasicBlock. + SmallDenseMap<const Instruction *, unsigned, 32> NumberedInsts; + + /// \brief Keep track of last instruction inserted into \p NumberedInsts. + /// It speeds up queries for uncached instructions by providing a start point + /// for new queries in OrderedBasicBlock::comesBefore. + BasicBlock::const_iterator LastInstFound; + + /// \brief The position/number to tag the next instruction to be found. + unsigned NextInstPos; + + /// \brief The source BasicBlock to map. + const BasicBlock *BB; + + /// \brief Given no cached results, find if \p A comes before \p B in \p BB. + /// Cache and number out instruction while walking \p BB. + bool comesBefore(const Instruction *A, const Instruction *B); + +public: + OrderedBasicBlock(const BasicBlock *BasicB); + + /// \brief Find out whether \p A dominates \p B, meaning whether \p A + /// comes before \p B in \p BB. This is a simplification that considers + /// cached instruction positions and ignores other basic blocks, being + /// only relevant to compare relative instructions positions inside \p BB. + bool dominates(const Instruction *A, const Instruction *B); +}; + +} // End llvm namespace + +#endif diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index cbdbb88f74071..f0f34f3a51f59 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -48,6 +48,7 @@ class PHITransAddr { /// InstInputs - The inputs for our symbolic address. SmallVector<Instruction*, 4> InstInputs; + public: PHITransAddr(Value *addr, const DataLayout &DL, AssumptionCache *AC) : Addr(addr), DL(DL), TLI(nullptr), AC(AC) { @@ -55,9 +56,9 @@ public: if (Instruction *I = dyn_cast<Instruction>(Addr)) InstInputs.push_back(I); } - + Value *getAddr() const { return Addr; } - + /// NeedsPHITranslationFromBlock - Return true if moving from the specified /// BasicBlock to its predecessors requires PHI translation. bool NeedsPHITranslationFromBlock(BasicBlock *BB) const { @@ -68,12 +69,12 @@ public: return true; return false; } - + /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true /// if we have some hope of doing it. This should be used as a filter to /// avoid calling PHITranslateValue in hopeless situations. bool IsPotentiallyPHITranslatable() const; - + /// PHITranslateValue - PHI translate the current address up the CFG from /// CurBB to Pred, updating our state to reflect any needed changes. If /// 'MustDominate' is true, the translated value must dominate @@ -90,18 +91,19 @@ public: /// Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, - SmallVectorImpl<Instruction*> &NewInsts); - + SmallVectorImpl<Instruction *> &NewInsts); + void dump() const; - + /// Verify - Check internal consistency of this data structure. If the /// structure is valid, it returns true. If invalid, it prints errors and /// returns false. bool Verify() const; + private: Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT); - + /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. @@ -109,8 +111,8 @@ private: /// Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree &DT, - SmallVectorImpl<Instruction*> &NewInsts); - + SmallVectorImpl<Instruction *> &NewInsts); + /// AddAsInput - If the specified value is an instruction, add it as an input. Value *AddAsInput(Value *V) { // If V is an instruction, it is now an input. @@ -118,7 +120,6 @@ private: InstInputs.push_back(VI); return V; } - }; } // end namespace llvm diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index d112ab1823b46..da17457d34462 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -22,27 +22,6 @@ namespace llvm { class ModulePass; class Pass; class PassInfo; - class LibCallInfo; - - //===--------------------------------------------------------------------===// - // - // createGlobalsModRefPass - This pass provides alias and mod/ref info for - // global values that do not have their addresses taken. - // - Pass *createGlobalsModRefPass(); - - //===--------------------------------------------------------------------===// - // - // createAliasDebugger - This pass helps debug clients of AA - // - Pass *createAliasDebugger(); - - //===--------------------------------------------------------------------===// - // - // createAliasAnalysisCounterPass - This pass counts alias queries and how the - // alias analysis implementation responds. - // - ModulePass *createAliasAnalysisCounterPass(); //===--------------------------------------------------------------------===// // @@ -53,59 +32,10 @@ namespace llvm { //===--------------------------------------------------------------------===// // - // createNoAAPass - This pass implements a "I don't know" alias analysis. - // - ImmutablePass *createNoAAPass(); - - //===--------------------------------------------------------------------===// - // - // createBasicAliasAnalysisPass - This pass implements the stateless alias - // analysis. - // - ImmutablePass *createBasicAliasAnalysisPass(); - - //===--------------------------------------------------------------------===// - // - // createCFLAliasAnalysisPass - This pass implements a set-based approach to - // alias analysis. - // - ImmutablePass *createCFLAliasAnalysisPass(); - - //===--------------------------------------------------------------------===// - // - /// createLibCallAliasAnalysisPass - Create an alias analysis pass that knows - /// about the semantics of a set of libcalls specified by LCI. The newly - /// constructed pass takes ownership of the pointer that is provided. - /// - FunctionPass *createLibCallAliasAnalysisPass(LibCallInfo *LCI); - - //===--------------------------------------------------------------------===// - // - // createScalarEvolutionAliasAnalysisPass - This pass implements a simple - // alias analysis using ScalarEvolution queries. - // - FunctionPass *createScalarEvolutionAliasAnalysisPass(); - - //===--------------------------------------------------------------------===// - // - // createTypeBasedAliasAnalysisPass - This pass implements metadata-based - // type-based alias analysis. - // - ImmutablePass *createTypeBasedAliasAnalysisPass(); - - //===--------------------------------------------------------------------===// - // - // createScopedNoAliasAAPass - This pass implements metadata-based - // scoped noalias analysis. - // - ImmutablePass *createScopedNoAliasAAPass(); - - //===--------------------------------------------------------------------===// - // - // createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based + // createObjCARCAAWrapperPass - This pass implements ObjC-ARC-based // alias analysis. // - ImmutablePass *createObjCARCAliasAnalysisPass(); + ImmutablePass *createObjCARCAAWrapperPass(); FunctionPass *createPAEvalPass(); diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index 8560f1f67160f..4988386fdc82c 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -47,7 +47,7 @@ namespace llvm { -// RegionTraits - Class to be specialized for different users of RegionInfo +// Class to be specialized for different users of RegionInfo // (i.e. BasicBlocks or MachineBasicBlocks). This is only to avoid needing to // pass around an unreasonable number of template parameters. template <class FuncT_> @@ -282,17 +282,16 @@ class RegionBase : public RegionNodeBase<Tr> { // Save the BasicBlock RegionNodes that are element of this Region. mutable BBNodeMapT BBNodeMap; - /// verifyBBInRegion - Check if a BB is in this Region. This check also works + /// Check if a BB is in this Region. This check also works /// if the region is incorrectly built. (EXPENSIVE!) void verifyBBInRegion(BlockT *BB) const; - /// verifyWalk - Walk over all the BBs of the region starting from BB and + /// Walk over all the BBs of the region starting from BB and /// verify that all reachable basic blocks are elements of the region. /// (EXPENSIVE!) void verifyWalk(BlockT *BB, std::set<BlockT *> *visitedBB) const; - /// verifyRegionNest - Verify if the region and its children are valid - /// regions (EXPENSIVE!) + /// Verify if the region and its children are valid regions (EXPENSIVE!) void verifyRegionNest() const; public: @@ -688,45 +687,50 @@ private: /// Map every BB to the smallest region, that contains BB. BBtoRegionMap BBtoRegion; - // isCommonDomFrontier - Returns true if BB is in the dominance frontier of + // Check whether the entries of BBtoRegion for the BBs of region + // SR are correct. Triggers an assertion if not. Calls itself recursively for + // subregions. + void verifyBBMap(const RegionT *SR) const; + + // Returns true if BB is in the dominance frontier of // entry, because it was inherited from exit. In the other case there is an // edge going from entry to BB without passing exit. bool isCommonDomFrontier(BlockT *BB, BlockT *entry, BlockT *exit) const; - // isRegion - Check if entry and exit surround a valid region, based on + // Check if entry and exit surround a valid region, based on // dominance tree and dominance frontier. bool isRegion(BlockT *entry, BlockT *exit) const; - // insertShortCut - Saves a shortcut pointing from entry to exit. + // Saves a shortcut pointing from entry to exit. // This function may extend this shortcut if possible. void insertShortCut(BlockT *entry, BlockT *exit, BBtoBBMap *ShortCut) const; - // getNextPostDom - Returns the next BB that postdominates N, while skipping + // Returns the next BB that postdominates N, while skipping // all post dominators that cannot finish a canonical region. DomTreeNodeT *getNextPostDom(DomTreeNodeT *N, BBtoBBMap *ShortCut) const; - // isTrivialRegion - A region is trivial, if it contains only one BB. + // A region is trivial, if it contains only one BB. bool isTrivialRegion(BlockT *entry, BlockT *exit) const; - // createRegion - Creates a single entry single exit region. + // Creates a single entry single exit region. RegionT *createRegion(BlockT *entry, BlockT *exit); - // findRegionsWithEntry - Detect all regions starting with bb 'entry'. + // Detect all regions starting with bb 'entry'. void findRegionsWithEntry(BlockT *entry, BBtoBBMap *ShortCut); - // scanForRegions - Detects regions in F. + // Detects regions in F. void scanForRegions(FuncT &F, BBtoBBMap *ShortCut); - // getTopMostParent - Get the top most parent with the same entry block. + // Get the top most parent with the same entry block. RegionT *getTopMostParent(RegionT *region); - // buildRegionsTree - build the region hierarchy after all region detected. + // Build the region hierarchy after all region detected. void buildRegionsTree(DomTreeNodeT *N, RegionT *region); - // updateStatistics - Update statistic about created regions. + // Update statistic about created regions. virtual void updateStatistics(RegionT *R) = 0; - // calculate - detect all regions in function and build the region tree. + // Detect all regions in function and build the region tree. void calculate(FuncT &F); public: @@ -796,12 +800,6 @@ public: RegionT *getTopLevelRegion() const { return TopLevelRegion; } - /// @brief Update RegionInfo after a basic block was split. - /// - /// @param NewBB The basic block that was created before OldBB. - /// @param OldBB The old basic block. - void splitBlock(BlockT *NewBB, BlockT *OldBB); - /// @brief Clear the Node Cache for all Regions. /// /// @see Region::clearNodeCache() @@ -847,6 +845,19 @@ public: void recalculate(Function &F, DominatorTree *DT, PostDominatorTree *PDT, DominanceFrontier *DF); + +#ifndef NDEBUG + /// @brief Opens a viewer to show the GraphViz visualization of the regions. + /// + /// Useful during debugging as an alternative to dump(). + void view(); + + /// @brief Opens a viewer to show the GraphViz visualization of this region + /// without instructions in the BasicBlocks. + /// + /// Useful during debugging as an alternative to dump(). + void viewOnly(); +#endif }; class RegionInfoPass : public FunctionPass { diff --git a/include/llvm/Analysis/RegionInfoImpl.h b/include/llvm/Analysis/RegionInfoImpl.h index b31eefc15f784..134cd8f96fbea 100644 --- a/include/llvm/Analysis/RegionInfoImpl.h +++ b/include/llvm/Analysis/RegionInfoImpl.h @@ -236,7 +236,7 @@ std::string RegionBase<Tr>::getNameStr() const { template <class Tr> void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const { if (!contains(BB)) - llvm_unreachable("Broken region found!"); + llvm_unreachable("Broken region found: enumerated BB not in region!"); BlockT *entry = getEntry(), *exit = getExit(); @@ -244,7 +244,8 @@ void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const { SE = BlockTraits::child_end(BB); SI != SE; ++SI) { if (!contains(*SI) && exit != *SI) - llvm_unreachable("Broken region found!"); + llvm_unreachable("Broken region found: edges leaving the region must go " + "to the exit node!"); } if (entry != BB) { @@ -252,7 +253,8 @@ void RegionBase<Tr>::verifyBBInRegion(BlockT *BB) const { SE = InvBlockTraits::child_end(BB); SI != SE; ++SI) { if (!contains(*SI)) - llvm_unreachable("Broken region found!"); + llvm_unreachable("Broken region found: edges entering the region must " + "go to the entry node!"); } } } @@ -442,16 +444,14 @@ typename Tr::RegionT *RegionBase<Tr>::getExpandedRegion() const { if (NumSuccessors == 0) return nullptr; - for (PredIterTy PI = InvBlockTraits::child_begin(getExit()), - PE = InvBlockTraits::child_end(getExit()); - PI != PE; ++PI) { - if (!DT->dominates(getEntry(), *PI)) - return nullptr; - } - RegionT *R = RI->getRegionFor(exit); if (R->getEntry() != exit) { + for (PredIterTy PI = InvBlockTraits::child_begin(getExit()), + PE = InvBlockTraits::child_end(getExit()); + PI != PE; ++PI) + if (!contains(*PI)) + return nullptr; if (Tr::getNumSuccessors(exit) == 1) return new RegionT(getEntry(), *BlockTraits::child_begin(exit), RI, DT); return nullptr; @@ -460,13 +460,11 @@ typename Tr::RegionT *RegionBase<Tr>::getExpandedRegion() const { while (R->getParent() && R->getParent()->getEntry() == exit) R = R->getParent(); - if (!DT->dominates(getEntry(), R->getExit())) { - for (PredIterTy PI = InvBlockTraits::child_begin(getExit()), - PE = InvBlockTraits::child_end(getExit()); - PI != PE; ++PI) { - if (!DT->dominates(R->getExit(), *PI)) - return nullptr; - } + for (PredIterTy PI = InvBlockTraits::child_begin(getExit()), + PE = InvBlockTraits::child_end(getExit()); + PI != PE; ++PI) { + if (!(contains(*PI) || R->contains(*PI))) + return nullptr; } return new RegionT(getEntry(), R->getExit(), RI, DT); @@ -542,6 +540,21 @@ RegionInfoBase<Tr>::~RegionInfoBase() { } template <class Tr> +void RegionInfoBase<Tr>::verifyBBMap(const RegionT *R) const { + assert(R && "Re must be non-null"); + for (auto I = R->element_begin(), E = R->element_end(); I != E; ++I) { + if (I->isSubRegion()) { + const RegionT *SR = I->template getNodeAs<RegionT>(); + verifyBBMap(SR); + } else { + BlockT *BB = I->template getNodeAs<BlockT>(); + if (getRegionFor(BB) != R) + llvm_unreachable("BB map does not match region nesting"); + } + } +} + +template <class Tr> bool RegionInfoBase<Tr>::isCommonDomFrontier(BlockT *BB, BlockT *entry, BlockT *exit) const { for (PredIterTy PI = InvBlockTraits::child_begin(BB), @@ -786,7 +799,14 @@ void RegionInfoBase<Tr>::releaseMemory() { template <class Tr> void RegionInfoBase<Tr>::verifyAnalysis() const { + // Do only verify regions if explicitely activated using XDEBUG or + // -verify-region-info + if (!RegionInfoBase<Tr>::VerifyRegionInfo) + return; + TopLevelRegion->verifyRegionNest(); + + verifyBBMap(TopLevelRegion); } // Region pass manager support. @@ -887,20 +907,6 @@ RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const { } template <class Tr> -void RegionInfoBase<Tr>::splitBlock(BlockT *NewBB, BlockT *OldBB) { - RegionT *R = getRegionFor(OldBB); - - setRegionFor(NewBB, R); - - while (R->getEntry() == OldBB && !R->isTopLevelRegion()) { - R->replaceEntry(NewBB); - R = R->getParent(); - } - - setRegionFor(OldBB, R); -} - -template <class Tr> void RegionInfoBase<Tr>::calculate(FuncT &F) { typedef typename std::add_pointer<FuncT>::type FuncPtrT; diff --git a/include/llvm/Analysis/RegionPrinter.h b/include/llvm/Analysis/RegionPrinter.h index 758748aad9e68..8f0035cfd8e68 100644 --- a/include/llvm/Analysis/RegionPrinter.h +++ b/include/llvm/Analysis/RegionPrinter.h @@ -17,10 +17,55 @@ namespace llvm { class FunctionPass; + class Function; + class RegionInfo; + FunctionPass *createRegionViewerPass(); FunctionPass *createRegionOnlyViewerPass(); FunctionPass *createRegionPrinterPass(); FunctionPass *createRegionOnlyPrinterPass(); + +#ifndef NDEBUG + /// @brief Open a viewer to display the GraphViz vizualization of the analysis + /// result. + /// + /// Practical to call in the debugger. + /// Includes the instructions in each BasicBlock. + /// + /// @param RI The analysis to display. + void viewRegion(llvm::RegionInfo *RI); + + /// @brief Analyze the regions of a function and open its GraphViz + /// visualization in a viewer. + /// + /// Useful to call in the debugger. + /// Includes the instructions in each BasicBlock. + /// The result of a new analysis may differ from the RegionInfo the pass + /// manager currently holds. + /// + /// @param F Function to analyze. + void viewRegion(const llvm::Function *F); + + /// @brief Open a viewer to display the GraphViz vizualization of the analysis + /// result. + /// + /// Useful to call in the debugger. + /// Shows only the BasicBlock names without their instructions. + /// + /// @param RI The analysis to display. + void viewRegionOnly(llvm::RegionInfo *RI); + + /// @brief Analyze the regions of a function and open its GraphViz + /// visualization in a viewer. + /// + /// Useful to call in the debugger. + /// Shows only the BasicBlock names without their instructions. + /// The result of a new analysis may differ from the RegionInfo the pass + /// manager currently holds. + /// + /// @param F Function to analyze. + void viewRegionOnly(const llvm::Function *F); +#endif } // End llvm namespace #endif diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index d47cab829cedb..c08335de3e7de 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -23,10 +23,12 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/PassManager.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Pass.h" #include "llvm/Support/Allocator.h" @@ -44,30 +46,33 @@ namespace llvm { class DataLayout; class TargetLibraryInfo; class LLVMContext; - class Loop; - class LoopInfo; class Operator; - class SCEVUnknown; class SCEV; - template<> struct FoldingSetTrait<SCEV>; + class SCEVAddRecExpr; + class SCEVConstant; + class SCEVExpander; + class SCEVPredicate; + class SCEVUnknown; + + template <> struct FoldingSetTrait<SCEV>; + template <> struct FoldingSetTrait<SCEVPredicate>; - /// SCEV - This class represents an analyzed expression in the program. These - /// are opaque objects that the client is not allowed to do much with - /// directly. + /// This class represents an analyzed expression in the program. These are + /// opaque objects that the client is not allowed to do much with directly. /// class SCEV : public FoldingSetNode { friend struct FoldingSetTrait<SCEV>; - /// FastID - A reference to an Interned FoldingSetNodeID for this node. - /// The ScalarEvolution's BumpPtrAllocator holds the data. + /// A reference to an Interned FoldingSetNodeID for this node. The + /// ScalarEvolution's BumpPtrAllocator holds the data. FoldingSetNodeIDRef FastID; // The SCEV baseclass this node corresponds to const unsigned short SCEVType; protected: - /// SubclassData - This field is initialized to zero and may be used in - /// subclasses to store miscellaneous information. + /// This field is initialized to zero and may be used in subclasses to store + /// miscellaneous information. unsigned short SubclassData; private: @@ -104,37 +109,32 @@ namespace llvm { unsigned getSCEVType() const { return SCEVType; } - /// getType - Return the LLVM type of this SCEV expression. + /// Return the LLVM type of this SCEV expression. /// Type *getType() const; - /// isZero - Return true if the expression is a constant zero. + /// Return true if the expression is a constant zero. /// bool isZero() const; - /// isOne - Return true if the expression is a constant one. + /// Return true if the expression is a constant one. /// bool isOne() const; - /// isAllOnesValue - Return true if the expression is a constant - /// all-ones value. + /// Return true if the expression is a constant all-ones value. /// bool isAllOnesValue() const; - /// isNonConstantNegative - Return true if the specified scev is negated, - /// but not a constant. + /// Return true if the specified scev is negated, but not a constant. bool isNonConstantNegative() const; - /// print - Print out the internal representation of this scalar to the - /// specified stream. This should really only be used for debugging - /// purposes. + /// Print out the internal representation of this scalar to the specified + /// stream. This should really only be used for debugging purposes. void print(raw_ostream &OS) const; -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - /// dump - This method is used for debugging. + /// This method is used for debugging. /// void dump() const; -#endif }; // Specialize FoldingSetTrait for SCEV to avoid needing to compute @@ -157,11 +157,10 @@ namespace llvm { return OS; } - /// SCEVCouldNotCompute - An object of this class is returned by queries that - /// could not be answered. For example, if you ask for the number of - /// iterations of a linked-list traversal loop, you will get one of these. - /// None of the standard SCEV operations are valid on this class, it is just a - /// marker. + /// An object of this class is returned by queries that could not be answered. + /// For example, if you ask for the number of iterations of a linked-list + /// traversal loop, you will get one of these. None of the standard SCEV + /// operations are valid on this class, it is just a marker. struct SCEVCouldNotCompute : public SCEV { SCEVCouldNotCompute(); @@ -169,22 +168,162 @@ namespace llvm { static bool classof(const SCEV *S); }; - /// ScalarEvolution - This class is the main scalar evolution driver. Because - /// client code (intentionally) can't do much with the SCEV objects directly, - /// they must ask this class for services. - /// - class ScalarEvolution : public FunctionPass { + /// SCEVPredicate - This class represents an assumption made using SCEV + /// expressions which can be checked at run-time. + class SCEVPredicate : public FoldingSetNode { + friend struct FoldingSetTrait<SCEVPredicate>; + + /// A reference to an Interned FoldingSetNodeID for this node. The + /// ScalarEvolution's BumpPtrAllocator holds the data. + FoldingSetNodeIDRef FastID; + + public: + enum SCEVPredicateKind { P_Union, P_Equal }; + + protected: + SCEVPredicateKind Kind; + ~SCEVPredicate() = default; + SCEVPredicate(const SCEVPredicate&) = default; + SCEVPredicate &operator=(const SCEVPredicate&) = default; + + public: + SCEVPredicate(const FoldingSetNodeIDRef ID, SCEVPredicateKind Kind); + + SCEVPredicateKind getKind() const { return Kind; } + + /// \brief Returns the estimated complexity of this predicate. + /// This is roughly measured in the number of run-time checks required. + virtual unsigned getComplexity() const { return 1; } + + /// \brief Returns true if the predicate is always true. This means that no + /// assumptions were made and nothing needs to be checked at run-time. + virtual bool isAlwaysTrue() const = 0; + + /// \brief Returns true if this predicate implies \p N. + virtual bool implies(const SCEVPredicate *N) const = 0; + + /// \brief Prints a textual representation of this predicate with an + /// indentation of \p Depth. + virtual void print(raw_ostream &OS, unsigned Depth = 0) const = 0; + + /// \brief Returns the SCEV to which this predicate applies, or nullptr + /// if this is a SCEVUnionPredicate. + virtual const SCEV *getExpr() const = 0; + }; + + inline raw_ostream &operator<<(raw_ostream &OS, const SCEVPredicate &P) { + P.print(OS); + return OS; + } + + // Specialize FoldingSetTrait for SCEVPredicate to avoid needing to compute + // temporary FoldingSetNodeID values. + template <> + struct FoldingSetTrait<SCEVPredicate> + : DefaultFoldingSetTrait<SCEVPredicate> { + + static void Profile(const SCEVPredicate &X, FoldingSetNodeID &ID) { + ID = X.FastID; + } + + static bool Equals(const SCEVPredicate &X, const FoldingSetNodeID &ID, + unsigned IDHash, FoldingSetNodeID &TempID) { + return ID == X.FastID; + } + static unsigned ComputeHash(const SCEVPredicate &X, + FoldingSetNodeID &TempID) { + return X.FastID.ComputeHash(); + } + }; + + /// SCEVEqualPredicate - This class represents an assumption that two SCEV + /// expressions are equal, and this can be checked at run-time. We assume + /// that the left hand side is a SCEVUnknown and the right hand side a + /// constant. + class SCEVEqualPredicate final : public SCEVPredicate { + /// We assume that LHS == RHS, where LHS is a SCEVUnknown and RHS a + /// constant. + const SCEVUnknown *LHS; + const SCEVConstant *RHS; + public: - /// LoopDisposition - An enum describing the relationship between a - /// SCEV and a loop. + SCEVEqualPredicate(const FoldingSetNodeIDRef ID, const SCEVUnknown *LHS, + const SCEVConstant *RHS); + + /// Implementation of the SCEVPredicate interface + bool implies(const SCEVPredicate *N) const override; + void print(raw_ostream &OS, unsigned Depth = 0) const override; + bool isAlwaysTrue() const override; + const SCEV *getExpr() const override; + + /// \brief Returns the left hand side of the equality. + const SCEVUnknown *getLHS() const { return LHS; } + + /// \brief Returns the right hand side of the equality. + const SCEVConstant *getRHS() const { return RHS; } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVPredicate *P) { + return P->getKind() == P_Equal; + } + }; + + /// SCEVUnionPredicate - This class represents a composition of other + /// SCEV predicates, and is the class that most clients will interact with. + /// This is equivalent to a logical "AND" of all the predicates in the union. + class SCEVUnionPredicate final : public SCEVPredicate { + private: + typedef DenseMap<const SCEV *, SmallVector<const SCEVPredicate *, 4>> + PredicateMap; + + /// Vector with references to all predicates in this union. + SmallVector<const SCEVPredicate *, 16> Preds; + /// Maps SCEVs to predicates for quick look-ups. + PredicateMap SCEVToPreds; + + public: + SCEVUnionPredicate(); + + const SmallVectorImpl<const SCEVPredicate *> &getPredicates() const { + return Preds; + } + + /// \brief Adds a predicate to this union. + void add(const SCEVPredicate *N); + + /// \brief Returns a reference to a vector containing all predicates + /// which apply to \p Expr. + ArrayRef<const SCEVPredicate *> getPredicatesForExpr(const SCEV *Expr); + + /// Implementation of the SCEVPredicate interface + bool isAlwaysTrue() const override; + bool implies(const SCEVPredicate *N) const override; + void print(raw_ostream &OS, unsigned Depth) const override; + const SCEV *getExpr() const override; + + /// \brief We estimate the complexity of a union predicate as the size + /// number of predicates in the union. + unsigned getComplexity() const override { return Preds.size(); } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVPredicate *P) { + return P->getKind() == P_Union; + } + }; + + /// The main scalar evolution driver. Because client code (intentionally) + /// can't do much with the SCEV objects directly, they must ask this class + /// for services. + class ScalarEvolution { + public: + /// An enum describing the relationship between a SCEV and a loop. enum LoopDisposition { LoopVariant, ///< The SCEV is loop-variant (unknown). LoopInvariant, ///< The SCEV is loop-invariant. LoopComputable ///< The SCEV varies predictably with the loop. }; - /// BlockDisposition - An enum describing the relationship between a - /// SCEV and a basic block. + /// An enum describing the relationship between a SCEV and a basic block. enum BlockDisposition { DoesNotDominateBlock, ///< The SCEV does not dominate the block. DominatesBlock, ///< The SCEV dominates the block. @@ -207,9 +346,9 @@ namespace llvm { } private: - /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be - /// notified whenever a Value is deleted. - class SCEVCallbackVH : public CallbackVH { + /// A CallbackVH to arrange for ScalarEvolution to be notified whenever a + /// Value is deleted. + class SCEVCallbackVH final : public CallbackVH { ScalarEvolution *SE; void deleted() override; void allUsesReplacedWith(Value *New) override; @@ -221,35 +360,34 @@ namespace llvm { friend class SCEVExpander; friend class SCEVUnknown; - /// F - The function we are analyzing. + /// The function we are analyzing. /// - Function *F; - - /// The tracker for @llvm.assume intrinsics in this function. - AssumptionCache *AC; + Function &F; - /// LI - The loop information for the function we are currently analyzing. + /// The target library information for the target we are targeting. /// - LoopInfo *LI; + TargetLibraryInfo &TLI; + + /// The tracker for @llvm.assume intrinsics in this function. + AssumptionCache &AC; - /// TLI - The target library information for the target we are targeting. + /// The dominator tree. /// - TargetLibraryInfo *TLI; + DominatorTree &DT; - /// DT - The dominator tree. + /// The loop information for the function we are currently analyzing. /// - DominatorTree *DT; + LoopInfo &LI; - /// CouldNotCompute - This SCEV is used to represent unknown trip - /// counts and things. - SCEVCouldNotCompute CouldNotCompute; + /// This SCEV is used to represent unknown trip counts and things. + std::unique_ptr<SCEVCouldNotCompute> CouldNotCompute; - /// ValueExprMapType - The typedef for ValueExprMap. + /// The typedef for ValueExprMap. /// typedef DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *> > ValueExprMapType; - /// ValueExprMap - This is a cache of the values we have analyzed so far. + /// This is a cache of the values we have analyzed so far. /// ValueExprMapType ValueExprMap; @@ -260,10 +398,14 @@ namespace llvm { /// conditions dominating the backedge of a loop. bool WalkingBEDominatingConds; - /// ExitLimit - Information about the number of loop iterations for which a - /// loop exit's branch condition evaluates to the not-taken path. This is a - /// temporary pair of exact and max expressions that are eventually - /// summarized in ExitNotTakenInfo and BackedgeTakenInfo. + /// Set to true by isKnownPredicateViaSplitting when we're trying to prove a + /// predicate by splitting it into a set of independent predicates. + bool ProvingSplitPredicate; + + /// Information about the number of loop iterations for which a loop exit's + /// branch condition evaluates to the not-taken path. This is a temporary + /// pair of exact and max expressions that are eventually summarized in + /// ExitNotTakenInfo and BackedgeTakenInfo. struct ExitLimit { const SCEV *Exact; const SCEV *Max; @@ -272,16 +414,16 @@ namespace llvm { ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {} - /// hasAnyInfo - Test whether this ExitLimit contains any computed - /// information, or whether it's all SCEVCouldNotCompute values. + /// Test whether this ExitLimit contains any computed information, or + /// whether it's all SCEVCouldNotCompute values. bool hasAnyInfo() const { return !isa<SCEVCouldNotCompute>(Exact) || !isa<SCEVCouldNotCompute>(Max); } }; - /// ExitNotTakenInfo - Information about the number of times a particular - /// loop exit may be reached before exiting the loop. + /// Information about the number of times a particular loop exit may be + /// reached before exiting the loop. struct ExitNotTakenInfo { AssertingVH<BasicBlock> ExitingBlock; const SCEV *ExactNotTaken; @@ -289,14 +431,14 @@ namespace llvm { ExitNotTakenInfo() : ExitingBlock(nullptr), ExactNotTaken(nullptr) {} - /// isCompleteList - Return true if all loop exits are computable. + /// Return true if all loop exits are computable. bool isCompleteList() const { return NextExit.getInt() == 0; } void setIncomplete() { NextExit.setInt(1); } - /// getNextExit - Return a pointer to the next exit's not-taken info. + /// Return a pointer to the next exit's not-taken info. ExitNotTakenInfo *getNextExit() const { return NextExit.getPointer(); } @@ -304,16 +446,16 @@ namespace llvm { void setNextExit(ExitNotTakenInfo *ENT) { NextExit.setPointer(ENT); } }; - /// BackedgeTakenInfo - Information about the backedge-taken count - /// of a loop. This currently includes an exact count and a maximum count. + /// Information about the backedge-taken count of a loop. This currently + /// includes an exact count and a maximum count. /// class BackedgeTakenInfo { - /// ExitNotTaken - A list of computable exits and their not-taken counts. - /// Loops almost never have more than one computable exit. + /// A list of computable exits and their not-taken counts. Loops almost + /// never have more than one computable exit. ExitNotTakenInfo ExitNotTaken; - /// Max - An expression indicating the least maximum backedge-taken - /// count of the loop that is known, or a SCEVCouldNotCompute. + /// An expression indicating the least maximum backedge-taken count of the + /// loop that is known, or a SCEVCouldNotCompute. const SCEV *Max; public: @@ -324,80 +466,78 @@ namespace llvm { SmallVectorImpl< std::pair<BasicBlock *, const SCEV *> > &ExitCounts, bool Complete, const SCEV *MaxCount); - /// hasAnyInfo - Test whether this BackedgeTakenInfo contains any - /// computed information, or whether it's all SCEVCouldNotCompute - /// values. + /// Test whether this BackedgeTakenInfo contains any computed information, + /// or whether it's all SCEVCouldNotCompute values. bool hasAnyInfo() const { return ExitNotTaken.ExitingBlock || !isa<SCEVCouldNotCompute>(Max); } - /// getExact - Return an expression indicating the exact backedge-taken - /// count of the loop if it is known, or SCEVCouldNotCompute - /// otherwise. This is the number of times the loop header can be - /// guaranteed to execute, minus one. + /// Return an expression indicating the exact backedge-taken count of the + /// loop if it is known, or SCEVCouldNotCompute otherwise. This is the + /// number of times the loop header can be guaranteed to execute, minus + /// one. const SCEV *getExact(ScalarEvolution *SE) const; - /// getExact - Return the number of times this loop exit may fall through - /// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not - /// to exit via this block before this number of iterations, but may exit - /// via another block. + /// Return the number of times this loop exit may fall through to the back + /// edge, or SCEVCouldNotCompute. The loop is guaranteed not to exit via + /// this block before this number of iterations, but may exit via another + /// block. const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) const; - /// getMax - Get the max backedge taken count for the loop. + /// Get the max backedge taken count for the loop. const SCEV *getMax(ScalarEvolution *SE) const; /// Return true if any backedge taken count expressions refer to the given /// subexpression. bool hasOperand(const SCEV *S, ScalarEvolution *SE) const; - /// clear - Invalidate this result and free associated memory. + /// Invalidate this result and free associated memory. void clear(); }; - /// BackedgeTakenCounts - Cache the backedge-taken count of the loops for - /// this function as they are computed. + /// Cache the backedge-taken count of the loops for this function as they + /// are computed. DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts; - /// ConstantEvolutionLoopExitValue - This map contains entries for all of - /// the PHI instructions that we attempt to compute constant evolutions for. - /// This allows us to avoid potentially expensive recomputation of these - /// properties. An instruction maps to null if we are unable to compute its - /// exit value. + /// This map contains entries for all of the PHI instructions that we + /// attempt to compute constant evolutions for. This allows us to avoid + /// potentially expensive recomputation of these properties. An instruction + /// maps to null if we are unable to compute its exit value. DenseMap<PHINode*, Constant*> ConstantEvolutionLoopExitValue; - /// ValuesAtScopes - This map contains entries for all the expressions - /// that we attempt to compute getSCEVAtScope information for, which can - /// be expensive in extreme cases. + /// This map contains entries for all the expressions that we attempt to + /// compute getSCEVAtScope information for, which can be expensive in + /// extreme cases. DenseMap<const SCEV *, SmallVector<std::pair<const Loop *, const SCEV *>, 2> > ValuesAtScopes; - /// LoopDispositions - Memoized computeLoopDisposition results. + /// Memoized computeLoopDisposition results. DenseMap<const SCEV *, SmallVector<PointerIntPair<const Loop *, 2, LoopDisposition>, 2>> LoopDispositions; - /// computeLoopDisposition - Compute a LoopDisposition value. + /// Compute a LoopDisposition value. LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L); - /// BlockDispositions - Memoized computeBlockDisposition results. + /// Memoized computeBlockDisposition results. DenseMap< const SCEV *, SmallVector<PointerIntPair<const BasicBlock *, 2, BlockDisposition>, 2>> BlockDispositions; - /// computeBlockDisposition - Compute a BlockDisposition value. + /// Compute a BlockDisposition value. BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB); - /// UnsignedRanges - Memoized results from getRange + /// Memoized results from getRange DenseMap<const SCEV *, ConstantRange> UnsignedRanges; - /// SignedRanges - Memoized results from getRange + /// Memoized results from getRange DenseMap<const SCEV *, ConstantRange> SignedRanges; - /// RangeSignHint - Used to parameterize getRange + /// Used to parameterize getRange enum RangeSignHint { HINT_RANGE_UNSIGNED, HINT_RANGE_SIGNED }; - /// setRange - Set the memoized range for the given SCEV. + /// Set the memoized range for the given SCEV. const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint, const ConstantRange &CR) { DenseMap<const SCEV *, ConstantRange> &Cache = @@ -410,198 +550,275 @@ namespace llvm { return Pair.first->second; } - /// getRange - Determine the range for a particular SCEV. + /// Determine the range for a particular SCEV. ConstantRange getRange(const SCEV *S, RangeSignHint Hint); - /// createSCEV - We know that there is no SCEV for the specified value. - /// Analyze the expression. + /// We know that there is no SCEV for the specified value. Analyze the + /// expression. const SCEV *createSCEV(Value *V); - /// createNodeForPHI - Provide the special handling we need to analyze PHI - /// SCEVs. + /// Provide the special handling we need to analyze PHI SCEVs. const SCEV *createNodeForPHI(PHINode *PN); - /// createNodeForGEP - Provide the special handling we need to analyze GEP - /// SCEVs. + /// Helper function called from createNodeForPHI. + const SCEV *createAddRecFromPHI(PHINode *PN); + + /// Helper function called from createNodeForPHI. + const SCEV *createNodeFromSelectLikePHI(PHINode *PN); + + /// Provide special handling for a select-like instruction (currently this + /// is either a select instruction or a phi node). \p I is the instruction + /// being processed, and it is assumed equivalent to "Cond ? TrueVal : + /// FalseVal". + const SCEV *createNodeForSelectOrPHI(Instruction *I, Value *Cond, + Value *TrueVal, Value *FalseVal); + + /// Provide the special handling we need to analyze GEP SCEVs. const SCEV *createNodeForGEP(GEPOperator *GEP); - /// computeSCEVAtScope - Implementation code for getSCEVAtScope; called - /// at most once for each SCEV+Loop pair. + /// Implementation code for getSCEVAtScope; called at most once for each + /// SCEV+Loop pair. /// const SCEV *computeSCEVAtScope(const SCEV *S, const Loop *L); - /// ForgetSymbolicValue - This looks up computed SCEV values for all - /// instructions that depend on the given instruction and removes them from - /// the ValueExprMap map if they reference SymName. This is used during PHI - /// resolution. + /// This looks up computed SCEV values for all instructions that depend on + /// the given instruction and removes them from the ValueExprMap map if they + /// reference SymName. This is used during PHI resolution. void ForgetSymbolicName(Instruction *I, const SCEV *SymName); - /// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given - /// loop, lazily computing new values if the loop hasn't been analyzed - /// yet. + /// Return the BackedgeTakenInfo for the given loop, lazily computing new + /// values if the loop hasn't been analyzed yet. const BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L); - /// ComputeBackedgeTakenCount - Compute the number of times the specified - /// loop will iterate. - BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L); + /// Compute the number of times the specified loop will iterate. + BackedgeTakenInfo computeBackedgeTakenCount(const Loop *L); - /// ComputeExitLimit - Compute the number of times the backedge of the - /// specified loop will execute if it exits via the specified block. - ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock); + /// Compute the number of times the backedge of the specified loop will + /// execute if it exits via the specified block. + ExitLimit computeExitLimit(const Loop *L, BasicBlock *ExitingBlock); - /// ComputeExitLimitFromCond - Compute the number of times the backedge of - /// the specified loop will execute if its exit condition were a conditional - /// branch of ExitCond, TBB, and FBB. - ExitLimit ComputeExitLimitFromCond(const Loop *L, + /// Compute the number of times the backedge of the specified loop will + /// execute if its exit condition were a conditional branch of ExitCond, + /// TBB, and FBB. + ExitLimit computeExitLimitFromCond(const Loop *L, Value *ExitCond, BasicBlock *TBB, BasicBlock *FBB, bool IsSubExpr); - /// ComputeExitLimitFromICmp - Compute the number of times the backedge of - /// the specified loop will execute if its exit condition were a conditional - /// branch of the ICmpInst ExitCond, TBB, and FBB. - ExitLimit ComputeExitLimitFromICmp(const Loop *L, + /// Compute the number of times the backedge of the specified loop will + /// execute if its exit condition were a conditional branch of the ICmpInst + /// ExitCond, TBB, and FBB. + ExitLimit computeExitLimitFromICmp(const Loop *L, ICmpInst *ExitCond, BasicBlock *TBB, BasicBlock *FBB, bool IsSubExpr); - /// ComputeExitLimitFromSingleExitSwitch - Compute the number of times the - /// backedge of the specified loop will execute if its exit condition were a - /// switch with a single exiting case to ExitingBB. + /// Compute the number of times the backedge of the specified loop will + /// execute if its exit condition were a switch with a single exiting case + /// to ExitingBB. ExitLimit - ComputeExitLimitFromSingleExitSwitch(const Loop *L, SwitchInst *Switch, + computeExitLimitFromSingleExitSwitch(const Loop *L, SwitchInst *Switch, BasicBlock *ExitingBB, bool IsSubExpr); - /// ComputeLoadConstantCompareExitLimit - Given an exit condition - /// of 'icmp op load X, cst', try to see if we can compute the - /// backedge-taken count. - ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI, + /// Given an exit condition of 'icmp op load X, cst', try to see if we can + /// compute the backedge-taken count. + ExitLimit computeLoadConstantCompareExitLimit(LoadInst *LI, Constant *RHS, const Loop *L, ICmpInst::Predicate p); - /// ComputeExitCountExhaustively - If the loop is known to execute a - /// constant number of times (the condition evolves only from constants), - /// try to evaluate a few iterations of the loop until we get the exit - /// condition gets a value of ExitWhen (true or false). If we cannot - /// evaluate the exit count of the loop, return CouldNotCompute. - const SCEV *ComputeExitCountExhaustively(const Loop *L, + /// Compute the exit limit of a loop that is controlled by a + /// "(IV >> 1) != 0" type comparison. We cannot compute the exact trip + /// count in these cases (since SCEV has no way of expressing them), but we + /// can still sometimes compute an upper bound. + /// + /// Return an ExitLimit for a loop whose backedge is guarded by `LHS Pred + /// RHS`. + ExitLimit computeShiftCompareExitLimit(Value *LHS, Value *RHS, + const Loop *L, + ICmpInst::Predicate Pred); + + /// If the loop is known to execute a constant number of times (the + /// condition evolves only from constants), try to evaluate a few iterations + /// of the loop until we get the exit condition gets a value of ExitWhen + /// (true or false). If we cannot evaluate the exit count of the loop, + /// return CouldNotCompute. + const SCEV *computeExitCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen); - /// HowFarToZero - Return the number of times an exit condition comparing - /// the specified value to zero will execute. If not computable, return - /// CouldNotCompute. + /// Return the number of times an exit condition comparing the specified + /// value to zero will execute. If not computable, return CouldNotCompute. ExitLimit HowFarToZero(const SCEV *V, const Loop *L, bool IsSubExpr); - /// HowFarToNonZero - Return the number of times an exit condition checking - /// the specified value for nonzero will execute. If not computable, return + /// Return the number of times an exit condition checking the specified + /// value for nonzero will execute. If not computable, return /// CouldNotCompute. ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L); - /// HowManyLessThans - Return the number of times an exit condition - /// containing the specified less-than comparison will execute. If not - /// computable, return CouldNotCompute. isSigned specifies whether the - /// less-than is signed. + /// Return the number of times an exit condition containing the specified + /// less-than comparison will execute. If not computable, return + /// CouldNotCompute. isSigned specifies whether the less-than is signed. ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS, const Loop *L, bool isSigned, bool IsSubExpr); ExitLimit HowManyGreaterThans(const SCEV *LHS, const SCEV *RHS, const Loop *L, bool isSigned, bool IsSubExpr); - /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB - /// (which may not be an immediate predecessor) which has exactly one - /// successor from which BB is reachable, or null if no such block is - /// found. + /// Return a predecessor of BB (which may not be an immediate predecessor) + /// which has exactly one successor from which BB is reachable, or null if + /// no such block is found. std::pair<BasicBlock *, BasicBlock *> getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB); - /// isImpliedCond - Test whether the condition described by Pred, LHS, and - /// RHS is true whenever the given FoundCondValue value evaluates to true. + /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the given FoundCondValue value evaluates to true. bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, Value *FoundCondValue, bool Inverse); - /// isImpliedCondOperands - Test whether the condition described by Pred, - /// LHS, and RHS is true whenever the condition described by Pred, FoundLHS, - /// and FoundRHS is true. + /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the condition described by FoundPred, FoundLHS, FoundRHS is + /// true. + bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, + const SCEV *RHS, ICmpInst::Predicate FoundPred, + const SCEV *FoundLHS, const SCEV *FoundRHS); + + /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the condition described by Pred, FoundLHS, and FoundRHS is + /// true. bool isImpliedCondOperands(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const SCEV *FoundLHS, const SCEV *FoundRHS); - /// isImpliedCondOperandsHelper - Test whether the condition described by - /// Pred, LHS, and RHS is true whenever the condition described by Pred, - /// FoundLHS, and FoundRHS is true. + /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the condition described by Pred, FoundLHS, and FoundRHS is + /// true. bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const SCEV *FoundLHS, const SCEV *FoundRHS); - /// isImpliedCondOperandsViaRanges - Test whether the condition described by - /// Pred, LHS, and RHS is true whenever the condition described by Pred, - /// FoundLHS, and FoundRHS is true. Utility function used by - /// isImpliedCondOperands. + /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the condition described by Pred, FoundLHS, and FoundRHS is + /// true. Utility function used by isImpliedCondOperands. bool isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const SCEV *FoundLHS, const SCEV *FoundRHS); - /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is - /// in the header of its containing loop, we know the loop executes a - /// constant number of times, and the PHI node is just a recurrence - /// involving constants, fold it. + /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the condition described by Pred, FoundLHS, and FoundRHS is + /// true. + /// + /// This routine tries to rule out certain kinds of integer overflow, and + /// then tries to reason about arithmetic properties of the predicates. + bool isImpliedCondOperandsViaNoOverflow(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS, + const SCEV *FoundLHS, + const SCEV *FoundRHS); + + /// If we know that the specified Phi is in the header of its containing + /// loop, we know the loop executes a constant number of times, and the PHI + /// node is just a recurrence involving constants, fold it. Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs, const Loop *L); - /// isKnownPredicateWithRanges - Test if the given expression is known to - /// satisfy the condition described by Pred and the known constant ranges - /// of LHS and RHS. + /// Test if the given expression is known to satisfy the condition described + /// by Pred and the known constant ranges of LHS and RHS. /// bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); - /// forgetMemoizedResults - Drop memoized information computed for S. + /// Try to prove the condition described by "LHS Pred RHS" by ruling out + /// integer overflow. + /// + /// For instance, this will return true for "A s< (A + C)<nsw>" if C is + /// positive. + bool isKnownPredicateViaNoOverflow(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS); + + /// Try to split Pred LHS RHS into logical conjunctions (and's) and try to + /// prove them individually. + bool isKnownPredicateViaSplitting(ICmpInst::Predicate Pred, const SCEV *LHS, + const SCEV *RHS); + + /// Try to match the Expr as "(L + R)<Flags>". + bool splitBinaryAdd(const SCEV *Expr, const SCEV *&L, const SCEV *&R, + SCEV::NoWrapFlags &Flags); + + /// Return true if More == (Less + C), where C is a constant. This is + /// intended to be used as a cheaper substitute for full SCEV subtraction. + bool computeConstantDifference(const SCEV *Less, const SCEV *More, + APInt &C); + + /// Drop memoized information computed for S. void forgetMemoizedResults(const SCEV *S); + /// Return an existing SCEV for V if there is one, otherwise return nullptr. + const SCEV *getExistingSCEV(Value *V); + /// Return false iff given SCEV contains a SCEVUnknown with NULL value- /// pointer. bool checkValidity(const SCEV *S) const; - // Return true if `ExtendOpTy`({`Start`,+,`Step`}) can be proved to be equal - // to {`ExtendOpTy`(`Start`),+,`ExtendOpTy`(`Step`)}. This is equivalent to - // proving no signed (resp. unsigned) wrap in {`Start`,+,`Step`} if - // `ExtendOpTy` is `SCEVSignExtendExpr` (resp. `SCEVZeroExtendExpr`). - // + /// Return true if `ExtendOpTy`({`Start`,+,`Step`}) can be proved to be + /// equal to {`ExtendOpTy`(`Start`),+,`ExtendOpTy`(`Step`)}. This is + /// equivalent to proving no signed (resp. unsigned) wrap in + /// {`Start`,+,`Step`} if `ExtendOpTy` is `SCEVSignExtendExpr` + /// (resp. `SCEVZeroExtendExpr`). + /// template<typename ExtendOpTy> bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step, const Loop *L); + bool isMonotonicPredicateImpl(const SCEVAddRecExpr *LHS, + ICmpInst::Predicate Pred, bool &Increasing); + + /// Return true if, for all loop invariant X, the predicate "LHS `Pred` X" + /// is monotonically increasing or decreasing. In the former case set + /// `Increasing` to true and in the latter case set `Increasing` to false. + /// + /// A predicate is said to be monotonically increasing if may go from being + /// false to being true as the loop iterates, but never the other way + /// around. A predicate is said to be monotonically decreasing if may go + /// from being true to being false as the loop iterates, but never the other + /// way around. + bool isMonotonicPredicate(const SCEVAddRecExpr *LHS, + ICmpInst::Predicate Pred, bool &Increasing); + + // Return SCEV no-wrap flags that can be proven based on reasoning + // about how poison produced from no-wrap flags on this value + // (e.g. a nuw add) would trigger undefined behavior on overflow. + SCEV::NoWrapFlags getNoWrapFlagsFromUB(const Value *V); + public: - static char ID; // Pass identification, replacement for typeid - ScalarEvolution(); + ScalarEvolution(Function &F, TargetLibraryInfo &TLI, AssumptionCache &AC, + DominatorTree &DT, LoopInfo &LI); + ~ScalarEvolution(); + ScalarEvolution(ScalarEvolution &&Arg); - LLVMContext &getContext() const { return F->getContext(); } + LLVMContext &getContext() const { return F.getContext(); } - /// isSCEVable - Test if values of the given type are analyzable within - /// the SCEV framework. This primarily includes integer types, and it - /// can optionally include pointer types if the ScalarEvolution class - /// has access to target-specific information. + /// Test if values of the given type are analyzable within the SCEV + /// framework. This primarily includes integer types, and it can optionally + /// include pointer types if the ScalarEvolution class has access to + /// target-specific information. bool isSCEVable(Type *Ty) const; - /// getTypeSizeInBits - Return the size in bits of the specified type, - /// for which isSCEVable must return true. + /// Return the size in bits of the specified type, for which isSCEVable must + /// return true. uint64_t getTypeSizeInBits(Type *Ty) const; - /// getEffectiveSCEVType - Return a type with the same bitwidth as - /// the given type and which represents how SCEV will treat the given - /// type, for which isSCEVable must return true. For pointer types, - /// this is the pointer-sized integer type. + /// Return a type with the same bitwidth as the given type and which + /// represents how SCEV will treat the given type, for which isSCEVable must + /// return true. For pointer types, this is the pointer-sized integer type. Type *getEffectiveSCEVType(Type *Ty) const; - /// getSCEV - Return a SCEV expression for the full generality of the - /// specified expression. + /// Return a SCEV expression for the full generality of the specified + /// expression. const SCEV *getSCEV(Value *V); const SCEV *getConstant(ConstantInt *V); @@ -615,35 +832,24 @@ namespace llvm { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { - SmallVector<const SCEV *, 2> Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); + SmallVector<const SCEV *, 2> Ops = {LHS, RHS}; return getAddExpr(Ops, Flags); } const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { - SmallVector<const SCEV *, 3> Ops; - Ops.push_back(Op0); - Ops.push_back(Op1); - Ops.push_back(Op2); + SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2}; return getAddExpr(Ops, Flags); } const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS, - SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) - { - SmallVector<const SCEV *, 2> Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { + SmallVector<const SCEV *, 2> Ops = {LHS, RHS}; return getMulExpr(Ops, Flags); } const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { - SmallVector<const SCEV *, 3> Ops; - Ops.push_back(Op0); - Ops.push_back(Op1); - Ops.push_back(Op2); + SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2}; return getMulExpr(Ops, Flags); } const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS); @@ -675,81 +881,80 @@ namespace llvm { const SCEV *getUnknown(Value *V); const SCEV *getCouldNotCompute(); - /// getSizeOfExpr - Return an expression for sizeof AllocTy that is type - /// IntTy + /// \brief Return a SCEV for the constant 0 of a specific type. + const SCEV *getZero(Type *Ty) { return getConstant(Ty, 0); } + + /// \brief Return a SCEV for the constant 1 of a specific type. + const SCEV *getOne(Type *Ty) { return getConstant(Ty, 1); } + + /// Return an expression for sizeof AllocTy that is type IntTy /// const SCEV *getSizeOfExpr(Type *IntTy, Type *AllocTy); - /// getOffsetOfExpr - Return an expression for offsetof on the given field - /// with type IntTy + /// Return an expression for offsetof on the given field with type IntTy /// const SCEV *getOffsetOfExpr(Type *IntTy, StructType *STy, unsigned FieldNo); - /// getNegativeSCEV - Return the SCEV object corresponding to -V. + /// Return the SCEV object corresponding to -V. /// - const SCEV *getNegativeSCEV(const SCEV *V); + const SCEV *getNegativeSCEV(const SCEV *V, + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); - /// getNotSCEV - Return the SCEV object corresponding to ~V. + /// Return the SCEV object corresponding to ~V. /// const SCEV *getNotSCEV(const SCEV *V); - /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1. + /// Return LHS-RHS. Minus is represented in SCEV as A+B*-1. const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); - /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion - /// of the input value to the specified type. If the type must be - /// extended, it is zero extended. + /// Return a SCEV corresponding to a conversion of the input value to the + /// specified type. If the type must be extended, it is zero extended. const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty); - /// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion - /// of the input value to the specified type. If the type must be - /// extended, it is sign extended. + /// Return a SCEV corresponding to a conversion of the input value to the + /// specified type. If the type must be extended, it is sign extended. const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty); - /// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of - /// the input value to the specified type. If the type must be extended, - /// it is zero extended. The conversion must not be narrowing. + /// Return a SCEV corresponding to a conversion of the input value to the + /// specified type. If the type must be extended, it is zero extended. The + /// conversion must not be narrowing. const SCEV *getNoopOrZeroExtend(const SCEV *V, Type *Ty); - /// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of - /// the input value to the specified type. If the type must be extended, - /// it is sign extended. The conversion must not be narrowing. + /// Return a SCEV corresponding to a conversion of the input value to the + /// specified type. If the type must be extended, it is sign extended. The + /// conversion must not be narrowing. const SCEV *getNoopOrSignExtend(const SCEV *V, Type *Ty); - /// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of - /// the input value to the specified type. If the type must be extended, - /// it is extended with unspecified bits. The conversion must not be - /// narrowing. + /// Return a SCEV corresponding to a conversion of the input value to the + /// specified type. If the type must be extended, it is extended with + /// unspecified bits. The conversion must not be narrowing. const SCEV *getNoopOrAnyExtend(const SCEV *V, Type *Ty); - /// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the - /// input value to the specified type. The conversion must not be - /// widening. + /// Return a SCEV corresponding to a conversion of the input value to the + /// specified type. The conversion must not be widening. const SCEV *getTruncateOrNoop(const SCEV *V, Type *Ty); - /// getUMaxFromMismatchedTypes - Promote the operands to the wider of - /// the types using zero-extension, and then perform a umax operation - /// with them. + /// Promote the operands to the wider of the types using zero-extension, and + /// then perform a umax operation with them. const SCEV *getUMaxFromMismatchedTypes(const SCEV *LHS, const SCEV *RHS); - /// getUMinFromMismatchedTypes - Promote the operands to the wider of - /// the types using zero-extension, and then perform a umin operation - /// with them. + /// Promote the operands to the wider of the types using zero-extension, and + /// then perform a umin operation with them. const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS, const SCEV *RHS); - /// getPointerBase - Transitively follow the chain of pointer-type operands - /// until reaching a SCEV that does not have a single pointer operand. This - /// returns a SCEVUnknown pointer for well-formed pointer-type expressions, - /// but corner cases do exist. + /// Transitively follow the chain of pointer-type operands until reaching a + /// SCEV that does not have a single pointer operand. This returns a + /// SCEVUnknown pointer for well-formed pointer-type expressions, but corner + /// cases do exist. const SCEV *getPointerBase(const SCEV *V); - /// getSCEVAtScope - Return a SCEV expression for the specified value - /// at the specified scope in the program. The L value specifies a loop - /// nest to evaluate the expression at, where null is the top-level or a - /// specified loop is immediately inside of the loop. + /// Return a SCEV expression for the specified value at the specified scope + /// in the program. The L value specifies a loop nest to evaluate the + /// expression at, where null is the top-level or a specified loop is + /// immediately inside of the loop. /// /// This method can be used to compute the exit value for a variable defined /// in a loop by querying what the value will hold in the parent loop. @@ -758,19 +963,17 @@ namespace llvm { /// original value V is returned. const SCEV *getSCEVAtScope(const SCEV *S, const Loop *L); - /// getSCEVAtScope - This is a convenience function which does - /// getSCEVAtScope(getSCEV(V), L). + /// This is a convenience function which does getSCEVAtScope(getSCEV(V), L). const SCEV *getSCEVAtScope(Value *V, const Loop *L); - /// isLoopEntryGuardedByCond - Test whether entry to the loop is protected - /// by a conditional between LHS and RHS. This is used to help avoid max - /// expressions in loop trip counts, and to eliminate casts. + /// Test whether entry to the loop is protected by a conditional between LHS + /// and RHS. This is used to help avoid max expressions in loop trip + /// counts, and to eliminate casts. bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); - /// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is - /// protected by a conditional between LHS and RHS. This is used to - /// to eliminate casts. + /// Test whether the backedge of the loop is protected by a conditional + /// between LHS and RHS. This is used to to eliminate casts. bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); @@ -781,13 +984,13 @@ namespace llvm { /// the single exiting block passed to it. See that routine for details. unsigned getSmallConstantTripCount(Loop *L); - /// getSmallConstantTripCount - Returns the maximum trip count of this loop - /// as a normal unsigned value. Returns 0 if the trip count is unknown or - /// not constant. This "trip count" assumes that control exits via - /// ExitingBlock. More precisely, it is the number of times that control may - /// reach ExitingBlock before taking the branch. For loops with multiple - /// exits, it may not be the number times that the loop header executes if - /// the loop exits prematurely via another branch. + /// Returns the maximum trip count of this loop as a normal unsigned + /// value. Returns 0 if the trip count is unknown or not constant. This + /// "trip count" assumes that control exits via ExitingBlock. More + /// precisely, it is the number of times that control may reach ExitingBlock + /// before taking the branch. For loops with multiple exits, it may not be + /// the number times that the loop header executes if the loop exits + /// prematurely via another branch. unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitingBlock); /// \brief Returns the largest constant divisor of the trip count of the @@ -798,25 +1001,25 @@ namespace llvm { /// the single exiting block passed to it. See that routine for details. unsigned getSmallConstantTripMultiple(Loop *L); - /// getSmallConstantTripMultiple - Returns the largest constant divisor of - /// the trip count of this loop as a normal unsigned value, if - /// possible. This means that the actual trip count is always a multiple of - /// the returned value (don't forget the trip count could very well be zero - /// as well!). As explained in the comments for getSmallConstantTripCount, - /// this assumes that control exits the loop via ExitingBlock. + /// Returns the largest constant divisor of the trip count of this loop as a + /// normal unsigned value, if possible. This means that the actual trip + /// count is always a multiple of the returned value (don't forget the trip + /// count could very well be zero as well!). As explained in the comments + /// for getSmallConstantTripCount, this assumes that control exits the loop + /// via ExitingBlock. unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitingBlock); - // getExitCount - Get the expression for the number of loop iterations for - // which this loop is guaranteed not to exit via ExitingBlock. Otherwise - // return SCEVCouldNotCompute. + /// Get the expression for the number of loop iterations for which this loop + /// is guaranteed not to exit via ExitingBlock. Otherwise return + /// SCEVCouldNotCompute. const SCEV *getExitCount(Loop *L, BasicBlock *ExitingBlock); - /// getBackedgeTakenCount - If the specified loop has a predictable - /// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute - /// object. The backedge-taken count is the number of times the loop header - /// will be branched to from within the loop. This is one less than the - /// trip count of the loop, since it doesn't count the first iteration, - /// when the header is branched to from outside the loop. + /// If the specified loop has a predictable backedge-taken count, return it, + /// otherwise return a SCEVCouldNotCompute object. The backedge-taken count + /// is the number of times the loop header will be branched to from within + /// the loop. This is one less than the trip count of the loop, since it + /// doesn't count the first iteration, when the header is branched to from + /// outside the loop. /// /// Note that it is not valid to call this method on a loop without a /// loop-invariant backedge-taken count (see @@ -824,24 +1027,23 @@ namespace llvm { /// const SCEV *getBackedgeTakenCount(const Loop *L); - /// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except - /// return the least SCEV value that is known never to be less than the - /// actual backedge taken count. + /// Similar to getBackedgeTakenCount, except return the least SCEV value + /// that is known never to be less than the actual backedge taken count. const SCEV *getMaxBackedgeTakenCount(const Loop *L); - /// hasLoopInvariantBackedgeTakenCount - Return true if the specified loop - /// has an analyzable loop-invariant backedge-taken count. + /// Return true if the specified loop has an analyzable loop-invariant + /// backedge-taken count. bool hasLoopInvariantBackedgeTakenCount(const Loop *L); - /// forgetLoop - This method should be called by the client when it has - /// changed a loop in a way that may effect ScalarEvolution's ability to - /// compute a trip count, or if the loop is deleted. This call is - /// potentially expensive for large loop bodies. + /// This method should be called by the client when it has changed a loop in + /// a way that may effect ScalarEvolution's ability to compute a trip count, + /// or if the loop is deleted. This call is potentially expensive for large + /// loop bodies. void forgetLoop(const Loop *L); - /// forgetValue - This method should be called by the client when it has - /// changed a value in a way that may effect its value, or which may - /// disconnect it from a def-use chain linking it to a loop. + /// This method should be called by the client when it has changed a value + /// in a way that may effect its value, or which may disconnect it from a + /// def-use chain linking it to a loop. void forgetValue(Value *V); /// \brief Called when the client has changed the disposition of values in @@ -851,92 +1053,97 @@ namespace llvm { /// recompute is simpler. void forgetLoopDispositions(const Loop *L) { LoopDispositions.clear(); } - /// GetMinTrailingZeros - Determine the minimum number of zero bits that S - /// is guaranteed to end in (at every loop iteration). It is, at the same - /// time, the minimum number of times S is divisible by 2. For example, - /// given {4,+,8} it returns 2. If S is guaranteed to be 0, it returns the - /// bitwidth of S. + /// Determine the minimum number of zero bits that S is guaranteed to end in + /// (at every loop iteration). It is, at the same time, the minimum number + /// of times S is divisible by 2. For example, given {4,+,8} it returns 2. + /// If S is guaranteed to be 0, it returns the bitwidth of S. uint32_t GetMinTrailingZeros(const SCEV *S); - /// getUnsignedRange - Determine the unsigned range for a particular SCEV. + /// Determine the unsigned range for a particular SCEV. /// ConstantRange getUnsignedRange(const SCEV *S) { return getRange(S, HINT_RANGE_UNSIGNED); } - /// getSignedRange - Determine the signed range for a particular SCEV. + /// Determine the signed range for a particular SCEV. /// ConstantRange getSignedRange(const SCEV *S) { return getRange(S, HINT_RANGE_SIGNED); } - /// isKnownNegative - Test if the given expression is known to be negative. + /// Test if the given expression is known to be negative. /// bool isKnownNegative(const SCEV *S); - /// isKnownPositive - Test if the given expression is known to be positive. + /// Test if the given expression is known to be positive. /// bool isKnownPositive(const SCEV *S); - /// isKnownNonNegative - Test if the given expression is known to be - /// non-negative. + /// Test if the given expression is known to be non-negative. /// bool isKnownNonNegative(const SCEV *S); - /// isKnownNonPositive - Test if the given expression is known to be - /// non-positive. + /// Test if the given expression is known to be non-positive. /// bool isKnownNonPositive(const SCEV *S); - /// isKnownNonZero - Test if the given expression is known to be - /// non-zero. + /// Test if the given expression is known to be non-zero. /// bool isKnownNonZero(const SCEV *S); - /// isKnownPredicate - Test if the given expression is known to satisfy - /// the condition described by Pred, LHS, and RHS. + /// Test if the given expression is known to satisfy the condition described + /// by Pred, LHS, and RHS. /// bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); - /// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with - /// predicate Pred. Return true iff any changes were made. If the - /// operands are provably equal or unequal, LHS and RHS are set to - /// the same value and Pred is set to either ICMP_EQ or ICMP_NE. + /// Return true if the result of the predicate LHS `Pred` RHS is loop + /// invariant with respect to L. Set InvariantPred, InvariantLHS and + /// InvariantLHS so that InvariantLHS `InvariantPred` InvariantRHS is the + /// loop invariant form of LHS `Pred` RHS. + bool isLoopInvariantPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, + const SCEV *RHS, const Loop *L, + ICmpInst::Predicate &InvariantPred, + const SCEV *&InvariantLHS, + const SCEV *&InvariantRHS); + + /// Simplify LHS and RHS in a comparison with predicate Pred. Return true + /// iff any changes were made. If the operands are provably equal or + /// unequal, LHS and RHS are set to the same value and Pred is set to either + /// ICMP_EQ or ICMP_NE. /// bool SimplifyICmpOperands(ICmpInst::Predicate &Pred, const SCEV *&LHS, const SCEV *&RHS, unsigned Depth = 0); - /// getLoopDisposition - Return the "disposition" of the given SCEV with - /// respect to the given loop. + /// Return the "disposition" of the given SCEV with respect to the given + /// loop. LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L); - /// isLoopInvariant - Return true if the value of the given SCEV is - /// unchanging in the specified loop. + /// Return true if the value of the given SCEV is unchanging in the + /// specified loop. bool isLoopInvariant(const SCEV *S, const Loop *L); - /// hasComputableLoopEvolution - Return true if the given SCEV changes value - /// in a known way in the specified loop. This property being true implies - /// that the value is variant in the loop AND that we can emit an expression - /// to compute the value of the expression at any particular loop iteration. + /// Return true if the given SCEV changes value in a known way in the + /// specified loop. This property being true implies that the value is + /// variant in the loop AND that we can emit an expression to compute the + /// value of the expression at any particular loop iteration. bool hasComputableLoopEvolution(const SCEV *S, const Loop *L); - /// getLoopDisposition - Return the "disposition" of the given SCEV with - /// respect to the given block. + /// Return the "disposition" of the given SCEV with respect to the given + /// block. BlockDisposition getBlockDisposition(const SCEV *S, const BasicBlock *BB); - /// dominates - Return true if elements that makes up the given SCEV - /// dominate the specified basic block. + /// Return true if elements that makes up the given SCEV dominate the + /// specified basic block. bool dominates(const SCEV *S, const BasicBlock *BB); - /// properlyDominates - Return true if elements that makes up the given SCEV - /// properly dominate the specified basic block. + /// Return true if elements that makes up the given SCEV properly dominate + /// the specified basic block. bool properlyDominates(const SCEV *S, const BasicBlock *BB); - /// hasOperand - Test whether the given SCEV has Op as a direct or - /// indirect operand. + /// Test whether the given SCEV has Op as a direct or indirect operand. bool hasOperand(const SCEV *S, const SCEV *Op) const; /// Return the size of an element read or written by Inst. @@ -948,11 +1155,8 @@ namespace llvm { SmallVectorImpl<const SCEV *> &Sizes, const SCEV *ElementSize) const; - bool runOnFunction(Function &F) override; - void releaseMemory() override; - void getAnalysisUsage(AnalysisUsage &AU) const override; - void print(raw_ostream &OS, const Module* = nullptr) const override; - void verifyAnalysis() const override; + void print(raw_ostream &OS) const; + void verify() const; /// Collect parametric terms occurring in step expressions. void collectParametricTerms(const SCEV *Expr, @@ -1034,6 +1238,18 @@ namespace llvm { SmallVectorImpl<const SCEV *> &Sizes, const SCEV *ElementSize); + /// Return the DataLayout associated with the module this SCEV instance is + /// operating on. + const DataLayout &getDataLayout() const { + return F.getParent()->getDataLayout(); + } + + const SCEVPredicate *getEqualPredicate(const SCEVUnknown *LHS, + const SCEVConstant *RHS); + + /// Re-writes the SCEV according to the Predicates in \p Preds. + const SCEV *rewriteUsingPredicate(const SCEV *Scev, SCEVUnionPredicate &A); + private: /// Compute the backedge taken count knowing the interval difference, the /// stride and presence of the equality in the comparison. @@ -1054,13 +1270,112 @@ namespace llvm { private: FoldingSet<SCEV> UniqueSCEVs; + FoldingSet<SCEVPredicate> UniquePreds; BumpPtrAllocator SCEVAllocator; - /// FirstUnknown - The head of a linked list of all SCEVUnknown - /// values that have been allocated. This is used by releaseMemory - /// to locate them all and call their destructors. + /// The head of a linked list of all SCEVUnknown values that have been + /// allocated. This is used by releaseMemory to locate them all and call + /// their destructors. SCEVUnknown *FirstUnknown; }; + + /// \brief Analysis pass that exposes the \c ScalarEvolution for a function. + class ScalarEvolutionAnalysis { + static char PassID; + + public: + typedef ScalarEvolution Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + /// \brief Provide a name for the analysis for debugging and logging. + static StringRef name() { return "ScalarEvolutionAnalysis"; } + + ScalarEvolution run(Function &F, AnalysisManager<Function> *AM); + }; + + /// \brief Printer pass for the \c ScalarEvolutionAnalysis results. + class ScalarEvolutionPrinterPass { + raw_ostream &OS; + + public: + explicit ScalarEvolutionPrinterPass(raw_ostream &OS) : OS(OS) {} + PreservedAnalyses run(Function &F, AnalysisManager<Function> *AM); + + static StringRef name() { return "ScalarEvolutionPrinterPass"; } + }; + + class ScalarEvolutionWrapperPass : public FunctionPass { + std::unique_ptr<ScalarEvolution> SE; + + public: + static char ID; + + ScalarEvolutionWrapperPass(); + + ScalarEvolution &getSE() { return *SE; } + const ScalarEvolution &getSE() const { return *SE; } + + bool runOnFunction(Function &F) override; + void releaseMemory() override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + void print(raw_ostream &OS, const Module * = nullptr) const override; + void verifyAnalysis() const override; + }; + + /// An interface layer with SCEV used to manage how we see SCEV expressions + /// for values in the context of existing predicates. We can add new + /// predicates, but we cannot remove them. + /// + /// This layer has multiple purposes: + /// - provides a simple interface for SCEV versioning. + /// - guarantees that the order of transformations applied on a SCEV + /// expression for a single Value is consistent across two different + /// getSCEV calls. This means that, for example, once we've obtained + /// an AddRec expression for a certain value through expression + /// rewriting, we will continue to get an AddRec expression for that + /// Value. + /// - lowers the number of expression rewrites. + class PredicatedScalarEvolution { + public: + PredicatedScalarEvolution(ScalarEvolution &SE); + const SCEVUnionPredicate &getUnionPredicate() const; + /// \brief Returns the SCEV expression of V, in the context of the current + /// SCEV predicate. + /// The order of transformations applied on the expression of V returned + /// by ScalarEvolution is guaranteed to be preserved, even when adding new + /// predicates. + const SCEV *getSCEV(Value *V); + /// \brief Adds a new predicate. + void addPredicate(const SCEVPredicate &Pred); + /// \brief Returns the ScalarEvolution analysis used. + ScalarEvolution *getSE() const { return &SE; } + + private: + /// \brief Increments the version number of the predicate. + /// This needs to be called every time the SCEV predicate changes. + void updateGeneration(); + /// Holds a SCEV and the version number of the SCEV predicate used to + /// perform the rewrite of the expression. + typedef std::pair<unsigned, const SCEV *> RewriteEntry; + /// Maps a SCEV to the rewrite result of that SCEV at a certain version + /// number. If this number doesn't match the current Generation, we will + /// need to do a rewrite. To preserve the transformation order of previous + /// rewrites, we will rewrite the previous result instead of the original + /// SCEV. + DenseMap<const SCEV *, RewriteEntry> RewriteMap; + /// The ScalarEvolution analysis. + ScalarEvolution &SE; + /// The SCEVPredicate that forms our context. We will rewrite all + /// expressions assuming that this predicate true. + SCEVUnionPredicate Preds; + /// Marks the version of the SCEV predicate used. When rewriting a SCEV + /// expression we mark it with the version of the predicate. We use this to + /// figure out if the predicate has changed from the last rewrite of the + /// SCEV. If so, we need to perform a new rewrite. + unsigned Generation; + }; } #endif diff --git a/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h b/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h new file mode 100644 index 0000000000000..7bbbf55620479 --- /dev/null +++ b/include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h @@ -0,0 +1,79 @@ +//===- ScalarEvolutionAliasAnalysis.h - SCEV-based AA -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the interface for a SCEV-based alias analysis. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONALIASANALYSIS_H +#define LLVM_ANALYSIS_SCALAREVOLUTIONALIASANALYSIS_H + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" + +namespace llvm { + +/// A simple alias analysis implementation that uses ScalarEvolution to answer +/// queries. +class SCEVAAResult : public AAResultBase<SCEVAAResult> { + ScalarEvolution &SE; + +public: + explicit SCEVAAResult(const TargetLibraryInfo &TLI, ScalarEvolution &SE) + : AAResultBase(TLI), SE(SE) {} + SCEVAAResult(SCEVAAResult &&Arg) : AAResultBase(std::move(Arg)), SE(Arg.SE) {} + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + +private: + Value *GetBaseValue(const SCEV *S); +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class SCEVAA { +public: + typedef SCEVAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + SCEVAAResult run(Function &F, AnalysisManager<Function> *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "SCEVAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the SCEVAAResult object. +class SCEVAAWrapperPass : public FunctionPass { + std::unique_ptr<SCEVAAResult> Result; + +public: + static char ID; + + SCEVAAWrapperPass(); + + SCEVAAResult &getResult() { return *Result; } + const SCEVAAResult &getResult() const { return *Result; } + + bool runOnFunction(Function &F) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +/// Creates an instance of \c SCEVAAWrapperPass. +FunctionPass *createSCEVAAWrapperPass(); + +} + +#endif diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 8ec2078258d11..b9939168a99d3 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -117,9 +117,14 @@ namespace llvm { /// \brief Return true for expressions that may incur non-trivial cost to /// evaluate at runtime. - bool isHighCostExpansion(const SCEV *Expr, Loop *L) { + /// + /// At is an optional parameter which specifies point in code where user is + /// going to expand this expression. Sometimes this knowledge can lead to a + /// more accurate cost estimation. + bool isHighCostExpansion(const SCEV *Expr, Loop *L, + const Instruction *At = nullptr) { SmallPtrSet<const SCEV *, 8> Processed; - return isHighCostExpansionHelper(Expr, L, Processed); + return isHighCostExpansionHelper(Expr, L, At, Processed); } /// \brief This method returns the canonical induction variable of the @@ -146,6 +151,22 @@ namespace llvm { /// block. Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I); + /// \brief Generates a code sequence that evaluates this predicate. + /// The inserted instructions will be at position \p Loc. + /// The result will be of type i1 and will have a value of 0 when the + /// predicate is false and 1 otherwise. + Value *expandCodeForPredicate(const SCEVPredicate *Pred, Instruction *Loc); + + /// \brief A specialized variant of expandCodeForPredicate, handling the + /// case when we are expanding code for a SCEVEqualPredicate. + Value *expandEqualPredicate(const SCEVEqualPredicate *Pred, + Instruction *Loc); + + /// \brief A specialized variant of expandCodeForPredicate, handling the + /// case when we are expanding code for a SCEVUnionPredicate. + Value *expandUnionPredicate(const SCEVUnionPredicate *Pred, + Instruction *Loc); + /// \brief Set the current IV increment loop and position. void setIVIncInsertPos(const Loop *L, Instruction *Pos) { assert(!CanonicalMode && @@ -193,11 +214,22 @@ namespace llvm { void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); } + /// \brief Try to find LLVM IR value for S available at the point At. + /// + /// L is a hint which tells in which loop to look for the suitable value. + /// On success return value which is equivalent to the expanded S at point + /// At. Return nullptr if value was not found. + /// + /// Note that this function does not perform an exhaustive search. I.e if it + /// didn't find any value it does not mean that there is no such value. + Value *findExistingExpansion(const SCEV *S, const Instruction *At, Loop *L); + private: LLVMContext &getContext() const { return SE.getContext(); } /// \brief Recursive helper function for isHighCostExpansion. bool isHighCostExpansionHelper(const SCEV *S, Loop *L, + const Instruction *At, SmallPtrSetImpl<const SCEV *> &Processed); /// \brief Insert the specified binary operator, doing a small amount diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index da24de281d475..16992680577c1 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -43,6 +43,7 @@ namespace llvm { SCEV(ID, scConstant), V(v) {} public: ConstantInt *getValue() const { return V; } + const APInt &getAPInt() const { return getValue()->getValue(); } Type *getType() const { return V->getType(); } @@ -404,7 +405,7 @@ namespace llvm { /// value, and only represent it as its LLVM Value. This is the "bottom" /// value for the analysis. /// - class SCEVUnknown : public SCEV, private CallbackVH { + class SCEVUnknown final : public SCEV, private CallbackVH { friend class ScalarEvolution; // Implement CallbackVH. @@ -553,64 +554,56 @@ namespace llvm { T.visitAll(Root); } - typedef DenseMap<const Value*, Value*> ValueToValueMap; - - /// The SCEVParameterRewriter takes a scalar evolution expression and updates - /// the SCEVUnknown components following the Map (Value -> Value). - struct SCEVParameterRewriter - : public SCEVVisitor<SCEVParameterRewriter, const SCEV*> { + /// Recursively visits a SCEV expression and re-writes it. + template<typename SC> + class SCEVRewriteVisitor : public SCEVVisitor<SC, const SCEV *> { + protected: + ScalarEvolution &SE; public: - static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE, - ValueToValueMap &Map, - bool InterpretConsts = false) { - SCEVParameterRewriter Rewriter(SE, Map, InterpretConsts); - return Rewriter.visit(Scev); - } - - SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M, bool C) - : SE(S), Map(M), InterpretConsts(C) {} + SCEVRewriteVisitor(ScalarEvolution &SE) : SE(SE) {} const SCEV *visitConstant(const SCEVConstant *Constant) { return Constant; } const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) { - const SCEV *Operand = visit(Expr->getOperand()); + const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand()); return SE.getTruncateExpr(Operand, Expr->getType()); } const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { - const SCEV *Operand = visit(Expr->getOperand()); + const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand()); return SE.getZeroExtendExpr(Operand, Expr->getType()); } const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { - const SCEV *Operand = visit(Expr->getOperand()); + const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand()); return SE.getSignExtendExpr(Operand, Expr->getType()); } const SCEV *visitAddExpr(const SCEVAddExpr *Expr) { SmallVector<const SCEV *, 2> Operands; for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); + Operands.push_back(((SC*)this)->visit(Expr->getOperand(i))); return SE.getAddExpr(Operands); } const SCEV *visitMulExpr(const SCEVMulExpr *Expr) { SmallVector<const SCEV *, 2> Operands; for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); + Operands.push_back(((SC*)this)->visit(Expr->getOperand(i))); return SE.getMulExpr(Operands); } const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) { - return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS())); + return SE.getUDivExpr(((SC*)this)->visit(Expr->getLHS()), + ((SC*)this)->visit(Expr->getRHS())); } const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { SmallVector<const SCEV *, 2> Operands; for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); + Operands.push_back(((SC*)this)->visit(Expr->getOperand(i))); return SE.getAddRecExpr(Operands, Expr->getLoop(), Expr->getNoWrapFlags()); } @@ -618,18 +611,43 @@ namespace llvm { const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) { SmallVector<const SCEV *, 2> Operands; for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); + Operands.push_back(((SC*)this)->visit(Expr->getOperand(i))); return SE.getSMaxExpr(Operands); } const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) { SmallVector<const SCEV *, 2> Operands; for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); + Operands.push_back(((SC*)this)->visit(Expr->getOperand(i))); return SE.getUMaxExpr(Operands); } const SCEV *visitUnknown(const SCEVUnknown *Expr) { + return Expr; + } + + const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { + return Expr; + } + }; + + typedef DenseMap<const Value*, Value*> ValueToValueMap; + + /// The SCEVParameterRewriter takes a scalar evolution expression and updates + /// the SCEVUnknown components following the Map (Value -> Value). + class SCEVParameterRewriter : public SCEVRewriteVisitor<SCEVParameterRewriter> { + public: + static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE, + ValueToValueMap &Map, + bool InterpretConsts = false) { + SCEVParameterRewriter Rewriter(SE, Map, InterpretConsts); + return Rewriter.visit(Scev); + } + + SCEVParameterRewriter(ScalarEvolution &SE, ValueToValueMap &M, bool C) + : SCEVRewriteVisitor(SE), Map(M), InterpretConsts(C) {} + + const SCEV *visitUnknown(const SCEVUnknown *Expr) { Value *V = Expr->getValue(); if (Map.count(V)) { Value *NV = Map[V]; @@ -640,68 +658,26 @@ namespace llvm { return Expr; } - const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { - return Expr; - } - private: - ScalarEvolution &SE; ValueToValueMap ⤅ bool InterpretConsts; }; typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT; - /// The SCEVApplyRewriter takes a scalar evolution expression and applies + /// The SCEVLoopAddRecRewriter takes a scalar evolution expression and applies /// the Map (Loop -> SCEV) to all AddRecExprs. - struct SCEVApplyRewriter - : public SCEVVisitor<SCEVApplyRewriter, const SCEV*> { + class SCEVLoopAddRecRewriter + : public SCEVRewriteVisitor<SCEVLoopAddRecRewriter> { public: static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map, ScalarEvolution &SE) { - SCEVApplyRewriter Rewriter(SE, Map); + SCEVLoopAddRecRewriter Rewriter(SE, Map); return Rewriter.visit(Scev); } - SCEVApplyRewriter(ScalarEvolution &S, LoopToScevMapT &M) - : SE(S), Map(M) {} - - const SCEV *visitConstant(const SCEVConstant *Constant) { - return Constant; - } - - const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) { - const SCEV *Operand = visit(Expr->getOperand()); - return SE.getTruncateExpr(Operand, Expr->getType()); - } - - const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { - const SCEV *Operand = visit(Expr->getOperand()); - return SE.getZeroExtendExpr(Operand, Expr->getType()); - } - - const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { - const SCEV *Operand = visit(Expr->getOperand()); - return SE.getSignExtendExpr(Operand, Expr->getType()); - } - - const SCEV *visitAddExpr(const SCEVAddExpr *Expr) { - SmallVector<const SCEV *, 2> Operands; - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); - return SE.getAddExpr(Operands); - } - - const SCEV *visitMulExpr(const SCEVMulExpr *Expr) { - SmallVector<const SCEV *, 2> Operands; - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); - return SE.getMulExpr(Operands); - } - - const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) { - return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS())); - } + SCEVLoopAddRecRewriter(ScalarEvolution &SE, LoopToScevMapT &M) + : SCEVRewriteVisitor(SE), Map(M) {} const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { SmallVector<const SCEV *, 2> Operands; @@ -714,41 +690,18 @@ namespace llvm { if (0 == Map.count(L)) return Res; - const SCEVAddRecExpr *Rec = (const SCEVAddRecExpr *) Res; + const SCEVAddRecExpr *Rec = cast<SCEVAddRecExpr>(Res); return Rec->evaluateAtIteration(Map[L], SE); } - const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) { - SmallVector<const SCEV *, 2> Operands; - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); - return SE.getSMaxExpr(Operands); - } - - const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) { - SmallVector<const SCEV *, 2> Operands; - for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) - Operands.push_back(visit(Expr->getOperand(i))); - return SE.getUMaxExpr(Operands); - } - - const SCEV *visitUnknown(const SCEVUnknown *Expr) { - return Expr; - } - - const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) { - return Expr; - } - private: - ScalarEvolution &SE; LoopToScevMapT ⤅ }; /// Applies the Map (Loop -> SCEV) to the given Scev. static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map, ScalarEvolution &SE) { - return SCEVApplyRewriter::rewrite(Scev, Map, SE); + return SCEVLoopAddRecRewriter::rewrite(Scev, Map, SE); } } diff --git a/include/llvm/Analysis/ScopedNoAliasAA.h b/include/llvm/Analysis/ScopedNoAliasAA.h new file mode 100644 index 0000000000000..175561687157e --- /dev/null +++ b/include/llvm/Analysis/ScopedNoAliasAA.h @@ -0,0 +1,92 @@ +//===- ScopedNoAliasAA.h - Scoped No-Alias Alias Analysis -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the interface for a metadata-based scoped no-alias analysis. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_SCOPEDNOALIASAA_H +#define LLVM_ANALYSIS_SCOPEDNOALIASAA_H + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" + +namespace llvm { + +/// A simple AA result which uses scoped-noalias metadata to answer queries. +class ScopedNoAliasAAResult : public AAResultBase<ScopedNoAliasAAResult> { + friend AAResultBase<ScopedNoAliasAAResult>; + +public: + explicit ScopedNoAliasAAResult(const TargetLibraryInfo &TLI) + : AAResultBase(TLI) {} + ScopedNoAliasAAResult(ScopedNoAliasAAResult &&Arg) + : AAResultBase(std::move(Arg)) {} + + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); + +private: + bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const; + void collectMDInDomain(const MDNode *List, const MDNode *Domain, + SmallPtrSetImpl<const MDNode *> &Nodes) const; +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class ScopedNoAliasAA { +public: + typedef ScopedNoAliasAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + ScopedNoAliasAAResult run(Function &F, AnalysisManager<Function> *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "ScopedNoAliasAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the ScopedNoAliasAAResult object. +class ScopedNoAliasAAWrapperPass : public ImmutablePass { + std::unique_ptr<ScopedNoAliasAAResult> Result; + +public: + static char ID; + + ScopedNoAliasAAWrapperPass(); + + ScopedNoAliasAAResult &getResult() { return *Result; } + const ScopedNoAliasAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +//===--------------------------------------------------------------------===// +// +// createScopedNoAliasAAWrapperPass - This pass implements metadata-based +// scoped noalias analysis. +// +ImmutablePass *createScopedNoAliasAAWrapperPass(); +} + +#endif diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h index 9ccae5ff89b77..2c7f5dd73547e 100644 --- a/include/llvm/Analysis/SparsePropagation.h +++ b/include/llvm/Analysis/SparsePropagation.h @@ -21,19 +21,19 @@ #include <vector> namespace llvm { - class Value; - class Constant; - class Argument; - class Instruction; - class PHINode; - class TerminatorInst; - class BasicBlock; - class Function; - class SparseSolver; - class raw_ostream; +class Value; +class Constant; +class Argument; +class Instruction; +class PHINode; +class TerminatorInst; +class BasicBlock; +class Function; +class SparseSolver; +class raw_ostream; + +template <typename T> class SmallVectorImpl; - template<typename T> class SmallVectorImpl; - /// AbstractLatticeFunction - This class is implemented by the dataflow instance /// to specify what the lattice values are and how they handle merges etc. /// This gives the client the power to compute lattice values from instructions, @@ -44,8 +44,10 @@ namespace llvm { class AbstractLatticeFunction { public: typedef void *LatticeVal; + private: LatticeVal UndefVal, OverdefinedVal, UntrackedVal; + public: AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal, LatticeVal untrackedVal) { @@ -54,18 +56,16 @@ public: UntrackedVal = untrackedVal; } virtual ~AbstractLatticeFunction(); - + LatticeVal getUndefVal() const { return UndefVal; } LatticeVal getOverdefinedVal() const { return OverdefinedVal; } LatticeVal getUntrackedVal() const { return UntrackedVal; } - + /// IsUntrackedValue - If the specified Value is something that is obviously /// uninteresting to the analysis (and would always return UntrackedVal), /// this function can return true to avoid pointless work. - virtual bool IsUntrackedValue(Value *V) { - return false; - } - + virtual bool IsUntrackedValue(Value *V) { return false; } + /// ComputeConstant - Given a constant value, compute and return a lattice /// value corresponding to the specified constant. virtual LatticeVal ComputeConstant(Constant *C) { @@ -74,10 +74,8 @@ public: /// IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is /// one that the we want to handle through ComputeInstructionState. - virtual bool IsSpecialCasedPHI(PHINode *PN) { - return false; - } - + virtual bool IsSpecialCasedPHI(PHINode *PN) { return false; } + /// GetConstant - If the specified lattice value is representable as an LLVM /// constant value, return it. Otherwise return null. The returned value /// must be in the same LLVM type as Val. @@ -90,42 +88,41 @@ public: virtual LatticeVal ComputeArgument(Argument *I) { return getOverdefinedVal(); // always safe } - + /// MergeValues - Compute and return the merge of the two specified lattice /// values. Merging should only move one direction down the lattice to /// guarantee convergence (toward overdefined). virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) { return getOverdefinedVal(); // always safe, never useful. } - + /// ComputeInstructionState - Given an instruction and a vector of its operand /// values, compute the result value of the instruction. virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS) { return getOverdefinedVal(); // always safe, never useful. } - + /// PrintValue - Render the specified lattice value to the specified stream. virtual void PrintValue(LatticeVal V, raw_ostream &OS); }; - /// SparseSolver - This class is a general purpose solver for Sparse Conditional /// Propagation with a programmable lattice function. /// class SparseSolver { typedef AbstractLatticeFunction::LatticeVal LatticeVal; - + /// LatticeFunc - This is the object that knows the lattice and how to do /// compute transfer functions. AbstractLatticeFunction *LatticeFunc; - - DenseMap<Value*, LatticeVal> ValueState; // The state each value is in. - SmallPtrSet<BasicBlock*, 16> BBExecutable; // The bbs that are executable. - - std::vector<Instruction*> InstWorkList; // Worklist of insts to process. - - std::vector<BasicBlock*> BBWorkList; // The BasicBlock work list - + + DenseMap<Value *, LatticeVal> ValueState; // The state each value is in. + SmallPtrSet<BasicBlock *, 16> BBExecutable; // The bbs that are executable. + + std::vector<Instruction *> InstWorkList; // Worklist of insts to process. + + std::vector<BasicBlock *> BBWorkList; // The BasicBlock work list + /// KnownFeasibleEdges - Entries in this set are edges which have already had /// PHI nodes retriggered. typedef std::pair<BasicBlock*,BasicBlock*> Edge; @@ -133,17 +130,16 @@ class SparseSolver { SparseSolver(const SparseSolver&) = delete; void operator=(const SparseSolver&) = delete; + public: explicit SparseSolver(AbstractLatticeFunction *Lattice) - : LatticeFunc(Lattice) {} - ~SparseSolver() { - delete LatticeFunc; - } - + : LatticeFunc(Lattice) {} + ~SparseSolver() { delete LatticeFunc; } + /// Solve - Solve for constants and executable blocks. /// void Solve(Function &F); - + void Print(Function &F, raw_ostream &OS) const; /// getLatticeState - Return the LatticeVal object that corresponds to the @@ -153,7 +149,7 @@ public: DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V); return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal(); } - + /// getOrInitValueState - Return the LatticeVal object that corresponds to the /// value, initializing the value's state if it hasn't been entered into the /// map yet. This function is necessary because not all values should start @@ -161,7 +157,7 @@ public: /// constants should be marked as constants. /// LatticeVal getOrInitValueState(Value *V); - + /// isEdgeFeasible - Return true if the control flow edge from the 'From' /// basic block to the 'To' basic block is currently feasible. If /// AggressiveUndef is true, then this treats values with unknown lattice @@ -176,29 +172,28 @@ public: bool isBlockExecutable(BasicBlock *BB) const { return BBExecutable.count(BB); } - + private: /// UpdateState - When the state for some instruction is potentially updated, /// this function notices and adds I to the worklist if needed. void UpdateState(Instruction &Inst, LatticeVal V); - + /// MarkBlockExecutable - This method can be used by clients to mark all of /// the blocks that are known to be intrinsically live in the processed unit. void MarkBlockExecutable(BasicBlock *BB); - + /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB /// work list if it is not already executable. void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest); - + /// getFeasibleSuccessors - Return a vector of booleans to indicate which /// successors are reachable from a given terminator instruction. void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs, bool AggressiveUndef); - + void visitInst(Instruction &I); void visitPHINode(PHINode &I); void visitTerminatorInst(TerminatorInst &TI); - }; } // end namespace llvm diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def index 1c1fdfef980d0..7798e3c882480 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.def +++ b/include/llvm/Analysis/TargetLibraryInfo.def @@ -27,6 +27,86 @@ #define TLI_DEFINE_STRING_INTERNAL(string_repr) string_repr, #endif +/// void *new(unsigned int); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_int) +TLI_DEFINE_STRING_INTERNAL("??2@YAPAXI@Z") + +/// void *new(unsigned int, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_int_nothrow) +TLI_DEFINE_STRING_INTERNAL("??2@YAPAXIABUnothrow_t@std@@@Z") + +/// void *new(unsigned long long); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_longlong) +TLI_DEFINE_STRING_INTERNAL("??2@YAPEAX_K@Z") + +/// void *new(unsigned long long, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_longlong_nothrow) +TLI_DEFINE_STRING_INTERNAL("??2@YAPEAX_KAEBUnothrow_t@std@@@Z") + +/// void operator delete(void*); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_ptr32) +TLI_DEFINE_STRING_INTERNAL("??3@YAXPAX@Z") + +/// void operator delete(void*, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_ptr32_nothrow) +TLI_DEFINE_STRING_INTERNAL("??3@YAXPAXABUnothrow_t@std@@@Z") + +/// void operator delete(void*, unsigned int); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_ptr32_int) +TLI_DEFINE_STRING_INTERNAL("??3@YAXPAXI@Z") + +/// void operator delete(void*); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_ptr64) +TLI_DEFINE_STRING_INTERNAL("??3@YAXPEAX@Z") + +/// void operator delete(void*, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_ptr64_nothrow) +TLI_DEFINE_STRING_INTERNAL("??3@YAXPEAXAEBUnothrow_t@std@@@Z") + +/// void operator delete(void*, unsigned long long); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_ptr64_longlong) +TLI_DEFINE_STRING_INTERNAL("??3@YAXPEAX_K@Z") + +/// void *new[](unsigned int); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_array_int) +TLI_DEFINE_STRING_INTERNAL("??_U@YAPAXI@Z") + +/// void *new[](unsigned int, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_array_int_nothrow) +TLI_DEFINE_STRING_INTERNAL("??_U@YAPAXIABUnothrow_t@std@@@Z") + +/// void *new[](unsigned long long); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_array_longlong) +TLI_DEFINE_STRING_INTERNAL("??_U@YAPEAX_K@Z") + +/// void *new[](unsigned long long, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_new_array_longlong_nothrow) +TLI_DEFINE_STRING_INTERNAL("??_U@YAPEAX_KAEBUnothrow_t@std@@@Z") + +/// void operator delete[](void*); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_array_ptr32) +TLI_DEFINE_STRING_INTERNAL("??_V@YAXPAX@Z") + +/// void operator delete[](void*, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_array_ptr32_nothrow) +TLI_DEFINE_STRING_INTERNAL("??_V@YAXPAXABUnothrow_t@std@@@Z") + +/// void operator delete[](void*, unsigned int); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_array_ptr32_int) +TLI_DEFINE_STRING_INTERNAL("??_V@YAXPAXI@Z") + +/// void operator delete[](void*); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_array_ptr64) +TLI_DEFINE_STRING_INTERNAL("??_V@YAXPEAX@Z") + +/// void operator delete[](void*, nothrow); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_array_ptr64_nothrow) +TLI_DEFINE_STRING_INTERNAL("??_V@YAXPEAXAEBUnothrow_t@std@@@Z") + +/// void operator delete[](void*, unsigned long long); +TLI_DEFINE_ENUM_INTERNAL(msvc_delete_array_ptr64_longlong) +TLI_DEFINE_STRING_INTERNAL("??_V@YAXPEAX_K@Z") + /// int _IO_getc(_IO_FILE * __fp); TLI_DEFINE_ENUM_INTERNAL(under_IO_getc) TLI_DEFINE_STRING_INTERNAL("_IO_getc") @@ -406,6 +486,15 @@ TLI_DEFINE_STRING_INTERNAL("floorf") /// long double floorl(long double x); TLI_DEFINE_ENUM_INTERNAL(floorl) TLI_DEFINE_STRING_INTERNAL("floorl") +/// int fls(int i); +TLI_DEFINE_ENUM_INTERNAL(fls) +TLI_DEFINE_STRING_INTERNAL("fls") +/// int flsl(long int i); +TLI_DEFINE_ENUM_INTERNAL(flsl) +TLI_DEFINE_STRING_INTERNAL("flsl") +/// int flsll(long long int i); +TLI_DEFINE_ENUM_INTERNAL(flsll) +TLI_DEFINE_STRING_INTERNAL("flsll") /// double fmax(double x, double y); TLI_DEFINE_ENUM_INTERNAL(fmax) TLI_DEFINE_STRING_INTERNAL("fmax") @@ -664,6 +753,7 @@ TLI_DEFINE_STRING_INTERNAL("modff") /// long double modfl(long double value, long double *iptr); TLI_DEFINE_ENUM_INTERNAL(modfl) TLI_DEFINE_STRING_INTERNAL("modfl") + /// double nearbyint(double x); TLI_DEFINE_ENUM_INTERNAL(nearbyint) TLI_DEFINE_STRING_INTERNAL("nearbyint") diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h index e0a1ee378274a..7becdf033dd29 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.h +++ b/include/llvm/Analysis/TargetLibraryInfo.h @@ -42,7 +42,7 @@ class PreservedAnalyses; /// /// This class constructs tables that hold the target library information and /// make it available. However, it is somewhat expensive to compute and only -/// depends on the triple. So users typicaly interact with the \c +/// depends on the triple. So users typically interact with the \c /// TargetLibraryInfo wrapper below. class TargetLibraryInfoImpl { friend class TargetLibraryInfo; @@ -201,13 +201,13 @@ public: } bool isFunctionVectorizable(StringRef F, unsigned VF) const { return Impl->isFunctionVectorizable(F, VF); - }; + } bool isFunctionVectorizable(StringRef F) const { return Impl->isFunctionVectorizable(F); - }; + } StringRef getVectorizedFunction(StringRef F, unsigned VF) const { return Impl->getVectorizedFunction(F, VF); - }; + } /// \brief Tests if the function is both available and a candidate for /// optimized code generation. diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index 01f00896410e2..3913cc3f107c3 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -42,11 +42,13 @@ class Value; /// \brief Information about a load/store intrinsic defined by the target. struct MemIntrinsicInfo { MemIntrinsicInfo() - : ReadMem(false), WriteMem(false), Vol(false), MatchingId(0), + : ReadMem(false), WriteMem(false), IsSimple(false), MatchingId(0), NumMemRefs(0), PtrVal(nullptr) {} bool ReadMem; bool WriteMem; - bool Vol; + /// True only if this memory operation is non-volatile, non-atomic, and + /// unordered. (See LoadInst/StoreInst for details on each) + bool IsSimple; // Same Id is set by the target for corresponding load/store intrinsics. unsigned short MatchingId; int NumMemRefs; @@ -97,11 +99,14 @@ public: /// /// Many APIs in this interface return a cost. This enum defines the /// fundamental values that should be used to interpret (and produce) those - /// costs. The costs are returned as an unsigned rather than a member of this + /// costs. The costs are returned as an int rather than a member of this /// enumeration because it is expected that the cost of one IR instruction /// may have a multiplicative factor to it or otherwise won't fit directly /// into the enum. Moreover, it is common to sum or average costs which works /// better as simple integral values. Thus this enum only provides constants. + /// Also note that the returned costs are signed integers to make it natural + /// to add, subtract, and test with zero (a common boundary condition). It is + /// not expected that 2^32 is a realistic cost to be modeling at any point. /// /// Note that these costs should usually reflect the intersection of code-size /// cost and execution cost. A free instruction is typically one that folds @@ -128,15 +133,15 @@ public: /// /// The returned cost is defined in terms of \c TargetCostConstants, see its /// comments for a detailed explanation of the cost values. - unsigned getOperationCost(unsigned Opcode, Type *Ty, - Type *OpTy = nullptr) const; + int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy = nullptr) const; /// \brief Estimate the cost of a GEP operation when lowered. /// /// The contract for this function is the same as \c getOperationCost except /// that it supports an interface that provides extra information specific to /// the GEP operation. - unsigned getGEPCost(const Value *Ptr, ArrayRef<const Value *> Operands) const; + int getGEPCost(Type *PointeeType, const Value *Ptr, + ArrayRef<const Value *> Operands) const; /// \brief Estimate the cost of a function call when lowered. /// @@ -147,31 +152,30 @@ public: /// This is the most basic query for estimating call cost: it only knows the /// function type and (potentially) the number of arguments at the call site. /// The latter is only interesting for varargs function types. - unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const; + int getCallCost(FunctionType *FTy, int NumArgs = -1) const; /// \brief Estimate the cost of calling a specific function when lowered. /// /// This overload adds the ability to reason about the particular function /// being called in the event it is a library call with special lowering. - unsigned getCallCost(const Function *F, int NumArgs = -1) const; + int getCallCost(const Function *F, int NumArgs = -1) const; /// \brief Estimate the cost of calling a specific function when lowered. /// /// This overload allows specifying a set of candidate argument values. - unsigned getCallCost(const Function *F, - ArrayRef<const Value *> Arguments) const; + int getCallCost(const Function *F, ArrayRef<const Value *> Arguments) const; /// \brief Estimate the cost of an intrinsic when lowered. /// /// Mirrors the \c getCallCost method but uses an intrinsic identifier. - unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef<Type *> ParamTys) const; + int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<Type *> ParamTys) const; /// \brief Estimate the cost of an intrinsic when lowered. /// /// Mirrors the \c getCallCost method but uses an intrinsic identifier. - unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef<const Value *> Arguments) const; + int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<const Value *> Arguments) const; /// \brief Estimate the cost of a given IR user when lowered. /// @@ -188,7 +192,7 @@ public: /// /// The returned cost is defined in terms of \c TargetCostConstants, see its /// comments for a detailed explanation of the cost values. - unsigned getUserCost(const User *U) const; + int getUserCost(const User *U) const; /// \brief Return true if branch divergence exists. /// @@ -308,12 +312,17 @@ public: bool HasBaseReg, int64_t Scale, unsigned AddrSpace = 0) const; - /// \brief Return true if the target works with masked instruction - /// AVX2 allows masks for consecutive load and store for i32 and i64 elements. - /// AVX-512 architecture will also allow masks for non-consecutive memory - /// accesses. - bool isLegalMaskedStore(Type *DataType, int Consecutive) const; - bool isLegalMaskedLoad(Type *DataType, int Consecutive) const; + /// \brief Return true if the target supports masked load/store + /// AVX2 and AVX-512 targets allow masks for consecutive load and store for + /// 32 and 64 bit elements. + bool isLegalMaskedStore(Type *DataType) const; + bool isLegalMaskedLoad(Type *DataType) const; + + /// \brief Return true if the target supports masked gather/scatter + /// AVX-512 fully supports gather and scatter for vectors with 32 and 64 + /// bits scalar type. + bool isLegalMaskedScatter(Type *DataType) const; + bool isLegalMaskedGather(Type *DataType) const; /// \brief Return the cost of the scaling factor used in the addressing /// mode represented by AM for this target, for a load/store @@ -350,6 +359,9 @@ public: /// \brief Don't restrict interleaved unrolling to small loops. bool enableAggressiveInterleaving(bool LoopHasReductions) const; + /// \brief Enable matching of interleaved access groups. + bool enableInterleavedAccessVectorization() const; + /// \brief Return hardware support for population count. PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const; @@ -358,19 +370,19 @@ public: /// \brief Return the expected cost of supporting the floating point operation /// of the specified type. - unsigned getFPOpCost(Type *Ty) const; + int getFPOpCost(Type *Ty) const; /// \brief Return the expected cost of materializing for the given integer /// immediate of the specified type. - unsigned getIntImmCost(const APInt &Imm, Type *Ty) const; + int getIntImmCost(const APInt &Imm, Type *Ty) const; /// \brief Return the expected cost of materialization for the given integer /// immediate of the specified type for a given instruction. The cost can be /// zero if the immediate can be folded into the specified instruction. - unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm, - Type *Ty) const; - unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, - Type *Ty) const; + int getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm, + Type *Ty) const; + int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, + Type *Ty) const; /// @} /// \name Vector Target Information @@ -410,43 +422,51 @@ public: unsigned getMaxInterleaveFactor(unsigned VF) const; /// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc. - unsigned - getArithmeticInstrCost(unsigned Opcode, Type *Ty, - OperandValueKind Opd1Info = OK_AnyValue, - OperandValueKind Opd2Info = OK_AnyValue, - OperandValueProperties Opd1PropInfo = OP_None, - OperandValueProperties Opd2PropInfo = OP_None) const; + int getArithmeticInstrCost( + unsigned Opcode, Type *Ty, OperandValueKind Opd1Info = OK_AnyValue, + OperandValueKind Opd2Info = OK_AnyValue, + OperandValueProperties Opd1PropInfo = OP_None, + OperandValueProperties Opd2PropInfo = OP_None) const; /// \return The cost of a shuffle instruction of kind Kind and of type Tp. /// The index and subtype parameters are used by the subvector insertion and /// extraction shuffle kinds. - unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0, - Type *SubTp = nullptr) const; + int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0, + Type *SubTp = nullptr) const; /// \return The expected cost of cast instructions, such as bitcast, trunc, /// zext, etc. - unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const; + int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) const; /// \return The expected cost of control-flow related instructions such as /// Phi, Ret, Br. - unsigned getCFInstrCost(unsigned Opcode) const; + int getCFInstrCost(unsigned Opcode) const; /// \returns The expected cost of compare and select instructions. - unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy = nullptr) const; + int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy = nullptr) const; /// \return The expected cost of vector Insert and Extract. /// Use -1 to indicate that there is no information on the index value. - unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index = -1) const; + int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index = -1) const; /// \return The cost of Load and Store instructions. - unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, - unsigned AddressSpace) const; + int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace) const; /// \return The cost of masked Load and Store instructions. - unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, - unsigned AddressSpace) const; + int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace) const; + + /// \return The cost of Gather or Scatter operation + /// \p Opcode - is a type of memory access Load or Store + /// \p DataTy - a vector type of the data to be loaded or stored + /// \p Ptr - pointer [or vector of pointers] - address[es] in memory + /// \p VariableMask - true when the memory access is predicated with a mask + /// that is not a compile-time constant + /// \p Alignment - alignment of single element + int getGatherScatterOpCost(unsigned Opcode, Type *DataTy, Value *Ptr, + bool VariableMask, unsigned Alignment) const; /// \return The cost of the interleaved memory operation. /// \p Opcode is the memory operation code @@ -456,11 +476,9 @@ public: /// load allows gaps) /// \p Alignment is the alignment of the memory operation /// \p AddressSpace is address space of the pointer. - unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, - unsigned Factor, - ArrayRef<unsigned> Indices, - unsigned Alignment, - unsigned AddressSpace) const; + int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, + ArrayRef<unsigned> Indices, unsigned Alignment, + unsigned AddressSpace) const; /// \brief Calculate the cost of performing a vector reduction. /// @@ -475,16 +493,18 @@ public: /// Split: /// (v0, v1, v2, v3) /// ((v0+v2), (v1+v3), undef, undef) - unsigned getReductionCost(unsigned Opcode, Type *Ty, - bool IsPairwiseForm) const; + int getReductionCost(unsigned Opcode, Type *Ty, bool IsPairwiseForm) const; + + /// \returns The cost of Intrinsic instructions. Types analysis only. + int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef<Type *> Tys) const; - /// \returns The cost of Intrinsic instructions. - unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, - ArrayRef<Type *> Tys) const; + /// \returns The cost of Intrinsic instructions. Analyses the real arguments. + int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef<Value *> Args) const; /// \returns The cost of Call instructions. - unsigned getCallInstrCost(Function *F, Type *RetTy, - ArrayRef<Type *> Tys) const; + int getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) const; /// \returns The number of pieces into which the provided type must be /// split during legalization. Zero is returned when the answer is unknown. @@ -497,7 +517,7 @@ public: /// The 'IsComplex' parameter is a hint that the address computation is likely /// to involve multiple instructions and as such unlikely to be merged into /// the address indexing mode. - unsigned getAddressComputationCost(Type *Ty, bool IsComplex = false) const; + int getAddressComputationCost(Type *Ty, bool IsComplex = false) const; /// \returns The cost, if any, of keeping values of the given types alive /// over a callsite. @@ -521,8 +541,8 @@ public: /// \returns True if the two functions have compatible attributes for inlining /// purposes. - bool hasCompatibleFunctionAttributes(const Function *Caller, - const Function *Callee) const; + bool areInlineCompatible(const Function *Caller, + const Function *Callee) const; /// @} @@ -542,18 +562,18 @@ class TargetTransformInfo::Concept { public: virtual ~Concept() = 0; virtual const DataLayout &getDataLayout() const = 0; - virtual unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0; - virtual unsigned getGEPCost(const Value *Ptr, - ArrayRef<const Value *> Operands) = 0; - virtual unsigned getCallCost(FunctionType *FTy, int NumArgs) = 0; - virtual unsigned getCallCost(const Function *F, int NumArgs) = 0; - virtual unsigned getCallCost(const Function *F, + virtual int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0; + virtual int getGEPCost(Type *PointeeType, const Value *Ptr, + ArrayRef<const Value *> Operands) = 0; + virtual int getCallCost(FunctionType *FTy, int NumArgs) = 0; + virtual int getCallCost(const Function *F, int NumArgs) = 0; + virtual int getCallCost(const Function *F, + ArrayRef<const Value *> Arguments) = 0; + virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<Type *> ParamTys) = 0; + virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) = 0; - virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef<Type *> ParamTys) = 0; - virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef<const Value *> Arguments) = 0; - virtual unsigned getUserCost(const User *U) = 0; + virtual int getUserCost(const User *U) = 0; virtual bool hasBranchDivergence() = 0; virtual bool isSourceOfDivergence(const Value *V) = 0; virtual bool isLoweredToCall(const Function *F) = 0; @@ -564,8 +584,10 @@ public: int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) = 0; - virtual bool isLegalMaskedStore(Type *DataType, int Consecutive) = 0; - virtual bool isLegalMaskedLoad(Type *DataType, int Consecutive) = 0; + virtual bool isLegalMaskedStore(Type *DataType) = 0; + virtual bool isLegalMaskedLoad(Type *DataType) = 0; + virtual bool isLegalMaskedScatter(Type *DataType) = 0; + virtual bool isLegalMaskedGather(Type *DataType) = 0; virtual int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) = 0; @@ -576,14 +598,15 @@ public: virtual unsigned getJumpBufSize() = 0; virtual bool shouldBuildLookupTables() = 0; virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0; + virtual bool enableInterleavedAccessVectorization() = 0; virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) = 0; virtual bool haveFastSqrt(Type *Ty) = 0; - virtual unsigned getFPOpCost(Type *Ty) = 0; - virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) = 0; - virtual unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm, - Type *Ty) = 0; - virtual unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx, - const APInt &Imm, Type *Ty) = 0; + virtual int getFPOpCost(Type *Ty) = 0; + virtual int getIntImmCost(const APInt &Imm, Type *Ty) = 0; + virtual int getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm, + Type *Ty) = 0; + virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, + Type *Ty) = 0; virtual unsigned getNumberOfRegisters(bool Vector) = 0; virtual unsigned getRegisterBitWidth(bool Vector) = 0; virtual unsigned getMaxInterleaveFactor(unsigned VF) = 0; @@ -592,40 +615,44 @@ public: OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo, OperandValueProperties Opd2PropInfo) = 0; - virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index, - Type *SubTp) = 0; - virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) = 0; - virtual unsigned getCFInstrCost(unsigned Opcode) = 0; - virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy) = 0; - virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index) = 0; - virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, - unsigned Alignment, - unsigned AddressSpace) = 0; - virtual unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, + virtual int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index, + Type *SubTp) = 0; + virtual int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) = 0; + virtual int getCFInstrCost(unsigned Opcode) = 0; + virtual int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy) = 0; + virtual int getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index) = 0; + virtual int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace) = 0; + virtual int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) = 0; + virtual int getGatherScatterOpCost(unsigned Opcode, Type *DataTy, + Value *Ptr, bool VariableMask, + unsigned Alignment) = 0; + virtual int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, + unsigned Factor, + ArrayRef<unsigned> Indices, unsigned Alignment, unsigned AddressSpace) = 0; - virtual unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, - unsigned Factor, - ArrayRef<unsigned> Indices, - unsigned Alignment, - unsigned AddressSpace) = 0; - virtual unsigned getReductionCost(unsigned Opcode, Type *Ty, - bool IsPairwiseForm) = 0; - virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, - ArrayRef<Type *> Tys) = 0; - virtual unsigned getCallInstrCost(Function *F, Type *RetTy, + virtual int getReductionCost(unsigned Opcode, Type *Ty, + bool IsPairwiseForm) = 0; + virtual int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef<Type *> Tys) = 0; + virtual int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef<Value *> Args) = 0; + virtual int getCallInstrCost(Function *F, Type *RetTy, + ArrayRef<Type *> Tys) = 0; virtual unsigned getNumberOfParts(Type *Tp) = 0; - virtual unsigned getAddressComputationCost(Type *Ty, bool IsComplex) = 0; + virtual int getAddressComputationCost(Type *Ty, bool IsComplex) = 0; virtual unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) = 0; virtual bool getTgtMemIntrinsic(IntrinsicInst *Inst, MemIntrinsicInfo &Info) = 0; virtual Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst, Type *ExpectedType) = 0; - virtual bool hasCompatibleFunctionAttributes(const Function *Caller, - const Function *Callee) const = 0; + virtual bool areInlineCompatible(const Function *Caller, + const Function *Callee) const = 0; }; template <typename T> @@ -640,32 +667,32 @@ public: return Impl.getDataLayout(); } - unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override { + int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override { return Impl.getOperationCost(Opcode, Ty, OpTy); } - unsigned getGEPCost(const Value *Ptr, - ArrayRef<const Value *> Operands) override { - return Impl.getGEPCost(Ptr, Operands); + int getGEPCost(Type *PointeeType, const Value *Ptr, + ArrayRef<const Value *> Operands) override { + return Impl.getGEPCost(PointeeType, Ptr, Operands); } - unsigned getCallCost(FunctionType *FTy, int NumArgs) override { + int getCallCost(FunctionType *FTy, int NumArgs) override { return Impl.getCallCost(FTy, NumArgs); } - unsigned getCallCost(const Function *F, int NumArgs) override { + int getCallCost(const Function *F, int NumArgs) override { return Impl.getCallCost(F, NumArgs); } - unsigned getCallCost(const Function *F, - ArrayRef<const Value *> Arguments) override { + int getCallCost(const Function *F, + ArrayRef<const Value *> Arguments) override { return Impl.getCallCost(F, Arguments); } - unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef<Type *> ParamTys) override { + int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<Type *> ParamTys) override { return Impl.getIntrinsicCost(IID, RetTy, ParamTys); } - unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef<const Value *> Arguments) override { + int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef<const Value *> Arguments) override { return Impl.getIntrinsicCost(IID, RetTy, Arguments); } - unsigned getUserCost(const User *U) override { return Impl.getUserCost(U); } + int getUserCost(const User *U) override { return Impl.getUserCost(U); } bool hasBranchDivergence() override { return Impl.hasBranchDivergence(); } bool isSourceOfDivergence(const Value *V) override { return Impl.isSourceOfDivergence(V); @@ -688,11 +715,17 @@ public: return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale, AddrSpace); } - bool isLegalMaskedStore(Type *DataType, int Consecutive) override { - return Impl.isLegalMaskedStore(DataType, Consecutive); + bool isLegalMaskedStore(Type *DataType) override { + return Impl.isLegalMaskedStore(DataType); + } + bool isLegalMaskedLoad(Type *DataType) override { + return Impl.isLegalMaskedLoad(DataType); + } + bool isLegalMaskedScatter(Type *DataType) override { + return Impl.isLegalMaskedScatter(DataType); } - bool isLegalMaskedLoad(Type *DataType, int Consecutive) override { - return Impl.isLegalMaskedLoad(DataType, Consecutive); + bool isLegalMaskedGather(Type *DataType) override { + return Impl.isLegalMaskedGather(DataType); } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, @@ -715,24 +748,25 @@ public: bool enableAggressiveInterleaving(bool LoopHasReductions) override { return Impl.enableAggressiveInterleaving(LoopHasReductions); } + bool enableInterleavedAccessVectorization() override { + return Impl.enableInterleavedAccessVectorization(); + } PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) override { return Impl.getPopcntSupport(IntTyWidthInBit); } bool haveFastSqrt(Type *Ty) override { return Impl.haveFastSqrt(Ty); } - unsigned getFPOpCost(Type *Ty) override { - return Impl.getFPOpCost(Ty); - } + int getFPOpCost(Type *Ty) override { return Impl.getFPOpCost(Ty); } - unsigned getIntImmCost(const APInt &Imm, Type *Ty) override { + int getIntImmCost(const APInt &Imm, Type *Ty) override { return Impl.getIntImmCost(Imm, Ty); } - unsigned getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm, - Type *Ty) override { + int getIntImmCost(unsigned Opc, unsigned Idx, const APInt &Imm, + Type *Ty) override { return Impl.getIntImmCost(Opc, Idx, Imm, Ty); } - unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, - Type *Ty) override { + int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, + Type *Ty) override { return Impl.getIntImmCost(IID, Idx, Imm, Ty); } unsigned getNumberOfRegisters(bool Vector) override { @@ -752,56 +786,62 @@ public: return Impl.getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info, Opd1PropInfo, Opd2PropInfo); } - unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index, - Type *SubTp) override { + int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index, + Type *SubTp) override { return Impl.getShuffleCost(Kind, Tp, Index, SubTp); } - unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) override { + int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src) override { return Impl.getCastInstrCost(Opcode, Dst, Src); } - unsigned getCFInstrCost(unsigned Opcode) override { + int getCFInstrCost(unsigned Opcode) override { return Impl.getCFInstrCost(Opcode); } - unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy) override { + int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy) override { return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy); } - unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index) override { + int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) override { return Impl.getVectorInstrCost(Opcode, Val, Index); } - unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, - unsigned AddressSpace) override { + int getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace) override { return Impl.getMemoryOpCost(Opcode, Src, Alignment, AddressSpace); } - unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, - unsigned AddressSpace) override { + int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace) override { return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace); } - unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, - unsigned Factor, - ArrayRef<unsigned> Indices, - unsigned Alignment, - unsigned AddressSpace) override { + int getGatherScatterOpCost(unsigned Opcode, Type *DataTy, + Value *Ptr, bool VariableMask, + unsigned Alignment) override { + return Impl.getGatherScatterOpCost(Opcode, DataTy, Ptr, VariableMask, + Alignment); + } + int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, + ArrayRef<unsigned> Indices, unsigned Alignment, + unsigned AddressSpace) override { return Impl.getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices, Alignment, AddressSpace); } - unsigned getReductionCost(unsigned Opcode, Type *Ty, - bool IsPairwiseForm) override { + int getReductionCost(unsigned Opcode, Type *Ty, + bool IsPairwiseForm) override { return Impl.getReductionCost(Opcode, Ty, IsPairwiseForm); } - unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, - ArrayRef<Type *> Tys) override { + int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef<Type *> Tys) override { return Impl.getIntrinsicInstrCost(ID, RetTy, Tys); } - unsigned getCallInstrCost(Function *F, Type *RetTy, - ArrayRef<Type *> Tys) override { + int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef<Value *> Args) override { + return Impl.getIntrinsicInstrCost(ID, RetTy, Args); + } + int getCallInstrCost(Function *F, Type *RetTy, + ArrayRef<Type *> Tys) override { return Impl.getCallInstrCost(F, RetTy, Tys); } unsigned getNumberOfParts(Type *Tp) override { return Impl.getNumberOfParts(Tp); } - unsigned getAddressComputationCost(Type *Ty, bool IsComplex) override { + int getAddressComputationCost(Type *Ty, bool IsComplex) override { return Impl.getAddressComputationCost(Ty, IsComplex); } unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) override { @@ -815,9 +855,9 @@ public: Type *ExpectedType) override { return Impl.getOrCreateResultFromMemIntrinsic(Inst, ExpectedType); } - bool hasCompatibleFunctionAttributes(const Function *Caller, - const Function *Callee) const override { - return Impl.hasCompatibleFunctionAttributes(Caller, Callee); + bool areInlineCompatible(const Function *Caller, + const Function *Callee) const override { + return Impl.areInlineCompatible(Caller, Callee); } }; @@ -856,7 +896,7 @@ public: /// /// The callback will be called with a particular function for which the TTI /// is needed and must return a TTI object for that function. - TargetIRAnalysis(std::function<Result(Function &)> TTICallback); + TargetIRAnalysis(std::function<Result(const Function &)> TTICallback); // Value semantics. We spell out the constructors for MSVC. TargetIRAnalysis(const TargetIRAnalysis &Arg) @@ -872,7 +912,7 @@ public: return *this; } - Result run(Function &F); + Result run(const Function &F); private: static char PassID; @@ -887,10 +927,10 @@ private: /// the analysis and thus use a function_ref which would be lighter weight. /// This may also be less error prone as the callback is likely to reference /// the external TargetMachine, and that reference needs to never dangle. - std::function<Result(Function &)> TTICallback; + std::function<Result(const Function &)> TTICallback; /// \brief Helper function used as the callback in the default constructor. - static Result getDefaultTTI(Function &F); + static Result getDefaultTTI(const Function &F); }; /// \brief Wrapper pass for TargetTransformInfo. @@ -914,7 +954,7 @@ public: explicit TargetTransformInfoWrapperPass(TargetIRAnalysis TIRA); - TargetTransformInfo &getTTI(Function &F); + TargetTransformInfo &getTTI(const Function &F); }; /// \brief Create an analysis pass wrapper around a TTI object. diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 035cb04870a1c..43815234051e1 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -19,8 +19,10 @@ #include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" +#include "llvm/Analysis/VectorUtils.h" namespace llvm { @@ -60,6 +62,14 @@ public: // Otherwise, the default basic cost is used. return TTI::TCC_Basic; + case Instruction::FDiv: + case Instruction::FRem: + case Instruction::SDiv: + case Instruction::SRem: + case Instruction::UDiv: + case Instruction::URem: + return TTI::TCC_Expensive; + case Instruction::IntToPtr: { // An inttoptr cast is free so long as the input is a legal integer type // which doesn't contain values outside the range of a pointer. @@ -92,7 +102,8 @@ public: } } - unsigned getGEPCost(const Value *Ptr, ArrayRef<const Value *> Operands) { + unsigned getGEPCost(Type *PointeeType, const Value *Ptr, + ArrayRef<const Value *> Operands) { // In the basic model, we just assume that all-constant GEPs will be folded // into their uses via addressing modes. for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx) @@ -137,9 +148,6 @@ public: case Intrinsic::objectsize: case Intrinsic::ptr_annotation: case Intrinsic::var_annotation: - case Intrinsic::experimental_gc_result_int: - case Intrinsic::experimental_gc_result_float: - case Intrinsic::experimental_gc_result_ptr: case Intrinsic::experimental_gc_result: case Intrinsic::experimental_gc_relocate: // These intrinsics don't actually represent code after lowering. @@ -199,9 +207,13 @@ public: return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1); } - bool isLegalMaskedStore(Type *DataType, int Consecutive) { return false; } + bool isLegalMaskedStore(Type *DataType) { return false; } + + bool isLegalMaskedLoad(Type *DataType) { return false; } + + bool isLegalMaskedScatter(Type *DataType) { return false; } - bool isLegalMaskedLoad(Type *DataType, int Consecutive) { return false; } + bool isLegalMaskedGather(Type *DataType) { return false; } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, bool HasBaseReg, int64_t Scale, unsigned AddrSpace) { @@ -226,6 +238,8 @@ public: bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; } + bool enableInterleavedAccessVectorization() { return false; } + TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) { return TTI::PSK_Software; } @@ -287,6 +301,12 @@ public: return 1; } + unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy, Value *Ptr, + bool VariableMask, + unsigned Alignment) { + return 1; + } + unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices, @@ -299,6 +319,10 @@ public: ArrayRef<Type *> Tys) { return 1; } + unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef<Value *> Args) { + return 1; + } unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) { return 1; @@ -321,8 +345,8 @@ public: return nullptr; } - bool hasCompatibleFunctionAttributes(const Function *Caller, - const Function *Callee) const { + bool areInlineCompatible(const Function *Caller, + const Function *Callee) const { return (Caller->getFnAttribute("target-cpu") == Callee->getFnAttribute("target-cpu")) && (Caller->getFnAttribute("target-features") == @@ -378,6 +402,61 @@ public: return static_cast<T *>(this)->getCallCost(F, Arguments.size()); } + using BaseT::getGEPCost; + + unsigned getGEPCost(Type *PointeeType, const Value *Ptr, + ArrayRef<const Value *> Operands) { + const GlobalValue *BaseGV = nullptr; + if (Ptr != nullptr) { + // TODO: will remove this when pointers have an opaque type. + assert(Ptr->getType()->getScalarType()->getPointerElementType() == + PointeeType && + "explicit pointee type doesn't match operand's pointee type"); + BaseGV = dyn_cast<GlobalValue>(Ptr->stripPointerCasts()); + } + bool HasBaseReg = (BaseGV == nullptr); + int64_t BaseOffset = 0; + int64_t Scale = 0; + + // Assumes the address space is 0 when Ptr is nullptr. + unsigned AS = + (Ptr == nullptr ? 0 : Ptr->getType()->getPointerAddressSpace()); + auto GTI = gep_type_begin(PointerType::get(PointeeType, AS), Operands); + for (auto I = Operands.begin(); I != Operands.end(); ++I, ++GTI) { + // We assume that the cost of Scalar GEP with constant index and the + // cost of Vector GEP with splat constant index are the same. + const ConstantInt *ConstIdx = dyn_cast<ConstantInt>(*I); + if (!ConstIdx) + if (auto Splat = getSplatValue(*I)) + ConstIdx = dyn_cast<ConstantInt>(Splat); + if (isa<SequentialType>(*GTI)) { + int64_t ElementSize = DL.getTypeAllocSize(GTI.getIndexedType()); + if (ConstIdx) + BaseOffset += ConstIdx->getSExtValue() * ElementSize; + else { + // Needs scale register. + if (Scale != 0) + // No addressing mode takes two scale registers. + return TTI::TCC_Basic; + Scale = ElementSize; + } + } else { + StructType *STy = cast<StructType>(*GTI); + // For structures the index is always splat or scalar constant + assert(ConstIdx && "Unexpected GEP index"); + uint64_t Field = ConstIdx->getZExtValue(); + BaseOffset += DL.getStructLayout(STy)->getElementOffset(Field); + } + } + + if (static_cast<T *>(this)->isLegalAddressingMode( + PointerType::get(*GTI, AS), const_cast<GlobalValue *>(BaseGV), + BaseOffset, HasBaseReg, Scale, AS)) { + return TTI::TCC_Free; + } + return TTI::TCC_Basic; + } + using BaseT::getIntrinsicCost; unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, @@ -397,9 +476,9 @@ public: return TTI::TCC_Free; // Model all PHI nodes as free. if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) { - SmallVector<const Value *, 4> Indices(GEP->idx_begin(), GEP->idx_end()); - return static_cast<T *>(this) - ->getGEPCost(GEP->getPointerOperand(), Indices); + SmallVector<Value *, 4> Indices(GEP->idx_begin(), GEP->idx_end()); + return static_cast<T *>(this)->getGEPCost( + GEP->getSourceElementType(), GEP->getPointerOperand(), Indices); } if (auto CS = ImmutableCallSite(U)) { diff --git a/include/llvm/Analysis/TypeBasedAliasAnalysis.h b/include/llvm/Analysis/TypeBasedAliasAnalysis.h new file mode 100644 index 0000000000000..7b44ac73f1fac --- /dev/null +++ b/include/llvm/Analysis/TypeBasedAliasAnalysis.h @@ -0,0 +1,93 @@ +//===- TypeBasedAliasAnalysis.h - Type-Based Alias Analysis -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This is the interface for a metadata-based TBAA. See the source file for +/// details on the algorithm. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H +#define LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Metadata.h" +#include "llvm/Pass.h" + +namespace llvm { + +/// A simple AA result that uses TBAA metadata to answer queries. +class TypeBasedAAResult : public AAResultBase<TypeBasedAAResult> { + friend AAResultBase<TypeBasedAAResult>; + +public: + explicit TypeBasedAAResult(const TargetLibraryInfo &TLI) + : AAResultBase(TLI) {} + TypeBasedAAResult(TypeBasedAAResult &&Arg) : AAResultBase(std::move(Arg)) {} + + /// Handle invalidation events from the new pass manager. + /// + /// By definition, this result is stateless and so remains valid. + bool invalidate(Function &, const PreservedAnalyses &) { return false; } + + AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB); + bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal); + FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS); + FunctionModRefBehavior getModRefBehavior(const Function *F); + ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc); + ModRefInfo getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2); + +private: + bool Aliases(const MDNode *A, const MDNode *B) const; + bool PathAliases(const MDNode *A, const MDNode *B) const; +}; + +/// Analysis pass providing a never-invalidated alias analysis result. +class TypeBasedAA { +public: + typedef TypeBasedAAResult Result; + + /// \brief Opaque, unique identifier for this analysis pass. + static void *ID() { return (void *)&PassID; } + + TypeBasedAAResult run(Function &F, AnalysisManager<Function> *AM); + + /// \brief Provide access to a name for this pass for debugging purposes. + static StringRef name() { return "TypeBasedAA"; } + +private: + static char PassID; +}; + +/// Legacy wrapper pass to provide the TypeBasedAAResult object. +class TypeBasedAAWrapperPass : public ImmutablePass { + std::unique_ptr<TypeBasedAAResult> Result; + +public: + static char ID; + + TypeBasedAAWrapperPass(); + + TypeBasedAAResult &getResult() { return *Result; } + const TypeBasedAAResult &getResult() const { return *Result; } + + bool doInitialization(Module &M) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +//===--------------------------------------------------------------------===// +// +// createTypeBasedAAWrapperPass - This pass implements metadata-based +// type-based alias analysis. +// +ImmutablePass *createTypeBasedAAWrapperPass(); +} + +#endif diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 653821d022717..8e0291068472d 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -16,20 +16,23 @@ #define LLVM_ANALYSIS_VALUETRACKING_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Instruction.h" #include "llvm/Support/DataTypes.h" namespace llvm { - class Value; - class Instruction; class APInt; - class DataLayout; - class StringRef; - class MDNode; + class AddOperator; class AssumptionCache; + class DataLayout; class DominatorTree; - class TargetLibraryInfo; + class Instruction; + class Loop; class LoopInfo; + class MDNode; + class StringRef; + class TargetLibraryInfo; + class Value; /// Determine which bits of V are known to be either zero or one and return /// them in the KnownZero/KnownOne bit sets. @@ -46,9 +49,10 @@ namespace llvm { const DominatorTree *DT = nullptr); /// Compute known bits from the range metadata. /// \p KnownZero the set of bits that are known to be zero + /// \p KnownOne the set of bits that are known to be one void computeKnownBitsFromRangeMetadata(const MDNode &Ranges, - APInt &KnownZero); - /// Returns true if LHS and RHS have no common bits set. + APInt &KnownZero, APInt &KnownOne); + /// Return true if LHS and RHS have no common bits set. bool haveNoCommonBitsSet(Value *LHS, Value *RHS, const DataLayout &DL, AssumptionCache *AC = nullptr, const Instruction *CxtI = nullptr, @@ -66,7 +70,7 @@ namespace llvm { /// exactly one bit set when defined. For vectors return true if every /// element is known to be a power of two when defined. Supports values with /// integer or pointer type and vectors of integers. If 'OrZero' is set then - /// returns true if the given value is either a power of two or zero. + /// return true if the given value is either a power of two or zero. bool isKnownToBeAPowerOfTwo(Value *V, const DataLayout &DL, bool OrZero = false, unsigned Depth = 0, AssumptionCache *AC = nullptr, @@ -82,6 +86,19 @@ namespace llvm { const Instruction *CxtI = nullptr, const DominatorTree *DT = nullptr); + /// Returns true if the give value is known to be non-negative. + bool isKnownNonNegative(Value *V, const DataLayout &DL, unsigned Depth = 0, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, + const DominatorTree *DT = nullptr); + + /// isKnownNonEqual - Return true if the given values are known to be + /// non-equal when defined. Supports scalar integer types only. + bool isKnownNonEqual(Value *V1, Value *V2, const DataLayout &DL, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, + const DominatorTree *DT = nullptr); + /// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use /// this predicate to simplify operations downstream. Mask is known to be /// zero for bits that V cannot have. @@ -118,12 +135,12 @@ namespace llvm { bool LookThroughSExt = false, unsigned Depth = 0); - /// CannotBeNegativeZero - Return true if we can prove that the specified FP + /// CannotBeNegativeZero - Return true if we can prove that the specified FP /// value is never equal to -0.0. /// bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0); - /// CannotBeOrderedLessThanZero - Return true if we can prove that the + /// CannotBeOrderedLessThanZero - Return true if we can prove that the /// specified FP value is either a NaN or never less than 0.0. /// bool CannotBeOrderedLessThanZero(const Value *V, unsigned Depth = 0); @@ -134,7 +151,7 @@ namespace llvm { /// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated /// byte store (e.g. i16 0x1234), return null. Value *isBytewiseValue(Value *V); - + /// FindInsertedValue - Given an aggregrate and an sequence of indices, see if /// the scalar value indexed is already around as a register, for example if /// it were inserted directly into the aggregrate. @@ -156,7 +173,7 @@ namespace llvm { return GetPointerBaseWithConstantOffset(const_cast<Value *>(Ptr), Offset, DL); } - + /// getConstantStringInfo - This function computes the length of a /// null-terminated C string pointed to by V. If successful, it returns true /// and returns the string in Str. If unsuccessful, it returns false. This @@ -227,7 +244,17 @@ namespace llvm { const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr); - + + /// Returns true if V is always a dereferenceable pointer with alignment + /// greater or equal than requested. If the context instruction is specified + /// performs context-sensitive analysis and returns true if the pointer is + /// dereferenceable at the specified instruction. + bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, + const DataLayout &DL, + const Instruction *CtxI = nullptr, + const DominatorTree *DT = nullptr, + const TargetLibraryInfo *TLI = nullptr); + /// isSafeToSpeculativelyExecute - Return true if the instruction does not /// have any effects besides calculating the result and does not have /// undefined behavior. @@ -257,6 +284,16 @@ namespace llvm { const DominatorTree *DT = nullptr, const TargetLibraryInfo *TLI = nullptr); + /// Returns true if the result or effects of the given instructions \p I + /// depend on or influence global memory. + /// Memory dependence arises for example if the instruction reads from + /// memory or may produce effects or undefined behaviour. Memory dependent + /// instructions generally cannot be reorderd with respect to other memory + /// dependent instructions or moved into non-dominated basic blocks. + /// Instructions which just compute a value based on the values of their + /// operands are not memory dependent. + bool mayBeMemoryDependent(const Instruction &I); + /// isKnownNonNull - Return true if this pointer couldn't possibly be null by /// its definition. This returns true for allocas, non-extern-weak globals /// and byval arguments. @@ -288,16 +325,98 @@ namespace llvm { AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT); - + OverflowResult computeOverflowForSignedAdd(Value *LHS, Value *RHS, + const DataLayout &DL, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, + const DominatorTree *DT = nullptr); + /// This version also leverages the sign bit of Add if known. + OverflowResult computeOverflowForSignedAdd(AddOperator *Add, + const DataLayout &DL, + AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, + const DominatorTree *DT = nullptr); + + /// Return true if this function can prove that the instruction I will + /// always transfer execution to one of its successors (including the next + /// instruction that follows within a basic block). E.g. this is not + /// guaranteed for function calls that could loop infinitely. + /// + /// In other words, this function returns false for instructions that may + /// transfer execution or fail to transfer execution in a way that is not + /// captured in the CFG nor in the sequence of instructions within a basic + /// block. + /// + /// Undefined behavior is assumed not to happen, so e.g. division is + /// guaranteed to transfer execution to the following instruction even + /// though division by zero might cause undefined behavior. + bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I); + + /// Return true if this function can prove that the instruction I + /// is executed for every iteration of the loop L. + /// + /// Note that this currently only considers the loop header. + bool isGuaranteedToExecuteForEveryIteration(const Instruction *I, + const Loop *L); + + /// Return true if this function can prove that I is guaranteed to yield + /// full-poison (all bits poison) if at least one of its operands are + /// full-poison (all bits poison). + /// + /// The exact rules for how poison propagates through instructions have + /// not been settled as of 2015-07-10, so this function is conservative + /// and only considers poison to be propagated in uncontroversial + /// cases. There is no attempt to track values that may be only partially + /// poison. + bool propagatesFullPoison(const Instruction *I); + + /// Return either nullptr or an operand of I such that I will trigger + /// undefined behavior if I is executed and that operand has a full-poison + /// value (all bits poison). + const Value *getGuaranteedNonFullPoisonOp(const Instruction *I); + + /// Return true if this function can prove that if PoisonI is executed + /// and yields a full-poison value (all bits poison), then that will + /// trigger undefined behavior. + /// + /// Note that this currently only considers the basic block that is + /// the parent of I. + bool isKnownNotFullPoison(const Instruction *PoisonI); + /// \brief Specific patterns of select instructions we can match. enum SelectPatternFlavor { SPF_UNKNOWN = 0, - SPF_SMIN, // Signed minimum - SPF_UMIN, // Unsigned minimum - SPF_SMAX, // Signed maximum - SPF_UMAX, // Unsigned maximum - SPF_ABS, // Absolute value - SPF_NABS // Negated absolute value + SPF_SMIN, /// Signed minimum + SPF_UMIN, /// Unsigned minimum + SPF_SMAX, /// Signed maximum + SPF_UMAX, /// Unsigned maximum + SPF_FMINNUM, /// Floating point minnum + SPF_FMAXNUM, /// Floating point maxnum + SPF_ABS, /// Absolute value + SPF_NABS /// Negated absolute value + }; + /// \brief Behavior when a floating point min/max is given one NaN and one + /// non-NaN as input. + enum SelectPatternNaNBehavior { + SPNB_NA = 0, /// NaN behavior not applicable. + SPNB_RETURNS_NAN, /// Given one NaN input, returns the NaN. + SPNB_RETURNS_OTHER, /// Given one NaN input, returns the non-NaN. + SPNB_RETURNS_ANY /// Given one NaN input, can return either (or + /// it has been determined that no operands can + /// be NaN). + }; + struct SelectPatternResult { + SelectPatternFlavor Flavor; + SelectPatternNaNBehavior NaNBehavior; /// Only applicable if Flavor is + /// SPF_FMINNUM or SPF_FMAXNUM. + bool Ordered; /// When implementing this min/max pattern as + /// fcmp; select, does the fcmp have to be + /// ordered? + + /// \brief Return true if \p SPF is a min or a max pattern. + static bool isMinOrMax(SelectPatternFlavor SPF) { + return !(SPF == SPF_UNKNOWN || SPF == SPF_ABS || SPF == SPF_NABS); + } }; /// Pattern match integer [SU]MIN, [SU]MAX and ABS idioms, returning the kind /// and providing the out parameter results if we successfully match. @@ -314,9 +433,26 @@ namespace llvm { /// /// -> LHS = %a, RHS = i32 4, *CastOp = Instruction::SExt /// - SelectPatternFlavor matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, + SelectPatternResult matchSelectPattern(Value *V, Value *&LHS, Value *&RHS, Instruction::CastOps *CastOp = nullptr); + /// Parse out a conservative ConstantRange from !range metadata. + /// + /// E.g. if RangeMD is !{i32 0, i32 10, i32 15, i32 20} then return [0, 20). + ConstantRange getConstantRangeFromMetadata(MDNode &RangeMD); + + /// Return true if RHS is known to be implied by LHS. A & B must be i1 + /// (boolean) values or a vector of such values. Note that the truth table for + /// implication is the same as <=u on i1 values (but not <=s!). The truth + /// table for both is: + /// | T | F (B) + /// T | T | F + /// F | T | T + /// (A) + bool isImpliedCondition(Value *LHS, Value *RHS, const DataLayout &DL, + unsigned Depth = 0, AssumptionCache *AC = nullptr, + const Instruction *CxtI = nullptr, + const DominatorTree *DT = nullptr); } // end namespace llvm #endif diff --git a/include/llvm/Analysis/VectorUtils.h b/include/llvm/Analysis/VectorUtils.h index d8e9ca42e6232..531803adf5e48 100644 --- a/include/llvm/Analysis/VectorUtils.h +++ b/include/llvm/Analysis/VectorUtils.h @@ -14,15 +14,19 @@ #ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H #define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/MapVector.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" namespace llvm { +struct DemandedBits; class GetElementPtrInst; class Loop; class ScalarEvolution; +class TargetTransformInfo; class Type; class Value; @@ -62,8 +66,8 @@ Intrinsic::ID getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI); /// pointer. unsigned getGEPInductionOperand(const GetElementPtrInst *Gep); -/// \brief If the argument is a GEP, then returns the operand identified by -/// getGEPInductionOperand. However, if there is some other non-loop-invariant +/// \brief If the argument is a GEP, then returns the operand identified by +/// getGEPInductionOperand. However, if there is some other non-loop-invariant /// operand, it returns that instead. Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp); @@ -79,6 +83,50 @@ Value *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp); /// from the vector. Value *findScalarElement(Value *V, unsigned EltNo); +/// \brief Get splat value if the input is a splat vector or return nullptr. +/// The value may be extracted from a splat constants vector or from +/// a sequence of instructions that broadcast a single value into a vector. +const Value *getSplatValue(const Value *V); + +/// \brief Compute a map of integer instructions to their minimum legal type +/// size. +/// +/// C semantics force sub-int-sized values (e.g. i8, i16) to be promoted to int +/// type (e.g. i32) whenever arithmetic is performed on them. +/// +/// For targets with native i8 or i16 operations, usually InstCombine can shrink +/// the arithmetic type down again. However InstCombine refuses to create +/// illegal types, so for targets without i8 or i16 registers, the lengthening +/// and shrinking remains. +/// +/// Most SIMD ISAs (e.g. NEON) however support vectors of i8 or i16 even when +/// their scalar equivalents do not, so during vectorization it is important to +/// remove these lengthens and truncates when deciding the profitability of +/// vectorization. +/// +/// This function analyzes the given range of instructions and determines the +/// minimum type size each can be converted to. It attempts to remove or +/// minimize type size changes across each def-use chain, so for example in the +/// following code: +/// +/// %1 = load i8, i8* +/// %2 = add i8 %1, 2 +/// %3 = load i16, i16* +/// %4 = zext i8 %2 to i32 +/// %5 = zext i16 %3 to i32 +/// %6 = add i32 %4, %5 +/// %7 = trunc i32 %6 to i16 +/// +/// Instruction %6 must be done at least in i16, so computeMinimumValueSizes +/// will return: {%1: 16, %2: 16, %3: 16, %4: 16, %5: 16, %6: 16, %7: 16}. +/// +/// If the optional TargetTransformInfo is provided, this function tries harder +/// to do less work by only looking at illegal types. +MapVector<Instruction*, uint64_t> +computeMinimumValueSizes(ArrayRef<BasicBlock*> Blocks, + DemandedBits &DB, + const TargetTransformInfo *TTI=nullptr); + } // llvm namespace #endif |
