Skip to content

Conversation

vchuravy
Copy link
Contributor

Noticed that this was missing while experimenting with llvm-dialects.

Is there already an interface for specifing return attributes / per-argument interfaces?

@nhaehnle
Copy link
Member

Thanks!

Is there already an interface for specifing return attributes / per-argument interfaces?

No. Look how llvm_dialects::genDialectDefs invokes LlvmAttributeTrait::addAttribute to generate the code that adds attributes to attribute lists. We'd have to extend both the invocation site to support adding attributes at indices other than FunctionIndex, and the Trait hierarchy to represent attributes in argument or return position.

Perhaps an LlvmArgEnumAttributeTrait class in TableGen that allows defining

def NoCaptureArg<int idx> : LlvmArgEnumAttributeTrait<idx, "NoCapture">;
// etc.

and similar for return attributes.

@nhaehnle nhaehnle merged commit a3f36a8 into GPUOpen-Drivers:dev Oct 17, 2024
8 checks passed
@nhaehnle
Copy link
Member

Thinking about this a bit more, working with indices when defining operations is a bit clunky. Perhaps the TableGen should look like this:

def FooOp : ... {
  let arguments = (ins Ptr:$ptr);
  let results = (outs Ptr:$result);

  let value_traits = [
    (ReadOnly $ptr),
    (NoCapture $ptr),
    (NonNull $result),
  ];
}

We could then potentially re-use the LlvmEnumAttributeTrait TableGen class, but perhaps add a field that indicates which positions the attribute can appear in.

@vchuravy vchuravy deleted the vc/speculatable branch October 17, 2024 08:23
@sstipano
Copy link
Contributor

I've implemented this def NoCaptureArg<int idx> : LlvmArgEnumAttributeTrait<idx, "NoCapture">; in #120 without knowing this discussion existed.

I'd like to restart discussion about this. Should we continue with what's proposed here? (#110)

Thinking about this a bit more, working with indices when defining operations is a bit clunky. Perhaps the TableGen should look like this:

def FooOp : ... {
  let arguments = (ins Ptr:$ptr);
  let results = (outs Ptr:$result);

  let value_traits = [
    (ReadOnly $ptr),
    (NoCapture $ptr),
    (NonNull $result),
  ];
}

We could then potentially re-use the LlvmEnumAttributeTrait TableGen class, but perhaps add a field that indicates which positions the attribute can appear in.

But still, we would need to modify the code for adding attributes and obtain the index somehow? Maybe by finding the argument in the (ins) list?

@nhaehnle
Copy link
Member

nhaehnle commented Mar 3, 2025

Yes, I think it would be good to continue this. And yes, you'd have to match up the $ptr from the value_traits with the argument list from the ins.

@sstipano
Copy link
Contributor

sstipano commented Mar 5, 2025

Yes, I think it would be good to continue this. And yes, you'd have to match up the $ptr from the value_traits with the argument list from the ins.

I experimented a bit with the implementation of this approach. Do we need to keep the caching of traits in Trait *GenDialectsContext::getTrait(...)? Caching is currently a problem, because with value_traits, all attribute traits come from the same record and we always get the cached trait, instead of creating new one. I think if we were to continue with this approach, caching is not possible.

@sstipano
Copy link
Contributor

sstipano commented Mar 6, 2025

Nevermind, created #121 with the implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants