97#ifndef LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
98#define LLVM_TRANSFORMS_IPO_ATTRIBUTOR_H
150template <
typename Fn>
class function_ref;
151struct AADepGraphNode;
154struct AbstractAttribute;
155struct InformationCache;
157struct AttributorCallGraph;
187 using Base = std::pair<Value *, const Instruction *>;
207 const Value &V,
bool ForAnalysisOnly =
true);
231std::optional<Value *>
233 const std::optional<Value *> &
B,
Type *Ty);
259 "Inconsistent state!");
276 if (R.isUnassigned())
302 if (L.Offset < R.Offset)
304 if (L.Offset == R.Offset)
305 return L.Size < R.Size;
315 static constexpr int64_t
Unassigned = std::numeric_limits<int32_t>::min();
316 static constexpr int64_t
Unknown = std::numeric_limits<int32_t>::max();
320 OS <<
"[" << R.Offset <<
", " << R.Size <<
"]";
325 return A.Offset ==
B.Offset &&
A.Size ==
B.Size;
335 RangeTy *RangePtr =
nullptr);
352 bool OnlyExact =
false);
366 bool OnlyExact =
false);
390 std::function<
bool(
const Function &
F)> GoBackwardsCB =
nullptr);
397 std::function<
bool(
const Function &
F)> GoBackwardsCB =
nullptr);
416 return Base::getEmptyKey();
419 return Base::getTombstoneKey();
422 return Base::getHashValue(VAC);
427 return Base::isEqual(
LHS,
RHS);
441 return Base::getHashValue(S);
445 return Base::isEqual(
LHS,
RHS);
458 super::getTombstoneKey());
463 for (
const auto *
II : *BES)
471 if (
LHS == getEmptyKey() ||
RHS == getEmptyKey() ||
472 LHS == getTombstoneKey() ||
RHS == getTombstoneKey())
474 auto SizeLHS =
LHS ?
LHS->size() : 0;
475 auto SizeRHS =
RHS ?
RHS->size() : 0;
476 if (SizeLHS != SizeRHS)
520 return cast<AbstractAttribute>(DT.getPointer());
537 OS <<
"AADepNode Impl\n";
612 if (
auto *Arg = dyn_cast<Argument>(&V))
614 if (
auto *CB = dyn_cast<CallBase>(&V))
693 return Enc ==
RHS.Enc &&
RHS.CBContext == CBContext;
704 switch (getEncodingBits()) {
706 case ENC_RETURNED_VALUE:
707 case ENC_FLOATING_FUNCTION:
708 return *getAsValuePtr();
709 case ENC_CALL_SITE_ARGUMENT_USE:
710 return *(getAsUsePtr()->getUser());
724 return dyn_cast_if_present<Function>(
725 CB->getCalledOperand()->stripPointerCasts());
760 if (isa<Function>(V))
761 return &cast<Function>(V);
762 if (isa<Argument>(V))
763 return cast<Argument>(V).getParent();
764 if (isa<Instruction>(V))
765 return cast<Instruction>(V).getFunction();
772 if (
auto *
I = dyn_cast<Instruction>(&V))
774 if (
auto *Arg = dyn_cast<Argument>(&V))
775 if (!Arg->getParent()->isDeclaration())
776 return &Arg->getParent()->getEntryBlock().front();
777 if (
auto *
F = dyn_cast<Function>(&V))
778 if (!
F->isDeclaration())
779 return &(
F->getEntryBlock().front());
805 return getArgNo(
true);
814 return getArgNo(
false);
835 "There is no attribute index for a floating or invalid position!");
855 return CB->setAttributes(AttrList);
864 "Only valid for function/call site positions!");
866 return CB->arg_size();
875 "Only valid for function/call site positions!");
877 return CB->getArgOperand(ArgNo);
883 char EncodingBits = getEncodingBits();
884 if (EncodingBits == ENC_CALL_SITE_ARGUMENT_USE)
886 if (EncodingBits == ENC_FLOATING_FUNCTION)
889 Value *V = getAsValuePtr();
892 if (isa<Argument>(V))
894 if (isa<Function>(V))
896 if (isa<CallBase>(V))
927 Result.CBContext =
nullptr;
950 : CBContext(CBContext) {
957 : CBContext(CBContext) {
964 if (isa<Function>(AnchorVal) || isa<CallBase>(AnchorVal))
965 Enc = {&AnchorVal, ENC_FLOATING_FUNCTION};
967 Enc = {&AnchorVal, ENC_VALUE};
971 Enc = {&AnchorVal, ENC_VALUE};
975 Enc = {&AnchorVal, ENC_RETURNED_VALUE};
978 Enc = {&AnchorVal, ENC_VALUE};
982 "Cannot create call site argument IRP with an anchor value!");
991 int getArgNo(
bool CallbackCalleeArgIfApplicable)
const {
992 if (CallbackCalleeArgIfApplicable)
994 return Arg->getArgNo();
997 return cast<Argument>(getAsValuePtr())->getArgNo();
999 Use &
U = *getAsUsePtr();
1000 return cast<CallBase>(
U.getUser())->getArgOperandNo(&U);
1012 "Use constructor is for call site arguments only!");
1013 Enc = {&
U, ENC_CALL_SITE_ARGUMENT_USE};
1022 Value *getAsValuePtr()
const {
1023 assert(getEncodingBits() != ENC_CALL_SITE_ARGUMENT_USE &&
1024 "Not a value pointer!");
1030 Use *getAsUsePtr()
const {
1031 assert(getEncodingBits() == ENC_CALL_SITE_ARGUMENT_USE &&
1032 "Not a value pointer!");
1038 static bool isReturnPosition(
char EncodingBits) {
1039 return EncodingBits == ENC_RETURNED_VALUE;
1044 bool isReturnPosition()
const {
return isReturnPosition(getEncodingBits()); }
1054 ENC_RETURNED_VALUE = 0b01,
1055 ENC_FLOATING_FUNCTION = 0b10,
1056 ENC_CALL_SITE_ARGUMENT_USE = 0b11,
1061 static constexpr int NumEncodingBits =
1062 PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
1063 static_assert(NumEncodingBits >= 2,
"At least two bits are required!");
1066 PointerIntPair<void *, NumEncodingBits, char> Enc;
1073 char getEncodingBits()
const {
return Enc.getInt(); }
1118 using iterator =
decltype(IRPositions)::iterator;
1139 template <
typename,
typename =
void>
1142 template <
typename Analysis>
1144 bool RequestCachedOnly =
false) {
1145 if (!LegacyPass && !FAM)
1148 if (CachedOnly || RequestCachedOnly)
1152 if constexpr (HasLegacyWrapper<Analysis>) {
1153 if (!CachedOnly && !RequestCachedOnly)
1160 ->getAnalysisIfAvailable<typename Analysis::LegacyWrapper>())
1161 return &
P->getResult();
1168 assert(FAM &&
"Can only be used from the new PM!");
1173 :
FAM(&
FAM), CachedOnly(CachedOnly) {}
1175 : LegacyPass(
P), CachedOnly(CachedOnly) {}
1180 Pass *LegacyPass =
nullptr;
1184 bool CachedOnly =
false;
1187template <
typename Analysis>
1189 Analysis, std::void_t<typename Analysis::LegacyWrapper>> =
true;
1206 bool UseExplorer =
true)
1208 TargetTriple(M.getTargetTriple()) {
1228 for (
auto &It : FuncInfoMap)
1229 It.getSecond()->~FunctionInfo();
1232 for (
auto *BES : BESets)
1233 BES->~InstExclusionSetTy();
1235 Explorer->~MustBeExecutedContextExplorer();
1241 template <
typename CBTy>
1243 bool LookThroughConstantExprUses =
true) {
1250 if (LookThroughConstantExprUses && isa<ConstantExpr>(U.getUser())) {
1251 for (
Use &CEU : cast<ConstantExpr>(U.getUser())->
uses())
1272 return getFunctionInfo(
F).OpcodeInstMap;
1277 return getFunctionInfo(
F).RWInsts;
1293 FunctionInfo &FI = getFunctionInfo(*Arg.
getParent());
1294 return FI.CalledViaMustTail || FI.ContainsMustTailCall;
1298 return AssumeOnlyValues.contains(&
I);
1306 template <
typename AP>
1308 bool CachedOnly =
false) {
1321 auto It = BESets.find(BES);
1322 if (It != BESets.end())
1325 bool Success = BESets.insert(UniqueBES).second;
1348 struct FunctionInfo {
1360 bool CalledViaMustTail;
1363 bool ContainsMustTailCall;
1367 DenseMap<const Function *, FunctionInfo *> FuncInfoMap;
1370 FunctionInfo &getFunctionInfo(
const Function &
F) {
1371 FunctionInfo *&FI = FuncInfoMap[&
F];
1373 FI =
new (Allocator) FunctionInfo();
1374 initializeInformationCache(
F, *FI);
1381 SmallVector<Function *> IndirectlyCallableFunctions;
1387 void initializeInformationCache(
const Function &
F, FunctionInfo &FI);
1390 const DataLayout &DL;
1396 MustBeExecutedContextExplorer *Explorer =
nullptr;
1402 SetVector<const Instruction *> AssumeOnlyValues;
1405 DenseSet<const AA::InstExclusionSetTy *> BESets;
1411 SmallPtrSet<const Function *, 8> InlineableFunctions;
1414 Triple TargetTriple;
1459 Function &AssumedCallee,
unsigned NumAssumedCallees)>
1487 "How many AAs should be initialized");
1558 template <
typename AAType>
1561 return getOrCreateAAFor<AAType>(IRP, &QueryingAA, DepClass,
1570 template <
typename AAType>
1573 DepClassTy DepClass,
bool ForceUpdate =
false,
1574 bool UpdateAfterInit =
true) {
1575 if (!shouldPropagateCallBaseContext(IRP))
1578 if (AAType *AAPtr = lookupAAFor<AAType>(IRP, QueryingAA, DepClass,
1580 if (ForceUpdate && Phase == AttributorPhase::UPDATE)
1585 bool ShouldUpdateAA;
1586 if (!shouldInitialize<AAType>(IRP, ShouldUpdateAA))
1594 auto &AA = AAType::createForPosition(IRP, *
this);
1601 if (Phase == AttributorPhase::SEEDING && !shouldSeedAttribute(AA)) {
1602 AA.getState().indicatePessimisticFixpoint();
1610 return AA.getName() +
1611 std::to_string(AA.getIRPosition().getPositionKind());
1613 ++InitializationChainLength;
1614 AA.initialize(*
this);
1615 --InitializationChainLength;
1618 if (!ShouldUpdateAA) {
1619 AA.getState().indicatePessimisticFixpoint();
1625 if (UpdateAfterInit) {
1626 AttributorPhase OldPhase = Phase;
1627 Phase = AttributorPhase::UPDATE;
1640 template <
typename AAType>
1642 return getOrCreateAAFor<AAType>(IRP,
nullptr,
1648 template <
typename AAType>
1652 bool AllowInvalidState =
false) {
1653 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1654 "Cannot query an attribute with a type not derived from "
1655 "'AbstractAttribute'!");
1662 AAType *AA =
static_cast<AAType *
>(AAPtr);
1671 if (!AllowInvalidState && !AA->getState().isValidState())
1701 static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
1702 "Cannot register an attribute with a type not derived from "
1703 "'AbstractAttribute'!");
1709 assert(!AAPtr &&
"Attribute already in map!");
1713 if (Phase == AttributorPhase::SEEDING || Phase == AttributorPhase::UPDATE)
1730 unsigned NumAssumedCallees) {
1733 *
this, AA, CB, Callee, NumAssumedCallees)
1744 return Functions.
empty() || Functions.
count(Fn);
1750 if (Phase == AttributorPhase::MANIFEST || Phase == AttributorPhase::CLEANUP)
1757 if (!AssociatedFn && AAType::requiresCalleeForCallBase())
1761 if (AAType::requiresNonAsmForCallBase() &&
1767 if (AAType::requiresCallersForArgOrFunction())
1773 if (!AAType::isValidIRPositionForUpdate(*
this, IRP))
1782 template <
typename AAType>
1784 if (!AAType::isValidIRPositionForInit(*
this, IRP))
1800 ShouldUpdateAA = shouldUpdateAA<AAType>(IRP);
1802 return !AAType::hasTrivialInitializer() || ShouldUpdateAA;
1822 return F.hasExactDefinition() || InfoCache.InlineableFunctions.count(&
F) ||
1832 "Only local linkage is assumed dead initially.");
1843 Value *&V = ToBeChangedUses[&U];
1844 if (V && (V->stripPointerCasts() == NV.stripPointerCasts() ||
1845 isa_and_nonnull<UndefValue>(V)))
1847 assert((!V || V == &NV || isa<UndefValue>(NV)) &&
1848 "Use was registered twice for replacement with different values!");
1857 bool ChangeDroppable =
true) {
1859 auto *CB = cast<CallBase>(IRP.
getCtxI());
1864 auto &Entry = ToBeChangedValues[&V];
1865 Value *CurNV = get<0>(Entry);
1867 isa<UndefValue>(CurNV)))
1869 assert((!CurNV || CurNV == &NV || isa<UndefValue>(NV)) &&
1870 "Value replacement was registered twice with different values!");
1871 Entry = {&NV, ChangeDroppable};
1878 ToBeChangedToUnreachableInsts.insert(
I);
1885 InvokeWithDeadSuccessor.insert(&
II);
1899 ManifestAddedBlocks.insert(&BB);
1905 ToBeDeletedFunctions.insert(&
F);
1919 bool IgnoreSubsumingPositions =
false,
1932 bool IgnoreSubsumingPositions =
false);
1943 bool ForceReplace =
false);
1948 template <Attribute::AttrKind AK,
typename AAType>
1952 template <
typename DescTy>
1966 bool &UsedAssumedInformation);
1969 bool &UsedAssumedInformation) {
1977 bool &UsedAssumedInformation,
1983 bool &UsedAssumedInformation,
1986 UsedAssumedInformation, S);
1995 bool &UsedAssumedInformation,
2008 bool &UsedAssumedInformation,
2009 bool RecurseForSelectAndPHI =
true);
2020 SimplificationCallbacks[IRP].emplace_back(CB);
2025 return SimplificationCallbacks.count(IRP);
2032 std::function<std::optional<Constant *>(
2037 GlobalVariableSimplificationCallbacks[&GV].emplace_back(CB);
2042 return GlobalVariableSimplificationCallbacks.count(&GV);
2048 std::optional<Constant *>
2051 bool &UsedAssumedInformation) {
2052 assert(GlobalVariableSimplificationCallbacks.contains(&GV));
2053 for (
auto &CB : GlobalVariableSimplificationCallbacks.lookup(&GV)) {
2054 auto SimplifiedGV = CB(GV, AA, UsedAssumedInformation);
2056 assert(SimplifiedGV.has_value() &&
"SimplifiedGV has not value");
2057 return *SimplifiedGV;
2066 VirtualUseCallbacks[&V].emplace_back(CB);
2072 SimplificationCallbacks;
2078 GlobalVariableSimplificationCallbacks;
2081 VirtualUseCallbacks;
2085 std::optional<Value *>
2088 bool &UsedAssumedInformation);
2094 bool &UsedAssumedInformation,
2095 bool CheckBBLivenessOnly =
false,
2102 const AAIsDead *LivenessAA,
bool &UsedAssumedInformation,
2103 bool CheckBBLivenessOnly =
false,
2105 bool CheckForDeadStore =
false);
2111 const AAIsDead *FnLivenessAA,
bool &UsedAssumedInformation,
2112 bool CheckBBLivenessOnly =
false,
2119 const AAIsDead *FnLivenessAA,
bool &UsedAssumedInformation,
2120 bool CheckBBLivenessOnly =
false,
2150 bool CheckBBLivenessOnly =
false,
2152 bool IgnoreDroppableUses =
true,
2154 EquivalentUseCB =
nullptr);
2167 template <
typename RemarkKind,
typename RemarkCallBack>
2169 RemarkCallBack &&RemarkCB)
const {
2178 return RemarkCB(RemarkKind(Configuration.
PassName, RemarkName,
I))
2179 <<
" [" << RemarkName <<
"]";
2183 return RemarkCB(RemarkKind(Configuration.
PassName, RemarkName,
I));
2188 template <
typename RemarkKind,
typename RemarkCallBack>
2190 RemarkCallBack &&RemarkCB)
const {
2198 return RemarkCB(RemarkKind(Configuration.
PassName, RemarkName,
F))
2199 <<
" [" << RemarkName <<
"]";
2203 return RemarkCB(RemarkKind(Configuration.
PassName, RemarkName,
F));
2245 return ReplacementTypes;
2258 : A(A), ReplacedFn(*Arg.
getParent()), ReplacedArg(Arg),
2259 ReplacementTypes(ReplacementTypes),
2260 CalleeRepairCB(
std::
move(CalleeRepairCB)),
2261 ACSRepairCB(
std::
move(ACSRepairCB)) {}
2317 bool RequireAllCallSites,
2318 bool &UsedAssumedInformation);
2328 const Function &Fn,
bool RequireAllCallSites,
2330 bool &UsedAssumedInformation,
2331 bool CheckPotentiallyDead =
false);
2341 bool RecurseForSelectAndPHI =
true);
2352 bool &UsedAssumedInformation,
2353 bool CheckBBLivenessOnly =
false,
2354 bool CheckPotentiallyDead =
false);
2363 bool &UsedAssumedInformation,
2364 bool CheckBBLivenessOnly =
false,
2365 bool CheckPotentiallyDead =
false);
2372 bool &UsedAssumedInformation,
2373 bool CheckBBLivenessOnly =
false,
2374 bool CheckPotentiallyDead =
false) {
2377 {(
unsigned)Instruction::Invoke, (
unsigned)Instruction::CallBr,
2379 UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
2389 bool &UsedAssumedInformation);
2449 return CGModifiedFunctions;
2459 void runTillFixpoint();
2471 void identifyDeadInternalFunctions();
2479 void rememberDependences();
2482 bool shouldPropagateCallBaseContext(
const IRPosition &IRP);
2498 using AAMapKeyTy = std::pair<const char *, IRPosition>;
2504 ArgumentReplacementMap;
2534 using DependenceVector = SmallVector<DepInfo, 8>;
2535 SmallVector<DependenceVector *, 16> DependenceStack;
2538 DenseSet<const Function *> VisitedFunctions;
2542 SmallMapVector<Use *, Value *, 32> ToBeChangedUses;
2546 SmallMapVector<Value *, PointerIntPair<Value *, 1, bool>, 32>
2550 SmallSetVector<WeakVH, 16> ToBeChangedToUnreachableInsts;
2553 SmallSetVector<WeakVH, 16> InvokeWithDeadSuccessor;
2557 enum class AttributorPhase {
2562 } Phase = AttributorPhase::SEEDING;
2565 unsigned InitializationChainLength = 0;
2570 SmallPtrSet<BasicBlock *, 8> ManifestAddedBlocks;
2571 SmallSetVector<Function *, 8> ToBeDeletedFunctions;
2572 SmallSetVector<BasicBlock *, 8> ToBeDeletedBlocks;
2573 SmallSetVector<WeakVH, 8> ToBeDeletedInsts;
2578 SmallSetVector<AbstractAttribute *, 16> QueryAAsAwaitingUpdate;
2581 const AttributorConfig Configuration;
2584 friend AttributorCallGraph;
2642template <
typename base_ty, base_ty BestState, base_ty WorstState>
2696 return !(*
this == R);
2714 joinOR(R.getAssumed(), R.getKnown());
2718 joinAND(R.getAssumed(), R.getKnown());
2742template <
typename base_ty =
uint32_t, base_ty BestState = ~base_ty(0),
2743 base_ty WorstState = 0>
2753 return (this->
Known & BitsEncoding) == BitsEncoding;
2758 return (this->
Assumed & BitsEncoding) == BitsEncoding;
2765 this->
Known |= Bits;
2788 void handleNewAssumedValue(
base_t Value)
override {
2792 void joinOR(
base_t AssumedValue,
base_t KnownValue)
override {
2793 this->
Known |= KnownValue;
2794 this->
Assumed |= AssumedValue;
2796 void joinAND(
base_t AssumedValue,
base_t KnownValue)
override {
2797 this->
Known &= KnownValue;
2798 this->
Assumed &= AssumedValue;
2804template <
typename base_ty =
uint32_t, base_ty BestState = ~base_ty(0),
2805 base_ty WorstState = 0>
2837 void handleNewAssumedValue(
base_t Value)
override {
2841 void joinOR(
base_t AssumedValue,
base_t KnownValue)
override {
2842 this->
Known = std::max(this->
Known, KnownValue);
2845 void joinAND(
base_t AssumedValue,
base_t KnownValue)
override {
2846 this->
Known = std::min(this->
Known, KnownValue);
2853template <
typename base_ty = u
int32_t>
2873 void handleNewAssumedValue(
base_t Value)
override {
2877 void joinOR(
base_t AssumedValue,
base_t KnownValue)
override {
2881 void joinAND(
base_t AssumedValue,
base_t KnownValue)
override {
2911 void handleNewAssumedValue(
base_t Value)
override {
2915 void handleNewKnownValue(
base_t Value)
override {
2919 void joinOR(
base_t AssumedValue,
base_t KnownValue)
override {
2920 Known |= KnownValue;
2923 void joinAND(
base_t AssumedValue,
base_t KnownValue)
override {
2924 Known &= KnownValue;
2951 return ConstantRange::getFull(
BitWidth);
2956 return ConstantRange::getEmpty(
BitWidth);
3051 : Universal(
false), Set(Assumptions) {}
3054 : Universal(Universal), Set(Assumptions) {}
3065 bool IsUniversal = Universal;
3069 if (
RHS.isUniversal())
3078 Universal &=
RHS.isUniversal();
3079 return IsUniversal != Universal ||
Size != Set.
size();
3085 bool IsUniversal = Universal;
3089 if (!
RHS.isUniversal() && !Universal)
3092 Universal |=
RHS.isUniversal();
3093 return IsUniversal != Universal ||
Size != Set.
size();
3109 : Known(Known), Assumed(
true), IsAtFixedpoint(
false) {}
3119 IsAtFixedpoint =
true;
3126 IsAtFixedpoint =
true;
3146 unsigned SizeBefore = Assumed.
getSet().
size();
3153 return SizeBefore != Assumed.
getSet().
size() ||
3166 SetContents Assumed;
3168 bool IsAtFixedpoint;
3188template <Attribute::AttrKind AK,
typename BaseType,
typename AAType>
3210 bool IgnoreSubsumingPositions =
false) {
3213 if (AAType::isImpliedByPoison() &&
3216 return A.hasAttr(IRP, {ImpliedAttributeKind}, IgnoreSubsumingPositions,
3217 ImpliedAttributeKind);
3222 if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
3226 if (DeducedAttrs.
empty())
3228 return A.manifestAttrs(this->getIRPosition(), DeducedAttrs);
3327 assert((!IsFnInterface || AssociatedFn) &&
3328 "Function interface without a function?");
3337 return !IsFnInterface ||
A.isFunctionIPOAmendable(*AssociatedFn);
3428template <
typename base_ty, base_ty BestState, base_ty WorstState>
3435raw_ostream &
operator<<(raw_ostream &
OS,
const IntegerRangeState &State);
3463template <
typename StateType>
3465 auto Assumed = S.getAssumed();
3477 StateWrapper<BooleanState, AbstractAttribute>,
3491 const std::string
getName()
const override {
return "AANoUnwind"; }
3507 StateWrapper<BooleanState, AbstractAttribute>,
3513 bool IgnoreSubsumingPositions =
false) {
3515 assert(ImpliedAttributeKind == Attribute::NoSync);
3516 if (
A.hasAttr(IRP, {Attribute::NoSync}, IgnoreSubsumingPositions,
3524 if (!
F ||
F->isConvergent())
3528 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
3532 ME &= Attr.getMemoryEffects();
3546 return IRAttribute::isValidIRPositionForInit(
A, IRP);
3574 const std::string
getName()
const override {
return "AANoSync"; }
3591 StateWrapper<BooleanState, AbstractAttribute>,
3597 bool IgnoreSubsumingPositions =
false) {
3599 assert(ImpliedAttributeKind == Attribute::MustProgress);
3600 return A.hasAttr(IRP, {Attribute::MustProgress, Attribute::WillReturn},
3601 IgnoreSubsumingPositions, Attribute::MustProgress);
3615 const std::string
getName()
const override {
return "AAMustProgress"; }
3633 StateWrapper<BooleanState, AbstractAttribute>,
3649 return IRAttribute::isValidIRPositionForInit(
A, IRP);
3655 bool IgnoreSubsumingPositions =
false);
3667 const std::string
getName()
const override {
return "AANonNull"; }
3684 StateWrapper<BooleanState, AbstractAttribute>,
3698 const std::string
getName()
const override {
return "AANoRecurse"; }
3715 StateWrapper<BooleanState, AbstractAttribute>,
3721 bool IgnoreSubsumingPositions =
false) {
3723 assert(ImpliedAttributeKind == Attribute::WillReturn);
3725 IgnoreSubsumingPositions))
3730 Attribute::WillReturn));
3739 if (!
A.hasAttr(IRP, {Attribute::MustProgress}))
3743 A.getAttrs(IRP, {Attribute::Memory}, Attrs,
3748 ME &= Attr.getMemoryEffects();
3762 const std::string
getName()
const override {
return "AAWillReturn"; }
3778 :
public StateWrapper<BooleanState, AbstractAttribute> {
3799 const std::string
getName()
const override {
return "AAUndefinedBehavior"; }
3816 :
public StateWrapper<BooleanState, AbstractAttribute> {
3832 const std::string
getName()
const override {
return "AAIntraFnReachability"; }
3850 StateWrapper<BooleanState, AbstractAttribute>,
3858 return IRAttribute::isValidIRPositionForInit(
A, IRP);
3864 bool IgnoreSubsumingPositions =
false);
3879 const std::string
getName()
const override {
return "AANoAlias"; }
3896 StateWrapper<BooleanState, AbstractAttribute>,
3903 bool IgnoreSubsumingPositions =
false) {
3905 assert(ImpliedAttributeKind == Attribute::NoFree);
3907 IRP, {Attribute::ReadNone, Attribute::ReadOnly, Attribute::NoFree},
3908 IgnoreSubsumingPositions, Attribute::NoFree);
3916 return IRAttribute::isValidIRPositionForInit(
A, IRP);
3929 const std::string
getName()
const override {
return "AANoFree"; }
3946 StateWrapper<BooleanState, AbstractAttribute>,
3960 const std::string
getName()
const override {
return "AANoReturn"; }
3976 :
public StateWrapper<BitIntegerState<uint8_t, 3, 0>, AbstractAttribute> {
4027 "Instruction must be in the same anchor scope function.");
4055 const std::string
getName()
const override {
return "AAIsDead"; }
4080 DS.indicatePessimisticFixpoint();
4117 void computeKnownDerefBytesFromAccessedMap() {
4120 if (KnownBytes <
Access.first)
4122 KnownBytes = std::max(KnownBytes,
Access.first + (int64_t)
Access.second);
4155 void takeKnownDerefBytesMaximum(
uint64_t Bytes) {
4159 computeKnownDerefBytesFromAccessedMap();
4163 void takeAssumedDerefBytesMinimum(
uint64_t Bytes) {
4170 AccessedBytes = std::max(AccessedBytes,
Size);
4173 computeKnownDerefBytesFromAccessedMap();
4178 return this->DerefBytesState ==
R.DerefBytesState &&
4179 this->GlobalState ==
R.GlobalState;
4183 bool operator!=(
const DerefState &R)
const {
return !(*
this ==
R); }
4188 GlobalState ^=
R.GlobalState;
4195 GlobalState +=
R.GlobalState;
4202 GlobalState &=
R.GlobalState;
4209 GlobalState |=
R.GlobalState;
4217 StateWrapper<DerefState, AbstractAttribute>,
4218 AADereferenceable> {
4225 return IRAttribute::isValidIRPositionForInit(
A, IRP);
4251 const std::string
getName()
const override {
return "AADereferenceable"; }
4271 StateWrapper<AAAlignmentStateType, AbstractAttribute>,
4279 return IRAttribute::isValidIRPositionForInit(
A, IRP);
4289 const std::string
getName()
const override {
return "AAAlign"; }
4331 const std::string
getName()
const override {
return "AAInstanceInfo"; }
4349 Attribute::NoCapture,
4350 StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>,
4357 bool IgnoreSubsumingPositions =
false);
4369 return IRAttribute::isValidIRPositionForInit(
A, IRP);
4413 const std::string
getName()
const override {
return "AANoCapture"; }