diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp | 402 |
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; |
