66#define DEBUG_TYPE "basicaa"
73STATISTIC(SearchLimitReached,
"Number of times the limit to "
74 "decompose GEPs is reached");
75STATISTIC(SearchTimes,
"Number of times a GEP is decomposed");
83 FunctionAnalysisManager::Invalidator &Inv) {
106 bool RoundToAlign =
false) {
112 if (
Size->isScalable())
125 bool NullIsValidLoc) {
132 V.getPointerDereferenceableBytes(
DL, CanBeNull,
nullptr);
133 DerefBytes = (CanBeNull && NullIsValidLoc) ? 0 : DerefBytes;
147 bool NullIsValidLoc) {
185 std::optional<TypeSize> ObjectSize =
187 return ObjectSize && *ObjectSize ==
Size;
207 auto [CacheIt, Inserted] = IsCapturedCache.try_emplace(Object);
213 return ReturnCaptures ? CacheIt->second.WithRet : CacheIt->second.WithoutRet;
223 return Succs.
empty() ||
232 auto Iter = EarliestEscapes.try_emplace(Object);
237 Inst2Obj[EarliestInst].push_back(Object);
238 Iter.first->second = {EarliestInst, Res};
241 if (ReturnCaptures) {
242 assert(!
I &&
"Context instruction not supported if ReturnCaptures");
243 return Iter.first->second.second.WithRet;
246 auto IsNotCapturedBefore = [&]() {
248 Instruction *CaptureInst = Iter.first->second.first;
257 if (callsReturnsTwiceFn())
260 if (
I == CaptureInst) {
268 if (IsNotCapturedBefore())
270 return Iter.first->second.second.WithoutRet;
273bool EarliestEscapeAnalysis::callsReturnsTwiceFn() {
274 if (!CallsReturnsTwiceFn)
275 CallsReturnsTwiceFn =
277 return *CallsReturnsTwiceFn;
281 auto Iter = Inst2Obj.find(
I);
282 if (Iter != Inst2Obj.end()) {
283 for (
const Value *Obj : Iter->second)
284 EarliestEscapes.erase(Obj);
297 unsigned ZExtBits = 0;
298 unsigned SExtBits = 0;
299 unsigned TruncBits = 0;
301 bool IsNonNegative =
false;
303 explicit CastedValue(
const Value *V) : V(V) {}
304 explicit CastedValue(
const Value *
V,
unsigned ZExtBits,
unsigned SExtBits,
305 unsigned TruncBits,
bool IsNonNegative)
306 :
V(
V), ZExtBits(ZExtBits), SExtBits(SExtBits), TruncBits(TruncBits),
307 IsNonNegative(IsNonNegative) {}
310 return V->getType()->getPrimitiveSizeInBits() - TruncBits + ZExtBits +
314 CastedValue withValue(
const Value *NewV,
bool PreserveNonNeg)
const {
315 return CastedValue(NewV, ZExtBits, SExtBits, TruncBits,
316 IsNonNegative && PreserveNonNeg);
320 CastedValue withZExtOfValue(
const Value *NewV,
bool ZExtNonNegative)
const {
321 unsigned ExtendBy =
V->getType()->getPrimitiveSizeInBits() -
323 if (ExtendBy <= TruncBits)
326 return CastedValue(NewV, ZExtBits, SExtBits, TruncBits - ExtendBy,
330 ExtendBy -= TruncBits;
335 return CastedValue(NewV, ZExtBits + SExtBits + ExtendBy, 0, 0,
340 CastedValue withSExtOfValue(
const Value *NewV)
const {
341 unsigned ExtendBy =
V->getType()->getPrimitiveSizeInBits() -
343 if (ExtendBy <= TruncBits)
346 return CastedValue(NewV, ZExtBits, SExtBits, TruncBits - ExtendBy,
350 ExtendBy -= TruncBits;
353 return CastedValue(NewV, ZExtBits, SExtBits + ExtendBy, 0, IsNonNegative);
356 APInt evaluateWith(APInt
N)
const {
357 assert(
N.getBitWidth() ==
V->getType()->getPrimitiveSizeInBits() &&
358 "Incompatible bit width");
359 if (TruncBits)
N =
N.trunc(
N.getBitWidth() - TruncBits);
360 if (SExtBits)
N =
N.sext(
N.getBitWidth() + SExtBits);
361 if (ZExtBits)
N =
N.zext(
N.getBitWidth() + ZExtBits);
365 ConstantRange evaluateWith(ConstantRange
N)
const {
366 assert(
N.getBitWidth() ==
V->getType()->getPrimitiveSizeInBits() &&
367 "Incompatible bit width");
368 if (TruncBits)
N =
N.truncate(
N.getBitWidth() - TruncBits);
369 if (IsNonNegative && !
N.isAllNonNegative())
373 if (SExtBits)
N =
N.signExtend(
N.getBitWidth() + SExtBits);
374 if (ZExtBits)
N =
N.zeroExtend(
N.getBitWidth() + ZExtBits);
378 KnownBits evaluateWith(KnownBits K)
const {
379 assert(
K.getBitWidth() ==
V->getType()->getPrimitiveSizeInBits() &&
380 "Incompatible bit width");
382 K =
K.trunc(
K.getBitWidth() - TruncBits);
384 K =
K.sext(
K.getBitWidth() + SExtBits);
386 K =
K.zext(
K.getBitWidth() + ZExtBits);
390 bool canDistributeOver(
bool NUW,
bool NSW)
const {
394 return (!ZExtBits || NUW) && (!SExtBits || NSW);
397 bool hasSameCastsAs(
const CastedValue &
Other)
const {
398 if (
V->getType() !=
Other.V->getType())
401 if (ZExtBits ==
Other.ZExtBits && SExtBits ==
Other.SExtBits &&
402 TruncBits ==
Other.TruncBits)
406 if (IsNonNegative ||
Other.IsNonNegative)
407 return (ZExtBits + SExtBits ==
Other.ZExtBits +
Other.SExtBits &&
408 TruncBits ==
Other.TruncBits);
425 const APInt &
Offset,
bool IsNUW,
bool IsNSW)
429 : Val(Val), IsNUW(
true), IsNSW(
true) {
430 unsigned BitWidth = Val.getBitWidth();
438 bool NSW = IsNSW && (
Other.isOne() || (MulIsNSW &&
Offset.isZero()));
439 bool NUW = IsNUW && (
Other.isOne() || MulIsNUW);
445 APInt NewScale =
Scale.smul_ov(
Other, ScaleOverflow);
446 NSW &= !ScaleOverflow;
463 Val.evaluateWith(Const->getValue()),
true,
true);
467 APInt RHS = Val.evaluateWith(RHSC->getValue());
470 bool NUW =
true, NSW =
true;
472 NUW &= BOp->hasNoUnsignedWrap();
473 NSW &= BOp->hasNoSignedWrap();
475 if (!Val.canDistributeOver(NUW, NSW))
484 switch (BOp->getOpcode()) {
489 case Instruction::Or:
495 case Instruction::Add: {
503 case Instruction::Sub: {
511 case Instruction::Mul:
516 case Instruction::Shl: {
522 if (
RHS.getLimitedValue() > Val.getBitWidth())
530 unsigned BitWidth = Val.getBitWidth();
531 unsigned ShAmt =
RHS.getLimitedValue();
545 Val.withZExtOfValue(ZExt->getOperand(0), ZExt->hasNonNeg()),
DL,
559struct VariableGEPIndex {
574 bool hasNegatedScaleOf(
const VariableGEPIndex &
Other)
const {
575 if (IsNegated ==
Other.IsNegated)
576 return Scale == -
Other.Scale;
577 return Scale ==
Other.Scale;
584 void print(raw_ostream &OS)
const {
585 OS <<
"(V=" << Val.V->
getName()
586 <<
", zextbits=" << Val.ZExtBits
587 <<
", sextbits=" << Val.SExtBits
588 <<
", truncbits=" << Val.TruncBits
589 <<
", scale=" << Scale
591 <<
", negated=" << IsNegated <<
")";
613 OS <<
", inbounds=" << (
NWFlags.isInBounds() ?
"1" :
"0")
614 <<
", nuw=" << (
NWFlags.hasNoUnsignedWrap() ?
"1" :
"0")
615 <<
"(DecomposedGEP Base=" <<
Base->getName() <<
", Offset=" <<
Offset
617 for (
size_t i = 0; i <
VarIndices.size(); i++) {
641BasicAAResult::DecomposeGEPExpression(
const Value *V,
const DataLayout &DL,
648 unsigned IndexSize = DL.getIndexTypeSizeInBits(V->getType());
657 if (!GA->isInterposable()) {
658 V = GA->getAliasee();
666 if (
Op->getOpcode() == Instruction::BitCast ||
667 Op->getOpcode() == Instruction::AddrSpaceCast) {
668 Value *NewV =
Op->getOperand(0);
669 auto *NewVTy = NewV->
getType();
673 DL.getIndexTypeSizeInBits(NewVTy) != IndexSize) {
685 if (
PHI->getNumIncomingValues() == 1) {
686 V =
PHI->getIncomingValue(0);
721 I != E; ++
I, ++GTI) {
730 Decomposed.
Offset += DL.getStructLayout(STy)->getElementOffset(FieldNo);
747 CIdx->getValue().sextOrTrunc(IndexSize);
761 bool NonNeg = NUSW && NUW;
762 unsigned Width = Index->getType()->getIntegerBitWidth();
763 unsigned SExtBits = IndexSize > Width ? IndexSize - Width : 0;
764 unsigned TruncBits = IndexSize < Width ? Width - IndexSize : 0;
766 CastedValue(Index, 0, SExtBits, TruncBits, NonNeg), DL, 0, AC, DT);
772 Decomposed.
Offset += LE.Offset;
773 APInt Scale = LE.Scale;
781 for (
unsigned i = 0, e = Decomposed.
VarIndices.
size(); i != e; ++i) {
782 if ((Decomposed.
VarIndices[i].Val.V == LE.Val.V ||
784 Decomposed.
VarIndices[i].Val.hasSameCastsAs(LE.Val)) {
787 LE.IsNSW = LE.IsNUW =
false;
794 VariableGEPIndex Entry = {LE.Val, Scale, CtxI, LE.IsNSW,
802 }
while (--MaxLookup);
806 SearchLimitReached++;
813 assert(Visited.empty() &&
"Visited must be cleared after use!");
816 unsigned MaxLookup = 8;
823 if (!Visited.insert(V).second)
837 if (Arg->hasNoAliasAttr() && Arg->onlyReadsMemory()) {
848 if (!GV->isConstant())
864 if (PN->getNumIncomingValues() > MaxLookup)
872 }
while (!Worklist.
empty() && --MaxLookup);
875 if (!Worklist.
empty())
883 return II &&
II->getIntrinsicID() == IID;
895 if (
Call->hasReadingOperandBundles())
897 if (
Call->hasClobberingOperandBundles())
899 if (
Call->isVolatile()) {
912 return F->getMemoryEffects();
917 if (
Call->doesNotAccessMemory(ArgIdx))
920 if (
Call->onlyWritesMemory(ArgIdx))
923 if (
Call->onlyReadsMemory(ArgIdx))
932 if (!inst->getParent())
934 return inst->getParent()->getParent();
948 return !F1 || !F2 || F1 == F2;
956 "BasicAliasAnalysis doesn't support interprocedural queries.");
957 return aliasCheck(LocA.
Ptr, LocA.
Size, LocB.
Ptr, LocB.
Size, AAQI, CtxI);
970 "AliasAnalysis query involving multiple functions!");
981 if (CI->isTailCall() &&
982 !CI->getAttributes().hasAttrSomewhere(Attribute::ByVal))
995 if (ME.doesNotAccessMemory())
1010 Call->isInlineAsm()) {
1027 Object,
Call,
false,
false);
1037 if ((ArgMR | OtherMR) != OtherMR) {
1039 for (
const Use &U :
Call->data_ops()) {
1040 const Value *Arg = U;
1043 unsigned ArgIdx =
Call->getDataOperandNo(&U);
1045 Call->isArgOperand(&U)
1053 if (NewArgMR == ArgMR)
1059 ModRefInfo Result = ArgMR | OtherMR | SyncMR;
1062 if ((ErrnoMR | Result) != Result) {
1140 auto BaseObjectsAlias = [&]() {
1160 return BaseObjectsAlias();
1165 DominatorTree *DT = getDT(AAQI);
1166 DecomposedGEP DecompGEP1 = DecomposeGEPExpression(GEP1, DL, &AC, DT);
1167 DecomposedGEP DecompGEP2 = DecomposeGEPExpression(V2, DL, &AC, DT);
1170 if (DecompGEP1.Base == GEP1 && DecompGEP2.Base == V2)
1174 if (DecompGEP1.Offset.getBitWidth() != DecompGEP2.Offset.getBitWidth())
1175 return BaseObjectsAlias();
1178 if (DecompGEP1.VarIndices.size() < DecompGEP2.VarIndices.size()) {
1186 subtractDecomposedGEPs(DecompGEP1, DecompGEP2, AAQI);
1192 if (DecompGEP1.NWFlags.isInBounds() && DecompGEP1.VarIndices.empty() &&
1194 DecompGEP1.Offset.sge(V2Size.
getValue()) &&
1199 if (DecompGEP2.NWFlags.isInBounds() && DecompGEP1.VarIndices.empty() &&
1201 DecompGEP1.Offset.sle(-V1Size.
getValue()) &&
1207 if (DecompGEP1.Offset == 0 && DecompGEP1.VarIndices.empty())
1208 return AAQI.
AAR.
alias(MemoryLocation(DecompGEP1.Base, V1Size),
1209 MemoryLocation(DecompGEP2.Base, V2Size), AAQI);
1212 AliasResult BaseAlias =
1228 if (DecompGEP1.VarIndices.empty()) {
1229 APInt &
Off = DecompGEP1.Offset;
1232 LocationSize VLeftSize = V2Size;
1233 LocationSize VRightSize = V1Size;
1234 const bool Swapped =
Off.isNegative();
1250 const TypeSize LSize = VLeftSize.
getValue();
1252 if (
Off.ult(LSize)) {
1257 Off.ule(INT32_MAX) && (
Off + VRightSize.
getValue()).ule(LSize)) {
1274 if (!Overflow &&
Off.uge(UpperRange))
1281 if (DecompGEP1.VarIndices.size() == 1 &&
1282 DecompGEP1.VarIndices[0].Val.TruncBits == 0 &&
1283 DecompGEP1.Offset.isZero() &&
1286 const VariableGEPIndex &ScalableVar = DecompGEP1.VarIndices[0];
1288 ScalableVar.IsNegated ? -ScalableVar.Scale : ScalableVar.Scale;
1289 LocationSize VLeftSize = Scale.
isNegative() ? V1Size : V2Size;
1293 bool Overflows = !DecompGEP1.VarIndices[0].IsNSW;
1318 if (!DecompGEP1.VarIndices.empty() &&
1319 DecompGEP1.NWFlags.hasNoUnsignedWrap() && V2Size.
hasValue() &&
1329 unsigned BW = DecompGEP1.Offset.getBitWidth();
1337 auto [GCD, OffsetRange, VIKnownBits] = analyzeVariableOffsets(DecompGEP1, DT);
1345 APInt ModOffset = DecompGEP1.Offset.srem(GCD);
1349 (GCD - ModOffset).uge(V1Size.
getValue()))
1354 ConstantRange Range1 = OffsetRange.add(
1355 ConstantRange(APInt(BW, 0), APInt(BW, V1Size.
getValue())));
1356 ConstantRange Range2 =
1357 ConstantRange(APInt(BW, 0), APInt(BW, V2Size.
getValue()));
1363 if (
auto MinAbsVarIndex =
1364 computeMinAbsVarOffset(DecompGEP1, VIKnownBits, DT, AAQI)) {
1366 APInt OffsetLo = DecompGEP1.Offset - *MinAbsVarIndex;
1367 APInt OffsetHi = DecompGEP1.Offset + *MinAbsVarIndex;
1376 if (computeConstantOffsetHeuristic(DecompGEP1, V1Size, V2Size, &AC, DT, AAQI))
1406 if (isValueEqualInPotentialCycles(
SI->getCondition(), SI2->getCondition(),
1409 AAQI.
AAR.
alias(MemoryLocation(
SI->getTrueValue(), SISize),
1410 MemoryLocation(SI2->getTrueValue(), V2Size), AAQI);
1413 AliasResult ThisAlias =
1414 AAQI.
AAR.
alias(MemoryLocation(
SI->getFalseValue(), SISize),
1415 MemoryLocation(SI2->getFalseValue(), V2Size), AAQI);
1421 AliasResult Alias = AAQI.
AAR.
alias(MemoryLocation(
SI->getTrueValue(), SISize),
1422 MemoryLocation(V2, V2Size), AAQI);
1426 AliasResult ThisAlias =
1427 AAQI.
AAR.
alias(MemoryLocation(
SI->getFalseValue(), SISize),
1428 MemoryLocation(V2, V2Size), AAQI);
1445 std::optional<AliasResult> Alias;
1447 AliasResult ThisAlias = AAQI.
AAR.
alias(
1462 SmallVector<Value *, 4> V1Srcs;
1466 bool isRecursive =
false;
1467 auto CheckForRecPhi = [&](
Value *PV) {
1468 if (!Opts.basic_aa_recphi)
1477 SmallPtrSet<Value *, 4> UniqueSrc;
1483 if (CheckForRecPhi(PV1))
1486 if (UniqueSrc.
insert(PV1).second)
1512 AliasResult Alias = AAQI.
AAR.
alias(MemoryLocation(V1Srcs[0], PNSize),
1513 MemoryLocation(V2, V2Size), AAQI);
1526 for (
unsigned i = 1, e = V1Srcs.
size(); i != e; ++i) {
1529 AliasResult ThisAlias = AAQI.
AAR.
alias(
1530 MemoryLocation(
V, PNSize), MemoryLocation(V2, V2Size), AAQI);
1561 V1 =
V1->stripPointerCastsForAliasAnalysis();
1575 if (isValueEqualInPotentialCycles(
V1, V2, AAQI))
1628 if (Opts.basic_aa_separate_storage) {
1629 for (AssumptionCache::ResultElem &Elem : AC.assumptionsFor(
O1)) {
1634 OperandBundleUse OBU =
Assume->getOperandBundleAt(Elem.Index);
1644 DominatorTree *DT = getDT(AAQI);
1645 auto ValidAssumeForPtrContext = [&](
const Value *Ptr) {
1652 &*PtrA->getParent()->getEntryBlock().begin();
1659 if ((
O1 == HintO1 &&
O2 == HintO2) || (
O1 == HintO2 &&
O2 == HintO1)) {
1666 ValidAssumeForPtrContext(V2)))) {
1690 if (AAQI.
Depth >= 512)
1699 const bool Swapped =
V1 > V2;
1705 auto &
Entry = Pair.first->second;
1706 if (!
Entry.isDefinitive()) {
1711 if (
Entry.isAssumption())
1712 ++
Entry.NumAssumptionUses;
1723 aliasCheckRecursive(
V1, V1Size, V2, V2Size, AAQI,
O1,
O2);
1727 auto &
Entry = It->second;
1730 bool AssumptionDisproven =
1732 if (AssumptionDisproven)
1739 Entry.Result.swap(Swapped);
1744 if (AssumptionDisproven)
1760 if (AAQI.
Depth == 1) {
1779 AliasResult
Result = aliasGEP(GV1, V1Size, V2, V2Size,
O1,
O2, AAQI);
1783 AliasResult
Result = aliasGEP(GV2, V2Size,
V1, V1Size,
O2,
O1, AAQI);
1790 AliasResult
Result = aliasPHI(PN, V1Size, V2, V2Size, AAQI);
1794 AliasResult
Result = aliasPHI(PN, V2Size,
V1, V1Size, AAQI);
1801 AliasResult
Result = aliasSelect(
S1, V1Size, V2, V2Size, AAQI);
1805 AliasResult
Result = aliasSelect(S2, V2Size,
V1, V1Size, AAQI);
1836 if (
Loc.Size.hasValue() &&
1837 Loc.Size.getValue().getKnownMinValue() * 8 > TLI.getIntSize())
1846 if (GV->hasLocalLinkage())
1851 if (TLI.isErrnoFunctionCall())
1864bool BasicAAResult::isValueEqualInPotentialCycles(
const Value *V,
1876 if (!Inst || Inst->
getParent()->isEntryBlock())
1879 return isNotInCycle(Inst, getDT(AAQI),
nullptr,
nullptr);
1883void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
1884 const DecomposedGEP &SrcGEP,
1888 if (DestGEP.Offset.ult(SrcGEP.Offset))
1889 DestGEP.NWFlags = DestGEP.NWFlags.withoutNoUnsignedWrap();
1891 DestGEP.Offset -= SrcGEP.Offset;
1892 for (
const VariableGEPIndex &Src : SrcGEP.VarIndices) {
1896 for (
auto I :
enumerate(DestGEP.VarIndices)) {
1897 VariableGEPIndex &Dest =
I.value();
1898 if ((!isValueEqualInPotentialCycles(Dest.Val.V, Src.Val.V, AAQI) &&
1900 !Dest.Val.hasSameCastsAs(Src.Val))
1904 if (Dest.IsNegated) {
1905 Dest.Scale = -Dest.Scale;
1906 Dest.IsNegated =
false;
1912 if (Dest.Scale != Src.Scale) {
1915 if (Dest.Scale.
ult(Src.Scale))
1916 DestGEP.NWFlags = DestGEP.NWFlags.withoutNoUnsignedWrap();
1918 Dest.Scale -= Src.Scale;
1921 DestGEP.VarIndices.erase(DestGEP.VarIndices.begin() +
I.index());
1929 VariableGEPIndex
Entry = {Src.Val, Src.Scale, Src.CtxI, Src.IsNSW,
1931 DestGEP.VarIndices.push_back(Entry);
1934 DestGEP.NWFlags = DestGEP.NWFlags.withoutNoUnsignedWrap();
1940BasicAAResult::analyzeVariableOffsets(
const DecomposedGEP &
GEP,
1943 ConstantRange OffsetRange(
GEP.Offset);
1945 VarIndexKnownBits.
reserve(
GEP.VarIndices.size());
1947 for (
unsigned I = 0,
E =
GEP.VarIndices.size();
I !=
E; ++
I) {
1948 const VariableGEPIndex &
Index =
GEP.VarIndices[
I];
1949 const APInt &Scale =
Index.Scale;
1951 SimplifyQuery SQ(DL, DT, &AC,
Index.CtxI,
true);
1955 APInt ScaleForGCD = Scale;
1964 unsigned VarTZ =
Known.countMinTrailingZeros();
1968 ScaleForGCD <<= std::min(VarTZ, MaxShift);
1972 GCD = ScaleForGCD.
abs();
1981 CR =
Index.Val.evaluateWith(CR).sextOrTrunc(OffsetRange.getBitWidth());
1984 "Bit widths are normalized to MaxIndexSize");
1986 CR = CR.
smul_sat(ConstantRange(Scale));
1988 CR = CR.
smul_fast(ConstantRange(Scale));
1990 if (
Index.IsNegated)
1991 OffsetRange = OffsetRange.
sub(CR);
1993 OffsetRange = OffsetRange.
add(CR);
1996 return {GCD, OffsetRange, std::move(VarIndexKnownBits)};
2009 int MaxScaleValueBW = Var.Val.getBitWidth() - ValOrigBW;
2010 if (MaxScaleValueBW <= 0)
2012 return Var.Scale.
ule(
2016std::optional<APInt> BasicAAResult::computeMinAbsVarOffset(
2019 const auto &VarIndices =
GEP.VarIndices;
2020 if (VarIndices.size() == 1) {
2022 const VariableGEPIndex &Var = VarIndices[0];
2023 if (Var.Val.TruncBits == 0 &&
2024 isKnownNonZero(Var.Val.V, SimplifyQuery(DL, DT, &AC, Var.CtxI))) {
2029 return Var.Scale.
abs();
2032 return std::nullopt;
2035 if (VarIndices.size() == 2) {
2040 const VariableGEPIndex &Var0 = VarIndices[0];
2041 const VariableGEPIndex &Var1 = VarIndices[1];
2042 bool Preconditions =
2043 Var0.Val.TruncBits == 0 && Var0.Val.hasSameCastsAs(Var1.Val) &&
2048 return std::nullopt;
2050 if (Var0.hasNegatedScaleOf(Var1)) {
2052 SimplifyQuery(DL, DT, &AC, Var0.CtxI
2055 return Var0.Scale.
abs();
2058 return std::nullopt;
2069 bool EffectiveNeg0 = Var0.IsNegated ^ Var0.Scale.
isNegative();
2070 bool EffectiveNeg1 = Var1.IsNegated ^ Var1.Scale.
isNegative();
2071 if (EffectiveNeg0 != EffectiveNeg1) {
2072 APInt AbsScale0 = Var0.Scale.
abs();
2073 APInt AbsScale1 = Var1.Scale.
abs();
2075 APInt
C0 = AbsScale0.
udiv(ScaleGCD);
2076 APInt
C1 = AbsScale1.
udiv(ScaleGCD);
2080 auto Known0 =
KnownBits::mul(Var0.Val.evaluateWith(VIKnownBits[0]),
2083 auto Known1 =
KnownBits::mul(Var1.Val.evaluateWith(VIKnownBits[1]),
2091 return std::nullopt;
2094bool BasicAAResult::computeConstantOffsetHeuristic(
const DecomposedGEP &
GEP,
2100 if (
GEP.VarIndices.size() != 2 || !MaybeV1Size.
hasValue() ||
2107 const VariableGEPIndex &Var0 =
GEP.VarIndices[0], &Var1 =
GEP.VarIndices[1];
2111 if (Var0.Val.TruncBits != 0 || !Var0.Val.hasSameCastsAs(Var1.Val) ||
2112 !Var0.hasNegatedScaleOf(Var1) ||
2126 LinearExpression
E0 =
2128 LinearExpression E1 =
2130 if (
E0.Scale != E1.
Scale || !
E0.Val.hasSameCastsAs(E1.Val) ||
2131 !isValueEqualInPotentialCycles(
E0.Val.V, E1.Val.V, AAQI))
2141 APInt MinDiff =
E0.Offset - E1.
Offset, Wrapped = -MinDiff;
2143 APInt MinDiffBytes =
2150 return MinDiffBytes.
uge(V1Size +
GEP.Offset.abs()) &&
2151 MinDiffBytes.
uge(V2Size +
GEP.Offset.abs());
2171void BasicAAWrapperPass::anchor() {}
2174 "Basic Alias Analysis (stateless AA impl)",
true,
true)
2179 "Basic Alias Analysis (stateless AA impl)",
true,
true)
2191 TLIWP.getTLI(
F), ACT.getAssumptionCache(
F),
2192 &DTWP.getDomTree()));
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static bool isObjectSize(const Value *V, TypeSize Size, const DataLayout &DL, const TargetLibraryInfo &TLI, bool NullIsValidLoc)
Returns true if we can prove that the object specified by V has size Size.
static bool isArgumentOrArgumentLike(const Value *V)
static bool notDifferentParent(const Value *O1, const Value *O2)
static bool multiplyByScaleNoWrap(const VariableGEPIndex &Var)
Check whether V*Scale cannot wrap for any value of V, so that abs(V*Scale) >= abs(Scale) holds in the...
static LinearExpression GetLinearExpression(const CastedValue &Val, const DataLayout &DL, unsigned Depth, AssumptionCache *AC, DominatorTree *DT)
Analyzes the specified value as a linear expression: "A*V + B", where A and B are constant integers.
static bool isNotInCycle(const Instruction *I, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
static bool areBothVScale(const Value *V1, const Value *V2)
Return true if both V1 and V2 are VScale.
static TypeSize getMinimalExtentFrom(const Value &V, const LocationSize &LocSize, const DataLayout &DL, bool NullIsValidLoc)
Return the minimal extent from V to the end of the underlying object, assuming the result is used in ...
static AliasResult MergeAliasResults(AliasResult A, AliasResult B)
static bool isIntrinsicCall(const CallBase *Call, Intrinsic::ID IID)
static bool isObjectSmallerThan(const Value *V, const Value &OtherV, LocationSize OtherSize, const DataLayout &DL, const TargetLibraryInfo &TLI, bool NullIsValidLoc)
Returns true if we can prove that the object specified by V is smaller than the minimal extent access...
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares the LLVM IR specialization of the GenericCycle templates.
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file provides utility classes that use RAII to save and restore values.
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
This class stores info we want to provide to or retain within an alias query.
SmallVector< AAQueryInfo::LocPair, 4 > AssumptionBasedResults
Location pairs for which an assumption based result is currently stored.
unsigned Depth
Query depth used to distinguish recursive queries.
int NumAssumptionUses
How many active NoAlias assumption uses there are.
std::pair< AACacheLoc, AACacheLoc > LocPair
bool MayBeCrossIteration
Tracks whether the accesses may be on different cycle iterations.
bool AllowEphemerals
Whether ephemeral values should be allowed when checking assumes.
LLVM_ABI AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
LLVM_ABI AliasResult aliasErrno(const MemoryLocation &Loc, const Instruction *CtxI)
LLVM_ABI MemoryEffects getMemoryEffects(const CallBase *Call)
Return the behavior of the given call site.
LLVM_ABI ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx)
Get the ModRef info associated with a pointer argument of a call.
Class for arbitrary precision integers.
LLVM_ABI APInt umul_ov(const APInt &RHS, bool &Overflow) const
LLVM_ABI APInt udiv(const APInt &RHS) const
Unsigned division operation.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
APInt abs() const
Get the absolute value.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool isNegative() const
Determine sign of this APInt.
unsigned countr_zero() const
Count the number of trailing zero bits.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
unsigned getSignificantBits() const
Get the minimum bit size for this signed APInt.
LLVM_ABI APInt smul_ov(const APInt &RHS, bool &Overflow) const
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool ule(const APInt &RHS) const
Unsigned less or equal comparison.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo)
Return an APInt with exactly one bit set in the result.
bool uge(const APInt &RHS) const
Unsigned greater or equal comparison.
The possible results of an alias query.
void swap(bool DoSwap=true)
Helper for processing AliasResult for swapped memory location pairs.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
void setOffset(int32_t NewOffset)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
This class represents an incoming formal argument to a Function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
This is the AA result object for the basic, local, and stateless alias analysis.
LLVM_ABI ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)
Checks to see if the specified callsite can clobber the specified memory object.
LLVM_ABI ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx)
Get the location associated with a pointer argument of a callsite.
LLVM_ABI BasicAAResult(const DataLayout &DL, const Function &F, const TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree *DT=nullptr)
LLVM_ABI MemoryEffects getMemoryEffects(const CallBase *Call, AAQueryInfo &AAQI)
Returns the behavior when calling the given call site.
LLVM_ABI AliasResult aliasErrno(const MemoryLocation &Loc, const Instruction *CtxI)
LLVM_ABI ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, AAQueryInfo &AAQI, bool IgnoreLocals=false)
Returns a bitmask that should be unconditionally applied to the ModRef info of a memory location.
LLVM_ABI bool invalidate(Function &Fn, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle invalidation events in the new pass manager.
LLVM_ABI AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI, const Instruction *CtxI)
Legacy wrapper pass to provide the BasicAAResult object.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
LLVM_ABI BasicAAResult run(Function &F, FunctionAnalysisManager &AM)
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
This class represents a range of values.
LLVM_ABI ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
static LLVM_ABI ConstantRange fromKnownBits(const KnownBits &Known, bool IsSigned)
Initialize a range based on a known bits constraint.
LLVM_ABI ConstantRange smul_fast(const ConstantRange &Other) const
Return range of possible values for a signed multiplication of this and Other.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI ConstantRange smul_sat(const ConstantRange &Other) const
Perform a signed saturating multiplication of two constant ranges.
LLVM_ABI APInt getUnsignedMax() const
Return the largest unsigned value contained in the ConstantRange.
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
LLVM_ABI APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
LLVM_ABI ConstantRange sub(const ConstantRange &Other) const
Return a new range representing the possible values resulting from a subtraction of a value in this r...
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
void removeInstruction(Instruction *I)
CaptureComponents getCapturesBefore(const Value *Object, const Instruction *I, bool OrAt, bool ReturnCaptures) override
Return how Object may be captured before instruction I, considering only provenance captures.
FunctionPass class - This class is used to implement most global optimizations.
bool callsFunctionThatReturnsTwice() const
callsFunctionThatReturnsTwice - Return true if the function has a call to setjmp or other function th...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags all()
GEPNoWrapFlags withoutNoUnsignedWrap() const
bool hasNoUnsignedSignedWrap() const
bool hasNoUnsignedWrap() const
LLVM_ABI Type * getSourceElementType() const
GEPNoWrapFlags getNoWrapFlags() const
CycleRef getCycle(const BlockT *Block) const
Find the innermost cycle containing Block.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
bool mayBeBeforePointer() const
Whether accesses before the base pointer are possible.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
TypeSize getValue() const
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
static MemoryEffectsBase readOnly()
MemoryEffectsBase getWithoutLoc(Location Loc) const
Get new MemoryEffectsBase with NoModRef on the given Loc.
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
static MemoryEffectsBase writeOnly()
Representation for a specific memory location.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
const Value * Ptr
The address of the start of the location.
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
This is a utility class that provides an abstraction for the common functionality between Instruction...
op_range incoming_values()
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
This class represents the LLVM 'select' instruction.
CaptureComponents getCapturesBefore(const Value *Object, const Instruction *I, bool OrAt, bool ReturnCaptures) override
Return how Object may be captured before instruction I, considering only provenance captures.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Class to represent struct types.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
bool isPointerTy() const
True if this is an instance of PointerType.
bool isSized() const
Return true if it makes sense to take the size of this type.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
A Use represents the edge between a Value definition and its users.
const Use * const_op_iterator
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI const Value * stripPointerCastsForAliasAnalysis() const
Strip off pointer casts, all-zero GEPs, single-argument phi nodes and invariant group info.
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
LLVM_ABI APInt GreatestCommonDivisor(APInt A, APInt B, bool IsSigned=false)
Compute GCD of two APInt values.
bool match(Val *V, const Pattern &P)
auto m_VScale()
Matches a call to llvm.vscale().
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool capturesReadProvenanceOnly(CaptureComponents CC)
SaveAndRestore(T &) -> SaveAndRestore< T >
BundleAttr getBundleAttrFromOBU(OperandBundleUse OBU)
@ Known
Known to have no common set bits.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isBaseOfObject(const Value *V)
Return true if we know V to the base address of the corresponding memory object.
LLVM_ABI const Value * getArgumentAliasingToReturnedPointer(const CallBase *Call, bool MustPreserveOffset, bool MustPreserveProvenance=false)
This function returns call pointer argument that is considered the same by aliasing rules.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
@ O1
Optimize quickly without destroying debuggability.
@ O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
LLVM_ABI std::optional< TypeSize > getBaseObjectSize(const Value *Ptr, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Like getObjectSize(), but only returns the size of base objects (like allocas, global variables and a...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool isValidAssumeForContext(const Instruction *I, const Instruction *CtxI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL, const TargetLibraryInfo *TLI, ObjectSizeOpts Opts={})
Compute the size of the object pointed by Ptr.
bool capturesFullProvenance(CaptureComponents CC)
LLVM_ABI ModRefInfo getSyncEffects(AAResults *AA, const MemoryLocation &Loc, AAQueryInfo &AAQI)
Get ModRefInfo for a synchronizing operation, such as a fence or stronger than monotonic atomic load/...
bool isModSet(const ModRefInfo MRI)
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
generic_gep_type_iterator<> gep_type_iterator
bool isModOrRefSet(const ModRefInfo MRI)
constexpr unsigned MaxLookupSearchDepth
The max limit of the search depth in DecomposeGEPExpression() and getUnderlyingObject().
LLVM_ABI ConstantRange getVScaleRange(const Function *F, unsigned BitWidth)
Determine the possible constant range of vscale with the given bit width, based on the vscale_range f...
LLVM_ABI FunctionPass * createBasicAAWrapperPass()
CaptureComponents
Components of the pointer that may be captured.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
@ ArgMem
Access to memory via argument pointers.
@ InaccessibleMem
Memory that is inaccessible via LLVM IR.
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
LLVM_ABI bool isKnownNonEqual(const Value *V1, const Value *V2, const SimplifyQuery &SQ, unsigned Depth=0)
Return true if the given values are known to be non-equal when defined.
DWARFExpression::Operation Op
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
LLVM_ABI bool isPotentiallyReachableFromMany(SmallVectorImpl< BasicBlock * > &Worklist, const BasicBlock *StopBB, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether there is at least one path from a block in 'Worklist' to 'StopBB' without passing t...
LLVM_ABI std::pair< Instruction *, CaptureResult > FindEarliestCapture(const Value *V, Function &F, const DominatorTree &DT, CaptureComponents Mask, unsigned MaxUsesToExplore=0)
bool isModAndRefSet(const ModRefInfo MRI)
LLVM_ABI bool isIdentifiedFunctionLocal(const Value *V)
Return true if V is umabigously identified at the function-level.
constexpr unsigned BitWidth
LLVM_ABI bool isEscapeSource(const Value *V)
Returns true if the pointer is one which would have been considered an escape by isNotCapturedBefore.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
bool capturesNothing(CaptureComponents CC)
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SmallVector< VariableGEPIndex, 4 > VarIndices
void print(raw_ostream &OS) const
ConstantRange OffsetRange
SmallVector< KnownBits, 4 > VarIndexKnownBits
static constexpr int Definitive
Cache entry is neither an assumption nor does it use a (non-definitive) assumption.
static constexpr int AssumptionBased
Cache entry is not an assumption itself, but may be using an assumption from higher up the stack.
A special type used by analysis passes to provide an address that identifies that particular analysis...
virtual CaptureComponents getCapturesBefore(const Value *Object, const Instruction *I, bool OrAt, bool ReturnCaptures)=0
Return how Object may be captured before instruction I, considering only provenance captures.
virtual ~CaptureAnalysis()=0
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
static LLVM_ABI std::optional< bool > ne(const KnownBits &LHS, const KnownBits &RHS)
Determine if these known bits always give the same ICMP_NE result.
static LLVM_ABI KnownBits mul(const KnownBits &LHS, const KnownBits &RHS, bool NoUndefSelfMultiply=false)
Compute known bits resulting from multiplying LHS and RHS.
Linear expression BasePtr + Index * Scale + Offset.
LinearExpression(Value *BasePtr, unsigned BitWidth)
Various options to control the behavior of getObjectSize.
bool NullIsUnknownSize
If this is true, null pointers in address space 0 will be treated as though they can't be evaluated.
bool RoundToAlign
Whether to round the result up to the alignment of allocas, byval arguments, and global variables.