17#include "llvm/IR/IntrinsicsAMDGPU.h"
18#include "llvm/IR/IntrinsicsR600.h"
23#define DEBUG_TYPE "amdgpu-attributor"
27#define AMDGPU_ATTRIBUTE(Name, Str) Name##_POS,
30#include "AMDGPUAttributes.def"
34#define AMDGPU_ATTRIBUTE(Name, Str) Name = 1 << Name##_POS,
38#include "AMDGPUAttributes.def"
43#define AMDGPU_ATTRIBUTE(Name, Str) {Name, Str},
44static constexpr std::pair<ImplicitArgumentMask, StringLiteral>
46#include "AMDGPUAttributes.def"
56 bool HasApertureRegs,
bool SupportsGetDoorBellID,
57 unsigned CodeObjectVersion) {
59 case Intrinsic::amdgcn_workitem_id_x:
62 case Intrinsic::amdgcn_workgroup_id_x:
64 return WORKGROUP_ID_X;
65 case Intrinsic::amdgcn_workitem_id_y:
66 case Intrinsic::r600_read_tidig_y:
68 case Intrinsic::amdgcn_workitem_id_z:
69 case Intrinsic::r600_read_tidig_z:
71 case Intrinsic::amdgcn_workgroup_id_y:
72 case Intrinsic::r600_read_tgid_y:
73 return WORKGROUP_ID_Y;
74 case Intrinsic::amdgcn_workgroup_id_z:
75 case Intrinsic::r600_read_tgid_z:
76 return WORKGROUP_ID_Z;
77 case Intrinsic::amdgcn_cluster_id_x:
80 case Intrinsic::amdgcn_cluster_id_y:
82 case Intrinsic::amdgcn_cluster_id_z:
84 case Intrinsic::amdgcn_lds_kernel_id:
86 case Intrinsic::amdgcn_dispatch_ptr:
88 case Intrinsic::amdgcn_dispatch_id:
90 case Intrinsic::amdgcn_implicitarg_ptr:
91 return IMPLICIT_ARG_PTR;
94 case Intrinsic::amdgcn_queue_ptr:
97 case Intrinsic::amdgcn_is_shared:
98 case Intrinsic::amdgcn_is_private:
106 case Intrinsic::amdgcn_wwm:
107 case Intrinsic::amdgcn_strict_wwm:
108 return WHOLE_WAVE_MODE;
109 case Intrinsic::trap:
110 case Intrinsic::debugtrap:
111 case Intrinsic::ubsantrap:
112 if (SupportsGetDoorBellID)
136 return F.hasFnAttribute(Attribute::SanitizeAddress) ||
137 F.hasFnAttribute(Attribute::SanitizeThread) ||
138 F.hasFnAttribute(Attribute::SanitizeConcurrency) ||
139 F.hasFnAttribute(Attribute::SanitizeMemory) ||
140 F.hasFnAttribute(Attribute::SanitizeHWAddress) ||
141 F.hasFnAttribute(Attribute::SanitizeMemTag);
147 AMDGPUInformationCache(
const Module &M, AnalysisGetter &AG,
149 SetVector<Function *> *
CGSCC, TargetMachine &TM)
155 LLVMContext &Ctx =
M.getContext();
157 ImplicitAttrList.push_back({Mask, Attribute::get(Ctx, Name)});
159 llvm::sort(ImplicitAttrList, [](
const auto &
A,
const auto &
B) {
160 return A.second.getKindAsString() < B.second.getKindAsString();
163 unsigned COV = CodeObjectVersion;
164 ImplicitArgRanges = {
166 {AMDGPU::getMultigridSyncArgImplicitArgPosition(COV), 8}},
167 {HOSTCALL_PTR, {AMDGPU::getHostcallImplicitArgPosition(COV), 8}},
172 ImplicitArgRanges.push_back(
174 ImplicitArgRanges.push_back(
179 for (
auto [Mask,
Range] : ImplicitArgRanges) {
180 ImplicitArgsMask |=
Mask;
181 Begin = std::min(Begin,
Range.Offset);
193 getImplicitAttrList()
const {
194 return ImplicitAttrList;
197 enum ConstantStatus :
uint8_t {
200 ADDR_SPACE_CAST_PRIVATE_TO_FLAT = 1 << 1,
201 ADDR_SPACE_CAST_LOCAL_TO_FLAT = 1 << 2,
202 ADDR_SPACE_CAST_BOTH_TO_FLAT =
203 ADDR_SPACE_CAST_PRIVATE_TO_FLAT | ADDR_SPACE_CAST_LOCAL_TO_FLAT,
204 CS_WORST = DS_GLOBAL | ADDR_SPACE_CAST_BOTH_TO_FLAT,
207 std::optional<std::pair<unsigned, unsigned>>
208 getFlatWorkGroupSizeAttr(
const Function &
F)
const {
212 return std::make_pair(
R->first, *(
R->second));
215 std::pair<unsigned, unsigned>
216 getDefaultFlatWorkGroupSize(
const Function &
F)
const {
218 return ST.getDefaultFlatWorkGroupSize(
F.getCallingConv());
221 std::pair<unsigned, unsigned> getMaximumFlatWorkGroupRange()
const {
227 unsigned getCodeObjectVersion()
const {
return CodeObjectVersion; }
232 getImplicitArgRanges()
const {
233 return ImplicitArgRanges;
237 uint32_t getImplicitArgsMask()
const {
return ImplicitArgsMask; }
240 AA::RangeTy getImplicitArgsRange()
const {
return ImplicitArgsRange; }
245 std::optional<std::pair<unsigned, unsigned>>
253 return std::make_pair(Val->first, *(Val->second));
260 unsigned getMaxAddrSpace()
const override {
270 if (
CE->getOpcode() == Instruction::AddrSpaceCast) {
271 unsigned SrcAS =
CE->getOperand(0)->getType()->getPointerAddressSpace();
273 Status |= ADDR_SPACE_CAST_PRIVATE_TO_FLAT;
275 Status |= ADDR_SPACE_CAST_LOCAL_TO_FLAT;
286 const auto &It = ConstantStatus.find(
C);
287 if (It != ConstantStatus.end())
288 return It->second.value();
296 while (Result != CS_WORST && !Worklist.
empty()) {
299 std::optional<uint8_t> &CurCResultOrNone = ConstantStatus[CurC];
300 if (CurCResultOrNone) {
301 Result |= CurCResultOrNone.value();
307 CurCResult |= DS_GLOBAL;
310 CurCResult |= visitConstExpr(CE);
314 if (Visited.
insert(OpC).second)
319 CurCResultOrNone = CurCResult;
331 bool HasAperture = Features.test(AMDGPU::FEAT_APERTURE_REGS);
334 if (!IsNonEntryFunc && HasAperture)
340 if (IsNonEntryFunc && (
Access & DS_GLOBAL))
343 return !HasAperture && (
Access & ADDR_SPACE_CAST_BOTH_TO_FLAT);
346 bool checkConstForAddrSpaceCastFromPrivate(
const Constant *
C) {
348 return Access & ADDR_SPACE_CAST_PRIVATE_TO_FLAT;
358 const unsigned CodeObjectVersion;
365struct AAAMDAttributes
366 :
public StateWrapper<BitIntegerState<uint32_t, ALL_ARGUMENT_MASK, 0>,
368 using Base = StateWrapper<BitIntegerState<uint32_t, ALL_ARGUMENT_MASK, 0>,
371 AAAMDAttributes(
const IRPosition &IRP, Attributor &
A) : Base(IRP) {}
374 static AAAMDAttributes &createForPosition(
const IRPosition &IRP,
377 StringRef
getName()
const override {
return "AAAMDAttributes"; }
379 const char *getIdAddr()
const override {
return &ID; }
383 static bool classof(
const AbstractAttribute *AA) {
388 static const char ID;
390const char AAAMDAttributes::ID = 0;
392struct AAUniformWorkGroupSize
393 :
public StateWrapper<BooleanState, AbstractAttribute> {
394 using Base = StateWrapper<BooleanState, AbstractAttribute>;
395 AAUniformWorkGroupSize(
const IRPosition &IRP, Attributor &
A) : Base(IRP) {}
398 static AAUniformWorkGroupSize &createForPosition(
const IRPosition &IRP,
401 StringRef
getName()
const override {
return "AAUniformWorkGroupSize"; }
403 const char *getIdAddr()
const override {
return &ID; }
407 static bool classof(
const AbstractAttribute *AA) {
412 static const char ID;
414const char AAUniformWorkGroupSize::ID = 0;
416struct AAUniformWorkGroupSizeFunction :
public AAUniformWorkGroupSize {
417 AAUniformWorkGroupSizeFunction(
const IRPosition &IRP, Attributor &
A)
418 : AAUniformWorkGroupSize(IRP,
A) {}
422 CallingConv::ID
CC =
F->getCallingConv();
424 if (
CC != CallingConv::AMDGPU_KERNEL)
427 bool InitialValue =
F->hasFnAttribute(
"uniform-work-group-size");
430 indicateOptimisticFixpoint();
432 indicatePessimisticFixpoint();
438 auto CheckCallSite = [&](AbstractCallSite CS) {
441 <<
"->" << getAssociatedFunction()->
getName() <<
"\n");
443 const auto *CallerInfo =
A.getAAFor<AAUniformWorkGroupSize>(
445 if (!CallerInfo || !CallerInfo->isValidState())
449 CallerInfo->getState());
454 bool AllCallSitesKnown =
true;
455 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
456 return indicatePessimisticFixpoint();
463 return ChangeStatus::UNCHANGED;
465 LLVMContext &Ctx = getAssociatedFunction()->getContext();
466 return A.manifestAttrs(getIRPosition(),
467 {Attribute::get(Ctx,
"uniform-work-group-size")},
471 bool isValidState()
const override {
476 const std::string getAsStr(Attributor *)
const override {
477 return "AMDWorkGroupSize[" + std::to_string(getAssumed()) +
"]";
480 void trackStatistics()
const override {}
483AAUniformWorkGroupSize &
484AAUniformWorkGroupSize::createForPosition(
const IRPosition &IRP,
487 return *
new (
A.Allocator) AAUniformWorkGroupSizeFunction(IRP,
A);
489 "AAUniformWorkGroupSize is only valid for function position");
492struct AAAMDAttributesFunction :
public AAAMDAttributes {
493 AAAMDAttributesFunction(
const IRPosition &IRP, Attributor &
A)
494 : AAAMDAttributes(IRP,
A) {}
506 if (HasSanitizerAttrs) {
507 removeAssumedBits(IMPLICIT_ARG_PTR);
508 removeAssumedBits(HOSTCALL_PTR);
509 removeAssumedBits(FLAT_SCRATCH_INIT);
513 if (HasSanitizerAttrs &&
514 (Attr.first == IMPLICIT_ARG_PTR || Attr.first == HOSTCALL_PTR ||
515 Attr.first == FLAT_SCRATCH_INIT))
518 if (
F->hasFnAttribute(Attr.second))
519 addKnownBits(Attr.first);
522 if (
F->isDeclaration())
528 indicatePessimisticFixpoint();
536 auto OrigAssumed = getAssumed();
539 const AACallEdges *AAEdges =
A.getAAFor<AACallEdges>(
540 *
this, this->getIRPosition(), DepClassTy::REQUIRED);
543 return indicatePessimisticFixpoint();
547 bool NeedsImplicit =
false;
548 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
550 bool HasApertureRegs = Features.
test(AMDGPU::FEAT_APERTURE_REGS);
551 bool SupportsGetDoorbellID = Features.
test(AMDGPU::FEAT_GET_DOORBELL_ID);
552 unsigned COV = InfoCache.getCodeObjectVersion();
557 const AAAMDAttributes *AAAMD =
A.getAAFor<AAAMDAttributes>(
559 if (!AAAMD || !AAAMD->isValidState())
560 return indicatePessimisticFixpoint();
565 bool NonKernelOnly =
false;
568 HasApertureRegs, SupportsGetDoorbellID, COV);
579 if (!
Callee->hasFnAttribute(Attribute::NoCallback))
580 return indicatePessimisticFixpoint();
585 if ((IsNonEntryFunc || !NonKernelOnly))
586 removeAssumedBits(AttrMask);
592 removeAssumedBits(IMPLICIT_ARG_PTR);
594 if (isAssumed(QUEUE_PTR) && checkForQueuePtr(
A)) {
598 removeAssumedBits(IMPLICIT_ARG_PTR);
600 removeAssumedBits(QUEUE_PTR);
603 uint32_t Retrieved = getRetrievedImplicitArgs(
A);
605 if (Retrieved & MULTIGRID_SYNC_ARG) {
606 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
607 "multigrid_sync_arg needs implicitarg_ptr");
608 removeAssumedBits(MULTIGRID_SYNC_ARG);
611 if (Retrieved & HOSTCALL_PTR) {
612 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"hostcall needs implicitarg_ptr");
613 removeAssumedBits(HOSTCALL_PTR);
616 if (Retrieved & HEAP_PTR) {
617 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"heap_ptr needs implicitarg_ptr");
618 removeAssumedBits(HEAP_PTR);
621 if (isAssumed(QUEUE_PTR) && (Retrieved & QUEUE_PTR)) {
622 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"queue_ptr needs implicitarg_ptr");
623 removeAssumedBits(QUEUE_PTR);
626 if (isAssumed(LDS_KERNEL_ID) && (Retrieved & LDS_KERNEL_ID)) {
627 removeAssumedBits(LDS_KERNEL_ID);
630 if (isAssumed(DEFAULT_QUEUE) && (Retrieved & DEFAULT_QUEUE))
631 removeAssumedBits(DEFAULT_QUEUE);
633 if (isAssumed(COMPLETION_ACTION) && (Retrieved & COMPLETION_ACTION))
634 removeAssumedBits(COMPLETION_ACTION);
636 if (isAssumed(FLAT_SCRATCH_INIT) && needFlatScratchInit(
A))
637 removeAssumedBits(FLAT_SCRATCH_INIT);
639 return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED
640 : ChangeStatus::UNCHANGED;
645 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
646 for (
auto [Mask, Attr] : InfoCache.getImplicitAttrList()) {
651 return A.manifestAttrs(getIRPosition(), AttrList,
655 const std::string getAsStr(Attributor *)
const override {
657 raw_string_ostream OS(Str);
660 if (isAssumed(Attr.first))
661 OS <<
' ' << Attr.second;
666 void trackStatistics()
const override {}
669 bool checkForQueuePtr(Attributor &
A) {
673 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
675 bool NeedsQueuePtr =
false;
678 unsigned SrcAS =
static_cast<AddrSpaceCastInst &
>(
I).getSrcAddressSpace();
680 NeedsQueuePtr =
true;
686 bool HasApertureRegs =
687 InfoCache.getFeatures().test(AMDGPU::FEAT_APERTURE_REGS);
693 if (!HasApertureRegs) {
694 bool UsedAssumedInformation =
false;
695 A.checkForAllInstructions(CheckAddrSpaceCasts, *
this,
696 {Instruction::AddrSpaceCast},
697 UsedAssumedInformation);
704 if (!IsNonEntryFunc && HasApertureRegs)
707 for (BasicBlock &BB : *
F) {
708 for (Instruction &
I : BB) {
709 for (
const Use &U :
I.operands()) {
711 if (InfoCache.needsQueuePtr(
C, *
F))
723 uint32_t getImplicitArgsReadThrough(Attributor &
A,
const CallBase &
Call) {
724 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
725 uint32_t ArgsMask = InfoCache.getImplicitArgsMask();
726 const auto *PointerInfoAA =
A.getAAFor<AAPointerInfo>(
728 if (!PointerInfoAA || !PointerInfoAA->getState().isValidState())
735 auto CheckAccess = [&](
const AAPointerInfo::Access &Acc, bool) {
738 for (
const AA::RangeTy &AccRange : Acc.
getRanges()) {
739 for (
auto [Mask,
Range] : InfoCache.getImplicitArgRanges()) {
740 if (AccRange.mayOverlap(
Range))
745 return Read != ArgsMask;
748 if (!PointerInfoAA->forallInterferingAccesses(
749 InfoCache.getImplicitArgsRange(), CheckAccess))
756 uint32_t getRetrievedImplicitArgs(Attributor &
A) {
757 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
758 uint32_t
All = InfoCache.getImplicitArgsMask() | LDS_KERNEL_ID;
759 uint32_t Retrieved = 0;
763 case Intrinsic::amdgcn_implicitarg_ptr:
764 Retrieved |= getImplicitArgsReadThrough(
A,
Call);
766 case Intrinsic::amdgcn_lds_kernel_id:
767 Retrieved |= LDS_KERNEL_ID;
775 return Retrieved !=
All;
778 bool UsedAssumedInformation =
false;
779 if (!
A.checkForAllCallLikeInstructions(CheckCall, *
this,
780 UsedAssumedInformation))
787 bool needFlatScratchInit(Attributor &
A) {
788 assert(isAssumed(FLAT_SCRATCH_INIT));
797 bool UsedAssumedInformation =
false;
798 if (!
A.checkForAllInstructions(AddrSpaceCastNotFromPrivate, *
this,
799 {Instruction::AddrSpaceCast},
800 UsedAssumedInformation))
804 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
808 for (
const Use &U :
I.operands()) {
810 if (InfoCache.checkConstForAddrSpaceCastFromPrivate(
C))
820AAAMDAttributes &AAAMDAttributes::createForPosition(
const IRPosition &IRP,
823 return *
new (
A.Allocator) AAAMDAttributesFunction(IRP,
A);
828struct AAAMDSizeRangeAttribute
829 :
public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
830 using Base = StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t>;
834 AAAMDSizeRangeAttribute(
const IRPosition &IRP, Attributor &
A,
836 :
Base(IRP, 32), AttrName(AttrName) {}
838 void trackStatistics()
const override {}
840 template <
class AttributeImpl>
ChangeStatus updateImplImpl(Attributor &
A) {
843 auto CheckCallSite = [&](AbstractCallSite CS) {
846 <<
"->" << getAssociatedFunction()->
getName() <<
'\n');
848 const auto *CallerInfo =
A.getAAFor<AttributeImpl>(
850 if (!CallerInfo || !CallerInfo->isValidState())
859 bool AllCallSitesKnown =
true;
860 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
863 return indicatePessimisticFixpoint();
871 emitAttributeIfNotDefaultAfterClamp(Attributor &
A,
872 std::pair<unsigned, unsigned>
Default) {
874 unsigned Lower = getAssumed().getLower().getZExtValue();
875 unsigned Upper = getAssumed().getUpper().getZExtValue();
885 return ChangeStatus::UNCHANGED;
888 LLVMContext &Ctx =
F->getContext();
889 SmallString<10> Buffer;
890 raw_svector_ostream OS(Buffer);
892 return A.manifestAttrs(getIRPosition(),
893 {Attribute::get(Ctx, AttrName, OS.str())},
897 const std::string getAsStr(Attributor *)
const override {
899 raw_string_ostream OS(Str);
901 OS << getAssumed().getLower() <<
',' << getAssumed().getUpper() - 1;
908struct AAAMDFlatWorkGroupSize :
public AAAMDSizeRangeAttribute {
909 AAAMDFlatWorkGroupSize(
const IRPosition &IRP, Attributor &
A)
910 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-flat-work-group-size") {}
914 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
916 bool HasAttr =
false;
917 auto Range = InfoCache.getDefaultFlatWorkGroupSize(*
F);
918 auto MaxRange = InfoCache.getMaximumFlatWorkGroupRange();
920 if (
auto Attr = InfoCache.getFlatWorkGroupSizeAttr(*
F)) {
924 if (*Attr != MaxRange) {
932 if (
Range == MaxRange)
936 ConstantRange CR(APInt(32, Min), APInt(32, Max + 1));
937 IntegerRangeState IRS(CR);
941 indicateOptimisticFixpoint();
945 return updateImplImpl<AAAMDFlatWorkGroupSize>(
A);
949 static AAAMDFlatWorkGroupSize &createForPosition(
const IRPosition &IRP,
953 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
954 return emitAttributeIfNotDefaultAfterClamp(
955 A, InfoCache.getMaximumFlatWorkGroupRange());
958 StringRef
getName()
const override {
return "AAAMDFlatWorkGroupSize"; }
960 const char *getIdAddr()
const override {
return &
ID; }
964 static bool classof(
const AbstractAttribute *AA) {
969 static const char ID;
972const char AAAMDFlatWorkGroupSize::ID = 0;
974AAAMDFlatWorkGroupSize &
975AAAMDFlatWorkGroupSize::createForPosition(
const IRPosition &IRP,
978 return *
new (
A.Allocator) AAAMDFlatWorkGroupSize(IRP,
A);
980 "AAAMDFlatWorkGroupSize is only valid for function position");
983struct TupleDecIntegerRangeState :
public AbstractState {
984 DecIntegerState<uint32_t>
X,
Y, Z;
986 bool isValidState()
const override {
987 return X.isValidState() &&
Y.isValidState() &&
Z.isValidState();
990 bool isAtFixpoint()
const override {
991 return X.isAtFixpoint() &&
Y.isAtFixpoint() &&
Z.isAtFixpoint();
995 return X.indicateOptimisticFixpoint() |
Y.indicateOptimisticFixpoint() |
996 Z.indicateOptimisticFixpoint();
1000 return X.indicatePessimisticFixpoint() |
Y.indicatePessimisticFixpoint() |
1001 Z.indicatePessimisticFixpoint();
1004 TupleDecIntegerRangeState
operator^=(
const TupleDecIntegerRangeState &
Other) {
1015 TupleDecIntegerRangeState &getAssumed() {
return *
this; }
1016 const TupleDecIntegerRangeState &getAssumed()
const {
return *
this; }
1019using AAAMDMaxNumWorkgroupsState =
1020 StateWrapper<TupleDecIntegerRangeState, AbstractAttribute, uint32_t>;
1023struct AAAMDMaxNumWorkgroups
1024 :
public StateWrapper<TupleDecIntegerRangeState, AbstractAttribute> {
1025 using Base = StateWrapper<TupleDecIntegerRangeState, AbstractAttribute>;
1027 AAAMDMaxNumWorkgroups(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1034 X.takeKnownMinimum(MaxNumWorkgroups[0]);
1035 Y.takeKnownMinimum(MaxNumWorkgroups[1]);
1036 Z.takeKnownMinimum(MaxNumWorkgroups[2]);
1039 indicatePessimisticFixpoint();
1045 auto CheckCallSite = [&](AbstractCallSite CS) {
1048 <<
"->" << getAssociatedFunction()->
getName() <<
'\n');
1050 const auto *CallerInfo =
A.getAAFor<AAAMDMaxNumWorkgroups>(
1052 if (!CallerInfo || !CallerInfo->isValidState())
1060 bool AllCallSitesKnown =
true;
1061 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
1064 return indicatePessimisticFixpoint();
1070 static AAAMDMaxNumWorkgroups &createForPosition(
const IRPosition &IRP,
1075 LLVMContext &Ctx =
F->getContext();
1076 SmallString<32> Buffer;
1077 raw_svector_ostream OS(Buffer);
1078 OS <<
X.getAssumed() <<
',' <<
Y.getAssumed() <<
',' <<
Z.getAssumed();
1082 return A.manifestAttrs(
1084 {Attribute::get(Ctx,
"amdgpu-max-num-workgroups", OS.str())},
1088 StringRef
getName()
const override {
return "AAAMDMaxNumWorkgroups"; }
1090 const std::string getAsStr(Attributor *)
const override {
1091 std::string Buffer =
"AAAMDMaxNumWorkgroupsState[";
1092 raw_string_ostream OS(Buffer);
1093 OS <<
X.getAssumed() <<
',' <<
Y.getAssumed() <<
',' <<
Z.getAssumed()
1098 const char *getIdAddr()
const override {
return &
ID; }
1102 static bool classof(
const AbstractAttribute *AA) {
1106 void trackStatistics()
const override {}
1109 static const char ID;
1112const char AAAMDMaxNumWorkgroups::ID = 0;
1114AAAMDMaxNumWorkgroups &
1115AAAMDMaxNumWorkgroups::createForPosition(
const IRPosition &IRP, Attributor &
A) {
1117 return *
new (
A.Allocator) AAAMDMaxNumWorkgroups(IRP,
A);
1118 llvm_unreachable(
"AAAMDMaxNumWorkgroups is only valid for function position");
1122struct AAAMDWavesPerEU :
public AAAMDSizeRangeAttribute {
1123 AAAMDWavesPerEU(
const IRPosition &IRP, Attributor &
A)
1124 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-waves-per-eu") {}
1128 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
1131 if (
auto Attr = InfoCache.getWavesPerEUAttr(*
F)) {
1132 std::pair<unsigned, unsigned> MaxWavesPerEURange{
1133 1U, InfoCache.getMaxWavesPerEU()};
1134 if (*Attr != MaxWavesPerEURange) {
1135 auto [Min,
Max] = *Attr;
1136 ConstantRange
Range(APInt(32, Min), APInt(32, Max + 1));
1137 IntegerRangeState RangeState(
Range);
1138 this->getState() = RangeState;
1139 indicateOptimisticFixpoint();
1145 indicatePessimisticFixpoint();
1151 auto CheckCallSite = [&](AbstractCallSite CS) {
1155 <<
"->" <<
Func->getName() <<
'\n');
1158 const auto *CallerAA =
A.getAAFor<AAAMDWavesPerEU>(
1160 if (!CallerAA || !CallerAA->isValidState())
1163 ConstantRange Assumed = getAssumed();
1165 CallerAA->getAssumed().getLower().getZExtValue());
1167 CallerAA->getAssumed().getUpper().getZExtValue());
1168 ConstantRange
Range(APInt(32, Min), APInt(32, Max));
1169 IntegerRangeState RangeState(
Range);
1170 getState() = RangeState;
1171 Change |= getState() == Assumed ? ChangeStatus::UNCHANGED
1172 : ChangeStatus::CHANGED;
1177 bool AllCallSitesKnown =
true;
1178 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
1179 return indicatePessimisticFixpoint();
1185 static AAAMDWavesPerEU &createForPosition(
const IRPosition &IRP,
1189 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
1190 return emitAttributeIfNotDefaultAfterClamp(
1191 A, {1U, InfoCache.getMaxWavesPerEU()});
1194 StringRef
getName()
const override {
return "AAAMDWavesPerEU"; }
1196 const char *getIdAddr()
const override {
return &
ID; }
1200 static bool classof(
const AbstractAttribute *AA) {
1205 static const char ID;
1208const char AAAMDWavesPerEU::ID = 0;
1210AAAMDWavesPerEU &AAAMDWavesPerEU::createForPosition(
const IRPosition &IRP,
1213 return *
new (
A.Allocator) AAAMDWavesPerEU(IRP,
A);
1218static unsigned inlineAsmGetNumRequiredAGPRs(
const InlineAsm *IA,
1219 const CallBase &
Call) {
1222 unsigned AGPRDefCount = 0;
1223 unsigned AGPRUseCount = 0;
1224 unsigned MaxPhysReg = 0;
1228 for (
const InlineAsm::ConstraintInfo &CI :
IA->ParseConstraints()) {
1234 Ty = STy->getElementType(ResNo);
1249 for (StringRef Code : CI.Codes) {
1250 unsigned RegCount = 0;
1251 if (
Code.starts_with(
"a")) {
1262 MaxPhysReg = std::max(MaxPhysReg, std::min(RegIdx + NumRegs, 256u));
1272 AGPRDefCount =
alignTo(AGPRDefCount, RegCount);
1274 AGPRDefCount += RegCount;
1275 if (CI.isEarlyClobber) {
1276 AGPRUseCount =
alignTo(AGPRUseCount, RegCount);
1277 AGPRUseCount += RegCount;
1280 AGPRUseCount =
alignTo(AGPRUseCount, RegCount);
1281 AGPRUseCount += RegCount;
1286 unsigned MaxVirtReg = std::max(AGPRUseCount, AGPRDefCount);
1291 return std::min(MaxVirtReg + MaxPhysReg, 256u);
1297checkForAllPossibleCallees(Attributor &
A,
const AbstractAttribute &QueryingAA,
1303 if (Callee && !
Callee->hasMetadata(LLVMContext::MD_callback))
1304 return Pred(*Callee);
1306 const AACallEdges *CBEdges =
A.getAAFor<AACallEdges>(
1311 [&](
const Function *Fn) { return Pred(*Fn); });
1314struct AAAMDGPUMinAGPRAlloc
1315 :
public StateWrapper<DecIntegerState<>, AbstractAttribute> {
1316 using Base = StateWrapper<DecIntegerState<>, AbstractAttribute>;
1317 AAAMDGPUMinAGPRAlloc(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1319 static AAAMDGPUMinAGPRAlloc &createForPosition(
const IRPosition &IRP,
1322 return *
new (
A.Allocator) AAAMDGPUMinAGPRAlloc(IRP,
A);
1324 "AAAMDGPUMinAGPRAlloc is only valid for function position");
1329 auto [MinNumAGPR, MaxNumAGPR] =
1332 if (MinNumAGPR == 0) {
1333 indicateOptimisticFixpoint();
1338 indicatePessimisticFixpoint();
1341 const std::string getAsStr(Attributor *
A)
const override {
1342 std::string Str =
"amdgpu-agpr-alloc=";
1343 raw_string_ostream OS(Str);
1348 void trackStatistics()
const override {}
1351 DecIntegerState<> Maximum;
1363 unsigned NumRegs = inlineAsmGetNumRequiredAGPRs(IA, CB);
1370 case Intrinsic::write_register:
1371 case Intrinsic::read_register:
1372 case Intrinsic::read_volatile_register: {
1377 auto [
Kind, RegIdx, NumRegs] =
1391 case Intrinsic::trap:
1392 case Intrinsic::debugtrap:
1393 case Intrinsic::ubsantrap:
1394 return CB.
hasFnAttr(Attribute::NoCallback) ||
1401 return CB.
hasFnAttr(Attribute::NoCallback);
1406 const AAAMDGPUMinAGPRAlloc *CalleeInfo =
1407 A.getAAFor<AAAMDGPUMinAGPRAlloc>(
1409 if (!CalleeInfo || !CalleeInfo->isValidState())
1414 if (!checkForAllPossibleCallees(
A, *
this, CB, CheckCallee)) {
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();
1495 return checkForAllPossibleCallees(
1496 A, *
this, CB, [&](
const Function &Callee) {
1497 const AAAMDGPUNoLDSDMA *CalleeInfo =
A.getAAFor<AAAMDGPUNoLDSDMA>(
1499 return CalleeInfo && CalleeInfo->getAssumed();
1503 bool UsedAssumedInformation =
false;
1504 if (!
A.checkForAllCallLikeInstructions(CheckNoLDSDMA, *
this,
1505 UsedAssumedInformation))
1506 return indicatePessimisticFixpoint();
1508 return ChangeStatus::UNCHANGED;
1513 return ChangeStatus::UNCHANGED;
1515 LLVMContext &Ctx = getAssociatedFunction()->getContext();
1516 return A.manifestAttrs(getIRPosition(),
1517 {Attribute::get(Ctx,
"amdgpu-no-lds-dma")});
1520 bool isValidState()
const override {
return true; }
1522 const std::string getAsStr(Attributor *
A)
const override {
1523 return "AMDGPUNoLDSDMA[" + std::to_string(getAssumed()) +
"]";
1526 void trackStatistics()
const override {}
1528 StringRef
getName()
const override {
return "AAAMDGPUNoLDSDMA"; }
1529 const char *getIdAddr()
const override {
return &
ID; }
1533 static bool classof(
const AbstractAttribute *AA) {
1537 static const char ID;
1540const char AAAMDGPUNoLDSDMA::ID = 0;
1544struct AAAMDGPUClusterDims
1545 :
public StateWrapper<BooleanState, AbstractAttribute> {
1546 using Base = StateWrapper<BooleanState, AbstractAttribute>;
1547 AAAMDGPUClusterDims(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1550 static AAAMDGPUClusterDims &createForPosition(
const IRPosition &IRP,
1553 StringRef
getName()
const override {
return "AAAMDGPUClusterDims"; }
1555 const char *getIdAddr()
const override {
return &
ID; }
1559 static bool classof(
const AbstractAttribute *AA) {
1563 virtual const AMDGPU::ClusterDimsAttr &getClusterDims()
const = 0;
1566 static const char ID;
1569const char AAAMDGPUClusterDims::ID = 0;
1571struct AAAMDGPUClusterDimsFunction :
public AAAMDGPUClusterDims {
1572 AAAMDGPUClusterDimsFunction(
const IRPosition &IRP, Attributor &
A)
1573 : AAAMDGPUClusterDims(IRP,
A) {}
1577 assert(
F &&
"empty associated function");
1584 indicatePessimisticFixpoint();
1586 indicateOptimisticFixpoint();
1590 const std::string getAsStr(Attributor *
A)
const override {
1600 void trackStatistics()
const override {}
1603 auto OldState = Attr;
1605 auto CheckCallSite = [&](AbstractCallSite CS) {
1606 const auto *CallerAA =
A.getAAFor<AAAMDGPUClusterDims>(
1608 DepClassTy::REQUIRED);
1609 if (!CallerAA || !CallerAA->isValidState())
1612 return merge(CallerAA->getClusterDims());
1615 bool UsedAssumedInformation =
false;
1616 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
1618 UsedAssumedInformation))
1619 return indicatePessimisticFixpoint();
1621 return OldState == Attr ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
1626 return ChangeStatus::UNCHANGED;
1627 return A.manifestAttrs(
1629 {Attribute::get(getAssociatedFunction()->
getContext(), AttrName,
1634 const AMDGPU::ClusterDimsAttr &getClusterDims()
const override {
1639 bool merge(
const AMDGPU::ClusterDimsAttr &
Other) {
1654 if (
Other.isUnknown())
1679 AMDGPU::ClusterDimsAttr Attr;
1681 static constexpr char AttrName[] =
"amdgpu-cluster-dims";
1684AAAMDGPUClusterDims &
1685AAAMDGPUClusterDims::createForPosition(
const IRPosition &IRP, Attributor &
A) {
1687 return *
new (
A.Allocator) AAAMDGPUClusterDimsFunction(IRP,
A);
1688 llvm_unreachable(
"AAAMDGPUClusterDims is only valid for function position");
1691static bool runImpl(SetVector<Function *> &Functions,
bool IsModulePass,
1692 bool DeleteFns,
Module &M, AnalysisGetter &AG,
1693 TargetMachine &TM, AMDGPUAttributorOptions
Options,
1696 CallGraphUpdater CGUpdater;
1698 AMDGPUInformationCache InfoCache(M, AG,
Allocator,
nullptr, TM);
1701 &AAAMDFlatWorkGroupSize::ID, &AAAMDMaxNumWorkgroups::ID,
1708 AttributorConfig AC(CGUpdater);
1709 AC.IsClosedWorldModule =
Options.IsClosedWorld;
1711 AC.IsModulePass = IsModulePass;
1712 AC.DeleteFns = DeleteFns;
1713 AC.DefaultInitializeLiveInternals =
false;
1715 AC.UseLiveness =
false;
1716 unsigned IndirectCallSpecializationThreshold =
1717 static_cast<const AMDGPUTargetMachine &
>(TM)
1719 .indirect_call_specialization_threshold;
1720 AC.IndirectCalleeSpecializationCallback =
1721 [IndirectCallSpecializationThreshold](
1722 Attributor &
A,
const AbstractAttribute &AA, CallBase &CB,
1725 (NumAssumedCallees <= IndirectCallSpecializationThreshold);
1727 AC.IPOAmendableCB = [](
const Function &
F) {
1728 return F.getCallingConv() == CallingConv::AMDGPU_KERNEL;
1731 Attributor
A(Functions, InfoCache, AC);
1734 StringRef LTOPhaseStr =
to_string(LTOPhase);
1735 dbgs() <<
"[AMDGPUAttributor] Running at phase " << LTOPhaseStr <<
'\n'
1736 <<
"[AMDGPUAttributor] Module " <<
M.getName() <<
" is "
1737 << (AC.IsClosedWorldModule ?
"" :
"not ")
1738 <<
"assumed to be a closed world.\n";
1741 for (
auto *
F : Functions) {
1746 CallingConv::ID
CC =
F->getCallingConv();
1753 if (!
F->isDeclaration() && Features.
test(AMDGPU::FEAT_CLUSTERS))
1756 if (Features.
test(AMDGPU::FEAT_AGPR_ALLOC))
1760 Value *Ptr =
nullptr;
1762 Ptr = LI->getPointerOperand();
1764 Ptr =
SI->getPointerOperand();
1766 Ptr = RMW->getPointerOperand();
1768 Ptr = CmpX->getPointerOperand();
1778 if (
II->getIntrinsicID() == Intrinsic::amdgcn_make_buffer_rsrc)
1785 return A.run() == ChangeStatus::CHANGED;
1798 if (!
F.isDeclaration())
1799 Functions.insert(&
F);
1803 return runImpl(Functions,
true,
true, M, AG,
1804 TM, Options, LTOPhase)
1821 if (!
F->isIntrinsic())
1822 Functions.insert(
F);
1826 Module *M =
C.begin()->getFunction().getParent();
1829 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 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
bpf unwind BPF Unwind Lower
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.
static constexpr AAKindSet get()
Return the set of the kinds with the IDs KindIDs.
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
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Value * getCalledOperand() 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.
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
@ 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 E & operator^=(E &LHS, E RHS)
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.
@ CE
Windows NT (Windows on ARM)
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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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.
virtual bool hasUnknownCallee() const =0
Is there any call with a unknown callee.
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
NOTE: For now we simply pretend that the worst possible state is invalid.
ChangeStatus indicatePessimisticFixpoint() override
Indicate that the abstract state should converge to the pessimistic state.
Helper to tie a abstract state implementation to an abstract attribute.