[llvm] [AMDGPU][Attributor] Infer `inreg` attribute in `AMDGPUAttributor` (PR #101609)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 20 06:37:12 PDT 2024
================
@@ -1014,6 +1016,109 @@ struct AAAMDGPUNoAGPR
const char AAAMDGPUNoAGPR::ID = 0;
+struct AAAMDGPUUniform
+ : public IRAttribute<Attribute::InReg,
+ StateWrapper<BooleanState, AbstractAttribute>,
+ AAAMDGPUUniform> {
+ AAAMDGPUUniform(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
+
+ /// Create an abstract attribute view for the position \p IRP.
+ static AAAMDGPUUniform &createForPosition(const IRPosition &IRP,
+ Attributor &A);
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAAMDGPUUniform"; }
+
+ const std::string getAsStr(Attributor *A) const override {
+ return getAssumed() ? "inreg" : "non-inreg";
+ }
+
+ void trackStatistics() const override {}
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAAMDGPUUniform
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+};
+
+const char AAAMDGPUUniform::ID = 0;
+
+namespace {
+
+struct AAAMDGPUUniformArgument : public AAAMDGPUUniform {
+ AAAMDGPUUniformArgument(const IRPosition &IRP, Attributor &A)
+ : AAAMDGPUUniform(IRP, A) {}
+
+ void initialize(Attributor &A) override {
+ assert(
+ !AMDGPU::isEntryFunctionCC(getAssociatedFunction()->getCallingConv()));
+ if (getAssociatedArgument()->hasAttribute(Attribute::InReg))
+ indicateOptimisticFixpoint();
+ }
+
+ ChangeStatus updateImpl(Attributor &A) override {
+ unsigned ArgNo = getAssociatedArgument()->getArgNo();
+
+ auto isUniform = [&](AbstractCallSite ACS) -> bool {
+ CallBase *CB = ACS.getInstruction();
+ Value *V = CB->getArgOperandUse(ArgNo);
+ if (isa<Constant>(V))
+ return true;
+ if (auto *I = dyn_cast<Instruction>(V)) {
+ auto *UA = A.getInfoCache()
+ .getAnalysisResultForFunction<UniformityInfoAnalysis>(
+ *I->getFunction());
+ return UA && UA->isUniform(I);
+ } else if (auto *Arg = dyn_cast<Argument>(V)) {
+ auto *TTI =
+ A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
+ *Arg->getParent());
+ if (TTI && !TTI->isSourceOfDivergence(Arg))
+ return true;
+ // At this point, if it is an entry point argument, it means it is for
+ // sure divergent.
+ if (AMDGPU::isEntryFunctionCC(Arg->getParent()->getCallingConv()))
+ return false;
----------------
arsenm wrote:
The more important point is this check is incorrect. You should be doing the same thing as isSourceOfDivergence is doing for an Argument, rather than assuming something about all arguments based on being an entry point
https://github.com/llvm/llvm-project/pull/101609
More information about the llvm-commits
mailing list