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::SanitizeConcurrency) ||
145 F.hasFnAttribute(Attribute::SanitizeMemory) ||
146 F.hasFnAttribute(Attribute::SanitizeHWAddress) ||
147 F.hasFnAttribute(Attribute::SanitizeMemTag);
153 AMDGPUInformationCache(
const Module &M, AnalysisGetter &AG,
155 SetVector<Function *> *
CGSCC, TargetMachine &TM)
161 LLVMContext &Ctx =
M.getContext();
163 ImplicitAttrList.push_back({Mask, Attribute::get(Ctx, Name)});
165 llvm::sort(ImplicitAttrList, [](
const auto &
A,
const auto &
B) {
166 return A.second.getKindAsString() < B.second.getKindAsString();
169 unsigned COV = CodeObjectVersion;
170 ImplicitArgRanges = {
172 {AMDGPU::getMultigridSyncArgImplicitArgPosition(COV), 8}},
173 {HOSTCALL_PTR, {AMDGPU::getHostcallImplicitArgPosition(COV), 8}},
178 ImplicitArgRanges.push_back(
180 ImplicitArgRanges.push_back(
185 for (
auto [Mask,
Range] : ImplicitArgRanges) {
186 ImplicitArgsMask |=
Mask;
187 Begin = std::min(Begin,
Range.Offset);
199 getImplicitAttrList()
const {
200 return ImplicitAttrList;
203 enum ConstantStatus :
uint8_t {
206 ADDR_SPACE_CAST_PRIVATE_TO_FLAT = 1 << 1,
207 ADDR_SPACE_CAST_LOCAL_TO_FLAT = 1 << 2,
208 ADDR_SPACE_CAST_BOTH_TO_FLAT =
209 ADDR_SPACE_CAST_PRIVATE_TO_FLAT | ADDR_SPACE_CAST_LOCAL_TO_FLAT,
210 CS_WORST = DS_GLOBAL | ADDR_SPACE_CAST_BOTH_TO_FLAT,
213 std::optional<std::pair<unsigned, unsigned>>
214 getFlatWorkGroupSizeAttr(
const Function &
F)
const {
218 return std::make_pair(
R->first, *(
R->second));
221 std::pair<unsigned, unsigned>
222 getDefaultFlatWorkGroupSize(
const Function &
F)
const {
224 return ST.getDefaultFlatWorkGroupSize(
F.getCallingConv());
227 std::pair<unsigned, unsigned> getMaximumFlatWorkGroupRange()
const {
233 unsigned getCodeObjectVersion()
const {
return CodeObjectVersion; }
238 getImplicitArgRanges()
const {
239 return ImplicitArgRanges;
243 uint32_t getImplicitArgsMask()
const {
return ImplicitArgsMask; }
246 AA::RangeTy getImplicitArgsRange()
const {
return ImplicitArgsRange; }
251 std::optional<std::pair<unsigned, unsigned>>
259 return std::make_pair(Val->first, *(Val->second));
266 unsigned getMaxAddrSpace()
const override {
276 if (
CE->getOpcode() == Instruction::AddrSpaceCast) {
277 unsigned SrcAS =
CE->getOperand(0)->getType()->getPointerAddressSpace();
279 Status |= ADDR_SPACE_CAST_PRIVATE_TO_FLAT;
281 Status |= ADDR_SPACE_CAST_LOCAL_TO_FLAT;
292 const auto &It = ConstantStatus.find(
C);
293 if (It != ConstantStatus.end())
294 return It->second.value();
302 while (Result != CS_WORST && !Worklist.
empty()) {
305 std::optional<uint8_t> &CurCResultOrNone = ConstantStatus[CurC];
306 if (CurCResultOrNone) {
307 Result |= CurCResultOrNone.value();
313 CurCResult |= DS_GLOBAL;
316 CurCResult |= visitConstExpr(CE);
320 if (Visited.
insert(OpC).second)
325 CurCResultOrNone = CurCResult;
337 bool HasAperture = Features.test(AMDGPU::FEAT_APERTURE_REGS);
340 if (!IsNonEntryFunc && HasAperture)
346 if (IsNonEntryFunc && (
Access & DS_GLOBAL))
349 return !HasAperture && (
Access & ADDR_SPACE_CAST_BOTH_TO_FLAT);
352 bool checkConstForAddrSpaceCastFromPrivate(
const Constant *
C) {
354 return Access & ADDR_SPACE_CAST_PRIVATE_TO_FLAT;
364 const unsigned CodeObjectVersion;
371struct AAAMDAttributes
372 :
public StateWrapper<BitIntegerState<uint32_t, ALL_ARGUMENT_MASK, 0>,
374 using Base = StateWrapper<BitIntegerState<uint32_t, ALL_ARGUMENT_MASK, 0>,
377 AAAMDAttributes(
const IRPosition &IRP, Attributor &
A) : Base(IRP) {}
380 static AAAMDAttributes &createForPosition(
const IRPosition &IRP,
383 StringRef
getName()
const override {
return "AAAMDAttributes"; }
385 const char *getIdAddr()
const override {
return &ID; }
389 static bool classof(
const AbstractAttribute *AA) {
394 static const char ID;
396const char AAAMDAttributes::ID = 0;
398struct AAUniformWorkGroupSize
399 :
public StateWrapper<BooleanState, AbstractAttribute> {
400 using Base = StateWrapper<BooleanState, AbstractAttribute>;
401 AAUniformWorkGroupSize(
const IRPosition &IRP, Attributor &
A) : Base(IRP) {}
404 static AAUniformWorkGroupSize &createForPosition(
const IRPosition &IRP,
407 StringRef
getName()
const override {
return "AAUniformWorkGroupSize"; }
409 const char *getIdAddr()
const override {
return &ID; }
413 static bool classof(
const AbstractAttribute *AA) {
418 static const char ID;
420const char AAUniformWorkGroupSize::ID = 0;
422struct AAUniformWorkGroupSizeFunction :
public AAUniformWorkGroupSize {
423 AAUniformWorkGroupSizeFunction(
const IRPosition &IRP, Attributor &
A)
424 : AAUniformWorkGroupSize(IRP,
A) {}
428 CallingConv::ID
CC =
F->getCallingConv();
430 if (
CC != CallingConv::AMDGPU_KERNEL)
433 bool InitialValue =
F->hasFnAttribute(
"uniform-work-group-size");
436 indicateOptimisticFixpoint();
438 indicatePessimisticFixpoint();
444 auto CheckCallSite = [&](AbstractCallSite CS) {
447 <<
"->" << getAssociatedFunction()->
getName() <<
"\n");
449 const auto *CallerInfo =
A.getAAFor<AAUniformWorkGroupSize>(
451 if (!CallerInfo || !CallerInfo->isValidState())
455 CallerInfo->getState());
460 bool AllCallSitesKnown =
true;
461 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
462 return indicatePessimisticFixpoint();
469 return ChangeStatus::UNCHANGED;
471 LLVMContext &Ctx = getAssociatedFunction()->getContext();
472 return A.manifestAttrs(getIRPosition(),
473 {Attribute::get(Ctx,
"uniform-work-group-size")},
477 bool isValidState()
const override {
482 const std::string getAsStr(Attributor *)
const override {
483 return "AMDWorkGroupSize[" + std::to_string(getAssumed()) +
"]";
486 void trackStatistics()
const override {}
489AAUniformWorkGroupSize &
490AAUniformWorkGroupSize::createForPosition(
const IRPosition &IRP,
493 return *
new (
A.Allocator) AAUniformWorkGroupSizeFunction(IRP,
A);
495 "AAUniformWorkGroupSize is only valid for function position");
498struct AAAMDAttributesFunction :
public AAAMDAttributes {
499 AAAMDAttributesFunction(
const IRPosition &IRP, Attributor &
A)
500 : AAAMDAttributes(IRP,
A) {}
512 if (HasSanitizerAttrs) {
513 removeAssumedBits(IMPLICIT_ARG_PTR);
514 removeAssumedBits(HOSTCALL_PTR);
515 removeAssumedBits(FLAT_SCRATCH_INIT);
519 if (HasSanitizerAttrs &&
520 (Attr.first == IMPLICIT_ARG_PTR || Attr.first == HOSTCALL_PTR ||
521 Attr.first == FLAT_SCRATCH_INIT))
524 if (
F->hasFnAttribute(Attr.second))
525 addKnownBits(Attr.first);
528 if (
F->isDeclaration())
534 indicatePessimisticFixpoint();
542 auto OrigAssumed = getAssumed();
545 const AACallEdges *AAEdges =
A.getAAFor<AACallEdges>(
546 *
this, this->getIRPosition(), DepClassTy::REQUIRED);
549 return indicatePessimisticFixpoint();
553 bool NeedsImplicit =
false;
554 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
556 bool HasApertureRegs = Features.
test(AMDGPU::FEAT_APERTURE_REGS);
557 bool SupportsGetDoorbellID = Features.
test(AMDGPU::FEAT_GET_DOORBELL_ID);
558 unsigned COV = InfoCache.getCodeObjectVersion();
563 const AAAMDAttributes *AAAMD =
A.getAAFor<AAAMDAttributes>(
565 if (!AAAMD || !AAAMD->isValidState())
566 return indicatePessimisticFixpoint();
571 bool NonKernelOnly =
false;
574 HasApertureRegs, SupportsGetDoorbellID, COV);
585 if (!
Callee->hasFnAttribute(Attribute::NoCallback))
586 return indicatePessimisticFixpoint();
591 if ((IsNonEntryFunc || !NonKernelOnly))
592 removeAssumedBits(AttrMask);
598 removeAssumedBits(IMPLICIT_ARG_PTR);
600 if (isAssumed(QUEUE_PTR) && checkForQueuePtr(
A)) {
604 removeAssumedBits(IMPLICIT_ARG_PTR);
606 removeAssumedBits(QUEUE_PTR);
609 uint32_t Retrieved = getRetrievedImplicitArgs(
A);
611 if (Retrieved & MULTIGRID_SYNC_ARG) {
612 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
613 "multigrid_sync_arg needs implicitarg_ptr");
614 removeAssumedBits(MULTIGRID_SYNC_ARG);
617 if (Retrieved & HOSTCALL_PTR) {
618 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"hostcall needs implicitarg_ptr");
619 removeAssumedBits(HOSTCALL_PTR);
622 if (Retrieved & HEAP_PTR) {
623 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"heap_ptr needs implicitarg_ptr");
624 removeAssumedBits(HEAP_PTR);
627 if (isAssumed(QUEUE_PTR) && (Retrieved & QUEUE_PTR)) {
628 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"queue_ptr needs implicitarg_ptr");
629 removeAssumedBits(QUEUE_PTR);
632 if (isAssumed(LDS_KERNEL_ID) && (Retrieved & LDS_KERNEL_ID)) {
633 removeAssumedBits(LDS_KERNEL_ID);
636 if (isAssumed(DEFAULT_QUEUE) && (Retrieved & DEFAULT_QUEUE))
637 removeAssumedBits(DEFAULT_QUEUE);
639 if (isAssumed(COMPLETION_ACTION) && (Retrieved & COMPLETION_ACTION))
640 removeAssumedBits(COMPLETION_ACTION);
642 if (isAssumed(FLAT_SCRATCH_INIT) && needFlatScratchInit(
A))
643 removeAssumedBits(FLAT_SCRATCH_INIT);
645 return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED
646 : ChangeStatus::UNCHANGED;
651 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
652 for (
auto [Mask, Attr] : InfoCache.getImplicitAttrList()) {
657 return A.manifestAttrs(getIRPosition(), AttrList,
661 const std::string getAsStr(Attributor *)
const override {
663 raw_string_ostream OS(Str);
666 if (isAssumed(Attr.first))
667 OS <<
' ' << Attr.second;
672 void trackStatistics()
const override {}
675 bool checkForQueuePtr(Attributor &
A) {
679 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
681 bool NeedsQueuePtr =
false;
684 unsigned SrcAS =
static_cast<AddrSpaceCastInst &
>(
I).getSrcAddressSpace();
686 NeedsQueuePtr =
true;
692 bool HasApertureRegs =
693 InfoCache.getFeatures().test(AMDGPU::FEAT_APERTURE_REGS);
699 if (!HasApertureRegs) {
700 bool UsedAssumedInformation =
false;
701 A.checkForAllInstructions(CheckAddrSpaceCasts, *
this,
702 {Instruction::AddrSpaceCast},
703 UsedAssumedInformation);
710 if (!IsNonEntryFunc && HasApertureRegs)
713 for (BasicBlock &BB : *
F) {
714 for (Instruction &
I : BB) {
715 for (
const Use &U :
I.operands()) {
717 if (InfoCache.needsQueuePtr(
C, *
F))
729 uint32_t getImplicitArgsReadThrough(Attributor &
A,
const CallBase &
Call) {
730 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
731 uint32_t ArgsMask = InfoCache.getImplicitArgsMask();
732 const auto *PointerInfoAA =
A.getAAFor<AAPointerInfo>(
734 if (!PointerInfoAA || !PointerInfoAA->getState().isValidState())
741 auto CheckAccess = [&](
const AAPointerInfo::Access &Acc, bool) {
744 for (
const AA::RangeTy &AccRange : Acc.
getRanges()) {
745 for (
auto [Mask,
Range] : InfoCache.getImplicitArgRanges()) {
746 if (AccRange.mayOverlap(
Range))
751 return Read != ArgsMask;
754 if (!PointerInfoAA->forallInterferingAccesses(
755 InfoCache.getImplicitArgsRange(), CheckAccess))
762 uint32_t getRetrievedImplicitArgs(Attributor &
A) {
763 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
764 uint32_t
All = InfoCache.getImplicitArgsMask() | LDS_KERNEL_ID;
765 uint32_t Retrieved = 0;
769 case Intrinsic::amdgcn_implicitarg_ptr:
770 Retrieved |= getImplicitArgsReadThrough(
A,
Call);
772 case Intrinsic::amdgcn_lds_kernel_id:
773 Retrieved |= LDS_KERNEL_ID;
781 return Retrieved !=
All;
784 bool UsedAssumedInformation =
false;
785 if (!
A.checkForAllCallLikeInstructions(CheckCall, *
this,
786 UsedAssumedInformation))
793 bool needFlatScratchInit(Attributor &
A) {
794 assert(isAssumed(FLAT_SCRATCH_INIT));
803 bool UsedAssumedInformation =
false;
804 if (!
A.checkForAllInstructions(AddrSpaceCastNotFromPrivate, *
this,
805 {Instruction::AddrSpaceCast},
806 UsedAssumedInformation))
810 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
814 for (
const Use &U :
I.operands()) {
816 if (InfoCache.checkConstForAddrSpaceCastFromPrivate(
C))
826AAAMDAttributes &AAAMDAttributes::createForPosition(
const IRPosition &IRP,
829 return *
new (
A.Allocator) AAAMDAttributesFunction(IRP,
A);
834struct AAAMDSizeRangeAttribute
835 :
public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
836 using Base = StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t>;
840 AAAMDSizeRangeAttribute(
const IRPosition &IRP, Attributor &
A,
842 :
Base(IRP, 32), AttrName(AttrName) {}
844 void trackStatistics()
const override {}
846 template <
class AttributeImpl>
ChangeStatus updateImplImpl(Attributor &
A) {
849 auto CheckCallSite = [&](AbstractCallSite CS) {
852 <<
"->" << getAssociatedFunction()->
getName() <<
'\n');
854 const auto *CallerInfo =
A.getAAFor<AttributeImpl>(
856 if (!CallerInfo || !CallerInfo->isValidState())
865 bool AllCallSitesKnown =
true;
866 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
869 return indicatePessimisticFixpoint();
877 emitAttributeIfNotDefaultAfterClamp(Attributor &
A,
878 std::pair<unsigned, unsigned>
Default) {
880 unsigned Lower = getAssumed().getLower().getZExtValue();
881 unsigned Upper = getAssumed().getUpper().getZExtValue();
891 return ChangeStatus::UNCHANGED;
894 LLVMContext &Ctx =
F->getContext();
895 SmallString<10> Buffer;
896 raw_svector_ostream OS(Buffer);
898 return A.manifestAttrs(getIRPosition(),
899 {Attribute::get(Ctx, AttrName, OS.str())},
903 const std::string getAsStr(Attributor *)
const override {
905 raw_string_ostream OS(Str);
907 OS << getAssumed().getLower() <<
',' << getAssumed().getUpper() - 1;
914struct AAAMDFlatWorkGroupSize :
public AAAMDSizeRangeAttribute {
915 AAAMDFlatWorkGroupSize(
const IRPosition &IRP, Attributor &
A)
916 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-flat-work-group-size") {}
920 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
922 bool HasAttr =
false;
923 auto Range = InfoCache.getDefaultFlatWorkGroupSize(*
F);
924 auto MaxRange = InfoCache.getMaximumFlatWorkGroupRange();
926 if (
auto Attr = InfoCache.getFlatWorkGroupSizeAttr(*
F)) {
930 if (*Attr != MaxRange) {
938 if (
Range == MaxRange)
942 ConstantRange CR(APInt(32, Min), APInt(32, Max + 1));
943 IntegerRangeState IRS(CR);
947 indicateOptimisticFixpoint();
951 return updateImplImpl<AAAMDFlatWorkGroupSize>(
A);
955 static AAAMDFlatWorkGroupSize &createForPosition(
const IRPosition &IRP,
959 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
960 return emitAttributeIfNotDefaultAfterClamp(
961 A, InfoCache.getMaximumFlatWorkGroupRange());
964 StringRef
getName()
const override {
return "AAAMDFlatWorkGroupSize"; }
966 const char *getIdAddr()
const override {
return &
ID; }
970 static bool classof(
const AbstractAttribute *AA) {
975 static const char ID;
978const char AAAMDFlatWorkGroupSize::ID = 0;
980AAAMDFlatWorkGroupSize &
981AAAMDFlatWorkGroupSize::createForPosition(
const IRPosition &IRP,
984 return *
new (
A.Allocator) AAAMDFlatWorkGroupSize(IRP,
A);
986 "AAAMDFlatWorkGroupSize is only valid for function position");
989struct TupleDecIntegerRangeState :
public AbstractState {
990 DecIntegerState<uint32_t>
X,
Y, Z;
992 bool isValidState()
const override {
993 return X.isValidState() &&
Y.isValidState() &&
Z.isValidState();
996 bool isAtFixpoint()
const override {
997 return X.isAtFixpoint() &&
Y.isAtFixpoint() &&
Z.isAtFixpoint();
1001 return X.indicateOptimisticFixpoint() |
Y.indicateOptimisticFixpoint() |
1002 Z.indicateOptimisticFixpoint();
1006 return X.indicatePessimisticFixpoint() |
Y.indicatePessimisticFixpoint() |
1007 Z.indicatePessimisticFixpoint();
1010 TupleDecIntegerRangeState
operator^=(
const TupleDecIntegerRangeState &
Other) {
1021 TupleDecIntegerRangeState &getAssumed() {
return *
this; }
1022 const TupleDecIntegerRangeState &getAssumed()
const {
return *
this; }
1025using AAAMDMaxNumWorkgroupsState =
1026 StateWrapper<TupleDecIntegerRangeState, AbstractAttribute, uint32_t>;
1029struct AAAMDMaxNumWorkgroups
1030 :
public StateWrapper<TupleDecIntegerRangeState, AbstractAttribute> {
1031 using Base = StateWrapper<TupleDecIntegerRangeState, AbstractAttribute>;
1033 AAAMDMaxNumWorkgroups(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1040 X.takeKnownMinimum(MaxNumWorkgroups[0]);
1041 Y.takeKnownMinimum(MaxNumWorkgroups[1]);
1042 Z.takeKnownMinimum(MaxNumWorkgroups[2]);
1045 indicatePessimisticFixpoint();
1051 auto CheckCallSite = [&](AbstractCallSite CS) {
1054 <<
"->" << getAssociatedFunction()->
getName() <<
'\n');
1056 const auto *CallerInfo =
A.getAAFor<AAAMDMaxNumWorkgroups>(
1058 if (!CallerInfo || !CallerInfo->isValidState())
1066 bool AllCallSitesKnown =
true;
1067 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
1070 return indicatePessimisticFixpoint();
1076 static AAAMDMaxNumWorkgroups &createForPosition(
const IRPosition &IRP,
1081 LLVMContext &Ctx =
F->getContext();
1082 SmallString<32> Buffer;
1083 raw_svector_ostream OS(Buffer);
1084 OS <<
X.getAssumed() <<
',' <<
Y.getAssumed() <<
',' <<
Z.getAssumed();
1088 return A.manifestAttrs(
1090 {Attribute::get(Ctx,
"amdgpu-max-num-workgroups", OS.str())},
1094 StringRef
getName()
const override {
return "AAAMDMaxNumWorkgroups"; }
1096 const std::string getAsStr(Attributor *)
const override {
1097 std::string Buffer =
"AAAMDMaxNumWorkgroupsState[";
1098 raw_string_ostream OS(Buffer);
1099 OS <<
X.getAssumed() <<
',' <<
Y.getAssumed() <<
',' <<
Z.getAssumed()
1104 const char *getIdAddr()
const override {
return &
ID; }
1108 static bool classof(
const AbstractAttribute *AA) {
1112 void trackStatistics()
const override {}
1115 static const char ID;
1118const char AAAMDMaxNumWorkgroups::ID = 0;
1120AAAMDMaxNumWorkgroups &
1121AAAMDMaxNumWorkgroups::createForPosition(
const IRPosition &IRP, Attributor &
A) {
1123 return *
new (
A.Allocator) AAAMDMaxNumWorkgroups(IRP,
A);
1124 llvm_unreachable(
"AAAMDMaxNumWorkgroups is only valid for function position");
1128struct AAAMDWavesPerEU :
public AAAMDSizeRangeAttribute {
1129 AAAMDWavesPerEU(
const IRPosition &IRP, Attributor &
A)
1130 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-waves-per-eu") {}
1134 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
1137 if (
auto Attr = InfoCache.getWavesPerEUAttr(*
F)) {
1138 std::pair<unsigned, unsigned> MaxWavesPerEURange{
1139 1U, InfoCache.getMaxWavesPerEU()};
1140 if (*Attr != MaxWavesPerEURange) {
1141 auto [Min,
Max] = *Attr;
1142 ConstantRange
Range(APInt(32, Min), APInt(32, Max + 1));
1143 IntegerRangeState RangeState(
Range);
1144 this->getState() = RangeState;
1145 indicateOptimisticFixpoint();
1151 indicatePessimisticFixpoint();
1157 auto CheckCallSite = [&](AbstractCallSite CS) {
1161 <<
"->" <<
Func->getName() <<
'\n');
1164 const auto *CallerAA =
A.getAAFor<AAAMDWavesPerEU>(
1166 if (!CallerAA || !CallerAA->isValidState())
1169 ConstantRange Assumed = getAssumed();
1171 CallerAA->getAssumed().getLower().getZExtValue());
1173 CallerAA->getAssumed().getUpper().getZExtValue());
1174 ConstantRange
Range(APInt(32, Min), APInt(32, Max));
1175 IntegerRangeState RangeState(
Range);
1176 getState() = RangeState;
1177 Change |= getState() == Assumed ? ChangeStatus::UNCHANGED
1178 : ChangeStatus::CHANGED;
1183 bool AllCallSitesKnown =
true;
1184 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
1185 return indicatePessimisticFixpoint();
1191 static AAAMDWavesPerEU &createForPosition(
const IRPosition &IRP,
1195 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
1196 return emitAttributeIfNotDefaultAfterClamp(
1197 A, {1U, InfoCache.getMaxWavesPerEU()});
1200 StringRef
getName()
const override {
return "AAAMDWavesPerEU"; }
1202 const char *getIdAddr()
const override {
return &
ID; }
1206 static bool classof(
const AbstractAttribute *AA) {
1211 static const char ID;
1214const char AAAMDWavesPerEU::ID = 0;
1216AAAMDWavesPerEU &AAAMDWavesPerEU::createForPosition(
const IRPosition &IRP,
1219 return *
new (
A.Allocator) AAAMDWavesPerEU(IRP,
A);
1224static unsigned inlineAsmGetNumRequiredAGPRs(
const InlineAsm *IA,
1225 const CallBase &
Call) {
1228 unsigned AGPRDefCount = 0;
1229 unsigned AGPRUseCount = 0;
1230 unsigned MaxPhysReg = 0;
1234 for (
const InlineAsm::ConstraintInfo &CI :
IA->ParseConstraints()) {
1240 Ty = STy->getElementType(ResNo);
1255 for (StringRef Code : CI.Codes) {
1256 unsigned RegCount = 0;
1257 if (
Code.starts_with(
"a")) {
1268 MaxPhysReg = std::max(MaxPhysReg, std::min(RegIdx + NumRegs, 256u));
1278 AGPRDefCount =
alignTo(AGPRDefCount, RegCount);
1280 AGPRDefCount += RegCount;
1281 if (CI.isEarlyClobber) {
1282 AGPRUseCount =
alignTo(AGPRUseCount, RegCount);
1283 AGPRUseCount += RegCount;
1286 AGPRUseCount =
alignTo(AGPRUseCount, RegCount);
1287 AGPRUseCount += RegCount;
1292 unsigned MaxVirtReg = std::max(AGPRUseCount, AGPRDefCount);
1297 return std::min(MaxVirtReg + MaxPhysReg, 256u);
1303checkForAllPossibleCallees(Attributor &
A,
const AbstractAttribute &QueryingAA,
1305 function_ref<
bool(
const Function &)> Pred) {
1309 if (Callee && !
Callee->hasMetadata(LLVMContext::MD_callback))
1310 return Pred(*Callee);
1312 const AACallEdges *CBEdges =
A.getAAFor<AACallEdges>(
1317 [&](
const Function *Fn) { return Pred(*Fn); });
1320struct AAAMDGPUMinAGPRAlloc
1321 :
public StateWrapper<DecIntegerState<>, AbstractAttribute> {
1322 using Base = StateWrapper<DecIntegerState<>, AbstractAttribute>;
1323 AAAMDGPUMinAGPRAlloc(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1325 static AAAMDGPUMinAGPRAlloc &createForPosition(
const IRPosition &IRP,
1328 return *
new (
A.Allocator) AAAMDGPUMinAGPRAlloc(IRP,
A);
1330 "AAAMDGPUMinAGPRAlloc is only valid for function position");
1335 auto [MinNumAGPR, MaxNumAGPR] =
1338 if (MinNumAGPR == 0) {
1339 indicateOptimisticFixpoint();
1344 indicatePessimisticFixpoint();
1347 const std::string getAsStr(Attributor *
A)
const override {
1348 std::string Str =
"amdgpu-agpr-alloc=";
1349 raw_string_ostream OS(Str);
1354 void trackStatistics()
const override {}
1357 DecIntegerState<> Maximum;
1369 unsigned NumRegs = inlineAsmGetNumRequiredAGPRs(IA, CB);
1376 case Intrinsic::write_register:
1377 case Intrinsic::read_register:
1378 case Intrinsic::read_volatile_register: {
1383 auto [
Kind, RegIdx, NumRegs] =
1397 case Intrinsic::trap:
1398 case Intrinsic::debugtrap:
1399 case Intrinsic::ubsantrap:
1400 return CB.
hasFnAttr(Attribute::NoCallback) ||
1407 return CB.
hasFnAttr(Attribute::NoCallback);
1412 const AAAMDGPUMinAGPRAlloc *CalleeInfo =
1413 A.getAAFor<AAAMDGPUMinAGPRAlloc>(
1415 if (!CalleeInfo || !CalleeInfo->isValidState())
1420 if (!checkForAllPossibleCallees(
A, *
this, CB, CheckCallee)) {
1428 bool UsedAssumedInformation =
false;
1429 if (!
A.checkForAllCallLikeInstructions(CheckForMinAGPRAllocs, *
this,
1430 UsedAssumedInformation))
1431 return indicatePessimisticFixpoint();
1437 LLVMContext &Ctx = getAssociatedFunction()->getContext();
1438 SmallString<4> Buffer;
1439 raw_svector_ostream OS(Buffer);
1442 return A.manifestAttrs(
1443 getIRPosition(), {Attribute::get(Ctx,
"amdgpu-agpr-alloc", OS.str())});
1446 StringRef
getName()
const override {
return "AAAMDGPUMinAGPRAlloc"; }
1447 const char *getIdAddr()
const override {
return &
ID; }
1451 static bool classof(
const AbstractAttribute *AA) {
1455 static const char ID;
1458const char AAAMDGPUMinAGPRAlloc::ID = 0;
1461struct AAAMDGPUNoLDSDMA :
public StateWrapper<BooleanState, AbstractAttribute> {
1462 using Base = StateWrapper<BooleanState, AbstractAttribute>;
1463 AAAMDGPUNoLDSDMA(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1466 static AAAMDGPUNoLDSDMA &createForPosition(
const IRPosition &IRP,
1469 "AAAMDGPUNoLDSDMA is only valid for function position");
1470 return *
new (
A.Allocator) AAAMDGPUNoLDSDMA(IRP,
A);
1474 const Function *
F = getAssociatedFunction();
1475 if (
F->hasFnAttribute(
"amdgpu-no-lds-dma")) {
1476 indicateOptimisticFixpoint();
1480 if (
F->isDeclaration())
1481 indicatePessimisticFixpoint();
1501 return checkForAllPossibleCallees(
1502 A, *
this, CB, [&](
const Function &Callee) {
1503 const AAAMDGPUNoLDSDMA *CalleeInfo =
A.getAAFor<AAAMDGPUNoLDSDMA>(
1505 return CalleeInfo && CalleeInfo->getAssumed();
1509 bool UsedAssumedInformation =
false;
1510 if (!
A.checkForAllCallLikeInstructions(CheckNoLDSDMA, *
this,
1511 UsedAssumedInformation))
1512 return indicatePessimisticFixpoint();
1514 return ChangeStatus::UNCHANGED;
1519 return ChangeStatus::UNCHANGED;
1521 LLVMContext &Ctx = getAssociatedFunction()->getContext();
1522 return A.manifestAttrs(getIRPosition(),
1523 {Attribute::get(Ctx,
"amdgpu-no-lds-dma")});
1526 bool isValidState()
const override {
return true; }
1528 const std::string getAsStr(Attributor *
A)
const override {
1529 return "AMDGPUNoLDSDMA[" + std::to_string(getAssumed()) +
"]";
1532 void trackStatistics()
const override {}
1534 StringRef
getName()
const override {
return "AAAMDGPUNoLDSDMA"; }
1535 const char *getIdAddr()
const override {
return &
ID; }
1539 static bool classof(
const AbstractAttribute *AA) {
1543 static const char ID;
1546const char AAAMDGPUNoLDSDMA::ID = 0;
1550struct AAAMDGPUClusterDims
1551 :
public StateWrapper<BooleanState, AbstractAttribute> {
1552 using Base = StateWrapper<BooleanState, AbstractAttribute>;
1553 AAAMDGPUClusterDims(
const IRPosition &IRP, Attributor &
A) :
Base(IRP) {}
1556 static AAAMDGPUClusterDims &createForPosition(
const IRPosition &IRP,
1559 StringRef
getName()
const override {
return "AAAMDGPUClusterDims"; }
1561 const char *getIdAddr()
const override {
return &
ID; }
1565 static bool classof(
const AbstractAttribute *AA) {
1569 virtual const AMDGPU::ClusterDimsAttr &getClusterDims()
const = 0;
1572 static const char ID;
1575const char AAAMDGPUClusterDims::ID = 0;
1577struct AAAMDGPUClusterDimsFunction :
public AAAMDGPUClusterDims {
1578 AAAMDGPUClusterDimsFunction(
const IRPosition &IRP, Attributor &
A)
1579 : AAAMDGPUClusterDims(IRP,
A) {}
1583 assert(
F &&
"empty associated function");
1590 indicatePessimisticFixpoint();
1592 indicateOptimisticFixpoint();
1596 const std::string getAsStr(Attributor *
A)
const override {
1606 void trackStatistics()
const override {}
1609 auto OldState = Attr;
1611 auto CheckCallSite = [&](AbstractCallSite CS) {
1612 const auto *CallerAA =
A.getAAFor<AAAMDGPUClusterDims>(
1614 DepClassTy::REQUIRED);
1615 if (!CallerAA || !CallerAA->isValidState())
1618 return merge(CallerAA->getClusterDims());
1621 bool UsedAssumedInformation =
false;
1622 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
1624 UsedAssumedInformation))
1625 return indicatePessimisticFixpoint();
1627 return OldState == Attr ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
1632 return ChangeStatus::UNCHANGED;
1633 return A.manifestAttrs(
1635 {Attribute::get(getAssociatedFunction()->
getContext(), AttrName,
1640 const AMDGPU::ClusterDimsAttr &getClusterDims()
const override {
1645 bool merge(
const AMDGPU::ClusterDimsAttr &
Other) {
1660 if (
Other.isUnknown())
1685 AMDGPU::ClusterDimsAttr Attr;
1687 static constexpr char AttrName[] =
"amdgpu-cluster-dims";
1690AAAMDGPUClusterDims &
1691AAAMDGPUClusterDims::createForPosition(
const IRPosition &IRP, Attributor &
A) {
1693 return *
new (
A.Allocator) AAAMDGPUClusterDimsFunction(IRP,
A);
1694 llvm_unreachable(
"AAAMDGPUClusterDims is only valid for function position");
1697static bool runImpl(SetVector<Function *> &Functions,
bool IsModulePass,
1698 bool DeleteFns,
Module &M, AnalysisGetter &AG,
1699 TargetMachine &TM, AMDGPUAttributorOptions
Options,
1702 CallGraphUpdater CGUpdater;
1704 AMDGPUInformationCache InfoCache(M, AG,
Allocator,
nullptr, TM);
1705 DenseSet<const char *>
Allowed(
1706 {&AAAMDAttributes::ID, &AAUniformWorkGroupSize::ID,
1708 &AAAMDMaxNumWorkgroups::ID, &AAAMDWavesPerEU::ID,
1712 &AAAMDGPUClusterDims::ID, &AAAMDGPUNoLDSDMA::ID, &
AAAlign::ID});
1714 AttributorConfig AC(CGUpdater);
1715 AC.IsClosedWorldModule =
Options.IsClosedWorld;
1717 AC.IsModulePass = IsModulePass;
1718 AC.DeleteFns = DeleteFns;
1719 AC.DefaultInitializeLiveInternals =
false;
1721 AC.UseLiveness =
false;
1722 AC.IndirectCalleeSpecializationCallback =
1723 [](Attributor &
A,
const AbstractAttribute &AA, CallBase &CB,
1728 AC.IPOAmendableCB = [](
const Function &
F) {
1729 return F.getCallingConv() == CallingConv::AMDGPU_KERNEL;
1732 Attributor
A(Functions, InfoCache, AC);
1735 StringRef LTOPhaseStr =
to_string(LTOPhase);
1736 dbgs() <<
"[AMDGPUAttributor] Running at phase " << LTOPhaseStr <<
'\n'
1737 <<
"[AMDGPUAttributor] Module " <<
M.getName() <<
" is "
1738 << (AC.IsClosedWorldModule ?
"" :
"not ")
1739 <<
"assumed to be a closed world.\n";
1742 for (
auto *
F : Functions) {
1747 CallingConv::ID
CC =
F->getCallingConv();
1754 if (!
F->isDeclaration() && Features.
test(AMDGPU::FEAT_CLUSTERS))
1757 if (Features.
test(AMDGPU::FEAT_AGPR_ALLOC))
1761 Value *Ptr =
nullptr;
1763 Ptr = LI->getPointerOperand();
1765 Ptr =
SI->getPointerOperand();
1767 Ptr = RMW->getPointerOperand();
1769 Ptr = CmpX->getPointerOperand();
1779 if (
II->getIntrinsicID() == Intrinsic::amdgcn_make_buffer_rsrc)
1786 return A.run() == ChangeStatus::CHANGED;
1799 if (!
F.isDeclaration())
1800 Functions.insert(&
F);
1804 return runImpl(Functions,
true,
true, M, AG,
1805 TM, Options, LTOPhase)
1822 if (!
F->isIntrinsic())
1823 Functions.insert(
F);
1827 Module *M =
C.begin()->getFunction().getParent();
1830 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
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.
@ 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)
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.
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.