summaryrefslogtreecommitdiff
path: root/include/llvm/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Analysis')
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h1053
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h15
-rw-r--r--include/llvm/Analysis/AssumptionCache.h6
-rw-r--r--include/llvm/Analysis/BasicAliasAnalysis.h223
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfo.h42
-rw-r--r--include/llvm/Analysis/BlockFrequencyInfoImpl.h88
-rw-r--r--include/llvm/Analysis/BranchProbabilityInfo.h91
-rw-r--r--include/llvm/Analysis/CFG.h2
-rw-r--r--include/llvm/Analysis/CFLAliasAnalysis.h158
-rw-r--r--include/llvm/Analysis/CGSCCPassManager.h2
-rw-r--r--include/llvm/Analysis/CallGraph.h33
-rw-r--r--include/llvm/Analysis/CallGraphSCCPass.h17
-rw-r--r--include/llvm/Analysis/CaptureTracking.h7
-rw-r--r--include/llvm/Analysis/DOTGraphTraitsPass.h34
-rw-r--r--include/llvm/Analysis/DemandedBits.h75
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h61
-rw-r--r--include/llvm/Analysis/DivergenceAnalysis.h48
-rw-r--r--include/llvm/Analysis/EHPersonalities.h94
-rw-r--r--include/llvm/Analysis/GlobalsModRef.h160
-rw-r--r--include/llvm/Analysis/IVUsers.h2
-rw-r--r--include/llvm/Analysis/InlineCost.h63
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h2
-rw-r--r--include/llvm/Analysis/IteratedDominanceFrontier.h6
-rw-r--r--include/llvm/Analysis/LazyCallGraph.h113
-rw-r--r--include/llvm/Analysis/LazyValueInfo.h17
-rw-r--r--include/llvm/Analysis/LibCallAliasAnalysis.h71
-rw-r--r--include/llvm/Analysis/LibCallSemantics.h225
-rw-r--r--include/llvm/Analysis/Loads.h13
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h224
-rw-r--r--include/llvm/Analysis/LoopInfo.h111
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h8
-rw-r--r--include/llvm/Analysis/LoopPass.h19
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h5
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h39
-rw-r--r--include/llvm/Analysis/ObjCARCAliasAnalysis.h102
-rw-r--r--include/llvm/Analysis/ObjCARCAnalysisUtils.h287
-rw-r--r--include/llvm/Analysis/ObjCARCInstKind.h123
-rw-r--r--include/llvm/Analysis/OrderedBasicBlock.h66
-rw-r--r--include/llvm/Analysis/PHITransAddr.h23
-rw-r--r--include/llvm/Analysis/Passes.h74
-rw-r--r--include/llvm/Analysis/RegionInfo.h57
-rw-r--r--include/llvm/Analysis/RegionInfoImpl.h68
-rw-r--r--include/llvm/Analysis/RegionPrinter.h45
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h1005
-rw-r--r--include/llvm/Analysis/ScalarEvolutionAliasAnalysis.h79
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h36
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h149
-rw-r--r--include/llvm/Analysis/ScopedNoAliasAA.h92
-rw-r--r--include/llvm/Analysis/SparsePropagation.h93
-rw-r--r--include/llvm/Analysis/TargetLibraryInfo.def90
-rw-r--r--include/llvm/Analysis/TargetLibraryInfo.h8
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h362
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h101
-rw-r--r--include/llvm/Analysis/TypeBasedAliasAnalysis.h93
-rw-r--r--include/llvm/Analysis/ValueTracking.h180
-rw-r--r--include/llvm/Analysis/VectorUtils.h52
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 &Map;
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 &Map;
};
/// 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