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"; }
4441 DS.indicatePessimisticFixpoint();
4503 :
public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
4513 const std::string
getName()
const override {
return "AAValueSimplify"; }
4533 virtual std::optional<Value *>
4534 getAssumedSimplifiedValue(
Attributor &
A)
const = 0;
4554 const std::string
getName()
const override {
return "AAHeapToStack"; }
4579 :
public StateWrapper<BooleanState, AbstractAttribute> {
4609 const std::string
getName()
const override {
return "AAPrivatizablePtr"; }
4629 StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>,
4641 return IRAttribute::isValidIRPositionForInit(
A, IRP);
4684 const std::string
getName()
const override {
return "AAMemoryBehavior"; }
4704 StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>,
4721 return IRAttribute::isValidIRPositionForInit(
A, IRP);
4869 const std::string
getName()
const override {
return "AAMemoryLocation"; }
4886 :
public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
4923 std::optional<Constant *>
4928 return cast_or_null<Constant>(
4932 return std::nullopt;
4937 const std::string
getName()
const override {
return "AAValueConstantRange"; }
4966 : IsValidState(IsValid), UndefIsContained(
false) {}
4998 return UndefIsContained;
5008 return Set ==
RHS.getAssumedSet();
5040 IsValidState ^= PVS.IsValidState;
5046 IsValidState &= PVS.IsValidState;
5064 void checkAndInvalidate() {
5073 void reduceUndefValue() { UndefIsContained = UndefIsContained & Set.
empty(); }
5080 checkAndInvalidate();
5089 if (!
R.isValidState()) {
5095 UndefIsContained |=
R.undefIsContained();
5096 checkAndInvalidate();
5100 void unionWithUndef() {
5101 UndefIsContained =
true;
5108 if (!
R.isValidState())
5121 UndefIsContained &=
R.undefIsContained();
5126 BooleanState IsValidState;
5132 bool UndefIsContained;
5153 if (Caller == Callee)
5170 Callee.ModeF32 =
unionAssumed(Callee.ModeF32, Caller.ModeF32);
5245 :
public StateWrapper<PotentialConstantIntValuesState, AbstractAttribute> {
5270 std::optional<Constant *>
5283 return std::nullopt;
5291 return "AAPotentialConstantValues";
5308 :
public StateWrapper<PotentialLLVMValuesState, AbstractAttribute> {
5329 const std::string
getName()
const override {
return "AAPotentialValues"; }
5344 virtual bool getAssumedSimplifiedValues(
5354 StateWrapper<BooleanState, AbstractAttribute>,
5367 bool IgnoreSubsumingPositions =
false);
5379 const std::string
getName()
const override {
return "AANoUndef"; }
5395 Attribute::NoFPClass,
5396 StateWrapper<BitIntegerState<uint32_t, fcAllFlags, fcNone>,
5409 return IRAttribute::isValidIRPositionForInit(
A, IRP);
5430 const std::string
getName()
const override {
return "AANoFPClass"; }
5452 SetVector<Function *>::iterator> {
5519 const std::string
getName()
const override {
return "AACallEdges"; }
5562 return Node->optimisticEdgesBegin();
5566 return Node->optimisticEdgesEnd();
5580 return G->optimisticEdgesBegin();
5584 return G->optimisticEdgesEnd();
5606 :
public StateWrapper<BooleanState, AbstractAttribute> {
5641 const std::string
getName()
const override {
return "AAExecutionDomain"; }
5663 virtual std::pair<ExecutionDomainTy, ExecutionDomainTy>
5683 :
public StateWrapper<BooleanState, AbstractAttribute> {
5691 if (!Scope || Scope->isDeclaration())
5707 const std::string
getName()
const override {
return "AAInterFnReachability"; }
5739 const std::string
getName()
const override {
return "AANonConvergent"; }
5826 Offsets = std::move(NewOffsets);
5851 for (
unsigned i = 0, e = Offsets.size(); i != e; ++i) {
5852 assert(((i + 1 == e) || Offsets[i] < Offsets[i + 1]) &&
5853 "Expected strictly ascending offsets.");
5868 "Ensure the last element is the greatest.");
5875 std::set_difference(L.begin(), L.end(), R.begin(), R.end(),
5890 if (
RHS.isUnknown()) {
5900 bool Changed =
false;
5902 for (
auto &R :
RHS.Ranges) {
5903 auto Result =
insert(LPos, R);
5906 LPos = Result.first;
5907 Changed |= Result.second;
5921 if (R.offsetOrSizeAreUnknown()) {
5927 if (LB ==
Ranges.
end() || LB->Offset != R.Offset)
5929 bool Changed = *LB != R;
5931 if (LB->offsetOrSizeAreUnknown())
5933 return std::make_pair(LB, Changed);
5946 "Cannot increment if the offset is not yet computed!");
5997 : LocalI(LocalI), RemoteI(RemoteI),
Content(
Content), Ranges(Ranges),
5999 if (Ranges.size() > 1) {
6016 return LocalI == R.LocalI && RemoteI == R.RemoteI && Ranges == R.Ranges &&
6017 Content == R.Content &&
Kind == R.Kind;
6022 assert(RemoteI == R.RemoteI &&
"Expected same instruction!");
6023 assert(LocalI == R.LocalI &&
"Expected same instruction!");
6029 Ranges.
merge(R.Ranges);
6047 "Expect must or may access, not both.");
6049 "Expect assumption access or write access, never both.");
6051 "Cannot be a must access if there are multiple ranges.");
6072 "Cannot be a must access if there are multiple ranges.");
6079 "Cannot be a must access if there are multiple ranges.");
6095 return Content.has_value() && !*Content;
6107 "Value needs to be determined before accessing it.");
6145 std::optional<Value *> Content;
6162 const std::string
getName()
const override {
return "AAPointerInfo"; }
6193 bool FindInterferingWrites,
bool FindInterferingReads,
6211 :
public StateWrapper<SetState<StringRef>, AbstractAttribute,
6212 DenseSet<StringRef>> {
6218 :
Base(IRP, Known) {}
6228 const std::string
getName()
const override {
return "AAAssumptionInfo"; }
6262 const std::string
getName()
const override {
return "AAUnderlyingObjects"; }
6310 const std::string
getName()
const override {
return "AAAddressSpace"; }
6347 const std::string
getName()
const override {
return "AAAllocationInfo"; }
6359 std::optional<TypeSize>(
TypeSize(-1,
true));
6366 :
public StateWrapper<BooleanState, AbstractAttribute> {
6377 return GV->hasLocalLinkage();
6388 const std::string
getName()
const override {
return "AAGlobalValueInfo"; }
6405 :
public StateWrapper<BooleanState, AbstractAttribute> {
6413 auto *CB = cast<CallBase>(IRP.
getCtxI());
6414 return CB->getOpcode() == Instruction::Call && CB->isIndirectCall() &&
6415 !CB->isMustTailCall();
6427 const std::string
getName()
const override {
return "AAIndirectCallInfo"; }
6447 :
public StateWrapper<DenormalFPMathState, AbstractAttribute> {
6457 const std::string
getName()
const override {
return "AADenormalFPMath"; }
6484template <Attribute::AttrKind AK,
typename AAType = AbstractAttribute>
6487 bool IgnoreSubsumingPositions =
false,
6488 const AAType **AAPtr =
nullptr) {
6491#define CASE(ATTRNAME, AANAME, ...) \
6492 case Attribute::ATTRNAME: { \
6493 if (AANAME::isImpliedByIR(A, IRP, AK, IgnoreSubsumingPositions)) \
6494 return IsKnown = true; \
6497 const auto *AA = A.getAAFor<AANAME>(*QueryingAA, IRP, DepClass); \
6499 *AAPtr = reinterpret_cast<const AAType *>(AA); \
6500 if (!AA || !AA->isAssumed(__VA_ARGS__)) \
6502 IsKnown = AA->isKnown(__VA_ARGS__); \
6521 llvm_unreachable(
"hasAssumedIRAttr not available for this attribute kind");
aarch64 AArch64 CCMP Pass
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
This file contains the simple types necessary to represent the attributes associated with functions a...
#define CASE(ATTRNAME, AANAME,...)
static const Function * getParent(const Value *V)
block Block Frequency Analysis
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This header provides classes for managing passes over SCCs of the call graph.
This file provides interfaces used to manipulate a call graph, regardless if it is a "old style" Call...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseSet and SmallDenseSet classes.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Implements a lazy call graph analysis and related passes for the new pass manager.
This file implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
static SymbolRef::Type getType(const Symbol *Sym)
An Iterator for call edges, creates AACallEdges attributes in a lazy way.
AACallGraphNode * operator*() const
CallBase * getInstruction() const
Return the underlying instruction.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
unsigned getNumArgOperands() const
Return the number of parameters of the callee.
A container for analyses that lazily runs them and caches their results.
void clear(IRUnitT &IR, llvm::StringRef Name)
Clear any cached analysis results for a single unit of IR.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
const Function * getParent() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This represents the llvm.assume intrinsic.
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
@ None
No attributes have been set.
static bool isEnumAttrKind(AttrKind Kind)
LLVM Basic Block Representation.
Allocate memory in an ever growing pool, as if by bump-pointer.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph.
This class represents a range of values.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
bool isEmptySet() const
Return true if this set contains no members.
ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
static bool shouldExecute(unsigned CounterName)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
An instruction for ordering other memory operations.
AttributeList getAttributes() const
Return the attribute list for this Function.
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Type * getReturnType() const
Returns the type of the ret val.
Argument * getArg(unsigned i) const
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool hasLocalLinkage() const
Module * getParent()
Get the module that this global value is contained inside of...
This is an important class for using LLVM in a threaded context.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
static MemoryEffectsBase unknown()
Create MemoryEffectsBase that can read and write any memory.
A Module instance is used to store all the information related to an LLVM module.
Pass interface - Implemented by all 'passes'.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
PointerIntPair - This class implements a pair of a pointer and small integer.
void * getOpaqueValue() const
PointerTy getPointer() const
void setFromOpaqueValue(void *Val) &
Analysis pass which computes a PostDominatorTree.
A set of analyses that are preserved following a run of a transformation pass.
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
typename vector_type::const_iterator iterator
iterator end()
Get an iterator to the end of the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallSetIterator - This class implements a const_iterator for SmallSet by delegating to the underlyin...
A SetVector that performs no allocations if smaller than a certain size.
const_iterator begin() const
SmallSetIterator< int64_t, N, std::less< int64_t > > const_iterator
const_iterator end() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
A visitor class for IR positions.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
bool isNVPTX() const
Tests whether the target is NVPTX (32- or 64-bit).
The instances of the Type class are immutable: once they are created, they are never changed.
bool isArrayTy() const
True if this is an instance of ArrayType.
Type * getArrayElementType() const
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
StringRef getName() const
Return a constant reference to the value's name.
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
CRTP base class for adapting an iterator to a different type.
iterator_adaptor_base()=default
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
bool operator!=(const RangeTy &A, const RangeTy &B)
bool isPotentiallyAffectedByBarrier(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is potentially affected by a barrier.
bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
Constant * getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA, Value &Obj, Type &Ty, const TargetLibraryInfo *TLI, const DataLayout &DL, RangeTy *RangePtr=nullptr)
Return the initial value of Obj with type Ty if that is a constant.
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
E & operator^=(E &LHS, E RHS)
@ C
The default llvm calling convention, compatible with C.
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
DenseMap< RetainedKnowledgeKey, Assume2KnowledgeMap > RetainedKnowledgeMap
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
unsigned MaxInitializationChainLength
The value passed to the line option that defines the maximal initialization chain length.
APInt operator&(APInt a, const APInt &b)
void set_intersect(S1Ty &S1, const S2Ty &S2)
set_intersect(A, B) - Compute A := A ^ B Identical to set_intersection, except that it works on set<>...
bool operator!=(uint64_t V1, const APInt &V2)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt & operator+=(DynamicAPInt &A, int64_t B)
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
AttributorRunOption
Run options, used by the pass manager.
bool canSimplifyInvokeNoUnwind(const Function *F)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
bool operator&=(SparseBitVector< ElementSize > *LHS, const SparseBitVector< ElementSize > &RHS)
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
@ OPTIONAL
The target may be valid if the source is not.
@ NONE
Do not track a dependence between source and target.
@ REQUIRED
The target cannot be valid if the source is not.
APInt operator|(APInt a, const APInt &b)
Implement std::hash so that hash_code can be used in STL containers.
An abstract interface for address space information.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAssumptionInfo.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
virtual uint32_t getAddressSpace() const =0
Return the address space of the associated value.
static const char ID
Unique ID (due to the unique address)
const std::string getName() const override
See AbstractAttribute::getName()
AAAddressSpace(const IRPosition &IRP, Attributor &A)
static AAAddressSpace & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static const uint32_t InvalidAddressSpace
An abstract interface for all align attributes.
AAAlign(const IRPosition &IRP, Attributor &A)
static const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
const std::string getName() const override
See AbstractAttribute::getName()
Align getAssumedAlign() const
Return assumed alignment.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAlign.
static AAAlign & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
Align getKnownAlign() const
Return known alignment.
virtual std::optional< TypeSize > getAllocatedSize() const =0
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
const std::string getName() const override
See AbstractAttribute::getName()
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static AAAllocationInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AAAllocationInfo(const IRPosition &IRP, Attributor &A)
static constexpr const std::optional< TypeSize > HasNoAllocationSize
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAllocationInfo.
An abstract attribute for getting assumption information.
AAAssumptionInfo(const IRPosition &IRP, Attributor &A, const DenseSet< StringRef > &Known)
const std::string getName() const override
See AbstractAttribute::getName()
static const char ID
Unique ID (due to the unique address)
static AAAssumptionInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAAssumptionInfo.
virtual bool hasAssumption(const StringRef Assumption) const =0
Returns true if the assumption set contains the assumption Assumption.
An abstract state for querying live call edges.
AACallEdges(const IRPosition &IRP, Attributor &A)
virtual const SetVector< Function * > & getOptimisticEdges() const =0
Get the optimistic edges.
static bool requiresNonAsmForCallBase()
See AbstractAttribute::requiresNonAsmForCallBase.
AACallEdgeIterator optimisticEdgesBegin() const override
Iterator for exploring the call graph.
virtual bool hasUnknownCallee() const =0
Is there any call with a unknown callee.
static const char ID
Unique ID (due to the unique address)
virtual bool hasNonAsmUnknownCallee() const =0
Is there any call with a unknown callee, excluding any inline asm.
AACallEdgeIterator optimisticEdgesEnd() const override
Iterator for exploring the call graph.
static AACallEdges & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AACallEdges.
const std::string getName() const override
See AbstractAttribute::getName()
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
iterator_range< AACallEdgeIterator > optimisticEdgesRange() const
Iterator range for exploring the call graph.
virtual AACallEdgeIterator optimisticEdgesBegin() const =0
AACallGraphNode(Attributor &A)
virtual AACallEdgeIterator optimisticEdgesEnd() const =0
virtual ~AACallGraphNode()=default
Attributor & A
Reference to Attributor needed for GraphTraits implementation.
An abstract Attribute for specializing "dynamic" components of "denormal-fp-math" and "denormal-fp-ma...
const std::string getName() const override
See AbstractAttribute::getName()
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
AADenormalFPMath(const IRPosition &IRP, Attributor &A)
static AADenormalFPMath & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static const char ID
Unique ID (due to the unique address)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AADenormalFPMath.
static AbstractAttribute * DepGetValAA(const DepTy &DT)
mapped_iterator< DepSetTy::iterator, decltype(&DepGetVal)> iterator
virtual ~AADepGraphNode()=default
mapped_iterator< DepSetTy::iterator, decltype(&DepGetValAA)> aaiterator
static AADepGraphNode * DepGetVal(const DepTy &DT)
DepSetTy Deps
Set of dependency graph nodes which should be updated if this one is updated.
virtual void print(Attributor *, raw_ostream &OS) const
PointerIntPair< AADepGraphNode *, 1 > DepTy
void print(raw_ostream &OS) const
The data structure for the dependency graph.
AADepGraphNode SyntheticRoot
There is no root node for the dependency graph.
void print()
Print dependency graph.
static AADepGraphNode * DepGetVal(const DepTy &DT)
void dumpGraph()
Dump graph to file.
AADepGraphNode * GetEntryNode()
An abstract interface for all dereferenceable attribute.
uint32_t getKnownDereferenceableBytes() const
Return known dereferenceable bytes.
const std::string getName() const override
See AbstractAttribute::getName()
bool isAssumedGlobal() const
Return true if we assume that underlying value is dereferenceable(_or_null) globally.
bool isKnownGlobal() const
Return true if we know that underlying value is dereferenceable(_or_null) globally.
AADereferenceable(const IRPosition &IRP, Attributor &A)
uint32_t getAssumedDereferenceableBytes() const
Return assumed dereferenceable bytes.
static AADereferenceable & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static const char ID
Unique ID (due to the unique address)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AADereferenceable.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
Summary about the execution domain of a block or instruction.
bool IsExecutedByInitialThreadOnly
BarriersSetTy AlignedBarriers
void addAssumeInst(Attributor &A, AssumeInst &AI)
bool EncounteredNonLocalSideEffect
void addAlignedBarrier(Attributor &A, CallBase &CB)
void clearAssumeInstAndAlignedBarriers()
bool IsReachedFromAlignedBarrierOnly
bool IsReachingAlignedBarrierOnly
AssumesSetTy EncounteredAssumes
const std::string getName() const override
See AbstractAttribute::getName().
virtual bool isExecutedByInitialThreadOnly(const BasicBlock &) const =0
Check if a basic block is executed only by the initial thread.
bool isExecutedByInitialThreadOnly(const Instruction &I) const
Check if an instruction is executed only by the initial thread.
static AAExecutionDomain & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAExecutionDomain.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr().
virtual ExecutionDomainTy getFunctionExecutionDomain() const =0
virtual ExecutionDomainTy getExecutionDomain(const BasicBlock &) const =0
virtual bool isExecutedInAlignedRegion(Attributor &A, const Instruction &I) const =0
Check if the instruction I is executed in an aligned region, that is, the synchronizing effects befor...
AAExecutionDomain(const IRPosition &IRP, Attributor &A)
virtual bool isNoOpFence(const FenceInst &FI) const =0
Helper function to determine if FI is a no-op given the information about its execution from ExecDoma...
virtual std::pair< ExecutionDomainTy, ExecutionDomainTy > getExecutionDomain(const CallBase &CB) const =0
Return the execution domain with which the call CB is entered and the one with which it is left.
static const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static AAGlobalValueInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAGlobalValueInfo.
AAGlobalValueInfo(const IRPosition &IRP, Attributor &A)
const std::string getName() const override
See AbstractAttribute::getName()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static const char ID
Unique ID (due to the unique address)
virtual bool isPotentialUse(const Use &U) const =0
Return true iff U is a potential use of the associated global value.
const std::string getName() const override
See AbstractAttribute::getName()
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAHeapToStack.
virtual bool isAssumedHeapToStack(const CallBase &CB) const =0
Returns true if HeapToStack conversion is assumed to be possible.
virtual bool isAssumedHeapToStackRemovedFree(CallBase &CB) const =0
Returns true if HeapToStack conversion is assumed and the CB is a callsite to a free operation to be ...
static const char ID
Unique ID (due to the unique address)
AAHeapToStack(const IRPosition &IRP, Attributor &A)
static AAHeapToStack & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
An abstract interface for indirect call information interference.
static AAIndirectCallInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
virtual bool foreachCallee(function_ref< bool(Function *)> CB) const =0
Call \CB on each potential callee value and return true if all were known and CB returned true on all...
const std::string getName() const override
See AbstractAttribute::getName()
AAIndirectCallInfo(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAIndirectCallInfo This function should ret...
static const char ID
Unique ID (due to the unique address)
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
An abstract interface to track if a value leaves it's defining function instance.
const std::string getName() const override
See AbstractAttribute::getName()
static const char ID
Unique ID (due to the unique address)
bool isKnownUniqueForAnalysis() const
Return true if we know that the underlying value is unique in its scope wrt.
AAInstanceInfo(const IRPosition &IRP, Attributor &A)
bool isAssumedUniqueForAnalysis() const
Return true if we assume that the underlying value is unique in its scope wrt.
static AAInstanceInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAInstanceInfo.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
An abstract Attribute for computing reachability between functions.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AACallEdges.
const std::string getName() const override
See AbstractAttribute::getName()
static const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
static AAInterFnReachability & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
AAInterFnReachability(const IRPosition &IRP, Attributor &A)
An abstract interface to determine reachability of point A to B.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAIntraFnReachability.
AAIntraFnReachability(const IRPosition &IRP, Attributor &A)
const std::string getName() const override
See AbstractAttribute::getName()
static const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static AAIntraFnReachability & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
virtual bool isAssumedReachable(Attributor &A, const Instruction &From, const Instruction &To, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Returns true if 'From' instruction is assumed to reach, 'To' instruction.
An abstract interface for liveness abstract attribute.
virtual bool isKnownDead(const BasicBlock *BB) const =0
Returns true if BB is known dead.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAIsDead.
static const char ID
Unique ID (due to the unique address)
bool isLiveInstSet(T begin, T end) const
This method is used to check if at least one instruction in a collection of instructions is live.
virtual bool isKnownDead() const =0
Returns true if the underlying value is known dead.
virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const
Return if the edge from From BB to To BB is assumed dead.
virtual bool isAssumedDead(const Instruction *I) const =0
Returns true if I is assumed dead.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
virtual bool isAssumedDead() const =0
The query functions are protected such that other attributes need to go through the Attributor interf...
virtual bool isRemovableStore() const
Return true if the underlying value is a store that is known to be removable.
static AAIsDead & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
virtual bool isAssumedDead(const BasicBlock *BB) const =0
Returns true if BB is assumed dead.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
const std::string getName() const override
See AbstractAttribute::getName()
static bool mayCatchAsynchronousExceptions(const Function &F)
Determine if F might catch asynchronous exceptions.
AAIsDead(const IRPosition &IRP, Attributor &A)
virtual bool isKnownDead(const Instruction *I) const =0
Returns true if I is known dead.
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
static bool hasTrivialInitializer()
See AbstractAttribute::hasTrivialInitializer.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMemoryBehavior.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
const std::string getName() const override
See AbstractAttribute::getName()
static AAMemoryBehavior & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static const char ID
Unique ID (due to the unique address)
bool isKnownWriteOnly() const
Return true if we know that the underlying value is not read in its respective scope.
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
bool isAssumedWriteOnly() const
Return true if we assume that the underlying value is not read in its respective scope.
AAMemoryBehavior(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool isKnownReadOnly() const
Return true if we know that the underlying value is not accessed (=written) in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool isAssumedStackOnly() const
Return true if we assume that the associated functions has at most local/stack accesses.
static AAMemoryLocation & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
bool isKnownArgMemOnly() const
Return true if we know that the underlying value will only access argument pointees (see Attribute::A...
bool isKnownInaccessibleOrArgMemOnly() const
Return true if we know that the underlying value will only access inaccesible memory or argument poin...
static const char ID
Unique ID (due to the unique address)
AAMemoryLocation(const IRPosition &IRP, Attributor &A)
bool isKnownReadNone() const
Return true if we know that the associated functions has no observable accesses.
const std::string getName() const override
See AbstractAttribute::getName()
bool isAssumedSpecifiedMemOnly(MemoryLocationsKind MLK) const
Return true if only the memory locations specififed by MLK are assumed to be accessed by the associat...
bool isAssumedInaccessibleMemOnly() const
Return true if we assume that the underlying value will only access inaccesible memory only (see Attr...
bool isKnownInaccessibleMemOnly() const
Return true if we know that the underlying value will only access inaccesible memory only (see Attrib...
bool isAssumedInaccessibleOrArgMemOnly() const
Return true if we assume that the underlying value will only access inaccesible memory or argument po...
bool isKnowStackOnly() const
Return true if we know that the associated functions has at most local/stack accesses.
static bool requiresCalleeForCallBase()
See AbstractAttribute::requiresCalleeForCallBase.
AccessKind
Simple enum to distinguish read/write/read-write accesses.
StateType::base_t MemoryLocationsKind
MemoryLocationsKind getAssumedNotAccessedLocation() const
Return the locations that are assumed to be not accessed by the associated function,...
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMemoryLocation.
static bool hasTrivialInitializer()
See AbstractAttribute::hasTrivialInitializer.
bool isAssumedReadNone() const
Return true if we assume that the associated functions has no observable accesses.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
virtual bool checkForAllAccessesToMemoryKind(function_ref< bool(const Instruction *, const Value *, AccessKind, MemoryLocationsKind)> Pred, MemoryLocationsKind MLK) const =0
Check Pred on all accesses to the memory kinds specified by MLK.
const std::string getAsStr(Attributor *A) const override
See AbstractState::getAsStr(Attributor).
bool mayAccessArgMem() const
Return true if the underlying value may access memory through arguement pointers of the associated fu...
bool isAssumedArgMemOnly() const
Return true if we assume that the underlying value will only access argument pointees (see Attribute:...
static MemoryLocationsKind inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem)
Return the inverse of location Loc, thus for NO_XXX the return describes ONLY_XXX.
An abstract interface for all nonnull attributes.
bool isKnownMustProgress() const
Return true if we know that underlying value is nonnull.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAMustProgress.
bool isAssumedMustProgress() const
Return true if we assume that the underlying value is nonnull.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static AAMustProgress & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static const char ID
Unique ID (due to the unique address)
const std::string getName() const override
See AbstractAttribute::getName()
AAMustProgress(const IRPosition &IRP, Attributor &A)
An abstract interface for all noalias attributes.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoAlias.
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool isKnownNoAlias() const
Return true if we know that underlying value is noalias.
static const char ID
Unique ID (due to the unique address)
bool isAssumedNoAlias() const
Return true if we assume that the underlying value is alias.
static AANoAlias & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const std::string getName() const override
See AbstractAttribute::getName()
AANoAlias(const IRPosition &IRP, Attributor &A)
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
An abstract interface for all nocapture attributes.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
AANoCapture(const IRPosition &IRP, Attributor &A)
static AANoCapture & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const std::string getName() const override
See AbstractAttribute::getName()
static const char ID
Unique ID (due to the unique address)
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
bool isKnownNoCapture() const
Return true if we know that the underlying value is not captured in its respective scope.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoCapture.
bool isKnownNoCaptureMaybeReturned() const
Return true if we know that the underlying value is not captured in its respective scope but we allow...
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
bool isAssumedNoCapture() const
Return true if we assume that the underlying value is not captured in its respective scope.
static void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
FPClassTest getAssumedNoFPClass() const
Return the underlying assumed nofpclass.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
AANoFPClass(const IRPosition &IRP, Attributor &A)
static AANoFPClass & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoFPClass.
static const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
const std::string getName() const override
See AbstractAttribute::getName()
FPClassTest getKnownNoFPClass() const
Return the underlying known nofpclass.
An AbstractAttribute for nofree.
bool isKnownNoFree() const
Return true if "nofree" is known.
AANoFree(const IRPosition &IRP, Attributor &A)
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
bool isAssumedNoFree() const
Return true if "nofree" is assumed.
static const char ID
Unique ID (due to the unique address)
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoFree.
static AANoFree & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
const std::string getName() const override
See AbstractAttribute::getName()
An abstract attribute for norecurse.
const std::string getName() const override
See AbstractAttribute::getName()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoRecurse.
AANoRecurse(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool isAssumedNoRecurse() const
Return true if "norecurse" is assumed.
static AANoRecurse & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
bool isKnownNoRecurse() const
Return true if "norecurse" is known.
static const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoReturn.
static const char ID
Unique ID (due to the unique address)
bool isAssumedNoReturn() const
Return true if the underlying object is assumed to never return.
const std::string getName() const override
See AbstractAttribute::getName()
static AANoReturn & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
AANoReturn(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool isKnownNoReturn() const
Return true if the underlying object is known to never return.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
AANoSync(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
static AANoSync & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static const char ID
Unique ID (due to the unique address)
static bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
bool isAssumedNoSync() const
Returns true if "nosync" is assumed.
static bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
bool isKnownNoSync() const
Returns true if "nosync" is known.
const std::string getName() const override
See AbstractAttribute::getName()
static bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoSync.
An abstract interface for all noundef attributes.
bool isKnownNoUndef() const
Return true if we know that underlying value is noundef.
static bool isImpliedByUndef()
See IRAttribute::isImpliedByUndef.
bool isAssumedNoUndef() const
Return true if we assume that the underlying value is noundef.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoUndef.
static AANoUndef & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
AANoUndef(const IRPosition &IRP, Attributor &A)
static const char ID
Unique ID (due to the unique address)
static bool isImpliedByPoison()
See IRAttribute::isImpliedByPoison.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
const std::string getName() const override
See AbstractAttribute::getName()
const std::string getName() const override
See AbstractAttribute::getName()
AANoUnwind(const IRPosition &IRP, Attributor &A)
bool isAssumedNoUnwind() const
Returns true if nounwind is assumed.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANoUnwind.
static const char ID
Unique ID (due to the unique address)
static AANoUnwind & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
bool isKnownNoUnwind() const
Returns true if nounwind is known.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
An abstract Attribute for determining the necessity of the convergent attribute.
static const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
const std::string getName() const override
See AbstractAttribute::getName()
bool isAssumedNotConvergent() const
Return true if "non-convergent" is assumed.
bool isKnownNotConvergent() const
Return true if "non-convergent" is known.
AANonConvergent(const IRPosition &IRP, Attributor &A)
static AANonConvergent & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANonConvergent.
An abstract interface for all nonnull attributes.
static bool isImpliedByUndef()
See IRAttribute::isImpliedByUndef.
static AANonNull & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
static const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AANonNull.
const std::string getName() const override
See AbstractAttribute::getName()
AANonNull(const IRPosition &IRP, Attributor &A)
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
bool isAssumedNonNull() const
Return true if we assume that the underlying value is nonnull.
bool isKnownNonNull() const
Return true if we know that underlying value is nonnull.
static bool hasTrivialInitializer()
See AbstractAttribute::hasTrivialInitializer.
bool isWrittenValueUnknown() const
Return true if the value written cannot be determined at all.
const_iterator end() const
bool operator!=(const Access &R) const
std::optional< Value * > getContent() const
Return the written value which can be llvm::null if it is not yet determined.
Access & operator=(const Access &Other)=default
bool isAssumption() const
Return true if this is an assumption access.
void setWrittenValueUnknown()
Set the value written to nullptr, i.e., unknown.
const RangeList & getRanges() const
bool isWriteOrAssumption() const
Return true if this is a write access.
bool isRead() const
Return true if this is a read access.
bool isWrite() const
Return true if this is a write access.
Value * getWrittenValue() const
Return the value writen, if any.
Instruction * getLocalInst() const
Return the instruction that causes the access with respect to the local scope of the associated attri...
Access(Instruction *LocalI, Instruction *RemoteI, const RangeList &Ranges, std::optional< Value * > Content, AccessKind K, Type *Ty)
bool hasUniqueRange() const
Access(Instruction *LocalI, Instruction *RemoteI, int64_t Offset, int64_t Size, std::optional< Value * > Content, AccessKind Kind, Type *Ty)
Access(Instruction *I, int64_t Offset, int64_t Size, std::optional< Value * > Content, AccessKind Kind, Type *Ty)
Access(const Access &Other)=default
Type * getType() const
Return the type associated with the access, if known.
Access & operator&=(const Access &R)
const_iterator begin() const
void addRange(int64_t Offset, int64_t Size)
Add a range accessed by this Access.
Instruction * getRemoteInst() const
Return the actual instruction that causes the access.
const AA::RangeTy & getUniqueRange() const
bool operator==(const Access &R) const
bool isMustAccess() const
bool isWrittenValueYetUndetermined() const
Return true if the value written is not known yet.
AccessKind getKind() const
Return the access kind.
A helper containing a list of offsets computed for a Use.
bool isUnassigned() const
bool operator==(const OffsetInfo &RHS) const
bool insert(int64_t Offset)
bool operator!=(const OffsetInfo &RHS) const
const_iterator begin() const
const_iterator end() const
bool merge(const OffsetInfo &R)
Copy offsets from R into the current list.
void addToAll(int64_t Inc)
A container for a list of ranges.
const_iterator end() const
void addToAllOffsets(int64_t Inc)
Add the increment Inc to the offset of every range.
bool operator==(const RangeList &OI) const
RangeList(ArrayRef< int64_t > Offsets, int64_t Size)
bool isUnique() const
Return true iff there is exactly one range and it is known.
std::pair< iterator, bool > insert(iterator Pos, const RangeTy &R)
Insert R at the given iterator Pos, and merge if necessary.
RangeList(const RangeTy &R)
bool isUnknown() const
Return true iff the list contains an unknown range.
VecTy::const_iterator const_iterator
const_iterator begin() const
bool isUnassigned() const
Return true if no ranges have been inserted.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
const RangeTy & getUnique() const
Return the unique range, assuming it exists.
bool merge(const RangeList &RHS)
Merge the ranges in RHS into the current ranges.
std::pair< iterator, bool > insert(const RangeTy &R)
Insert the given range R, maintaining sorted order.
iterator setUnknown()
Discard all ranges and insert a single unknown range.
void push_back(const RangeTy &R)
An abstract interface for struct information.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
virtual bool reachesReturn() const =0
virtual bool forallInterferingAccesses(Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I, bool FindInterferingWrites, bool FindInterferingReads, function_ref< bool(const Access &, bool)> CB, bool &HasBeenWrittenTo, AA::RangeTy &Range, function_ref< bool(const Access &)> SkipCB=nullptr) const =0
Call CB on all accesses that might interfere with I and return true if all such accesses were known a...
virtual void addReturnedOffsetsTo(OffsetInfo &) const =0
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPointerInfo.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static AAPointerInfo & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
virtual const_bin_iterator begin() const =0
virtual bool forallInterferingAccesses(AA::RangeTy Range, function_ref< bool(const Access &, bool)> CB) const =0
Call CB on all accesses that might interfere with Range and return true if all such accesses were kno...
virtual const_bin_iterator end() const =0
const std::string getName() const override
See AbstractAttribute::getName()
static const char ID
Unique ID (due to the unique address)
AAPointerInfo(const IRPosition &IRP)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
PotentialConstantIntValuesState & getState() override
See AbstractAttribute::getState(...).
const PotentialConstantIntValuesState & getState() const override
AAPotentialConstantValues(const IRPosition &IRP, Attributor &A)
static const char ID
Unique ID (due to the unique address)
const std::string getName() const override
See AbstractAttribute::getName()
static AAPotentialConstantValues & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPotentialConstantValues.
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
std::optional< Constant * > getAssumedConstant(Attributor &A, const Instruction *CtxI=nullptr) const
Return assumed constant for the associated value.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
const std::string getName() const override
See AbstractAttribute::getName()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPotentialValues.
PotentialLLVMValuesState & getState() override
See AbstractAttribute::getState(...).
AAPotentialValues(const IRPosition &IRP, Attributor &A)
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
const PotentialLLVMValuesState & getState() const override
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static const char ID
Unique ID (due to the unique address)
static AAPotentialValues & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
bool isAssumedPrivatizablePtr() const
Returns true if pointer privatization is assumed to be possible.
virtual std::optional< Type * > getPrivatizableType() const =0
Return the type we can choose for a private copy of the underlying value.
static const char ID
Unique ID (due to the unique address)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAPricatizablePtr.
const std::string getName() const override
See AbstractAttribute::getName()
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
AAPrivatizablePtr(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
bool isKnownPrivatizablePtr() const
Returns true if pointer privatization is known to be possible.
static AAPrivatizablePtr & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
An abstract attribute for undefined behavior.
bool isKnownToCauseUB() const
Return true if "undefined behavior" is known.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static AAUndefinedBehavior & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static const char ID
Unique ID (due to the unique address)
virtual bool isAssumedToCauseUB(Instruction *I) const =0
Return true if "undefined behavior" is assumed for a specific instruction.
AAUndefinedBehavior(const IRPosition &IRP, Attributor &A)
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAUndefineBehavior.
bool isAssumedToCauseUB() const
Return true if "undefined behavior" is assumed.
const std::string getName() const override
See AbstractAttribute::getName()
virtual bool isKnownToCauseUB(Instruction *I) const =0
Return true if "undefined behavior" is known for a specific instruction.
An abstract attribute for getting all assumption underlying objects.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
const std::string getName() const override
See AbstractAttribute::getName()
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAUnderlyingObjects.
static const char ID
Unique ID (due to the unique address)
static AAUnderlyingObjects & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute biew for the position IRP.
AAUnderlyingObjects(const IRPosition &IRP)
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
An abstract interface for range value analysis.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
See AbstractAttribute::isValidIRPositionForInit.
std::optional< Constant * > getAssumedConstant(Attributor &A, const Instruction *CtxI=nullptr) const
Return an assumed constant for the associated value a program point CtxI.
virtual ConstantRange getAssumedConstantRange(Attributor &A, const Instruction *CtxI=nullptr) const =0
Return an assumed range for the associated value a program point CtxI.
static const char ID
Unique ID (due to the unique address)
static bool requiresCallersForArgOrFunction()
See AbstractAttribute::requiresCallersForArgOrFunction.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAValueConstantRange.
AAValueConstantRange(const IRPosition &IRP, Attributor &A)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
const std::string getName() const override
See AbstractAttribute::getName()
IntegerRangeState & getState() override
See AbstractAttribute::getState(...).
const IntegerRangeState & getState() const override
static AAValueConstantRange & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
virtual ConstantRange getKnownConstantRange(Attributor &A, const Instruction *CtxI=nullptr) const =0
Return a known range for the associated value at a program point CtxI.
An abstract interface for value simplify abstract attribute.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAValueSimplify.
static AAValueSimplify & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
const std::string getName() const override
See AbstractAttribute::getName()
static const char ID
Unique ID (due to the unique address)
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
AAValueSimplify(const IRPosition &IRP, Attributor &A)
An abstract attribute for willreturn.
bool isKnownWillReturn() const
Return true if "willreturn" is known.
const char * getIdAddr() const override
See AbstractAttribute::getIdAddr()
static const char ID
Unique ID (due to the unique address)
static AAWillReturn & createForPosition(const IRPosition &IRP, Attributor &A)
Create an abstract attribute view for the position IRP.
static bool classof(const AbstractAttribute *AA)
This function should return true if the type of the AA is AAWillReturn.
const std::string getName() const override
See AbstractAttribute::getName()
AAWillReturn(const IRPosition &IRP, Attributor &A)
static bool isImpliedByMustprogressAndReadonly(Attributor &A, const IRPosition &IRP)
Check for mustprogress and readonly as they imply willreturn.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
bool isAssumedWillReturn() const
Return true if "willreturn" is assumed.
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
bool offsetAndSizeAreUnknown() const
Return true if offset and size are unknown, thus this is the default unknown object.
static constexpr int64_t Unknown
bool offsetOrSizeAreUnknown() const
Return true if offset or size are unknown.
static constexpr int64_t Unassigned
Constants used to represent special offsets or sizes.
RangeTy & operator&=(const RangeTy &R)
static RangeTy getUnknown()
bool isUnassigned() const
Return true if the offset and size are unassigned.
static bool LessThan(const RangeTy &L, const RangeTy &R)
Comparison for sorting ranges.
bool mayOverlap(const RangeTy &Range) const
Return true if this offset and size pair might describe an address that overlaps with Range.
RangeTy(int64_t Offset, int64_t Size)
std::pair< Value *, const Instruction * > Base
ValueAndContext(Value &V, const Instruction *CtxI)
const Instruction * getCtxI() const
ValueAndContext(Value &V, const Instruction &CtxI)
ValueAndContext(const Base &B)
Base struct for all "concrete attribute" deductions.
ChangeStatus update(Attributor &A)
Hook for the Attributor to trigger an update of the internal state.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP)
Return false if an AA should not be created for IRP.
virtual ChangeStatus manifest(Attributor &A)
Hook for the Attributor to trigger the manifestation of the information represented by the abstract a...
virtual void printWithDeps(raw_ostream &OS) const
static bool classof(const AADepGraphNode *DGN)
This function is used to identify if an DGN is of type AbstractAttribute so that the dyn_cast and cas...
static bool requiresCalleeForCallBase()
Return true if this AA requires a "callee" (or an associted function) for a call site positon.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
IRPosition & getIRPosition()
virtual StateType & getState()=0
Return the internal abstract state for inspection.
virtual void initialize(Attributor &A)
Initialize the state with the information in the Attributor A.
static bool isValidIRPositionForUpdate(Attributor &A, const IRPosition &IRP)
Return false if an AA should not be updated for IRP.
virtual const std::string getName() const =0
This function should return the name of the AbstractAttribute.
virtual ~AbstractAttribute()=default
Virtual destructor.
virtual const std::string getAsStr(Attributor *A) const =0
This function should return the "summarized" assumed state as string.
static constexpr Attribute::AttrKind IRAttributeKind
Compile time access to the IR attribute kind.
virtual bool isQueryAA() const
A query AA is always scheduled as long as we do updates because it does lazy computation that cannot ...
virtual const StateType & getState() const =0
AbstractAttribute(const IRPosition &IRP)
static bool requiresNonAsmForCallBase()
Return true if this AA requires non-asm "callee" for a call site positon.
virtual ChangeStatus updateImpl(Attributor &A)=0
The actual update/transfer function which has to be implemented by the derived classes.
virtual void trackStatistics() const =0
Hook to enable custom statistic tracking, called after manifest that resulted in a change if statisti...
static bool requiresCallersForArgOrFunction()
Return true if this AA requires all callees for an argument or function positon.
const IRPosition & getIRPosition() const
Return an IR position, see struct IRPosition.
virtual const char * getIdAddr() const =0
This function should return the address of the ID of the AbstractAttribute.
static bool hasTrivialInitializer()
Return false if this AA does anything non-trivial (hence not done by default) in its initializer.
An interface to query the internal state of an abstract attribute.
virtual ~AbstractState()=default
virtual ChangeStatus indicatePessimisticFixpoint()=0
Indicate that the abstract state should converge to the pessimistic state.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
virtual ChangeStatus indicateOptimisticFixpoint()=0
Indicate that the abstract state should converge to the optimistic state.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Wrapper for FunctionAnalysisManager.
static constexpr bool HasLegacyWrapper
Analysis::Result * getAnalysis(const Function &F, bool RequestCachedOnly=false)
AnalysisGetter(FunctionAnalysisManager &FAM, bool CachedOnly=false)
void invalidateAnalyses()
Invalidates the analyses. Valid only when using the new pass manager.
AnalysisGetter(Pass *P, bool CachedOnly=false)
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
AACallEdgeIterator optimisticEdgesEnd() const override
AttributorCallGraph(Attributor &A)
AACallEdgeIterator optimisticEdgesBegin() const override
virtual ~AttributorCallGraph()=default
void populateAll() const
Force populate the entire call graph.
Configuration for the Attributor.
bool UseLiveness
Flag to determine if we should skip all liveness checks early on.
std::function< void(Attributor &A, const Function &F)> InitializationCallback
Callback function to be invoked on internal functions marked live.
std::optional< unsigned > MaxFixpointIterations
Maximum number of iterations to run until fixpoint.
DenseSet< const char * > * Allowed
If not null, a set limiting the attribute opportunities.
bool RewriteSignatures
Flag to determine if we rewrite function signatures.
OptimizationRemarkGetter OREGetter
bool DeleteFns
Flag to determine if we can delete functions or keep dead ones around.
bool IsClosedWorldModule
Flag to indicate if the entire world is contained in this module, that is, no outside functions exist...
CallGraphUpdater & CGUpdater
Helper to update an underlying call graph and to delete functions.
IPOAmendableCBTy IPOAmendableCB
bool IsModulePass
Is the user of the Attributor a module pass or not.
std::function< bool(Attributor &A, const AbstractAttribute &AA, CallBase &CB, Function &AssumedCallee, unsigned NumAssumedCallees)> IndirectCalleeSpecializationCallback
Callback function to determine if an indirect call targets should be made direct call targets (with a...
bool DefaultInitializeLiveInternals
Flag to determine if we want to initialize all default AAs for an internal function marked live.
AttributorConfig(CallGraphUpdater &CGUpdater)
A more lightweight version of the Attributor which only runs attribute inference but no simplificatio...
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
A more lightweight version of the Attributor which only runs attribute inference but no simplificatio...
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Helper struct used in the communication between an abstract attribute (AA) that wants to change the s...
unsigned getNumReplacementArgs() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
const SmallVectorImpl< Type * > & getReplacementTypes() const
const Argument & getReplacedArg() const
Attributor & getAttributor() const
Simple getters, see the corresponding members for details.
std::function< void(const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Function & getReplacedFn() const
The fixpoint analysis framework that orchestrates the attribute deduction.
bool registerFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes, ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB, ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB)
Register a rewrite for a function signature.
AAType & registerAA(AAType &AA)
Introduce a new abstract attribute into the fixpoint analysis.
bool checkForAllCallees(function_ref< bool(ArrayRef< const Function * > Callees)> Pred, const AbstractAttribute &QueryingAA, const CallBase &CB)
Check Pred on all potential Callees of CB.
bool isModulePass() const
Return true if this is a module pass, false otherwise.
void registerInvokeWithDeadSuccessor(InvokeInst &II)
Record that II has at least one dead successor block.
void registerSimplificationCallback(const IRPosition &IRP, const SimplifictionCallbackTy &CB)
bool changeAfterManifest(const IRPosition IRP, Value &NV, bool ChangeDroppable=true)
Helper function to replace all uses associated with IRP with NV.
bool isValidFunctionSignatureRewrite(Argument &Arg, ArrayRef< Type * > ReplacementTypes)
Check if we can rewrite a function signature.
static bool isInternalizable(Function &F)
Returns true if the function F can be internalized.
ChangeStatus removeAttrs(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AttrKinds)
Remove all AttrKinds attached to IRP.
void emitRemark(Instruction *I, StringRef RemarkName, RemarkCallBack &&RemarkCB) const
Emit a remark generically.
bool isRunOn(Function &Fn) const
Return true if we derive attributes for Fn.
bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, DepClassTy DepClass=DepClassTy::OPTIONAL)
Return true if AA (or its context instruction) is assumed dead.
bool checkForAllInstructions(function_ref< bool(Instruction &)> Pred, const Function *Fn, const AbstractAttribute *QueryingAA, ArrayRef< unsigned > Opcodes, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
Check Pred on all instructions in Fn with an opcode present in Opcodes.
void recordDependence(const AbstractAttribute &FromAA, const AbstractAttribute &ToAA, DepClassTy DepClass)
Explicitly record a dependence from FromAA to ToAA, that is if FromAA changes ToAA should be updated ...
static void createShallowWrapper(Function &F)
Create a shallow wrapper for F such that F has internal linkage afterwards.
bool isRunOn(Function *Fn) const
const AAType * getAAFor(const AbstractAttribute &QueryingAA, const IRPosition &IRP, DepClassTy DepClass)
Lookup an abstract attribute of type AAType at position IRP.
std::optional< Constant * > getAssumedInitializerFromCallBack(const GlobalVariable &GV, const AbstractAttribute *AA, bool &UsedAssumedInformation)
Return std::nullopt if there is no call back registered for GV or the call back is still not sure if ...
void deleteAfterManifest(Function &F)
Record that F is deleted after information was manifested.
std::optional< Value * > getAssumedSimplified(const IRPosition &IRP, const AbstractAttribute &AA, bool &UsedAssumedInformation, AA::ValueScope S)
If V is assumed simplified, return it, if it is unclear yet, return std::nullopt, otherwise return nu...
void emitRemark(Function *F, StringRef RemarkName, RemarkCallBack &&RemarkCB) const
Emit a remark on a function.
static Function * internalizeFunction(Function &F, bool Force=false)
Make another copy of the function F such that the copied version has internal linkage afterwards and ...
bool isFunctionIPOAmendable(const Function &F)
Determine whether the function F is IPO amendable.
const AAType * getOrCreateAAFor(IRPosition IRP, const AbstractAttribute *QueryingAA, DepClassTy DepClass, bool ForceUpdate=false, bool UpdateAfterInit=true)
The version of getAAFor that allows to omit a querying abstract attribute.
const SmallSetVector< Function *, 8 > & getModifiedFunctions()
bool checkForAllReadWriteInstructions(function_ref< bool(Instruction &)> Pred, AbstractAttribute &QueryingAA, bool &UsedAssumedInformation)
Check Pred on all Read/Write instructions.
void changeToUnreachableAfterManifest(Instruction *I)
Record that I is to be replaced with unreachable after information was manifested.
bool hasGlobalVariableSimplificationCallback(const GlobalVariable &GV)
Return true if there is a simplification callback for GV.
std::function< std::optional< Constant * >(const GlobalVariable &, const AbstractAttribute *, bool &)> GlobalVariableSimplifictionCallbackTy
Register CB as a simplification callback.
std::optional< Constant * > getAssumedConstant(const Value &V, const AbstractAttribute &AA, bool &UsedAssumedInformation)
bool checkForAllReturnedValues(function_ref< bool(Value &)> Pred, const AbstractAttribute &QueryingAA, AA::ValueScope S=AA::ValueScope::Intraprocedural, bool RecurseForSelectAndPHI=true)
Check Pred on all values potentially returned by the function associated with QueryingAA.
bool hasSimplificationCallback(const IRPosition &IRP)
Return true if there is a simplification callback for IRP.
bool isClosedWorldModule() const
Return true if the module contains the whole world, thus, no outside functions exist.
std::optional< Constant * > getAssumedConstant(const IRPosition &IRP, const AbstractAttribute &AA, bool &UsedAssumedInformation)
If IRP is assumed to be a constant, return it, if it is unclear yet, return std::nullopt,...
const AAType * getOrCreateAAFor(const IRPosition &IRP)
void registerGlobalVariableSimplificationCallback(const GlobalVariable &GV, const GlobalVariableSimplifictionCallbackTy &CB)
const DataLayout & getDataLayout() const
Return the data layout associated with the anchor scope.
void getAttrs(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AKs, SmallVectorImpl< Attribute > &Attrs, bool IgnoreSubsumingPositions=false)
Return the attributes of any kind in AKs existing in the IR at a position that will affect this one.
InformationCache & getInfoCache()
Return the internal information cache.
bool changeUseAfterManifest(Use &U, Value &NV)
Record that U is to be replaces with NV after information was manifested.
std::optional< Value * > translateArgumentToCallSiteContent(std::optional< Value * > V, CallBase &CB, const AbstractAttribute &AA, bool &UsedAssumedInformation)
Translate V from the callee context into the call site context.
AAType * lookupAAFor(const IRPosition &IRP, const AbstractAttribute *QueryingAA=nullptr, DepClassTy DepClass=DepClassTy::OPTIONAL, bool AllowInvalidState=false)
Return the attribute of AAType for IRP if existing and valid.
void markLiveInternalFunction(const Function &F)
Mark the internal function F as live.
void registerManifestAddedBasicBlock(BasicBlock &BB)
void registerVirtualUseCallback(const Value &V, const VirtualUseCallbackTy &CB)
bool checkForAllUses(function_ref< bool(const Use &, bool &)> Pred, const AbstractAttribute &QueryingAA, const Value &V, bool CheckBBLivenessOnly=false, DepClassTy LivenessDepClass=DepClassTy::OPTIONAL, bool IgnoreDroppableUses=true, function_ref< bool(const Use &OldU, const Use &NewU)> EquivalentUseCB=nullptr)
Check Pred on all (transitive) uses of V.
ChangeStatus manifestAttrs(const IRPosition &IRP, ArrayRef< Attribute > DeducedAttrs, bool ForceReplace=false)
Attach DeducedAttrs to IRP, if ForceReplace is set we do this even if the same attribute kind was alr...
bool hasAttr(const IRPosition &IRP, ArrayRef< Attribute::AttrKind > AKs, bool IgnoreSubsumingPositions=false, Attribute::AttrKind ImpliedAttributeKind=Attribute::None)
Return true if any kind in AKs existing in the IR at a position that will affect this one.
void registerForUpdate(AbstractAttribute &AA)
Allows a query AA to request an update if a new query was received.
void deleteAfterManifest(Instruction &I)
Record that I is deleted after information was manifested.
void deleteAfterManifest(BasicBlock &BB)
Record that BB is deleted after information was manifested.
void identifyDefaultAbstractAttributes(Function &F)
Determine opportunities to derive 'default' attributes in F and create abstract attribute objects for...
bool shouldInitialize(const IRPosition &IRP, bool &ShouldUpdateAA)
bool getAssumedSimplifiedValues(const IRPosition &IRP, const AbstractAttribute *AA, SmallVectorImpl< AA::ValueAndContext > &Values, AA::ValueScope S, bool &UsedAssumedInformation, bool RecurseForSelectAndPHI=true)
Try to simplify IRP and in the scope S.
BumpPtrAllocator & Allocator
The allocator used to allocate memory, e.g. for AbstractAttributes.
std::function< bool(Attributor &, const AbstractAttribute *)> VirtualUseCallbackTy
bool checkForAllCallLikeInstructions(function_ref< bool(Instruction &)> Pred, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool CheckBBLivenessOnly=false, bool CheckPotentiallyDead=false)
Check Pred on all call-like instructions (=CallBased derived).
bool shouldSpecializeCallSiteForCallee(const AbstractAttribute &AA, CallBase &CB, Function &Callee, unsigned NumAssumedCallees)
Return true if we should specialize the call site CB for the potential callee Fn.
ChangeStatus run()
Run the analyses until a fixpoint is reached or enforced (timeout).
static bool internalizeFunctions(SmallPtrSetImpl< Function * > &FnSet, DenseMap< Function *, Function * > &FnMap)
Make copies of each function in the set FnSet such that the copied version has internal linkage after...
std::optional< Value * > getAssumedSimplified(const Value &V, const AbstractAttribute &AA, bool &UsedAssumedInformation, AA::ValueScope S)
bool shouldUpdateAA(const IRPosition &IRP)
std::function< std::optional< Value * >(const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
bool checkForAllCallSites(function_ref< bool(AbstractCallSite)> Pred, const AbstractAttribute &QueryingAA, bool RequireAllCallSites, bool &UsedAssumedInformation)
Check Pred on all function call sites.
bool getAttrsFromAssumes(const IRPosition &IRP, Attribute::AttrKind AK, SmallVectorImpl< Attribute > &Attrs)
Return the attributes of kind AK existing in the IR as operand bundles of an llvm....
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & removeKnownBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "known bits".
BitIntegerState()=default
bool isAssumed(base_t BitsEncoding=BestState) const
Return true if the bits set in BitsEncoding are "assumed bits".
BitIntegerState(base_t Assumed)
BitIntegerState & removeAssumedBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "assumed bits" if not known.
BitIntegerState & intersectAssumedBits(base_t BitsEncoding)
Keep only "assumed bits" also set in BitsEncoding but all known ones.
bool isKnown(base_t BitsEncoding=BestState) const
Return true if the bits set in BitsEncoding are "known bits".
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
bool isKnown() const
Return true if the state is known to hold.
void setKnown(bool Value)
Set the known and asssumed value to Value.
IntegerStateBase::base_t base_t
BooleanState(base_t Assumed)
void setAssumed(bool Value)
Set the assumed value to Value but never below the known one.
bool isAssumed() const
Return true if the state is assumed to hold.
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
static bool isNodeHidden(const AACallGraphNode *Node, const AttributorCallGraph *Graph)
DOTGraphTraits(bool Simple=false)
std::string getNodeLabel(const AACallGraphNode *Node, const AttributorCallGraph *Graph)
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
Specialization of the integer state for a decreasing value, hence 0 is the best state and ~0u the wor...
DecIntegerState & takeKnownMinimum(base_t Value)
Take minimum of known and Value.
DecIntegerState & takeAssumedMaximum(base_t Value)
Take maximum of assumed and Value.
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
static DenormalMode unionAssumed(DenormalMode Callee, DenormalMode Caller)
DenormalState unionWith(DenormalState Caller) const
bool operator!=(const DenormalState Other) const
bool operator==(const DenormalState Other) const
static DenormalMode::DenormalModeKind unionDenormalKind(DenormalMode::DenormalModeKind Callee, DenormalMode::DenormalModeKind Caller)
bool IsAtFixedpoint
Explicitly track whether we've hit a fixed point.
ChangeStatus indicateOptimisticFixpoint() override
Indicate that the abstract state should converge to the optimistic state.
DenormalState getKnown() const
DenormalState getAssumed() const
bool isValidState() const override
Return if this abstract state is in a valid state.
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
DenormalFPMathState operator^=(const DenormalFPMathState &Caller)
ChangeStatus indicateFixpoint()
bool isModeFixed() const
Return true if there are no dynamic components to the denormal mode worth specializing.
bool isAtFixpoint() const override
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
DenormalFPMathState()=default
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
DenormalModeKind
Represent handled modes for denormal (aka subnormal) modes in the floating point environment.
@ Dynamic
Denormals have unknown treatment.
static constexpr DenormalMode getInvalid()
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static bool isEqual(const AA::ValueAndContext &LHS, const AA::ValueAndContext &RHS)
static AA::ValueAndContext getEmptyKey()
static unsigned getHashValue(const AA::ValueAndContext &VAC)
static AA::ValueAndContext getTombstoneKey()
static AA::ValueScope getTombstoneKey()
static AA::ValueScope getEmptyKey()
static bool isEqual(const AA::ValueScope &LHS, const AA::ValueScope &RHS)
static unsigned getHashValue(const AA::ValueScope &S)
static IRPosition getEmptyKey()
static IRPosition getTombstoneKey()
static bool isEqual(const IRPosition &a, const IRPosition &b)
static unsigned getHashValue(const IRPosition &IRP)
static unsigned getHashValue(const AA::InstExclusionSetTy *BES)
static bool isEqual(const AA::InstExclusionSetTy *LHS, const AA::InstExclusionSetTy *RHS)
static const AA::InstExclusionSetTy * getTombstoneKey()
static const AA::InstExclusionSetTy * getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
static DerefState getBestState(const DerefState &)
static DerefState getWorstState()
Return the worst possible representable state.
static DerefState getBestState()
static DerefState getWorstState(const DerefState &)
std::map< int64_t, uint64_t > AccessedBytesMap
Map representing for accessed memory offsets and sizes.
static AACallEdgeIterator child_end(AACallGraphNode *Node)
static AACallEdgeIterator child_begin(AACallGraphNode *Node)
static AACallGraphNode * getEntryNode(AttributorCallGraph *G)
static AACallEdgeIterator nodes_begin(const AttributorCallGraph *G)
static AACallEdgeIterator nodes_end(const AttributorCallGraph *G)
Helper class that provides common functionality to manifest IR attributes.
Attribute::AttrKind getAttrKind() const
Return the kind that identifies the abstract attribute implementation.
static constexpr Attribute::AttrKind IRAttributeKind
Compile time access to the IR attribute kind.
static bool hasTrivialInitializer()
Most boolean IRAttribute AAs don't do anything non-trivial in their initializers while non-boolean on...
static bool isImpliedByUndef()
Return true if the IR attribute(s) associated with this AA are implied for an undef value.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
static bool isImpliedByPoison()
Return true if the IR attribute(s) associated with this AA are implied for an poison value.
static bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind=AK, bool IgnoreSubsumingPositions=false)
IRAttribute(const IRPosition &IRP)
virtual void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, SmallVectorImpl< Attribute > &Attrs) const
Return the deduced attributes in Attrs.
Helper to describe and deal with positions in the LLVM-IR.
Function * getAssociatedFunction() const
Return the associated function, if any.
void setAttrList(const AttributeList &AttrList) const
Update the attributes associated with this function or call site scope.
unsigned getAttrIdx() const
Return the index in the attribute list for this position.
bool hasCallBaseContext() const
Check if the position has any call base context.
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Argument * getAssociatedArgument() const
Return the associated argument, if any.
bool isAnyCallSitePosition() const
bool operator!=(const IRPosition &RHS) const
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
AttributeList getAttrList() const
Return the attributes associated with this function or call site scope.
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
static const IRPosition TombstoneKey
Kind
The positions we distinguish in the IR.
@ IRP_ARGUMENT
An attribute for a function argument.
@ IRP_RETURNED
An attribute for the function return value.
@ IRP_CALL_SITE
An attribute for a call site (function scope).
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
@ IRP_FUNCTION
An attribute for a function (scope).
@ IRP_FLOAT
A position that is not associated with a spot suitable for attributes.
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
@ IRP_INVALID
An invalid position.
Instruction * getCtxI() const
Return the context instruction, if any.
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
static const IRPosition EmptyKey
Special DenseMap key values.
bool isFunctionScope() const
Return true if this is a function or call site position.
bool operator==(const IRPosition &RHS) const
static const IRPosition callsite_argument(AbstractCallSite ACS, unsigned ArgNo)
Create a position describing the argument of ACS at position ArgNo.
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Value * getArg(unsigned ArgNo) const
Return theargument ArgNo associated with this function or call site scope.
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Value * getAttrListAnchor() const
Return the value attributes are attached to.
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
bool isFnInterfaceKind() const
Return true if the position refers to a function interface, that is the function scope,...
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
IRPosition stripCallBaseContext() const
Return the same position without the call base context.
unsigned getNumArgs() const
Return the number of arguments associated with this function or call site scope.
Kind getPositionKind() const
Return the associated position kind.
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
IRPosition()
Default constructor available to create invalid positions implicitly.
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Specialization of the integer state for an increasing value, hence ~0u is the best state and 0 the wo...
static constexpr base_t getBestState(const IncIntegerState< base_ty, BestState, WorstState > &)
IncIntegerState(base_t Assumed)
static constexpr base_t getBestState()
Return the best possible representable state.
IncIntegerState & takeAssumedMinimum(base_t Value)
Take minimum of assumed and Value.
IncIntegerState & takeKnownMaximum(base_t Value)
Take maximum of known and Value.
State for an integer range.
IntegerRangeState operator^=(const IntegerRangeState &R)
"Clamp" this state with R.
IntegerRangeState operator&=(const IntegerRangeState &R)
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
void unionAssumed(const IntegerRangeState &R)
See IntegerRangeState::unionAssumed(..).
ConstantRange Assumed
State representing assumed range, initially set to empty.
IntegerRangeState(const ConstantRange &CR)
IntegerRangeState(uint32_t BitWidth)
bool operator==(const IntegerRangeState &R) const
Equality for IntegerRangeState.
void intersectKnown(const IntegerRangeState &R)
See IntegerRangeState::intersectKnown(..).
static ConstantRange getBestState(const IntegerRangeState &IRS)
bool isValidState() const override
See AbstractState::isValidState()
uint32_t BitWidth
Bitwidth of the associated value.
ConstantRange Known
State representing known range, initially set to [-inf, inf].
void unionAssumed(const ConstantRange &R)
Unite assumed range with the passed state.
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
ConstantRange getKnown() const
Return the known state encoding.
void intersectKnown(const ConstantRange &R)
Intersect known range with the passed state.
ConstantRange getAssumed() const
Return the assumed state encoding.
uint32_t getBitWidth() const
Return associated values' bit width.
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
static ConstantRange getWorstState(uint32_t BitWidth)
Return the worst possible representable state.
static ConstantRange getBestState(uint32_t BitWidth)
Return the best possible representable state.
Simple state with integers encoding.
bool isValidState() const override
See AbstractState::isValidState() NOTE: For now we simply pretend that the worst possible state is in...
virtual void handleNewAssumedValue(base_t Value)=0
Handle a new assumed value Value. Subtype dependent.
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
void operator|=(const IntegerStateBase< base_t, BestState, WorstState > &R)
virtual void handleNewKnownValue(base_t Value)=0
Handle a new known value Value. Subtype dependent.
base_t getKnown() const
Return the known state encoding.
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
void operator^=(const IntegerStateBase< base_t, BestState, WorstState > &R)
"Clamp" this state with R.
virtual void joinOR(base_t AssumedValue, base_t KnownValue)=0
Handle a value Value. Subtype dependent.
virtual void joinAND(base_t AssumedValue, base_t KnownValue)=0
Handle a new assumed value Value. Subtype dependent.
IntegerStateBase(base_t Assumed)
void operator+=(const IntegerStateBase< base_t, BestState, WorstState > &R)
"Clamp" this state with R.
base_t getAssumed() const
Return the assumed state encoding.
static constexpr base_t getWorstState()
Return the worst possible representable state.
static constexpr base_t getBestState()
Return the best possible representable state.
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
IntegerStateBase()=default
base_t Known
The known state encoding in an integer of type base_t.
static constexpr base_t getWorstState(const IntegerStateBase &)
bool operator!=(const IntegerStateBase< base_t, BestState, WorstState > &R) const
Inequality for IntegerStateBase.
bool operator==(const IntegerStateBase< base_t, BestState, WorstState > &R) const
Equality for IntegerStateBase.
void operator&=(const IntegerStateBase< base_t, BestState, WorstState > &R)
base_t Assumed
The assumed state encoding in an integer of type base_t.
static constexpr base_t getBestState(const IntegerStateBase &)
A "must be executed context" for a given program point PP is the set of instructions,...
A CRTP mix-in to automatically provide informational APIs needed for passes.
static PotentialValuesState getBestState(const PotentialValuesState &PVS)
PotentialValuesState & getAssumed()
Return the assumed state.
static unsigned MaxPotentialValues
Maximum number of potential values to be tracked.
bool undefIsContained() const
Returns whether this state contains an undef value or not.
bool contains(const MemberTy &V) const
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint(...)
void unionAssumed(const MemberTy &C)
Union assumed set with the passed value.
static PotentialValuesState getBestState()
Return empty set as the best state of potential values.
SmallSetVector< MemberTy, 8 > SetTy
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
void unionAssumed(const PotentialValuesState &PVS)
Union assumed set with assumed set of the passed state PVS.
PotentialValuesState(bool IsValid)
bool operator==(const PotentialValuesState &RHS) const
bool isValidState() const override
See AbstractState::isValidState(...)
PotentialValuesState operator&=(const PotentialValuesState &PVS)
static PotentialValuesState getWorstState()
Return full set as the worst state of potential values.
const PotentialValuesState & getAssumed() const
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
PotentialValuesState operator^=(const PotentialValuesState &PVS)
"Clamp" this state with PVS.
void unionAssumedWithUndef()
Union assumed set with an undef value.
const SetTy & getAssumedSet() const
Return this set.
A wrapper around a set that has semantics for handling unions and intersections with a "universal" se...
SetContents(bool Universal)
Creates a universal set with no concrete elements or an empty set.
SetContents(bool Universal, const DenseSet< BaseTy > &Assumptions)
bool getIntersection(const SetContents &RHS)
Finds A := A ^ B where A or B could be the "Universal" set which contains every possible attribute.
bool getUnion(const SetContents &RHS)
Finds A := A u B where A or B could be the "Universal" set which contains every possible attribute.
const DenseSet< BaseTy > & getSet() const
SetContents(const DenseSet< BaseTy > &Assumptions)
Creates a non-universal set with concrete values.
bool setContains(const BaseTy &Elem) const
Returns if the set state contains the element.
bool getIntersection(const SetContents &RHS)
Performs the set intersection between this set and RHS.
bool isValidState() const override
See AbstractState::isValidState()
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
const SetContents & getAssumed() const
Return the assumed state encoding.
const SetContents & getKnown() const
Return the known state encoding.
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
bool getUnion(const SetContents &RHS)
Performs the set union between this set and RHS.
SetState(const DenseSet< BaseTy > &Known)
Initializes the known state with an initial set and initializes the assumed state as universal.
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
StateWrapper(const IRPosition &IRP, Ts... Args)
const StateType & getState() const override
See AbstractAttribute::getState(...).
static ValueSimplifyStateType getWorstState(Type *Ty)
Return the worst possible representable state.
static ValueSimplifyStateType getBestState(const ValueSimplifyStateType &VS)
bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
ValueSimplifyStateType operator^=(const ValueSimplifyStateType &VS)
"Clamp" this state with PVS.
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
ValueSimplifyStateType(Type *Ty)
static ValueSimplifyStateType getBestState(Type *Ty)
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint(...)
bool isValidState() const override
See AbstractState::isValidState(...)
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
static ValueSimplifyStateType getWorstState(const ValueSimplifyStateType &VS)
BooleanState BS
Helper to track validity and fixpoint.
Type * Ty
The type of the original value.
bool operator==(const ValueSimplifyStateType &RHS) const
ValueSimplifyStateType getAssumed()
Return the assumed state encoding.
const ValueSimplifyStateType & getAssumed() const