17#include "llvm/IR/IntrinsicsAMDGPU.h"
18#include "llvm/IR/IntrinsicsR600.h"
23#define DEBUG_TYPE "amdgpu-attributor"
28 "amdgpu-indirect-call-specialization-threshold",
30 "A threshold controls whether an indirect call will be specialized"),
33#define AMDGPU_ATTRIBUTE(Name, Str) Name##_POS,
36#include "AMDGPUAttributes.def"
40#define AMDGPU_ATTRIBUTE(Name, Str) Name = 1 << Name##_POS,
44#include "AMDGPUAttributes.def"
49#define AMDGPU_ATTRIBUTE(Name, Str) {Name, Str},
50static constexpr std::pair<ImplicitArgumentMask, StringLiteral>
52#include "AMDGPUAttributes.def"
62 bool HasApertureRegs,
bool SupportsGetDoorBellID,
63 unsigned CodeObjectVersion) {
65 case Intrinsic::amdgcn_workitem_id_x:
68 case Intrinsic::amdgcn_workgroup_id_x:
70 return WORKGROUP_ID_X;
71 case Intrinsic::amdgcn_workitem_id_y:
72 case Intrinsic::r600_read_tidig_y:
74 case Intrinsic::amdgcn_workitem_id_z:
75 case Intrinsic::r600_read_tidig_z:
77 case Intrinsic::amdgcn_workgroup_id_y:
78 case Intrinsic::r600_read_tgid_y:
79 return WORKGROUP_ID_Y;
80 case Intrinsic::amdgcn_workgroup_id_z:
81 case Intrinsic::r600_read_tgid_z:
82 return WORKGROUP_ID_Z;
83 case Intrinsic::amdgcn_cluster_id_x:
86 case Intrinsic::amdgcn_cluster_id_y:
88 case Intrinsic::amdgcn_cluster_id_z:
90 case Intrinsic::amdgcn_lds_kernel_id:
92 case Intrinsic::amdgcn_dispatch_ptr:
94 case Intrinsic::amdgcn_dispatch_id:
96 case Intrinsic::amdgcn_implicitarg_ptr:
97 return IMPLICIT_ARG_PTR;
100 case Intrinsic::amdgcn_queue_ptr:
103 case Intrinsic::amdgcn_is_shared:
104 case Intrinsic::amdgcn_is_private:
112 case Intrinsic::amdgcn_wwm:
113 case Intrinsic::amdgcn_strict_wwm:
114 return WHOLE_WAVE_MODE;
115 case Intrinsic::trap:
116 case Intrinsic::debugtrap:
117 case Intrinsic::ubsantrap:
118 if (SupportsGetDoorBellID)
142 return F.hasFnAttribute(Attribute::SanitizeAddress) ||
143 F.hasFnAttribute(Attribute::SanitizeThread) ||
144 F.hasFnAttribute(Attribute::SanitizeMemory) ||
145 F.hasFnAttribute(Attribute::SanitizeHWAddress) ||
146 F.hasFnAttribute(Attribute::SanitizeMemTag);
152 AMDGPUInformationCache(
const Module &M, AnalysisGetter &AG,
154 SetVector<Function *> *
CGSCC, TargetMachine &TM)
160 LLVMContext &Ctx =
M.getContext();
162 ImplicitAttrList.push_back({Mask, Attribute::get(Ctx, Name)});
164 llvm::sort(ImplicitAttrList, [](
const auto &
A,
const auto &
B) {
165 return A.second.getKindAsString() < B.second.getKindAsString();
168 unsigned COV = CodeObjectVersion;
169 ImplicitArgRanges = {
171 {AMDGPU::getMultigridSyncArgImplicitArgPosition(COV), 8}},
172 {HOSTCALL_PTR, {AMDGPU::getHostcallImplicitArgPosition(COV), 8}},
177 ImplicitArgRanges.push_back(
179 ImplicitArgRanges.push_back(
184 for (
auto [Mask,
Range] : ImplicitArgRanges) {
185 ImplicitArgsMask |=
Mask;
186 Begin = std::min(Begin,
Range.Offset);
198 getImplicitAttrList()
const {
199 return ImplicitAttrList;
202 enum ConstantStatus :
uint8_t {
205 ADDR_SPACE_CAST_PRIVATE_TO_FLAT = 1 << 1,
206 ADDR_SPACE_CAST_LOCAL_TO_FLAT = 1 << 2,
207 ADDR_SPACE_CAST_BOTH_TO_FLAT =
208 ADDR_SPACE_CAST_PRIVATE_TO_FLAT | ADDR_SPACE_CAST_LOCAL_TO_FLAT,
209 CS_WORST = DS_GLOBAL | ADDR_SPACE_CAST_BOTH_TO_FLAT,
212 std::optional<std::pair<unsigned, unsigned>>
213 getFlatWorkGroupSizeAttr(
const Function &
F)
const {
217 return std::make_pair(
R->first, *(
R->second));
220 std::pair<unsigned, unsigned>
221 getDefaultFlatWorkGroupSize(
const Function &
F)
const {
223 return ST.getDefaultFlatWorkGroupSize(
F.getCallingConv());
226 std::pair<unsigned, unsigned> getMaximumFlatWorkGroupRange()
const {
232 unsigned getCodeObjectVersion()
const {
return CodeObjectVersion; }
237 getImplicitArgRanges()
const {
238 return ImplicitArgRanges;
242 uint32_t getImplicitArgsMask()
const {
return ImplicitArgsMask; }
245 AA::RangeTy getImplicitArgsRange()
const {
return ImplicitArgsRange; }
250 std::optional<std::pair<unsigned, unsigned>>
258 return std::make_pair(Val->first, *(Val->second));
265 unsigned getMaxAddrSpace()
const override {
275 if (
CE->getOpcode() == Instruction::AddrSpaceCast) {
276 unsigned SrcAS =
CE->getOperand(0)->getType()->getPointerAddressSpace();
278 Status |= ADDR_SPACE_CAST_PRIVATE_TO_FLAT;
280 Status |= ADDR_SPACE_CAST_LOCAL_TO_FLAT;
291 const auto &It = ConstantStatus.find(
C);
292 if (It != ConstantStatus.end())
293 return It->second.value();
301 while (Result != CS_WORST && !Worklist.
empty()) {
304 std::optional<uint8_t> &CurCResultOrNone = ConstantStatus[CurC];
305 if (CurCResultOrNone) {
306 Result |= CurCResultOrNone.value();
312 CurCResult |= DS_GLOBAL;
315 CurCResult |= visitConstExpr(CE);
319 if (Visited.
insert(OpC).second)
324 CurCResultOrNone = CurCResult;
336 bool HasAperture = Features.test(AMDGPU::FEAT_APERTURE_REGS);
339 if (!IsNonEntryFunc && HasAperture)
345 if (IsNonEntryFunc && (
Access & DS_GLOBAL))
348 return !HasAperture && (
Access & ADDR_SPACE_CAST_BOTH_TO_FLAT);
351 bool checkConstForAddrSpaceCastFromPrivate(
const Constant *
C) {
353 return Access & ADDR_SPACE_CAST_PRIVATE_TO_FLAT;
363 const unsigned CodeObjectVersion;
370struct AAAMDAttributes
371 :
public StateWrapper<BitIntegerState<uint32_t, ALL_ARGUMENT_MASK, 0>,
373 using Base = StateWrapper<BitIntegerState<uint32_t, ALL_ARGUMENT_MASK, 0>,
376 AAAMDAttributes(
const IRPosition &IRP, Attributor &
A) : Base(IRP) {}
379 static AAAMDAttributes &createForPosition(
const IRPosition &IRP,
383 StringRef
getName()
const override {
return "AAAMDAttributes"; }
386 const char *getIdAddr()
const override {
return &ID; }
390 static bool classof(
const AbstractAttribute *AA) {
395 static const char ID;
397const char AAAMDAttributes::ID = 0;
399struct AAUniformWorkGroupSize
400 :
public StateWrapper<BooleanState, AbstractAttribute> {
401 using Base = StateWrapper<BooleanState, AbstractAttribute>;
402 AAUniformWorkGroupSize(
const IRPosition &IRP, Attributor &
A) : Base(IRP) {}
405 static AAUniformWorkGroupSize &createForPosition(
const IRPosition &IRP,
409 StringRef
getName()
const override {
return "AAUniformWorkGroupSize"; }
412 const char *getIdAddr()
const override {
return &ID; }
416 static bool classof(
const AbstractAttribute *AA) {
421 static const char ID;
423const char AAUniformWorkGroupSize::ID = 0;
425struct AAUniformWorkGroupSizeFunction :
public AAUniformWorkGroupSize {
426 AAUniformWorkGroupSizeFunction(
const IRPosition &IRP, Attributor &
A)
427 : AAUniformWorkGroupSize(IRP,
A) {}
431 CallingConv::ID CC =
F->getCallingConv();
433 if (CC != CallingConv::AMDGPU_KERNEL)
436 bool InitialValue =
F->hasFnAttribute(
"uniform-work-group-size");
439 indicateOptimisticFixpoint();
441 indicatePessimisticFixpoint();
447 auto CheckCallSite = [&](AbstractCallSite CS) {
450 <<
"->" << getAssociatedFunction()->
getName() <<
"\n");
452 const auto *CallerInfo =
A.getAAFor<AAUniformWorkGroupSize>(
454 if (!CallerInfo || !CallerInfo->isValidState())
458 CallerInfo->getState());
463 bool AllCallSitesKnown =
true;
464 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
465 return indicatePessimisticFixpoint();
472 return ChangeStatus::UNCHANGED;
474 LLVMContext &Ctx = getAssociatedFunction()->getContext();
475 return A.manifestAttrs(getIRPosition(),
476 {Attribute::get(Ctx,
"uniform-work-group-size")},
480 bool isValidState()
const override {
485 const std::string getAsStr(Attributor *)
const override {
486 return "AMDWorkGroupSize[" + std::to_string(getAssumed()) +
"]";
490 void trackStatistics()
const override {}
493AAUniformWorkGroupSize &
494AAUniformWorkGroupSize::createForPosition(
const IRPosition &IRP,
497 return *
new (
A.Allocator) AAUniformWorkGroupSizeFunction(IRP,
A);
499 "AAUniformWorkGroupSize is only valid for function position");
502struct AAAMDAttributesFunction :
public AAAMDAttributes {
503 AAAMDAttributesFunction(
const IRPosition &IRP, Attributor &
A)
504 : AAAMDAttributes(IRP,
A) {}
516 if (HasSanitizerAttrs) {
517 removeAssumedBits(IMPLICIT_ARG_PTR);
518 removeAssumedBits(HOSTCALL_PTR);
519 removeAssumedBits(FLAT_SCRATCH_INIT);
523 if (HasSanitizerAttrs &&
524 (Attr.first == IMPLICIT_ARG_PTR || Attr.first == HOSTCALL_PTR ||
525 Attr.first == FLAT_SCRATCH_INIT))
528 if (
F->hasFnAttribute(Attr.second))
529 addKnownBits(Attr.first);
532 if (
F->isDeclaration())
538 indicatePessimisticFixpoint();
546 auto OrigAssumed = getAssumed();
549 const AACallEdges *AAEdges =
A.getAAFor<AACallEdges>(
550 *
this, this->getIRPosition(), DepClassTy::REQUIRED);
553 return indicatePessimisticFixpoint();
557 bool NeedsImplicit =
false;
558 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
560 bool HasApertureRegs = Features.
test(AMDGPU::FEAT_APERTURE_REGS);
561 bool SupportsGetDoorbellID = Features.
test(AMDGPU::FEAT_GET_DOORBELL_ID);
562 unsigned COV = InfoCache.getCodeObjectVersion();
567 const AAAMDAttributes *AAAMD =
A.getAAFor<AAAMDAttributes>(
569 if (!AAAMD || !AAAMD->isValidState())
570 return indicatePessimisticFixpoint();
575 bool NonKernelOnly =
false;
578 HasApertureRegs, SupportsGetDoorbellID, COV);
589 if (!
Callee->hasFnAttribute(Attribute::NoCallback))
590 return indicatePessimisticFixpoint();
595 if ((IsNonEntryFunc || !NonKernelOnly))
596 removeAssumedBits(AttrMask);
602 removeAssumedBits(IMPLICIT_ARG_PTR);
604 if (isAssumed(QUEUE_PTR) && checkForQueuePtr(
A)) {
608 removeAssumedBits(IMPLICIT_ARG_PTR);
610 removeAssumedBits(QUEUE_PTR);
613 uint32_t Retrieved = getRetrievedImplicitArgs(
A);
615 if (Retrieved & MULTIGRID_SYNC_ARG) {
616 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
617 "multigrid_sync_arg needs implicitarg_ptr");
618 removeAssumedBits(MULTIGRID_SYNC_ARG);
621 if (Retrieved & HOSTCALL_PTR) {
622 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"hostcall needs implicitarg_ptr");
623 removeAssumedBits(HOSTCALL_PTR);
626 if (Retrieved & HEAP_PTR) {
627 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"heap_ptr needs implicitarg_ptr");
628 removeAssumedBits(HEAP_PTR);
631 if (isAssumed(QUEUE_PTR) && (Retrieved & QUEUE_PTR)) {
632 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"queue_ptr needs implicitarg_ptr");
633 removeAssumedBits(QUEUE_PTR);
636 if (isAssumed(LDS_KERNEL_ID) && (Retrieved & LDS_KERNEL_ID)) {
637 removeAssumedBits(LDS_KERNEL_ID);
640 if (isAssumed(DEFAULT_QUEUE) && (Retrieved & DEFAULT_QUEUE))
641 removeAssumedBits(DEFAULT_QUEUE);
643 if (isAssumed(COMPLETION_ACTION) && (Retrieved & COMPLETION_ACTION))
644 removeAssumedBits(COMPLETION_ACTION);
646 if (isAssumed(FLAT_SCRATCH_INIT) && needFlatScratchInit(
A))
647 removeAssumedBits(FLAT_SCRATCH_INIT);
649 return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED
650 : ChangeStatus::UNCHANGED;
655 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
656 for (
auto [Mask, Attr] : InfoCache.getImplicitAttrList()) {
661 return A.manifestAttrs(getIRPosition(), AttrList,
665 const std::string getAsStr(Attributor *)
const override {
667 raw_string_ostream OS(Str);
670 if (isAssumed(Attr.first))
671 OS <<
' ' << Attr.second;
677 void trackStatistics()
const override {}
680 bool checkForQueuePtr(Attributor &
A) {
684 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
686 bool NeedsQueuePtr =
false;
689 unsigned SrcAS =
static_cast<AddrSpaceCastInst &
>(
I).getSrcAddressSpace();
691 NeedsQueuePtr =
true;
697 bool HasApertureRegs =
698 InfoCache.getFeatures().test(AMDGPU::FEAT_APERTURE_REGS);
704 if (!HasApertureRegs) {
705 bool UsedAssumedInformation =
false;
706 A.checkForAllInstructions(CheckAddrSpaceCasts, *
this,
707 {Instruction::AddrSpaceCast},
708 UsedAssumedInformation);
715 if (!IsNonEntryFunc && HasApertureRegs)
718 for (BasicBlock &BB : *
F) {
719 for (Instruction &
I : BB) {
720 for (
const Use &U :
I.operands()) {
722 if (InfoCache.needsQueuePtr(
C, *
F))
734 uint32_t getImplicitArgsReadThrough(Attributor &
A,
const CallBase &
Call) {
735 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
736 uint32_t ArgsMask = InfoCache.getImplicitArgsMask();
737 const auto *PointerInfoAA =
A.getAAFor<AAPointerInfo>(
739 if (!PointerInfoAA || !PointerInfoAA->getState().isValidState())
746 auto CheckAccess = [&](
const AAPointerInfo::Access &Acc, bool) {
749 for (
const AA::RangeTy &AccRange : Acc.
getRanges()) {
750 for (
auto [Mask,
Range] : InfoCache.getImplicitArgRanges()) {
751 if (AccRange.mayOverlap(
Range))
756 return Read != ArgsMask;
759 if (!PointerInfoAA->forallInterferingAccesses(
760 InfoCache.getImplicitArgsRange(), CheckAccess))
767 uint32_t getRetrievedImplicitArgs(Attributor &
A) {
768 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
769 uint32_t
All = InfoCache.getImplicitArgsMask() | LDS_KERNEL_ID;
770 uint32_t Retrieved = 0;
774 case Intrinsic::amdgcn_implicitarg_ptr:
775 Retrieved |= getImplicitArgsReadThrough(
A,
Call);
777 case Intrinsic::amdgcn_lds_kernel_id:
778 Retrieved |= LDS_KERNEL_ID;
786 return Retrieved !=
All;
789 bool UsedAssumedInformation =
false;
790 if (!
A.checkForAllCallLikeInstructions(CheckCall, *
this,
791 UsedAssumedInformation))
798 bool needFlatScratchInit(Attributor &
A) {
799 assert(isAssumed(FLAT_SCRATCH_INIT));
808 bool UsedAssumedInformation =
false;
809 if (!
A.checkForAllInstructions(AddrSpaceCastNotFromPrivate, *
this,
810 {Instruction::AddrSpaceCast},
811 UsedAssumedInformation))
815 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
819 for (
const Use &U :
I.operands()) {
821 if (InfoCache.checkConstForAddrSpaceCastFromPrivate(
C))
831AAAMDAttributes &AAAMDAttributes::createForPosition(
const IRPosition &IRP,
834 return *
new (
A.Allocator) AAAMDAttributesFunction(IRP,
A);
839struct AAAMDSizeRangeAttribute
840 :
public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
841 using Base = StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t>;
845 AAAMDSizeRangeAttribute(
const IRPosition &IRP, Attributor &
A,
847 :
Base(IRP, 32), AttrName(AttrName) {}
850 void trackStatistics()
const override {}
852 template <
class AttributeImpl>
ChangeStatus updateImplImpl(Attributor &
A) {
855 auto CheckCallSite = [&](AbstractCallSite CS) {
858 <<
"->" << getAssociatedFunction()->
getName() <<
'\n');
860 const auto *CallerInfo =
A.getAAFor<AttributeImpl>(
862 if (!CallerInfo || !CallerInfo->isValidState())
871 bool AllCallSitesKnown =
true;
872 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
875 return indicatePessimisticFixpoint();
883 emitAttributeIfNotDefaultAfterClamp(Attributor &
A,
884 std::pair<unsigned, unsigned>
Default) {
886 unsigned Lower = getAssumed().getLower().getZExtValue();
887 unsigned Upper = getAssumed().getUpper().getZExtValue();
897 return ChangeStatus::UNCHANGED;
900 LLVMContext &Ctx =
F->getContext();
901 SmallString<10> Buffer;
902 raw_svector_ostream OS(Buffer);
904 return A.manifestAttrs(getIRPosition(),
905 {Attribute::get(Ctx, AttrName, OS.str())},
909 const std::string getAsStr(Attributor *)
const override {
911 raw_string_ostream OS(Str);
913 OS << getAssumed().getLower() <<
',' << getAssumed().getUpper() - 1;
920struct AAAMDFlatWorkGroupSize :
public AAAMDSizeRangeAttribute {
921 AAAMDFlatWorkGroupSize(
const IRPosition &IRP, Attributor &
A)
922 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-flat-work-group-size") {}
926 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
928 bool HasAttr =
false;
929 auto Range = InfoCache.getDefaultFlatWorkGroupSize(*
F);
930 auto MaxRange = InfoCache.getMaximumFlatWorkGroupRange();
932 if (
auto Attr = InfoCache.getFlatWorkGroupSizeAttr(*
F)) {
936 if (*Attr != MaxRange) {
944 if (
Range == MaxRange)
948 ConstantRange CR(APInt(32, Min), APInt(32, Max + 1));
949 IntegerRangeState IRS(CR);
953 indicateOptimisticFixpoint();
957 return updateImplImpl<AAAMDFlatWorkGroupSize>(
A);
961 static AAAMDFlatWorkGroupSize &createForPosition(
const IRPosition &IRP,
965 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
966 return emitAttributeIfNotDefaultAfterClamp(
967 A, InfoCache.getMaximumFlatWorkGroupRange());
971 StringRef
getName()
const override {
return "AAAMDFlatWorkGroupSize"; }
974 const char *getIdAddr()
const override {
return &
ID; }
978 static bool classof(
const AbstractAttribute *AA) {
983 static const char ID;
986const char AAAMDFlatWorkGroupSize::ID = 0;
988AAAMDFlatWorkGroupSize &
989AAAMDFlatWorkGroupSize::createForPosition(
const IRPosition &IRP,
992 return *
new (
A.Allocator) AAAMDFlatWorkGroupSize(IRP,
A);
994 "AAAMDFlatWorkGroupSize is only valid for function position");
997struct TupleDecIntegerRangeState :
public AbstractState {
998 DecIntegerState<uint32_t>
X,
Y, Z;
1000 bool isValidState()
const override {
1001 return X.isValidState() &&
Y.isValidState() &&
Z.isValidState();
1004 bool isAtFixpoint()
const override {
1005 return X.isAtFixpoint() &&
Y.isAtFixpoint() &&
Z.isAtFixpoint();
1009 return X.indicateOptimisticFixpoint() |
Y.indicateOptimisticFixpoint() |
1010 Z.indicateOptimisticFixpoint();
1014 return X.indicatePessimisticFixpoint() |
Y.indicatePessimisticFixpoint() |
1015 Z.indicatePessimisticFixpoint();
1018 TupleDecIntegerRangeState
operator^=(
const TupleDecIntegerRangeState &
Other) {
1029 TupleDecIntegerRangeState &getAssumed() {
return *
this; }
1030 const TupleDecIntegerRangeState &getAssumed()
const {
return *
this; }
1033using AAAMDMaxNumWorkgroupsState =
1034 StateWrapper<TupleDecIntegerRangeState, AbstractAttribute, uint32_t>;
1037struct AAAMDMaxNumWorkgroups
1038 :
public StateWrapper<TupleDecIntegerRangeState, AbstractAttribute> {
1039 using Base = StateWrapper<TupleDecIntegerRangeState, AbstractAttribute>;
1041 AAAMDMaxNumWorkgroups(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1048 X.takeKnownMinimum(MaxNumWorkgroups[0]);
1049 Y.takeKnownMinimum(MaxNumWorkgroups[1]);
1050 Z.takeKnownMinimum(MaxNumWorkgroups[2]);
1053 indicatePessimisticFixpoint();
1059 auto CheckCallSite = [&](AbstractCallSite CS) {
1062 <<
"->" << getAssociatedFunction()->
getName() <<
'\n');
1064 const auto *CallerInfo =
A.getAAFor<AAAMDMaxNumWorkgroups>(
1066 if (!CallerInfo || !CallerInfo->isValidState())
1074 bool AllCallSitesKnown =
true;
1075 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
1078 return indicatePessimisticFixpoint();
1084 static AAAMDMaxNumWorkgroups &createForPosition(
const IRPosition &IRP,
1089 LLVMContext &Ctx =
F->getContext();
1090 SmallString<32> Buffer;
1091 raw_svector_ostream OS(Buffer);
1092 OS <<
X.getAssumed() <<
',' <<
Y.getAssumed() <<
',' <<
Z.getAssumed();
1096 return A.manifestAttrs(
1098 {Attribute::get(Ctx,
"amdgpu-max-num-workgroups", OS.str())},
1102 StringRef
getName()
const override {
return "AAAMDMaxNumWorkgroups"; }
1104 const std::string getAsStr(Attributor *)
const override {
1105 std::string Buffer =
"AAAMDMaxNumWorkgroupsState[";
1106 raw_string_ostream OS(Buffer);
1107 OS <<
X.getAssumed() <<
',' <<
Y.getAssumed() <<
',' <<
Z.getAssumed()
1112 const char *getIdAddr()
const override {
return &
ID; }
1116 static bool classof(
const AbstractAttribute *AA) {
1120 void trackStatistics()
const override {}
1123 static const char ID;
1126const char AAAMDMaxNumWorkgroups::ID = 0;
1128AAAMDMaxNumWorkgroups &
1129AAAMDMaxNumWorkgroups::createForPosition(
const IRPosition &IRP, Attributor &
A) {
1131 return *
new (
A.Allocator) AAAMDMaxNumWorkgroups(IRP,
A);
1132 llvm_unreachable(
"AAAMDMaxNumWorkgroups is only valid for function position");
1136struct AAAMDWavesPerEU :
public AAAMDSizeRangeAttribute {
1137 AAAMDWavesPerEU(
const IRPosition &IRP, Attributor &
A)
1138 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-waves-per-eu") {}
1142 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
1145 if (
auto Attr = InfoCache.getWavesPerEUAttr(*
F)) {
1146 std::pair<unsigned, unsigned> MaxWavesPerEURange{
1147 1U, InfoCache.getMaxWavesPerEU()};
1148 if (*Attr != MaxWavesPerEURange) {
1149 auto [Min,
Max] = *Attr;
1150 ConstantRange
Range(APInt(32, Min), APInt(32, Max + 1));
1151 IntegerRangeState RangeState(
Range);
1152 this->getState() = RangeState;
1153 indicateOptimisticFixpoint();
1159 indicatePessimisticFixpoint();
1165 auto CheckCallSite = [&](AbstractCallSite CS) {
1169 <<
"->" <<
Func->getName() <<
'\n');
1172 const auto *CallerAA =
A.getAAFor<AAAMDWavesPerEU>(
1174 if (!CallerAA || !CallerAA->isValidState())
1177 ConstantRange Assumed = getAssumed();
1179 CallerAA->getAssumed().getLower().getZExtValue());
1181 CallerAA->getAssumed().getUpper().getZExtValue());
1182 ConstantRange
Range(APInt(32, Min), APInt(32, Max));
1183 IntegerRangeState RangeState(
Range);
1184 getState() = RangeState;
1185 Change |= getState() == Assumed ? ChangeStatus::UNCHANGED
1186 : ChangeStatus::CHANGED;
1191 bool AllCallSitesKnown =
true;
1192 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
1193 return indicatePessimisticFixpoint();
1199 static AAAMDWavesPerEU &createForPosition(
const IRPosition &IRP,
1203 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
1204 return emitAttributeIfNotDefaultAfterClamp(
1205 A, {1U, InfoCache.getMaxWavesPerEU()});
1209 StringRef
getName()
const override {
return "AAAMDWavesPerEU"; }
1212 const char *getIdAddr()
const override {
return &
ID; }
1216 static bool classof(
const AbstractAttribute *AA) {
1221 static const char ID;
1224const char AAAMDWavesPerEU::ID = 0;
1226AAAMDWavesPerEU &AAAMDWavesPerEU::createForPosition(
const IRPosition &IRP,
1229 return *
new (
A.Allocator) AAAMDWavesPerEU(IRP,
A);
1234static unsigned inlineAsmGetNumRequiredAGPRs(
const InlineAsm *IA,
1235 const CallBase &
Call) {
1238 unsigned AGPRDefCount = 0;
1239 unsigned AGPRUseCount = 0;
1240 unsigned MaxPhysReg = 0;
1244 for (
const InlineAsm::ConstraintInfo &CI :
IA->ParseConstraints()) {
1250 Ty = STy->getElementType(ResNo);
1265 for (StringRef Code : CI.Codes) {
1266 unsigned RegCount = 0;
1267 if (
Code.starts_with(
"a")) {
1278 MaxPhysReg = std::max(MaxPhysReg, std::min(RegIdx + NumRegs, 256u));
1288 AGPRDefCount =
alignTo(AGPRDefCount, RegCount);
1290 AGPRDefCount += RegCount;
1291 if (CI.isEarlyClobber) {
1292 AGPRUseCount =
alignTo(AGPRUseCount, RegCount);
1293 AGPRUseCount += RegCount;
1296 AGPRUseCount =
alignTo(AGPRUseCount, RegCount);
1297 AGPRUseCount += RegCount;
1302 unsigned MaxVirtReg = std::max(AGPRUseCount, AGPRDefCount);
1307 return std::min(MaxVirtReg + MaxPhysReg, 256u);
1310struct AAAMDGPUMinAGPRAlloc
1311 :
public StateWrapper<DecIntegerState<>, AbstractAttribute> {
1312 using Base = StateWrapper<DecIntegerState<>, AbstractAttribute>;
1313 AAAMDGPUMinAGPRAlloc(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1315 static AAAMDGPUMinAGPRAlloc &createForPosition(
const IRPosition &IRP,
1318 return *
new (
A.Allocator) AAAMDGPUMinAGPRAlloc(IRP,
A);
1320 "AAAMDGPUMinAGPRAlloc is only valid for function position");
1325 auto [MinNumAGPR, MaxNumAGPR] =
1328 if (MinNumAGPR == 0) {
1329 indicateOptimisticFixpoint();
1334 indicatePessimisticFixpoint();
1337 const std::string getAsStr(Attributor *
A)
const override {
1338 std::string Str =
"amdgpu-agpr-alloc=";
1339 raw_string_ostream OS(Str);
1344 void trackStatistics()
const override {}
1347 DecIntegerState<> Maximum;
1354 const Value *CalleeOp = CB.getCalledOperand();
1359 unsigned NumRegs = inlineAsmGetNumRequiredAGPRs(IA, CB);
1363 switch (CB.getIntrinsicID()) {
1366 case Intrinsic::write_register:
1367 case Intrinsic::read_register:
1368 case Intrinsic::read_volatile_register: {
1373 auto [
Kind, RegIdx, NumRegs] =
1387 case Intrinsic::trap:
1388 case Intrinsic::debugtrap:
1389 case Intrinsic::ubsantrap:
1390 return CB.hasFnAttr(Attribute::NoCallback) ||
1391 !CB.hasFnAttr(
"trap-func-name");
1397 return CB.hasFnAttr(Attribute::NoCallback);
1401 auto *CBEdges =
A.getAAFor<AACallEdges>(
1403 if (!CBEdges || CBEdges->hasUnknownCallee()) {
1408 for (
const Function *PossibleCallee : CBEdges->getOptimisticEdges()) {
1409 const auto *CalleeInfo =
A.getAAFor<AAAMDGPUMinAGPRAlloc>(
1411 if (!CalleeInfo || !CalleeInfo->isValidState()) {
1422 bool UsedAssumedInformation =
false;
1423 if (!
A.checkForAllCallLikeInstructions(CheckForMinAGPRAllocs, *
this,
1424 UsedAssumedInformation))
1425 return indicatePessimisticFixpoint();
1431 LLVMContext &Ctx = getAssociatedFunction()->getContext();
1432 SmallString<4> Buffer;
1433 raw_svector_ostream OS(Buffer);
1436 return A.manifestAttrs(
1437 getIRPosition(), {Attribute::get(Ctx,
"amdgpu-agpr-alloc", OS.str())});
1440 StringRef
getName()
const override {
return "AAAMDGPUMinAGPRAlloc"; }
1441 const char *getIdAddr()
const override {
return &
ID; }
1445 static bool classof(
const AbstractAttribute *AA) {
1449 static const char ID;
1452const char AAAMDGPUMinAGPRAlloc::ID = 0;
1455struct AAAMDGPUNoLDSDMA :
public StateWrapper<BooleanState, AbstractAttribute> {
1456 using Base = StateWrapper<BooleanState, AbstractAttribute>;
1457 AAAMDGPUNoLDSDMA(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1460 static AAAMDGPUNoLDSDMA &createForPosition(
const IRPosition &IRP,
1463 "AAAMDGPUNoLDSDMA is only valid for function position");
1464 return *
new (
A.Allocator) AAAMDGPUNoLDSDMA(IRP,
A);
1468 const Function *
F = getAssociatedFunction();
1469 if (
F->hasFnAttribute(
"amdgpu-no-lds-dma")) {
1470 indicateOptimisticFixpoint();
1474 if (
F->isDeclaration())
1475 indicatePessimisticFixpoint();
1492 CB.hasFnAttr(Attribute::NoCallback);
1495 const auto *CBEdges =
A.getAAFor<AACallEdges>(
1497 if (!CBEdges || CBEdges->hasUnknownCallee())
1500 for (
const Function *PossibleCallee : CBEdges->getOptimisticEdges()) {
1501 const auto *CalleeInfo =
A.getAAFor<AAAMDGPUNoLDSDMA>(
1503 if (!CalleeInfo || !CalleeInfo->getAssumed())
1510 bool UsedAssumedInformation =
false;
1511 if (!
A.checkForAllCallLikeInstructions(CheckNoLDSDMA, *
this,
1512 UsedAssumedInformation))
1513 return indicatePessimisticFixpoint();
1515 return ChangeStatus::UNCHANGED;
1520 return ChangeStatus::UNCHANGED;
1522 LLVMContext &Ctx = getAssociatedFunction()->getContext();
1523 return A.manifestAttrs(getIRPosition(),
1524 {Attribute::get(Ctx,
"amdgpu-no-lds-dma")});
1527 bool isValidState()
const override {
return true; }
1529 const std::string getAsStr(Attributor *
A)
const override {
1530 return "AMDGPUNoLDSDMA[" + std::to_string(getAssumed()) +
"]";
1533 void trackStatistics()
const override {}
1535 StringRef
getName()
const override {
return "AAAMDGPUNoLDSDMA"; }
1536 const char *getIdAddr()
const override {
return &
ID; }
1540 static bool classof(
const AbstractAttribute *AA) {
1544 static const char ID;
1547const char AAAMDGPUNoLDSDMA::ID = 0;
1551struct AAAMDGPUClusterDims
1552 :
public StateWrapper<BooleanState, AbstractAttribute> {
1553 using Base = StateWrapper<BooleanState, AbstractAttribute>;
1554 AAAMDGPUClusterDims(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1557 static AAAMDGPUClusterDims &createForPosition(
const IRPosition &IRP,
1561 StringRef
getName()
const override {
return "AAAMDGPUClusterDims"; }
1564 const char *getIdAddr()
const override {
return &
ID; }
1568 static bool classof(
const AbstractAttribute *AA) {
1572 virtual const AMDGPU::ClusterDimsAttr &getClusterDims()
const = 0;
1575 static const char ID;
1578const char AAAMDGPUClusterDims::ID = 0;
1580struct AAAMDGPUClusterDimsFunction :
public AAAMDGPUClusterDims {
1581 AAAMDGPUClusterDimsFunction(
const IRPosition &IRP, Attributor &
A)
1582 : AAAMDGPUClusterDims(IRP,
A) {}
1586 assert(
F &&
"empty associated function");
1593 indicatePessimisticFixpoint();
1595 indicateOptimisticFixpoint();
1599 const std::string getAsStr(Attributor *
A)
const override {
1609 void trackStatistics()
const override {}
1612 auto OldState = Attr;
1614 auto CheckCallSite = [&](AbstractCallSite CS) {
1615 const auto *CallerAA =
A.getAAFor<AAAMDGPUClusterDims>(
1617 DepClassTy::REQUIRED);
1618 if (!CallerAA || !CallerAA->isValidState())
1621 return merge(CallerAA->getClusterDims());
1624 bool UsedAssumedInformation =
false;
1625 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
1627 UsedAssumedInformation))
1628 return indicatePessimisticFixpoint();
1630 return OldState == Attr ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
1635 return ChangeStatus::UNCHANGED;
1636 return A.manifestAttrs(
1638 {Attribute::get(getAssociatedFunction()->
getContext(), AttrName,
1643 const AMDGPU::ClusterDimsAttr &getClusterDims()
const override {
1648 bool merge(
const AMDGPU::ClusterDimsAttr &
Other) {
1663 if (
Other.isUnknown())
1688 AMDGPU::ClusterDimsAttr Attr;
1690 static constexpr char AttrName[] =
"amdgpu-cluster-dims";
1693AAAMDGPUClusterDims &
1694AAAMDGPUClusterDims::createForPosition(
const IRPosition &IRP, Attributor &
A) {
1696 return *
new (
A.Allocator) AAAMDGPUClusterDimsFunction(IRP,
A);
1697 llvm_unreachable(
"AAAMDGPUClusterDims is only valid for function position");
1700static bool runImpl(SetVector<Function *> &Functions,
bool IsModulePass,
1701 bool DeleteFns,
Module &M, AnalysisGetter &AG,
1702 TargetMachine &TM, AMDGPUAttributorOptions
Options,
1705 CallGraphUpdater CGUpdater;
1707 AMDGPUInformationCache InfoCache(M, AG,
Allocator,
nullptr, TM);
1708 DenseSet<const char *>
Allowed(
1709 {&AAAMDAttributes::ID, &AAUniformWorkGroupSize::ID,
1711 &AAAMDMaxNumWorkgroups::ID, &AAAMDWavesPerEU::ID,
1715 &AAAMDGPUClusterDims::ID, &AAAMDGPUNoLDSDMA::ID, &
AAAlign::ID});
1717 AttributorConfig AC(CGUpdater);
1718 AC.IsClosedWorldModule =
Options.IsClosedWorld;
1720 AC.IsModulePass = IsModulePass;
1721 AC.DeleteFns = DeleteFns;
1722 AC.DefaultInitializeLiveInternals =
false;
1724 AC.UseLiveness =
false;
1725 AC.IndirectCalleeSpecializationCallback =
1726 [](Attributor &
A,
const AbstractAttribute &AA, CallBase &CB,
1731 AC.IPOAmendableCB = [](
const Function &
F) {
1732 return F.getCallingConv() == CallingConv::AMDGPU_KERNEL;
1735 Attributor
A(Functions, InfoCache, AC);
1738 StringRef LTOPhaseStr =
to_string(LTOPhase);
1739 dbgs() <<
"[AMDGPUAttributor] Running at phase " << LTOPhaseStr <<
'\n'
1740 <<
"[AMDGPUAttributor] Module " <<
M.getName() <<
" is "
1741 << (AC.IsClosedWorldModule ?
"" :
"not ")
1742 <<
"assumed to be a closed world.\n";
1745 for (
auto *
F : Functions) {
1750 CallingConv::ID CC =
F->getCallingConv();
1757 if (!
F->isDeclaration() && Features.
test(AMDGPU::FEAT_CLUSTERS))
1760 if (Features.
test(AMDGPU::FEAT_AGPR_ALLOC))
1764 Value *Ptr =
nullptr;
1766 Ptr = LI->getPointerOperand();
1768 Ptr =
SI->getPointerOperand();
1770 Ptr = RMW->getPointerOperand();
1772 Ptr = CmpX->getPointerOperand();
1782 if (
II->getIntrinsicID() == Intrinsic::amdgcn_make_buffer_rsrc)
1789 return A.run() == ChangeStatus::CHANGED;
1802 if (!
F.isDeclaration())
1803 Functions.insert(&
F);
1807 return runImpl(Functions,
true,
true, M, AG,
1808 TM, Options, LTOPhase)
1825 if (!
F->isIntrinsic())
1826 Functions.insert(
F);
1830 Module *M =
C.begin()->getFunction().getParent();
1833 return runImpl(Functions,
false,
false, *M, AG,
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isDSAddress(const Constant *C)
static constexpr std::pair< ImplicitArgumentMask, StringLiteral > ImplicitAttrs[]
static cl::opt< unsigned > IndirectCallSpecializationThreshold("amdgpu-indirect-call-specialization-threshold", cl::desc("A threshold controls whether an indirect call will be specialized"), cl::init(3))
static ImplicitArgumentMask intrinsicToAttrMask(Intrinsic::ID ID, bool &NonKernelOnly, bool &NeedsImplicit, bool HasApertureRegs, bool SupportsGetDoorBellID, unsigned CodeObjectVersion)
static bool hasSanitizerAttributes(const Function &F)
Returns true if sanitizer attributes are present on a function.
ImplicitArgumentPositions
static bool castRequiresQueuePtr(unsigned SrcAS)
The AMDGPU TargetMachine interface definition for hw codegen targets.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runImpl(MachineFunction &MF)
AMD GCN specific subclass of TargetSubtarget.
static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)
static FeatureBitset getFeatures(MCSubtargetInfo &STI, StringRef CPU, StringRef TuneCPU, StringRef FS, StringTable ProcNames, ArrayRef< SubtargetSubTypeKV > ProcDesc, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Machine Check Debug Module
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
static StringRef getName(Value *V)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static ClusterDimsAttr get(const Function &F)
std::string to_string() const
bool isVariableDims() const
uint64_t getZExtValue() const
Get zero extended value.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
constexpr bool test(unsigned I) const
Value * getArgOperand(unsigned i) const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
A constant value that is initialized with an expression using other constant values.
const APInt & getLower() const
Return the lower value for this range.
const APInt & getUpper() const
Return the upper value for this range.
This is an important base class in LLVM.
A proxy from a FunctionAnalysisManager to an SCC.
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
unsigned getAddressSpace() const
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
A node in the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
A vector that has set insertion semantics.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::string str() const
Get the contents as an std::string.
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
A Use represents the edge between a Value definition and its users.
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Type * getType() const
All values are typed, get the type of this value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ FLAT_ADDRESS
Address space for flat memory.
@ PRIVATE_ADDRESS
Address space for private memory.
LLVM_ABI unsigned getMaxWavesPerEU(GPUKind AK)
constexpr unsigned getMaxFlatWorkGroupSize()
constexpr unsigned getMinFlatWorkGroupSize()
unsigned getAMDHSACodeObjectVersion(const Module &M)
unsigned getDefaultQueueImplicitArgPosition(unsigned CodeObjectVersion)
std::tuple< char, unsigned, unsigned > parseAsmPhysRegName(StringRef RegName)
Returns a valid charcode or 0 in the first entry if this is a valid physical register name.
bool isLDSDMAIntrinsic(unsigned IntrID)
Bitset< NUM_FEATURES > AMDGPUFeatureBitset
LLVM_READNONE constexpr bool isEntryFunctionCC(CallingConv::ID CC)
LLVM_ABI Triple::SubArchType getSubArch(GPUKind AK)
std::tuple< char, unsigned, unsigned > parseAsmConstraintPhysReg(StringRef Constraint)
Returns a valid charcode or 0 in the first entry if this is a valid physical register constraint.
LLVM_ABI GPUKind getGPUKindFromSubArch(Triple::SubArchType SubArch)
SmallVector< unsigned > getMaxNumWorkGroups(const Function &F)
LLVM_ABI const AMDGPUFeatureBitset & getFeatureBitset(GPUKind AK)
Returns AK's feature bitset, or an empty bitset if unknown.
unsigned getCompletionActionImplicitArgPosition(unsigned CodeObjectVersion)
std::pair< unsigned, unsigned > getIntegerPairAttribute(const Function &F, StringRef Name, std::pair< unsigned, unsigned > Default, bool OnlyFirstRequired)
LLVM_READNONE constexpr bool isGraphics(CallingConv::ID CC)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
E & operator^=(E &LHS, E RHS)
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
NodeAddr< CodeNode * > Code
NodeAddr< FuncNode * > Func
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
@ None
No LTO/ThinLTO behavior needed.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
const char * to_string(ThinOrFullLTOPhase Phase)
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
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...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
@ End
Run the machine verifier once, at the end of the pipeline.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual const SetVector< Function * > & getOptimisticEdges() const =0
Get the optimistic edges.
static LLVM_ABI 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.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
const RangeList & getRanges() const
Instruction * getRemoteInst() const
Return the actual instruction that causes the access.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
virtual const char * getIdAddr() const =0
This function should return the address of the ID of the AbstractAttribute.
Wrapper for FunctionAnalysisManager.
The fixpoint analysis framework that orchestrates the attribute deduction.
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
DecIntegerState & takeAssumedMaximum(base_t Value)
Take maximum of assumed and Value.
Helper to describe and deal with positions in the LLVM-IR.
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
@ IRP_FUNCTION
An attribute for a function (scope).
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Kind getPositionKind() const
Return the associated position kind.
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
bool isValidState() const override
See AbstractState::isValidState() NOTE: For now we simply pretend that the worst possible state is in...
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Helper to tie a abstract state implementation to an abstract attribute.