#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/SaveAndRestore.h"
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <optional>
#include <utility>
#define DEBUG_TYPE …
usingnamespacellvm;
static cl::opt<bool> EnableRecPhiAnalysis("basic-aa-recphi", cl::Hidden,
cl::init(true));
static cl::opt<bool> EnableSeparateStorageAnalysis("basic-aa-separate-storage",
cl::Hidden, cl::init(true));
STATISTIC(SearchLimitReached, "Number of times the limit to "
"decompose GEPs is reached");
STATISTIC(SearchTimes, "Number of times a GEP is decomposed");
static const unsigned MaxLookupSearchDepth = …;
bool BasicAAResult::invalidate(Function &Fn, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv) { … }
static std::optional<TypeSize> getObjectSize(const Value *V,
const DataLayout &DL,
const TargetLibraryInfo &TLI,
bool NullIsValidLoc,
bool RoundToAlign = false) { … }
static bool isObjectSmallerThan(const Value *V, TypeSize Size,
const DataLayout &DL,
const TargetLibraryInfo &TLI,
bool NullIsValidLoc) { … }
static TypeSize getMinimalExtentFrom(const Value &V,
const LocationSize &LocSize,
const DataLayout &DL,
bool NullIsValidLoc) { … }
static bool isObjectSize(const Value *V, TypeSize Size, const DataLayout &DL,
const TargetLibraryInfo &TLI, bool NullIsValidLoc) { … }
static bool areBothVScale(const Value *V1, const Value *V2) { … }
CaptureInfo::~CaptureInfo() = default;
bool SimpleCaptureInfo::isNotCapturedBefore(const Value *Object,
const Instruction *I, bool OrAt) { … }
static bool isNotInCycle(const Instruction *I, const DominatorTree *DT,
const LoopInfo *LI) { … }
bool EarliestEscapeInfo::isNotCapturedBefore(const Value *Object,
const Instruction *I, bool OrAt) { … }
void EarliestEscapeInfo::removeInstruction(Instruction *I) { … }
namespace {
struct CastedValue { … };
struct LinearExpression { … };
}
static LinearExpression GetLinearExpression(
const CastedValue &Val, const DataLayout &DL, unsigned Depth,
AssumptionCache *AC, DominatorTree *DT) { … }
static void adjustToIndexSize(APInt &Offset, unsigned IndexSize) { … }
namespace {
struct VariableGEPIndex { … };
}
struct BasicAAResult::DecomposedGEP { … };
BasicAAResult::DecomposedGEP
BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
AssumptionCache *AC, DominatorTree *DT) { … }
ModRefInfo BasicAAResult::getModRefInfoMask(const MemoryLocation &Loc,
AAQueryInfo &AAQI,
bool IgnoreLocals) { … }
static bool isIntrinsicCall(const CallBase *Call, Intrinsic::ID IID) { … }
MemoryEffects BasicAAResult::getMemoryEffects(const CallBase *Call,
AAQueryInfo &AAQI) { … }
MemoryEffects BasicAAResult::getMemoryEffects(const Function *F) { … }
ModRefInfo BasicAAResult::getArgModRefInfo(const CallBase *Call,
unsigned ArgIdx) { … }
#ifndef NDEBUG
static const Function *getParent(const Value *V) {
if (const Instruction *inst = dyn_cast<Instruction>(V)) {
if (!inst->getParent())
return nullptr;
return inst->getParent()->getParent();
}
if (const Argument *arg = dyn_cast<Argument>(V))
return arg->getParent();
return nullptr;
}
static bool notDifferentParent(const Value *O1, const Value *O2) {
const Function *F1 = getParent(O1);
const Function *F2 = getParent(O2);
return !F1 || !F2 || F1 == F2;
}
#endif
AliasResult BasicAAResult::alias(const MemoryLocation &LocA,
const MemoryLocation &LocB, AAQueryInfo &AAQI,
const Instruction *CtxI) { … }
ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
const MemoryLocation &Loc,
AAQueryInfo &AAQI) { … }
ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call1,
const CallBase *Call2,
AAQueryInfo &AAQI) { … }
static bool isBaseOfObject(const Value *V) { … }
AliasResult BasicAAResult::aliasGEP(
const GEPOperator *GEP1, LocationSize V1Size,
const Value *V2, LocationSize V2Size,
const Value *UnderlyingV1, const Value *UnderlyingV2, AAQueryInfo &AAQI) { … }
static AliasResult MergeAliasResults(AliasResult A, AliasResult B) { … }
AliasResult
BasicAAResult::aliasSelect(const SelectInst *SI, LocationSize SISize,
const Value *V2, LocationSize V2Size,
AAQueryInfo &AAQI) { … }
AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
const Value *V2, LocationSize V2Size,
AAQueryInfo &AAQI) { … }
AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
const Value *V2, LocationSize V2Size,
AAQueryInfo &AAQI,
const Instruction *CtxI) { … }
AliasResult BasicAAResult::aliasCheckRecursive(
const Value *V1, LocationSize V1Size,
const Value *V2, LocationSize V2Size,
AAQueryInfo &AAQI, const Value *O1, const Value *O2) { … }
bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V,
const Value *V2,
const AAQueryInfo &AAQI) { … }
void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
const DecomposedGEP &SrcGEP,
const AAQueryInfo &AAQI) { … }
bool BasicAAResult::constantOffsetHeuristic(const DecomposedGEP &GEP,
LocationSize MaybeV1Size,
LocationSize MaybeV2Size,
AssumptionCache *AC,
DominatorTree *DT,
const AAQueryInfo &AAQI) { … }
AnalysisKey BasicAA::Key;
BasicAAResult BasicAA::run(Function &F, FunctionAnalysisManager &AM) { … }
BasicAAWrapperPass::BasicAAWrapperPass() : … { … }
char BasicAAWrapperPass::ID = …;
void BasicAAWrapperPass::anchor() { … }
INITIALIZE_PASS_BEGIN(BasicAAWrapperPass, "basic-aa",
"Basic Alias Analysis (stateless AA impl)", true, true)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(BasicAAWrapperPass, "basic-aa",
"Basic Alias Analysis (stateless AA impl)", true, true)
FunctionPass *llvm::createBasicAAWrapperPass() { … }
bool BasicAAWrapperPass::runOnFunction(Function &F) { … }
void BasicAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { … }