summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp402
1 files changed, 263 insertions, 139 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
index 61b1d22edc33..f0aadab3302f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp
@@ -22,48 +22,71 @@
using namespace llvm;
-static constexpr StringLiteral ImplicitAttrNames[] = {
- // X ids unnecessarily propagated to kernels.
- "amdgpu-work-item-id-x", "amdgpu-work-item-id-y",
- "amdgpu-work-item-id-z", "amdgpu-work-group-id-x",
- "amdgpu-work-group-id-y", "amdgpu-work-group-id-z",
- "amdgpu-dispatch-ptr", "amdgpu-dispatch-id",
- "amdgpu-queue-ptr", "amdgpu-implicitarg-ptr"};
+enum ImplicitArgumentMask {
+ NOT_IMPLICIT_INPUT = 0,
+
+ // SGPRs
+ DISPATCH_PTR = 1 << 0,
+ QUEUE_PTR = 1 << 1,
+ DISPATCH_ID = 1 << 2,
+ IMPLICIT_ARG_PTR = 1 << 3,
+ WORKGROUP_ID_X = 1 << 4,
+ WORKGROUP_ID_Y = 1 << 5,
+ WORKGROUP_ID_Z = 1 << 6,
+
+ // VGPRS:
+ WORKITEM_ID_X = 1 << 7,
+ WORKITEM_ID_Y = 1 << 8,
+ WORKITEM_ID_Z = 1 << 9,
+ ALL_ARGUMENT_MASK = (1 << 10) - 1
+};
+
+static constexpr std::pair<ImplicitArgumentMask,
+ StringLiteral> ImplicitAttrs[] = {
+ {DISPATCH_PTR, "amdgpu-no-dispatch-ptr"},
+ {QUEUE_PTR, "amdgpu-no-queue-ptr"},
+ {DISPATCH_ID, "amdgpu-no-dispatch-id"},
+ {IMPLICIT_ARG_PTR, "amdgpu-no-implicitarg-ptr"},
+ {WORKGROUP_ID_X, "amdgpu-no-workgroup-id-x"},
+ {WORKGROUP_ID_Y, "amdgpu-no-workgroup-id-y"},
+ {WORKGROUP_ID_Z, "amdgpu-no-workgroup-id-z"},
+ {WORKITEM_ID_X, "amdgpu-no-workitem-id-x"},
+ {WORKITEM_ID_Y, "amdgpu-no-workitem-id-y"},
+ {WORKITEM_ID_Z, "amdgpu-no-workitem-id-z"}
+};
// We do not need to note the x workitem or workgroup id because they are always
// initialized.
//
// TODO: We should not add the attributes if the known compile time workgroup
// size is 1 for y/z.
-static StringRef intrinsicToAttrName(Intrinsic::ID ID, bool &NonKernelOnly,
- bool &IsQueuePtr) {
+static ImplicitArgumentMask
+intrinsicToAttrMask(Intrinsic::ID ID, bool &NonKernelOnly, bool &IsQueuePtr) {
switch (ID) {
case Intrinsic::amdgcn_workitem_id_x:
NonKernelOnly = true;
- return "amdgpu-work-item-id-x";
+ return WORKITEM_ID_X;
case Intrinsic::amdgcn_workgroup_id_x:
NonKernelOnly = true;
- return "amdgpu-work-group-id-x";
+ return WORKGROUP_ID_X;
case Intrinsic::amdgcn_workitem_id_y:
case Intrinsic::r600_read_tidig_y:
- return "amdgpu-work-item-id-y";
+ return WORKITEM_ID_Y;
case Intrinsic::amdgcn_workitem_id_z:
case Intrinsic::r600_read_tidig_z:
- return "amdgpu-work-item-id-z";
+ return WORKITEM_ID_Z;
case Intrinsic::amdgcn_workgroup_id_y:
case Intrinsic::r600_read_tgid_y:
- return "amdgpu-work-group-id-y";
+ return WORKGROUP_ID_Y;
case Intrinsic::amdgcn_workgroup_id_z:
case Intrinsic::r600_read_tgid_z:
- return "amdgpu-work-group-id-z";
+ return WORKGROUP_ID_Z;
case Intrinsic::amdgcn_dispatch_ptr:
- return "amdgpu-dispatch-ptr";
+ return DISPATCH_PTR;
case Intrinsic::amdgcn_dispatch_id:
- return "amdgpu-dispatch-id";
- case Intrinsic::amdgcn_kernarg_segment_ptr:
- return "amdgpu-kernarg-segment-ptr";
+ return DISPATCH_ID;
case Intrinsic::amdgcn_implicitarg_ptr:
- return "amdgpu-implicitarg-ptr";
+ return IMPLICIT_ARG_PTR;
case Intrinsic::amdgcn_queue_ptr:
case Intrinsic::amdgcn_is_shared:
case Intrinsic::amdgcn_is_private:
@@ -71,9 +94,9 @@ static StringRef intrinsicToAttrName(Intrinsic::ID ID, bool &NonKernelOnly,
case Intrinsic::trap:
case Intrinsic::debugtrap:
IsQueuePtr = true;
- return "amdgpu-queue-ptr";
+ return QUEUE_PTR;
default:
- return "";
+ return NOT_IMPLICIT_INPUT;
}
}
@@ -89,6 +112,7 @@ static bool isDSAddress(const Constant *C) {
return AS == AMDGPUAS::LOCAL_ADDRESS || AS == AMDGPUAS::REGION_ADDRESS;
}
+namespace {
class AMDGPUInformationCache : public InformationCache {
public:
AMDGPUInformationCache(const Module &M, AnalysisGetter &AG,
@@ -105,6 +129,17 @@ public:
return ST.hasApertureRegs();
}
+ std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) {
+ const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(F);
+ return ST.getFlatWorkGroupSizes(F);
+ }
+
+ std::pair<unsigned, unsigned>
+ getMaximumFlatWorkGroupRange(const Function &F) {
+ const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(F);
+ return {ST.getMinFlatWorkGroupSize(), ST.getMaxFlatWorkGroupSize()};
+ }
+
private:
/// Check if the ConstantExpr \p CE requires queue ptr attribute.
static bool visitConstExpr(const ConstantExpr *CE) {
@@ -163,8 +198,11 @@ private:
DenseMap<const Constant *, uint8_t> ConstantStatus;
};
-struct AAAMDAttributes : public StateWrapper<BooleanState, AbstractAttribute> {
- using Base = StateWrapper<BooleanState, AbstractAttribute>;
+struct AAAMDAttributes : public StateWrapper<
+ BitIntegerState<uint16_t, ALL_ARGUMENT_MASK, 0>, AbstractAttribute> {
+ using Base = StateWrapper<BitIntegerState<uint16_t, ALL_ARGUMENT_MASK, 0>,
+ AbstractAttribute>;
+
AAAMDAttributes(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
/// Create an abstract attribute view for the position \p IRP.
@@ -183,24 +221,24 @@ struct AAAMDAttributes : public StateWrapper<BooleanState, AbstractAttribute> {
return (AA->getIdAddr() == &ID);
}
- virtual const DenseSet<StringRef> &getAttributes() const = 0;
-
/// Unique ID (due to the unique address)
static const char ID;
};
const char AAAMDAttributes::ID = 0;
-struct AAAMDWorkGroupSize
+struct AAUniformWorkGroupSize
: public StateWrapper<BooleanState, AbstractAttribute> {
using Base = StateWrapper<BooleanState, AbstractAttribute>;
- AAAMDWorkGroupSize(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
+ AAUniformWorkGroupSize(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
/// Create an abstract attribute view for the position \p IRP.
- static AAAMDWorkGroupSize &createForPosition(const IRPosition &IRP,
- Attributor &A);
+ static AAUniformWorkGroupSize &createForPosition(const IRPosition &IRP,
+ Attributor &A);
/// See AbstractAttribute::getName().
- const std::string getName() const override { return "AAAMDWorkGroupSize"; }
+ const std::string getName() const override {
+ return "AAUniformWorkGroupSize";
+ }
/// See AbstractAttribute::getIdAddr().
const char *getIdAddr() const override { return &ID; }
@@ -214,11 +252,11 @@ struct AAAMDWorkGroupSize
/// Unique ID (due to the unique address)
static const char ID;
};
-const char AAAMDWorkGroupSize::ID = 0;
+const char AAUniformWorkGroupSize::ID = 0;
-struct AAAMDWorkGroupSizeFunction : public AAAMDWorkGroupSize {
- AAAMDWorkGroupSizeFunction(const IRPosition &IRP, Attributor &A)
- : AAAMDWorkGroupSize(IRP, A) {}
+struct AAUniformWorkGroupSizeFunction : public AAUniformWorkGroupSize {
+ AAUniformWorkGroupSizeFunction(const IRPosition &IRP, Attributor &A)
+ : AAUniformWorkGroupSize(IRP, A) {}
void initialize(Attributor &A) override {
Function *F = getAssociatedFunction();
@@ -244,10 +282,10 @@ struct AAAMDWorkGroupSizeFunction : public AAAMDWorkGroupSize {
auto CheckCallSite = [&](AbstractCallSite CS) {
Function *Caller = CS.getInstruction()->getFunction();
- LLVM_DEBUG(dbgs() << "[AAAMDWorkGroupSize] Call " << Caller->getName()
+ LLVM_DEBUG(dbgs() << "[AAUniformWorkGroupSize] Call " << Caller->getName()
<< "->" << getAssociatedFunction()->getName() << "\n");
- const auto &CallerInfo = A.getAAFor<AAAMDWorkGroupSize>(
+ const auto &CallerInfo = A.getAAFor<AAUniformWorkGroupSize>(
*this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
Change = Change | clampStateAndIndicateChange(this->getState(),
@@ -286,11 +324,13 @@ struct AAAMDWorkGroupSizeFunction : public AAAMDWorkGroupSize {
void trackStatistics() const override {}
};
-AAAMDWorkGroupSize &AAAMDWorkGroupSize::createForPosition(const IRPosition &IRP,
- Attributor &A) {
+AAUniformWorkGroupSize &
+AAUniformWorkGroupSize::createForPosition(const IRPosition &IRP,
+ Attributor &A) {
if (IRP.getPositionKind() == IRPosition::IRP_FUNCTION)
- return *new (A.Allocator) AAAMDWorkGroupSizeFunction(IRP, A);
- llvm_unreachable("AAAMDWorkGroupSize is only valid for function position");
+ return *new (A.Allocator) AAUniformWorkGroupSizeFunction(IRP, A);
+ llvm_unreachable(
+ "AAUniformWorkGroupSize is only valid for function position");
}
struct AAAMDAttributesFunction : public AAAMDAttributes {
@@ -299,14 +339,13 @@ struct AAAMDAttributesFunction : public AAAMDAttributes {
void initialize(Attributor &A) override {
Function *F = getAssociatedFunction();
- CallingConv::ID CC = F->getCallingConv();
- bool CallingConvSupportsAllImplicits = (CC != CallingConv::AMDGPU_Gfx);
+ for (auto Attr : ImplicitAttrs) {
+ if (F->hasFnAttribute(Attr.second))
+ addKnownBits(Attr.first);
+ }
- // Don't add attributes to instrinsics
- if (F->isIntrinsic()) {
- indicatePessimisticFixpoint();
+ if (F->isDeclaration())
return;
- }
// Ignore functions with graphics calling conventions, these are currently
// not allowed to have kernel arguments.
@@ -314,94 +353,47 @@ struct AAAMDAttributesFunction : public AAAMDAttributes {
indicatePessimisticFixpoint();
return;
}
-
- for (StringRef Attr : ImplicitAttrNames) {
- if (F->hasFnAttribute(Attr))
- Attributes.insert(Attr);
- }
-
- // TODO: We shouldn't need this in the future.
- if (CallingConvSupportsAllImplicits &&
- F->hasAddressTaken(nullptr, true, true, true)) {
- for (StringRef AttrName : ImplicitAttrNames) {
- Attributes.insert(AttrName);
- }
- }
}
ChangeStatus updateImpl(Attributor &A) override {
Function *F = getAssociatedFunction();
- ChangeStatus Change = ChangeStatus::UNCHANGED;
- bool IsNonEntryFunc = !AMDGPU::isEntryFunctionCC(F->getCallingConv());
- CallingConv::ID CC = F->getCallingConv();
- bool CallingConvSupportsAllImplicits = (CC != CallingConv::AMDGPU_Gfx);
- auto &InfoCache = static_cast<AMDGPUInformationCache &>(A.getInfoCache());
-
- auto AddAttribute = [&](StringRef AttrName) {
- if (Attributes.insert(AttrName).second)
- Change = ChangeStatus::CHANGED;
- };
+ // The current assumed state used to determine a change.
+ auto OrigAssumed = getAssumed();
// Check for Intrinsics and propagate attributes.
const AACallEdges &AAEdges = A.getAAFor<AACallEdges>(
*this, this->getIRPosition(), DepClassTy::REQUIRED);
+ if (AAEdges.hasNonAsmUnknownCallee())
+ return indicatePessimisticFixpoint();
- // We have to assume that we can reach a function with these attributes.
- // We do not consider inline assembly as a unknown callee.
- if (CallingConvSupportsAllImplicits && AAEdges.hasNonAsmUnknownCallee()) {
- for (StringRef AttrName : ImplicitAttrNames) {
- AddAttribute(AttrName);
- }
- }
+ bool IsNonEntryFunc = !AMDGPU::isEntryFunctionCC(F->getCallingConv());
+ auto &InfoCache = static_cast<AMDGPUInformationCache &>(A.getInfoCache());
bool NeedsQueuePtr = false;
- bool HasCall = false;
+
for (Function *Callee : AAEdges.getOptimisticEdges()) {
Intrinsic::ID IID = Callee->getIntrinsicID();
- if (IID != Intrinsic::not_intrinsic) {
- if (!IsNonEntryFunc && IID == Intrinsic::amdgcn_kernarg_segment_ptr) {
- AddAttribute("amdgpu-kernarg-segment-ptr");
- continue;
- }
-
- bool NonKernelOnly = false;
- StringRef AttrName =
- intrinsicToAttrName(IID, NonKernelOnly, NeedsQueuePtr);
-
- if (!AttrName.empty() && (IsNonEntryFunc || !NonKernelOnly))
- AddAttribute(AttrName);
-
+ if (IID == Intrinsic::not_intrinsic) {
+ const AAAMDAttributes &AAAMD = A.getAAFor<AAAMDAttributes>(
+ *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
+ *this &= AAAMD;
continue;
}
- HasCall = true;
- const AAAMDAttributes &AAAMD = A.getAAFor<AAAMDAttributes>(
- *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
- const DenseSet<StringRef> &CalleeAttributes = AAAMD.getAttributes();
- // Propagate implicit attributes from called function.
- for (StringRef AttrName : ImplicitAttrNames)
- if (CalleeAttributes.count(AttrName))
- AddAttribute(AttrName);
+ bool NonKernelOnly = false;
+ ImplicitArgumentMask AttrMask =
+ intrinsicToAttrMask(IID, NonKernelOnly, NeedsQueuePtr);
+ if (AttrMask != NOT_IMPLICIT_INPUT) {
+ if ((IsNonEntryFunc || !NonKernelOnly))
+ removeAssumedBits(AttrMask);
+ }
}
- HasCall |= AAEdges.hasUnknownCallee();
- if (!IsNonEntryFunc && HasCall)
- AddAttribute("amdgpu-calls");
-
- // Check the function body.
- auto CheckAlloca = [&](Instruction &I) {
- AddAttribute("amdgpu-stack-objects");
- return false;
- };
-
- bool UsedAssumedInformation = false;
- A.checkForAllInstructions(CheckAlloca, *this, {Instruction::Alloca},
- UsedAssumedInformation);
-
// If we found that we need amdgpu-queue-ptr, nothing else to do.
- if (NeedsQueuePtr || Attributes.count("amdgpu-queue-ptr")) {
- AddAttribute("amdgpu-queue-ptr");
- return Change;
+ if (NeedsQueuePtr) {
+ removeAssumedBits(QUEUE_PTR);
+ return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED :
+ ChangeStatus::UNCHANGED;
}
auto CheckAddrSpaceCasts = [&](Instruction &I) {
@@ -419,60 +411,68 @@ struct AAAMDAttributesFunction : public AAAMDAttributes {
// instructions, try it first.
// amdgpu-queue-ptr is not needed if aperture regs is present.
- if (!HasApertureRegs)
+ if (!HasApertureRegs) {
+ bool UsedAssumedInformation = false;
A.checkForAllInstructions(CheckAddrSpaceCasts, *this,
{Instruction::AddrSpaceCast},
UsedAssumedInformation);
+ }
// If we found that we need amdgpu-queue-ptr, nothing else to do.
if (NeedsQueuePtr) {
- AddAttribute("amdgpu-queue-ptr");
- return Change;
+ removeAssumedBits(QUEUE_PTR);
+ return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED :
+ ChangeStatus::UNCHANGED;
}
- if (!IsNonEntryFunc && HasApertureRegs)
- return Change;
+ if (!IsNonEntryFunc && HasApertureRegs) {
+ return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED :
+ ChangeStatus::UNCHANGED;
+ }
for (BasicBlock &BB : *F) {
for (Instruction &I : BB) {
for (const Use &U : I.operands()) {
if (const auto *C = dyn_cast<Constant>(U)) {
if (InfoCache.needsQueuePtr(C, *F)) {
- AddAttribute("amdgpu-queue-ptr");
- return Change;
+ removeAssumedBits(QUEUE_PTR);
+ return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED :
+ ChangeStatus::UNCHANGED;
}
}
}
}
}
- return Change;
+ return getAssumed() != OrigAssumed ? ChangeStatus::CHANGED :
+ ChangeStatus::UNCHANGED;
}
ChangeStatus manifest(Attributor &A) override {
SmallVector<Attribute, 8> AttrList;
LLVMContext &Ctx = getAssociatedFunction()->getContext();
- for (StringRef AttrName : Attributes)
- AttrList.push_back(Attribute::get(Ctx, AttrName));
+ for (auto Attr : ImplicitAttrs) {
+ if (isKnown(Attr.first))
+ AttrList.push_back(Attribute::get(Ctx, Attr.second));
+ }
return IRAttributeManifest::manifestAttrs(A, getIRPosition(), AttrList,
/* ForceReplace */ true);
}
const std::string getAsStr() const override {
- return "AMDInfo[" + std::to_string(Attributes.size()) + "]";
- }
-
- const DenseSet<StringRef> &getAttributes() const override {
- return Attributes;
+ std::string Str;
+ raw_string_ostream OS(Str);
+ OS << "AMDInfo[";
+ for (auto Attr : ImplicitAttrs)
+ OS << ' ' << Attr.second;
+ OS << " ]";
+ return OS.str();
}
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override {}
-
-private:
- DenseSet<StringRef> Attributes;
};
AAAMDAttributes &AAAMDAttributes::createForPosition(const IRPosition &IRP,
@@ -482,6 +482,118 @@ AAAMDAttributes &AAAMDAttributes::createForPosition(const IRPosition &IRP,
llvm_unreachable("AAAMDAttributes is only valid for function position");
}
+/// Propagate amdgpu-flat-work-group-size attribute.
+struct AAAMDFlatWorkGroupSize
+ : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
+ using Base = StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t>;
+ AAAMDFlatWorkGroupSize(const IRPosition &IRP, Attributor &A)
+ : Base(IRP, 32) {}
+
+ /// See AbstractAttribute::getState(...).
+ IntegerRangeState &getState() override { return *this; }
+ const IntegerRangeState &getState() const override { return *this; }
+
+ void initialize(Attributor &A) override {
+ Function *F = getAssociatedFunction();
+ auto &InfoCache = static_cast<AMDGPUInformationCache &>(A.getInfoCache());
+ unsigned MinGroupSize, MaxGroupSize;
+ std::tie(MinGroupSize, MaxGroupSize) = InfoCache.getFlatWorkGroupSizes(*F);
+ intersectKnown(
+ ConstantRange(APInt(32, MinGroupSize), APInt(32, MaxGroupSize + 1)));
+ }
+
+ ChangeStatus updateImpl(Attributor &A) override {
+ ChangeStatus Change = ChangeStatus::UNCHANGED;
+
+ auto CheckCallSite = [&](AbstractCallSite CS) {
+ Function *Caller = CS.getInstruction()->getFunction();
+ LLVM_DEBUG(dbgs() << "[AAAMDFlatWorkGroupSize] Call " << Caller->getName()
+ << "->" << getAssociatedFunction()->getName() << '\n');
+
+ const auto &CallerInfo = A.getAAFor<AAAMDFlatWorkGroupSize>(
+ *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
+
+ Change |=
+ clampStateAndIndicateChange(this->getState(), CallerInfo.getState());
+
+ return true;
+ };
+
+ bool AllCallSitesKnown = true;
+ if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
+ return indicatePessimisticFixpoint();
+
+ return Change;
+ }
+
+ ChangeStatus manifest(Attributor &A) override {
+ SmallVector<Attribute, 8> AttrList;
+ Function *F = getAssociatedFunction();
+ LLVMContext &Ctx = F->getContext();
+
+ auto &InfoCache = static_cast<AMDGPUInformationCache &>(A.getInfoCache());
+ unsigned Min, Max;
+ std::tie(Min, Max) = InfoCache.getMaximumFlatWorkGroupRange(*F);
+
+ // Don't add the attribute if it's the implied default.
+ if (getAssumed().getLower() == Min && getAssumed().getUpper() - 1 == Max)
+ return ChangeStatus::UNCHANGED;
+
+ SmallString<10> Buffer;
+ raw_svector_ostream OS(Buffer);
+ OS << getAssumed().getLower() << ',' << getAssumed().getUpper() - 1;
+
+ AttrList.push_back(
+ Attribute::get(Ctx, "amdgpu-flat-work-group-size", OS.str()));
+ return IRAttributeManifest::manifestAttrs(A, getIRPosition(), AttrList,
+ /* ForceReplace */ true);
+ }
+
+ const std::string getAsStr() const override {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ OS << "AMDFlatWorkGroupSize[";
+ OS << getAssumed().getLower() << ',' << getAssumed().getUpper() - 1;
+ OS << ']';
+ return OS.str();
+ }
+
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override {}
+
+ /// Create an abstract attribute view for the position \p IRP.
+ static AAAMDFlatWorkGroupSize &createForPosition(const IRPosition &IRP,
+ Attributor &A);
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override {
+ return "AAAMDFlatWorkGroupSize";
+ }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAAMDFlatWorkGroupSize
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+};
+
+const char AAAMDFlatWorkGroupSize::ID = 0;
+
+AAAMDFlatWorkGroupSize &
+AAAMDFlatWorkGroupSize::createForPosition(const IRPosition &IRP,
+ Attributor &A) {
+ if (IRP.getPositionKind() == IRPosition::IRP_FUNCTION)
+ return *new (A.Allocator) AAAMDFlatWorkGroupSize(IRP, A);
+ llvm_unreachable(
+ "AAAMDFlatWorkGroupSize is only valid for function position");
+}
+
class AMDGPUAttributor : public ModulePass {
public:
AMDGPUAttributor() : ModulePass(ID) {}
@@ -500,17 +612,28 @@ public:
bool runOnModule(Module &M) override {
SetVector<Function *> Functions;
AnalysisGetter AG;
- for (Function &F : M)
- Functions.insert(&F);
+ for (Function &F : M) {
+ if (!F.isIntrinsic())
+ Functions.insert(&F);
+ }
CallGraphUpdater CGUpdater;
BumpPtrAllocator Allocator;
AMDGPUInformationCache InfoCache(M, AG, Allocator, nullptr, *TM);
- Attributor A(Functions, InfoCache, CGUpdater);
+ DenseSet<const char *> Allowed(
+ {&AAAMDAttributes::ID, &AAUniformWorkGroupSize::ID,
+ &AAAMDFlatWorkGroupSize::ID, &AACallEdges::ID});
+
+ Attributor A(Functions, InfoCache, CGUpdater, &Allowed);
for (Function &F : M) {
- A.getOrCreateAAFor<AAAMDAttributes>(IRPosition::function(F));
- A.getOrCreateAAFor<AAAMDWorkGroupSize>(IRPosition::function(F));
+ if (!F.isIntrinsic()) {
+ A.getOrCreateAAFor<AAAMDAttributes>(IRPosition::function(F));
+ A.getOrCreateAAFor<AAUniformWorkGroupSize>(IRPosition::function(F));
+ if (!AMDGPU::isEntryFunctionCC(F.getCallingConv())) {
+ A.getOrCreateAAFor<AAAMDFlatWorkGroupSize>(IRPosition::function(F));
+ }
+ }
}
ChangeStatus Change = A.run();
@@ -521,6 +644,7 @@ public:
TargetMachine *TM;
static char ID;
};
+} // namespace
char AMDGPUAttributor::ID = 0;