aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h')
-rw-r--r--contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h321
1 files changed, 321 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h b/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h
new file mode 100644
index 0000000000..7557bd687b
--- /dev/null
+++ b/contrib/libs/llvm12/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -0,0 +1,321 @@
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- BasicAliasAnalysis.h - Stateless, local Alias Analysis ---*- 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
+//
+//===----------------------------------------------------------------------===//
+/// \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/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <utility>
+
+namespace llvm {
+
+struct AAMDNodes;
+class APInt;
+class AssumptionCache;
+class BasicBlock;
+class DataLayout;
+class DominatorTree;
+class Function;
+class GEPOperator;
+class LoopInfo;
+class PHINode;
+class SelectInst;
+class TargetLibraryInfo;
+class PhiValues;
+class Value;
+
+/// 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 due to IR changes.
+/// While it does retain some storage, that is used as an optimization and not
+/// to preserve information from query to query. However it does retain handles
+/// to various other analyses and must be recomputed when those analyses are.
+class BasicAAResult : public AAResultBase<BasicAAResult> {
+ friend AAResultBase<BasicAAResult>;
+
+ const DataLayout &DL;
+ const Function &F;
+ const TargetLibraryInfo &TLI;
+ AssumptionCache &AC;
+ DominatorTree *DT;
+ LoopInfo *LI;
+ PhiValues *PV;
+
+public:
+ BasicAAResult(const DataLayout &DL, const Function &F,
+ const TargetLibraryInfo &TLI, AssumptionCache &AC,
+ DominatorTree *DT = nullptr, LoopInfo *LI = nullptr,
+ PhiValues *PV = nullptr)
+ : AAResultBase(), DL(DL), F(F), TLI(TLI), AC(AC), DT(DT), LI(LI), PV(PV)
+ {}
+
+ BasicAAResult(const BasicAAResult &Arg)
+ : AAResultBase(Arg), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI), AC(Arg.AC),
+ DT(Arg.DT), LI(Arg.LI), PV(Arg.PV) {}
+ BasicAAResult(BasicAAResult &&Arg)
+ : AAResultBase(std::move(Arg)), DL(Arg.DL), F(Arg.F), TLI(Arg.TLI),
+ AC(Arg.AC), DT(Arg.DT), LI(Arg.LI), PV(Arg.PV) {}
+
+ /// Handle invalidation events in the new pass manager.
+ bool invalidate(Function &Fn, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv);
+
+ AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
+ AAQueryInfo &AAQI);
+
+ ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
+ AAQueryInfo &AAQI);
+
+ ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
+ AAQueryInfo &AAQI);
+
+ /// Chases pointers until we find a (constant global) or not.
+ bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
+ bool OrLocal);
+
+ /// Get the location associated with a pointer argument of a callsite.
+ ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
+
+ /// Returns the behavior when calling the given call site.
+ FunctionModRefBehavior getModRefBehavior(const CallBase *Call);
+
+ /// Returns the behavior when calling the given function. For use when the
+ /// call site is not known.
+ FunctionModRefBehavior getModRefBehavior(const Function *Fn);
+
+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;
+
+ APInt Scale;
+
+ // Context instruction to use when querying information about this index.
+ const Instruction *CxtI;
+
+ 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);
+ }
+
+ void dump() const {
+ print(dbgs());
+ dbgs() << "\n";
+ }
+ void print(raw_ostream &OS) const {
+ OS << "(V=" << V->getName()
+ << ", zextbits=" << ZExtBits
+ << ", sextbits=" << SExtBits
+ << ", scale=" << Scale << ")";
+ }
+ };
+
+ // Represents the internal structure of a GEP, decomposed into a base pointer,
+ // constant offsets, and variable scaled indices.
+ struct DecomposedGEP {
+ // Base pointer of the GEP
+ const Value *Base;
+ // Total constant offset from base.
+ APInt Offset;
+ // Scaled variable (non-constant) indices.
+ SmallVector<VariableGEPIndex, 4> VarIndices;
+ // Is GEP index scale compile-time constant.
+ bool HasCompileTimeConstantScale;
+
+ void dump() const {
+ print(dbgs());
+ dbgs() << "\n";
+ }
+ void print(raw_ostream &OS) const {
+ OS << "(DecomposedGEP Base=" << Base->getName()
+ << ", Offset=" << Offset
+ << ", VarIndices=[";
+ for (size_t i = 0; i < VarIndices.size(); i++) {
+ if (i != 0)
+ OS << ", ";
+ VarIndices[i].print(OS);
+ }
+ OS << "], HasCompileTimeConstantScale=" << HasCompileTimeConstantScale
+ << ")";
+ }
+ };
+
+ /// 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 DecomposedGEP
+ DecomposeGEPExpression(const Value *V, const DataLayout &DL,
+ AssumptionCache *AC, DominatorTree *DT);
+
+ static bool isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
+ const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
+ LocationSize ObjectAccessSize);
+
+ /// 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,
+ LocationSize V1Size, LocationSize V2Size,
+ const APInt &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, LocationSize V1Size,
+ const AAMDNodes &V1AAInfo, const Value *V2,
+ LocationSize V2Size, const AAMDNodes &V2AAInfo,
+ const Value *UnderlyingV1, const Value *UnderlyingV2,
+ AAQueryInfo &AAQI);
+
+ AliasResult aliasPHI(const PHINode *PN, LocationSize PNSize,
+ const AAMDNodes &PNAAInfo, const Value *V2,
+ LocationSize V2Size, const AAMDNodes &V2AAInfo,
+ AAQueryInfo &AAQI);
+
+ AliasResult aliasSelect(const SelectInst *SI, LocationSize SISize,
+ const AAMDNodes &SIAAInfo, const Value *V2,
+ LocationSize V2Size, const AAMDNodes &V2AAInfo,
+ AAQueryInfo &AAQI);
+
+ AliasResult aliasCheck(const Value *V1, LocationSize V1Size,
+ const AAMDNodes &V1AATag, const Value *V2,
+ LocationSize V2Size, const AAMDNodes &V2AATag,
+ AAQueryInfo &AAQI);
+
+ AliasResult aliasCheckRecursive(const Value *V1, LocationSize V1Size,
+ const AAMDNodes &V1AATag, const Value *V2,
+ LocationSize V2Size, const AAMDNodes &V2AATag,
+ AAQueryInfo &AAQI, const Value *O1,
+ const Value *O2);
+};
+
+/// Analysis pass providing a never-invalidated alias analysis result.
+class BasicAA : public AnalysisInfoMixin<BasicAA> {
+ friend AnalysisInfoMixin<BasicAA>;
+
+ static AnalysisKey Key;
+
+public:
+ using Result = BasicAAResult;
+
+ BasicAAResult run(Function &F, FunctionAnalysisManager &AM);
+};
+
+/// 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);
+
+/// This class is a functor to be used in legacy module or SCC passes for
+/// computing AA results for a function. We store the results in fields so that
+/// they live long enough to be queried, but we re-use them each time.
+class LegacyAARGetter {
+ Pass &P;
+ Optional<BasicAAResult> BAR;
+ Optional<AAResults> AAR;
+
+public:
+ LegacyAARGetter(Pass &P) : P(P) {}
+ AAResults &operator()(Function &F) {
+ BAR.emplace(createLegacyPMBasicAAResult(P, F));
+ AAR.emplace(createLegacyPMAAResults(P, F, *BAR));
+ return *AAR;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_BASICALIASANALYSIS_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif