//===- llvm/Analysis/AliasAnalysis.h - Alias Analysis Interface -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the generic AliasAnalysis interface, which is used as the // common interface used by all clients of alias analysis information, and // implemented by all alias analysis implementations. Mod/Ref information is // also captured by this interface. // // Implementations of this interface must implement the various virtual methods, // which automatically provides functionality for the entire suite of client // APIs. // // This API identifies memory regions with the MemoryLocation class. The pointer // component specifies the base memory address of the region. The Size specifies // the maximum size (in address units) of the memory region, or // MemoryLocation::UnknownSize if the size is not known. The TBAA tag // identifies the "type" of the memory reference; see the // TypeBasedAliasAnalysis class for details. // // Some non-obvious details include: // - Pointers that point to two completely different objects in memory never // alias, regardless of the value of the Size component. // - NoAlias doesn't imply inequal pointers. The most obvious example of this // is two pointers to constant memory. Even if they are equal, constant // memory is never stored to, so there will never be any dependencies. // In this and other situations, the pointers may be both NoAlias and // MustAlias at the same time. The current API can only return one result, // though this is rarely a problem in practice. // //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_ALIASANALYSIS_H #define LLVM_ANALYSIS_ALIASANALYSIS_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/IR/Function.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" #include "llvm/Support/ModRef.h" #include <cstdint> #include <functional> #include <memory> #include <optional> #include <vector> namespace llvm { class AtomicCmpXchgInst; class BasicBlock; class CatchPadInst; class CatchReturnInst; class DominatorTree; class FenceInst; class LoopInfo; class TargetLibraryInfo; /// The possible results of an alias query. /// /// These results are always computed between two MemoryLocation objects as /// a query to some alias analysis. /// /// Note that these are unscoped enumerations because we would like to support /// implicitly testing a result for the existence of any possible aliasing with /// a conversion to bool, but an "enum class" doesn't support this. The /// canonical names from the literature are suffixed and unique anyways, and so /// they serve as global constants in LLVM for these results. /// /// See docs/AliasAnalysis.html for more information on the specific meanings /// of these values. class AliasResult { … }; static_assert …; /// << operator for AliasResult. raw_ostream &operator<<(raw_ostream &OS, AliasResult AR); /// Virtual base class for providers of capture information. struct CaptureInfo { … }; /// Context-free CaptureInfo provider, which computes and caches whether an /// object is captured in the function at all, but does not distinguish whether /// it was captured before or after the context instruction. class SimpleCaptureInfo final : public CaptureInfo { … }; /// Context-sensitive CaptureInfo provider, which computes and caches the /// earliest common dominator closure of all captures. It provides a good /// approximation to a precise "captures before" analysis. class EarliestEscapeInfo final : public CaptureInfo { … }; /// Cache key for BasicAA results. It only includes the pointer and size from /// MemoryLocation, as BasicAA is AATags independent. Additionally, it includes /// the value of MayBeCrossIteration, which may affect BasicAA results. struct AACacheLoc { … }; template <> struct DenseMapInfo<AACacheLoc> { … }; class AAResults; /// This class stores info we want to provide to or retain within an alias /// query. By default, the root query is stateless and starts with a freshly /// constructed info object. Specific alias analyses can use this query info to /// store per-query state that is important for recursive or nested queries to /// avoid recomputing. To enable preserving this state across multiple queries /// where safe (due to the IR not changing), use a `BatchAAResults` wrapper. /// The information stored in an `AAQueryInfo` is currently limitted to the /// caches used by BasicAA, but can further be extended to fit other AA needs. class AAQueryInfo { … }; /// AAQueryInfo that uses SimpleCaptureInfo. class SimpleAAQueryInfo : public AAQueryInfo { … }; class BatchAAResults; class AAResults { … }; /// This class is a wrapper over an AAResults, and it is intended to be used /// only when there are no IR changes inbetween queries. BatchAAResults is /// reusing the same `AAQueryInfo` to preserve the state across queries, /// esentially making AA work in "batch mode". The internal state cannot be /// cleared, so to go "out-of-batch-mode", the user must either use AAResults, /// or create a new BatchAAResults. class BatchAAResults { … }; /// Temporary typedef for legacy code that uses a generic \c AliasAnalysis /// pointer or reference. 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 { … }; /// 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 { … }; /// A 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 class, and then /// override specific methods that they wish to customize. There is no need to /// use virtual anywhere. class AAResultBase { … }; /// Return true if this pointer is returned by a noalias function. bool isNoAliasCall(const Value *V); /// Return true if this pointer refers to a distinct and identifiable object. /// This returns true for: /// Global Variables and Functions (but not Global Aliases) /// Allocas /// ByVal and NoAlias Arguments /// NoAlias returns (e.g. calls to malloc) /// bool isIdentifiedObject(const Value *V); /// Return true if V is umabigously identified at the function-level. /// Different IdentifiedFunctionLocals can't alias. /// Further, an IdentifiedFunctionLocal can not alias with any function /// arguments other than itself, which is not necessarily true for /// IdentifiedObjects. bool isIdentifiedFunctionLocal(const Value *V); /// Returns true if the pointer is one which would have been considered an /// escape by isNonEscapingLocalObject. bool isEscapeSource(const Value *V); /// Return true if Object memory is not visible after an unwind, in the sense /// that program semantics cannot depend on Object containing any particular /// value on unwind. If the RequiresNoCaptureBeforeUnwind out parameter is set /// to true, then the memory is only not visible if the object has not been /// captured prior to the unwind. Otherwise it is not visible even if captured. bool isNotVisibleOnUnwind(const Value *Object, bool &RequiresNoCaptureBeforeUnwind); /// Return true if the Object is writable, in the sense that any location based /// on this pointer that can be loaded can also be stored to without trapping. /// Additionally, at the point Object is declared, stores can be introduced /// without data races. At later points, this is only the case if the pointer /// can not escape to a different thread. /// /// If ExplicitlyDereferenceableOnly is set to true, this property only holds /// for the part of Object that is explicitly marked as dereferenceable, e.g. /// using the dereferenceable(N) attribute. It does not necessarily hold for /// parts that are only known to be dereferenceable due to the presence of /// loads. bool isWritableObject(const Value *Object, bool &ExplicitlyDereferenceableOnly); /// 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. /// /// The result of this analysis is only invalidated if one of the particular /// aggregated AA results end up being invalidated. This removes the need to /// explicitly preserve the results of `AAManager`. Note that analyses should no /// longer be registered once the `AAManager` is run. class AAManager : public AnalysisInfoMixin<AAManager> { … }; /// A wrapper pass to provide the legacy pass manager access to a suitably /// prepared AAResults object. class AAResultsWrapperPass : public FunctionPass { … }; /// A wrapper pass for external alias analyses. This just squirrels away the /// callback used to run any analyses and register their results. struct ExternalAAWrapperPass : ImmutablePass { … }; /// 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); } // end namespace llvm #endif // LLVM_ANALYSIS_ALIASANALYSIS_H