18#include "llvm/IR/IntrinsicsAMDGPU.h"
19#include "llvm/IR/IntrinsicsR600.h"
23#define DEBUG_TYPE "amdgpu-attributor"
32 "amdgpu-kernarg-preload-count",
35#define AMDGPU_ATTRIBUTE(Name, Str) Name##_POS,
38 #include "AMDGPUAttributes.def"
42#define AMDGPU_ATTRIBUTE(Name, Str) Name = 1 << Name##_POS,
46 #include "AMDGPUAttributes.def"
50#define AMDGPU_ATTRIBUTE(Name, Str) {Name, Str},
53 #include "AMDGPUAttributes.def"
63 bool HasApertureRegs,
bool SupportsGetDoorBellID,
64 unsigned CodeObjectVersion) {
66 case Intrinsic::amdgcn_workitem_id_x:
69 case Intrinsic::amdgcn_workgroup_id_x:
71 return WORKGROUP_ID_X;
72 case Intrinsic::amdgcn_workitem_id_y:
73 case Intrinsic::r600_read_tidig_y:
75 case Intrinsic::amdgcn_workitem_id_z:
76 case Intrinsic::r600_read_tidig_z:
78 case Intrinsic::amdgcn_workgroup_id_y:
79 case Intrinsic::r600_read_tgid_y:
80 return WORKGROUP_ID_Y;
81 case Intrinsic::amdgcn_workgroup_id_z:
82 case Intrinsic::r600_read_tgid_z:
83 return WORKGROUP_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::trap:
107 if (SupportsGetDoorBellID)
133 return F.hasFnAttribute(Attribute::SanitizeAddress) ||
134 F.hasFnAttribute(Attribute::SanitizeThread) ||
135 F.hasFnAttribute(Attribute::SanitizeMemory) ||
136 F.hasFnAttribute(Attribute::SanitizeHWAddress) ||
137 F.hasFnAttribute(Attribute::SanitizeMemTag);
151 enum ConstantStatus { DS_GLOBAL = 1 << 0, ADDR_SPACE_CAST = 1 << 1 };
156 return ST.hasApertureRegs();
160 bool supportsGetDoorbellID(
Function &
F) {
162 return ST.supportsGetDoorbellID();
165 std::pair<unsigned, unsigned> getFlatWorkGroupSizes(
const Function &
F) {
167 return ST.getFlatWorkGroupSizes(
F);
170 std::pair<unsigned, unsigned>
171 getMaximumFlatWorkGroupRange(
const Function &
F) {
173 return {
ST.getMinFlatWorkGroupSize(),
ST.getMaxFlatWorkGroupSize()};
178 return CodeObjectVersion;
184 std::pair<unsigned, unsigned>
186 std::pair<unsigned, unsigned> FlatWorkGroupSize) {
188 return ST.getWavesPerEU(
F, FlatWorkGroupSize);
191 std::pair<unsigned, unsigned>
192 getEffectiveWavesPerEU(
const Function &
F,
193 std::pair<unsigned, unsigned> WavesPerEU,
194 std::pair<unsigned, unsigned> FlatWorkGroupSize) {
196 return ST.getEffectiveWavesPerEU(WavesPerEU, FlatWorkGroupSize);
201 return ST.getMaxWavesPerEU();
207 if (
CE->getOpcode() == Instruction::AddrSpaceCast) {
208 unsigned SrcAS =
CE->getOperand(0)->getType()->getPointerAddressSpace();
215 uint8_t getConstantAccess(
const Constant *
C,
217 auto It = ConstantStatus.find(
C);
218 if (It != ConstantStatus.end())
225 if (
const auto *CE = dyn_cast<ConstantExpr>(
C))
226 if (visitConstExpr(CE))
227 Result |= ADDR_SPACE_CAST;
229 for (
const Use &U :
C->operands()) {
230 const auto *OpC = dyn_cast<Constant>(U);
231 if (!OpC || !Visited.
insert(OpC).second)
234 Result |= getConstantAccess(OpC, Visited);
243 bool HasAperture = hasApertureRegs(Fn);
246 if (!IsNonEntryFunc && HasAperture)
250 uint8_t Access = getConstantAccess(
C, Visited);
253 if (IsNonEntryFunc && (Access & DS_GLOBAL))
256 return !HasAperture && (Access & ADDR_SPACE_CAST);
262 const unsigned CodeObjectVersion;
265struct AAAMDAttributes
266 :
public StateWrapper<BitIntegerState<uint32_t, ALL_ARGUMENT_MASK, 0>,
274 static AAAMDAttributes &createForPosition(
const IRPosition &IRP,
278 const std::string
getName()
const override {
return "AAAMDAttributes"; }
281 const char *getIdAddr()
const override {
return &
ID; }
290 static const char ID;
292const char AAAMDAttributes::ID = 0;
294struct AAUniformWorkGroupSize
295 :
public StateWrapper<BooleanState, AbstractAttribute> {
300 static AAUniformWorkGroupSize &createForPosition(
const IRPosition &IRP,
304 const std::string
getName()
const override {
305 return "AAUniformWorkGroupSize";
309 const char *getIdAddr()
const override {
return &
ID; }
318 static const char ID;
320const char AAUniformWorkGroupSize::ID = 0;
322struct AAUniformWorkGroupSizeFunction :
public AAUniformWorkGroupSize {
324 : AAUniformWorkGroupSize(IRP,
A) {}
333 bool InitialValue =
false;
334 if (
F->hasFnAttribute(
"uniform-work-group-size"))
335 InitialValue =
F->getFnAttribute(
"uniform-work-group-size")
340 indicateOptimisticFixpoint();
342 indicatePessimisticFixpoint();
351 <<
"->" << getAssociatedFunction()->
getName() <<
"\n");
353 const auto *CallerInfo =
A.getAAFor<AAUniformWorkGroupSize>(
359 CallerInfo->getState());
364 bool AllCallSitesKnown =
true;
365 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
366 return indicatePessimisticFixpoint();
373 LLVMContext &Ctx = getAssociatedFunction()->getContext();
376 getAssumed() ?
"true" :
"false"));
377 return A.manifestAttrs(getIRPosition(), AttrList,
381 bool isValidState()
const override {
386 const std::string getAsStr(
Attributor *)
const override {
387 return "AMDWorkGroupSize[" + std::to_string(getAssumed()) +
"]";
391 void trackStatistics()
const override {}
394AAUniformWorkGroupSize &
395AAUniformWorkGroupSize::createForPosition(
const IRPosition &IRP,
398 return *
new (
A.Allocator) AAUniformWorkGroupSizeFunction(IRP,
A);
400 "AAUniformWorkGroupSize is only valid for function position");
403struct AAAMDAttributesFunction :
public AAAMDAttributes {
405 : AAAMDAttributes(IRP,
A) {}
414 removeAssumedBits(IMPLICIT_ARG_PTR);
415 removeAssumedBits(HOSTCALL_PTR);
420 (Attr.first == IMPLICIT_ARG_PTR || Attr.first == HOSTCALL_PTR))
423 if (
F->hasFnAttribute(Attr.second))
424 addKnownBits(Attr.first);
427 if (
F->isDeclaration())
433 indicatePessimisticFixpoint();
441 auto OrigAssumed = getAssumed();
445 *
this, this->getIRPosition(), DepClassTy::REQUIRED);
447 return indicatePessimisticFixpoint();
451 bool NeedsImplicit =
false;
452 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
453 bool HasApertureRegs = InfoCache.hasApertureRegs(*
F);
454 bool SupportsGetDoorbellID = InfoCache.supportsGetDoorbellID(*
F);
455 unsigned COV = InfoCache.getCodeObjectVersion();
460 const AAAMDAttributes *AAAMD =
A.getAAFor<AAAMDAttributes>(
463 return indicatePessimisticFixpoint();
468 bool NonKernelOnly =
false;
471 HasApertureRegs, SupportsGetDoorbellID, COV);
473 if ((IsNonEntryFunc || !NonKernelOnly))
474 removeAssumedBits(AttrMask);
480 removeAssumedBits(IMPLICIT_ARG_PTR);
482 if (isAssumed(QUEUE_PTR) && checkForQueuePtr(
A)) {
486 removeAssumedBits(IMPLICIT_ARG_PTR);
488 removeAssumedBits(QUEUE_PTR);
491 if (funcRetrievesMultigridSyncArg(
A, COV)) {
492 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
493 "multigrid_sync_arg needs implicitarg_ptr");
494 removeAssumedBits(MULTIGRID_SYNC_ARG);
497 if (funcRetrievesHostcallPtr(
A, COV)) {
498 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"hostcall needs implicitarg_ptr");
499 removeAssumedBits(HOSTCALL_PTR);
502 if (funcRetrievesHeapPtr(
A, COV)) {
503 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"heap_ptr needs implicitarg_ptr");
504 removeAssumedBits(HEAP_PTR);
507 if (isAssumed(QUEUE_PTR) && funcRetrievesQueuePtr(
A, COV)) {
508 assert(!isAssumed(IMPLICIT_ARG_PTR) &&
"queue_ptr needs implicitarg_ptr");
509 removeAssumedBits(QUEUE_PTR);
512 if (isAssumed(LDS_KERNEL_ID) && funcRetrievesLDSKernelId(
A)) {
513 removeAssumedBits(LDS_KERNEL_ID);
516 if (isAssumed(DEFAULT_QUEUE) && funcRetrievesDefaultQueue(
A, COV))
517 removeAssumedBits(DEFAULT_QUEUE);
519 if (isAssumed(COMPLETION_ACTION) && funcRetrievesCompletionAction(
A, COV))
520 removeAssumedBits(COMPLETION_ACTION);
522 return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED
523 : ChangeStatus::UNCHANGED;
528 LLVMContext &Ctx = getAssociatedFunction()->getContext();
531 if (isKnown(Attr.first))
535 return A.manifestAttrs(getIRPosition(), AttrList,
539 const std::string getAsStr(
Attributor *)
const override {
544 if (isAssumed(Attr.first))
545 OS <<
' ' << Attr.second;
551 void trackStatistics()
const override {}
558 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
560 bool NeedsQueuePtr =
false;
565 NeedsQueuePtr =
true;
571 bool HasApertureRegs = InfoCache.hasApertureRegs(*
F);
577 if (!HasApertureRegs) {
578 bool UsedAssumedInformation =
false;
579 A.checkForAllInstructions(CheckAddrSpaceCasts, *
this,
580 {Instruction::AddrSpaceCast},
581 UsedAssumedInformation);
588 if (!IsNonEntryFunc && HasApertureRegs)
593 for (
const Use &U :
I.operands()) {
594 if (
const auto *
C = dyn_cast<Constant>(U)) {
595 if (InfoCache.needsQueuePtr(
C, *
F))
605 bool funcRetrievesMultigridSyncArg(
Attributor &
A,
unsigned COV) {
608 return funcRetrievesImplicitKernelArg(
A, Range);
611 bool funcRetrievesHostcallPtr(
Attributor &
A,
unsigned COV) {
614 return funcRetrievesImplicitKernelArg(
A, Range);
617 bool funcRetrievesDefaultQueue(
Attributor &
A,
unsigned COV) {
620 return funcRetrievesImplicitKernelArg(
A, Range);
623 bool funcRetrievesCompletionAction(
Attributor &
A,
unsigned COV) {
626 return funcRetrievesImplicitKernelArg(
A, Range);
629 bool funcRetrievesHeapPtr(
Attributor &
A,
unsigned COV) {
633 return funcRetrievesImplicitKernelArg(
A, Range);
636 bool funcRetrievesQueuePtr(
Attributor &
A,
unsigned COV) {
640 return funcRetrievesImplicitKernelArg(
A, Range);
651 auto &
Call = cast<CallBase>(
I);
652 if (
Call.getIntrinsicID() != Intrinsic::amdgcn_implicitarg_ptr)
666 bool UsedAssumedInformation =
false;
667 return !
A.checkForAllCallLikeInstructions(DoesNotLeadToKernelArgLoc, *
this,
668 UsedAssumedInformation);
673 auto &
Call = cast<CallBase>(
I);
674 return Call.getIntrinsicID() != Intrinsic::amdgcn_lds_kernel_id;
676 bool UsedAssumedInformation =
false;
677 return !
A.checkForAllCallLikeInstructions(DoesNotRetrieve, *
this,
678 UsedAssumedInformation);
682AAAMDAttributes &AAAMDAttributes::createForPosition(
const IRPosition &IRP,
685 return *
new (
A.Allocator) AAAMDAttributesFunction(IRP,
A);
690struct AAAMDSizeRangeAttribute
691 :
public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
698 :
Base(IRP, 32), AttrName(AttrName) {}
701 void trackStatistics()
const override {}
703 template <
class AttributeImpl>
710 <<
"->" << getAssociatedFunction()->
getName() <<
'\n');
723 bool AllCallSitesKnown =
true;
724 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
725 return indicatePessimisticFixpoint();
733 if (getAssumed().getLower() == Min && getAssumed().getUpper() - 1 == Max)
740 OS << getAssumed().getLower() <<
',' << getAssumed().getUpper() - 1;
741 return A.manifestAttrs(getIRPosition(),
746 const std::string getAsStr(
Attributor *)
const override {
750 OS << getAssumed().getLower() <<
',' << getAssumed().getUpper() - 1;
757struct AAAMDFlatWorkGroupSize :
public AAAMDSizeRangeAttribute {
759 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-flat-work-group-size") {}
763 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
764 unsigned MinGroupSize, MaxGroupSize;
765 std::tie(MinGroupSize, MaxGroupSize) = InfoCache.getFlatWorkGroupSizes(*
F);
770 indicatePessimisticFixpoint();
774 return updateImplImpl<AAAMDFlatWorkGroupSize>(
A);
778 static AAAMDFlatWorkGroupSize &createForPosition(
const IRPosition &IRP,
783 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
785 std::tie(Min, Max) = InfoCache.getMaximumFlatWorkGroupRange(*
F);
786 return emitAttributeIfNotDefault(
A, Min, Max);
790 const std::string
getName()
const override {
791 return "AAAMDFlatWorkGroupSize";
795 const char *getIdAddr()
const override {
return &
ID; }
804 static const char ID;
807const char AAAMDFlatWorkGroupSize::ID = 0;
809AAAMDFlatWorkGroupSize &
810AAAMDFlatWorkGroupSize::createForPosition(
const IRPosition &IRP,
813 return *
new (
A.Allocator) AAAMDFlatWorkGroupSize(IRP,
A);
815 "AAAMDFlatWorkGroupSize is only valid for function position");
819struct AAAMDWavesPerEU :
public AAAMDSizeRangeAttribute {
821 : AAAMDSizeRangeAttribute(IRP,
A,
"amdgpu-waves-per-eu") {}
823 bool isValidState()
const override {
829 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
831 if (
const auto *AssumedGroupSize =
A.getAAFor<AAAMDFlatWorkGroupSize>(
835 std::tie(Min, Max) = InfoCache.getWavesPerEU(
836 *
F, {AssumedGroupSize->getAssumed().getLower().getZExtValue(),
837 AssumedGroupSize->getAssumed().getUpper().getZExtValue() - 1});
840 intersectKnown(Range);
844 indicatePessimisticFixpoint();
848 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
855 <<
"->" <<
Func->getName() <<
'\n');
857 const auto *CallerInfo =
A.getAAFor<AAAMDWavesPerEU>(
859 const auto *AssumedGroupSize =
A.getAAFor<AAAMDFlatWorkGroupSize>(
861 if (!CallerInfo || !AssumedGroupSize)
865 std::tie(Min, Max) = InfoCache.getEffectiveWavesPerEU(
867 {CallerInfo->getAssumed().getLower().getZExtValue(),
868 CallerInfo->getAssumed().getUpper().getZExtValue() - 1},
869 {AssumedGroupSize->getAssumed().getLower().getZExtValue(),
870 AssumedGroupSize->getAssumed().getUpper().getZExtValue() - 1});
878 bool AllCallSitesKnown =
true;
879 if (!
A.checkForAllCallSites(CheckCallSite, *
this,
true, AllCallSitesKnown))
880 return indicatePessimisticFixpoint();
886 static AAAMDWavesPerEU &createForPosition(
const IRPosition &IRP,
891 auto &InfoCache =
static_cast<AMDGPUInformationCache &
>(
A.getInfoCache());
892 unsigned Max = InfoCache.getMaxWavesPerEU(*
F);
893 return emitAttributeIfNotDefault(
A, 1, Max);
897 const std::string
getName()
const override {
return "AAAMDWavesPerEU"; }
900 const char *getIdAddr()
const override {
return &
ID; }
909 static const char ID;
912const char AAAMDWavesPerEU::ID = 0;
914AAAMDWavesPerEU &AAAMDWavesPerEU::createForPosition(
const IRPosition &IRP,
917 return *
new (
A.Allocator) AAAMDWavesPerEU(IRP,
A);
943 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
955 if (!
F.isIntrinsic())
961 AMDGPUInformationCache InfoCache(M, AG, Allocator,
nullptr, *TM);
963 {&AAAMDAttributes::ID, &AAUniformWorkGroupSize::ID,
970 AC.IsModulePass =
true;
971 AC.DefaultInitializeLiveInternals =
false;
972 AC.IPOAmendableCB = [](
const Function &
F) {
979 if (!
F.isIntrinsic()) {
987 addPreloadKernArgHint(
F, *TM);
1006char AMDGPUAttributor::ID = 0;
static cl::opt< unsigned > KernargPreloadCount("amdgpu-kernarg-preload-count", cl::desc("How many kernel arguments to preload onto SGPRs"), cl::init(0))
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 funcRequiresHostcallPtr(const Function &F)
Returns true if the function requires the implicit argument be passed regardless of the function cont...
ImplicitArgumentPositions
static bool castRequiresQueuePtr(unsigned SrcAS)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
AMD GCN specific subclass of TargetSubtarget.
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
Target-Independent Code Generator Pass Configuration Options pass.
Class for arbitrary precision integers.
This class represents a conversion between pointers from one address space to another.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
This class represents an incoming formal argument to a Function.
bool hasByRefAttr() const
Return true if this argument has the byref attribute.
void addAttr(Attribute::AttrKind Kind)
bool hasNestAttr() const
Return true if this argument has the nest attribute.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM Basic Block Representation.
Allocate memory in an ever growing pool, as if by bump-pointer.
Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph.
A constant value that is initialized with an expression using other constant values.
This class represents a range of values.
This is an important base class in LLVM.
Legacy analysis pass which computes a CycleInfo.
Implements a dense probed hash-table based set.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
unsigned getAddressSpace() const
This is an important class for using LLVM in a threaded context.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Pass interface - Implemented by all 'passes'.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual bool doInitialization(Module &)
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
A vector that has set insertion semantics.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
Primary interface to the complete machine description for the target machine.
A Use represents the edge between a Value definition and its users.
bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
#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.
@ PRIVATE_ADDRESS
Address space for private memory.
unsigned getMaxWavesPerEU(const MCSubtargetInfo *STI)
unsigned getCodeObjectVersion(const Module &M)
bool isEntryFunctionCC(CallingConv::ID CC)
unsigned getDefaultQueueImplicitArgPosition(unsigned CodeObjectVersion)
unsigned getHostcallImplicitArgPosition(unsigned CodeObjectVersion)
unsigned getCompletionActionImplicitArgPosition(unsigned CodeObjectVersion)
unsigned getMultigridSyncArgImplicitArgPosition(unsigned CodeObjectVersion)
bool isGraphics(CallingConv::ID cc)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ C
The default llvm calling convention, compatible with C.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
void initializeCycleInfoWrapperPassPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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...
Pass * createAMDGPUAttributorPass()
@ REQUIRED
The target cannot be valid if the source is not.
An abstract state for querying live call edges.
virtual const SetVector< Function * > & getOptimisticEdges() const =0
Get the optimistic edges.
static const char ID
Unique ID (due to the unique address)
virtual bool hasNonAsmUnknownCallee() const =0
Is there any call with a unknown callee, excluding any inline asm.
Instruction * getRemoteInst() const
Return the actual instruction that causes the access.
An abstract interface for struct information.
virtual bool forallInterferingAccesses(AA::RangeTy Range, function_ref< bool(const Access &, bool)> CB) const =0
Call CB on all accesses that might interfere with Range and return true if all such accesses were kno...
static const char ID
Unique ID (due to the unique address)
static const char ID
Unique ID (due to the unique address)
static const char ID
Unique ID (due to the unique address)
static 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...
Base struct for all "concrete attribute" deductions.
virtual const char * getIdAddr() const =0
This function should return the address of the ID of the AbstractAttribute.
Wrapper for FunctionAnalysisManager.
Configuration for the Attributor.
The fixpoint analysis framework that orchestrates the attribute deduction.
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.
@ 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.
State for an integer range.
bool isValidState() const override
See AbstractState::isValidState()
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).