This is an archive of the discontinued LLVM Phabricator instance.

[TableGen] Support named arguments
ClosedPublic

Authored by wangpc on Jun 15 2023, 1:04 AM.

Details

Summary

We provide a way to specify arguments in the form of name=value
so that we don't have to specify all optional arguments before the
one we'd like to change. Required arguments can alse be specified
in this way.

Note that the argument can only be specified once regardless of
the way (named or positional) to specify and positional arguments
should be put before named arguments.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptJun 15 2023, 1:04 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
pcwang-thead requested review of this revision.Jun 15 2023, 1:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 15 2023, 1:04 AM
wangpc commandeered this revision.Jun 15 2023, 9:06 AM
wangpc added a reviewer: pcwang-thead.
wangpc removed a reviewer: pcwang-thead.
wangpc updated this revision to Diff 533195.Jun 21 2023, 2:51 AM
  • Refactor.
  • Add RISCV changes.
wangpc retitled this revision from [WIP][TableGen] Support named arguments to [TableGen][RISCV] Support named arguments.Jun 21 2023, 2:53 AM
wangpc edited the summary of this revision. (Show Details)
wangpc added inline comments.Jun 21 2023, 2:57 AM
llvm/lib/TableGen/TGParser.cpp
119–120

@nhaehnle
It seems that we can't define nested class in multiclass, so why do we need this?
Do you remember the context in D47431?

wangpc updated this revision to Diff 533198.Jun 21 2023, 3:05 AM

Remove commented out code.

wangpc edited the summary of this revision. (Show Details)Jun 21 2023, 3:06 AM

Thanks for this patch. It will make maintenance much easier!

llvm/lib/TableGen/TGParser.cpp
3138–3140

Does TemplateArgList production need to be updated to something along the lines of:

TemplateArgList ::= '<' [[NamedArg=]Value {',' [NamedArg=]Value}*] '>'
3214

nit: modifies element being iterated over, sets it to something in scope, but uses ArgName after we leave scope.

craig.topper added inline comments.Jun 21 2023, 6:01 PM
llvm/lib/TableGen/TGParser.h
293

Should the parameter be isDefm? Is see that's what one caller passes.

Nice. Don't forget to document it.

wangpc updated this revision to Diff 534323.Jun 25 2023, 2:59 AM
  • Rebase.
  • Address comments.
  • Update doc/ReleaseNotes.
wangpc updated this revision to Diff 534324.Jun 25 2023, 3:02 AM
wangpc marked 3 inline comments as done.
wangpc updated this revision to Diff 534878.Jun 27 2023, 2:23 AM
  • Refactor. ArgumentInits are added and we change the way to resolve arguments accordingly.
  • Rebase.
wangpc edited the summary of this revision. (Show Details)Jun 27 2023, 2:24 AM
wangpc updated this revision to Diff 534883.Jun 27 2023, 2:39 AM

Update doc.

wangpc edited the summary of this revision. (Show Details)Jun 27 2023, 2:41 AM
wangpc updated this revision to Diff 535264.Jun 28 2023, 12:41 AM

Fix comments.

llvm/include/llvm/TableGen/Record.h
511

Should we call Value->getBit() instead? If the argument is a bit, we'd like it to behave like getBit was called on a bit, but if the argument was a IntInit we'd like it to behave like getBit was called on an int.

Another approach could be to put an llvm_unreachable.

513

Do we really want to return nullptr for getCastTo and convertInitializerTo? Maybe it would be better to llvm_unreachable("TODO: Implement").

llvm/lib/TableGen/TGParser.cpp
598

Add test for this error path?

613

Add test for error path?

641

Add test for this error path?

758–759

nit: should we rename isDefm to IsDefm?

reames added a subscriber: reames.Jun 28 2023, 2:26 PM

I think this is generally excellent idea. The overall structure seems to make sense here, but some of the details of TGParser.cpp lost me in a way where I can't give meaningful review feedback.

I'd like to suggest that you split this patch. A pre-patch which does nothing but add the ArgumentInit class *for positional arguments only* would go a long way to reducing the verbose, but uninteresting parts of this diff. It would also be entirely NFC, and thus easier to test and review on that basis. Once that landed - I am offering to review it - this could be rebased, and attention focused on the more semantically useful bits.

On a similar note, I think the extraction of resolveClassArguments and resolveMultiClassArguments could be done as a standalone NFC. Doing so would eliminate the mixture of code motion and modification in the current patch.

Unless I'm missing something I don't see a test for trying to name the same argument twice, only for both positional and named

Please also split out the RISC-V changes into their own review; they don't belong with the TableGen feature itself

wangpc updated this revision to Diff 535726.Jun 29 2023, 4:54 AM
  • Rebase.
  • Add error test that specifies the same argument name twice.
wangpc retitled this revision from [TableGen][RISCV] Support named arguments to [TableGen] Support named arguments.Jun 29 2023, 4:54 AM
wangpc edited the summary of this revision. (Show Details)
wangpc marked 6 inline comments as done.Jun 29 2023, 5:03 AM
wangpc added inline comments.
llvm/include/llvm/TableGen/Record.h
513

I decided to delegate all these method to Value.

llvm/lib/TableGen/TGParser.cpp
641

These should have already been catched by llvm/test/TableGen/template-args.td.

wangpc updated this revision to Diff 536119.Jun 29 2023, 11:01 PM
wangpc marked 2 inline comments as done.

clang-format.

reames requested changes to this revision.Jul 5 2023, 12:49 PM
reames added inline comments.
llvm/include/llvm/TableGen/Record.h
546–547

I'm not 100% on this, but I don't think sub-classing is the right model here. I think this code would be a lot easier to follow with a single ArgumentInit class with an optional index, an optional name, and a value. A single isPositionalArg() method then let's you dispatch in the few places you need to.

llvm/lib/TableGen/TGParser.cpp
740

Stray change, remove.

llvm/lib/TableGen/TGParser.h
280

Stray change, remove.

This revision now requires changes to proceed.Jul 5 2023, 12:49 PM
MaskRay added inline comments.Jul 10 2023, 2:23 PM
llvm/include/llvm/TableGen/Record.h
323

Add a trailing comma so that next time we add a new member, we can avoid touching this IK_NamedArgumentInit line

llvm/test/TableGen/named-arguments.td
15

Add spaces so that def align with }. This just looks nicer.

100

I wonder whether tablegen parsing doesn't have error recovery so that we need an invocation for every test...

In clang we test many errors in one invocation...

wangpc updated this revision to Diff 538949.Jul 11 2023, 1:01 AM
  • Rebase.
  • No sub-typing for ArgumentInit.
  • Add spaces before def in tests.
wangpc marked 6 inline comments as done.Jul 11 2023, 1:08 AM
wangpc added inline comments.
llvm/include/llvm/TableGen/Record.h
546–547

The original patch was just like what you said when I started this patch. The complexity won't disappear, it just moves from sub-typing to branches I think.

llvm/test/TableGen/named-arguments.td
100

Yes, there is no error recovery for TableGen parser…
The parser is a really simple recursive descent parser for LL(1) grammar.

reames requested changes to this revision.Jul 11 2023, 12:06 PM
reames added inline comments.
llvm/include/llvm/TableGen/Record.h
496

Drop the union. The minimal space savings is not worth the awful and hard to debug problems.

You can use a signal value (i.e. -1 on Index) to track the type of the argument.

515–525

Add asserts on the kind for both this and the following accessor.

llvm/lib/TableGen/Record.cpp
382

Once you drop the union, this simplifies.

llvm/lib/TableGen/TGParser.cpp
119–120

The removal of this code needs to be resolved. I don't understand the context well enough to address this point.

3161

I'm missing something here. One the *first* named argument, aren't we constructing the value with the wrong type? Does that matter?

3170

I think this code might be easier to follow if you moved the error checking for name and unset value to the point the arguments are resolved. This would require that we support both a qualified and unqualified state in the argument name field which is not great. Unless, can we move resolution to the use of the named argument?

(Not at all sure of this proposal, take it as a weak suggestion only.)

3189

Please use early-return here.

This revision now requires changes to proceed.Jul 11 2023, 12:06 PM
arsenm added a subscriber: arsenm.Jul 11 2023, 12:12 PM
arsenm added inline comments.
llvm/include/llvm/TableGen/Record.h
496

or use std::variant

wangpc updated this revision to Diff 539432.Jul 12 2023, 2:09 AM
wangpc marked 2 inline comments as done.
  • Use std::variant instead of union.
  • Address @reames 's comments.
wangpc marked 6 inline comments as done.Jul 12 2023, 2:38 AM
wangpc added inline comments.
llvm/lib/TableGen/TGParser.cpp
119–120

The removed code assumed that we can define classes inside a multiclass, so the name of outer multiclass is concatenated to the qualified name. But for current TableGen grammar, we can't define classes in multiclass, so it is unnecessary.

The reason why we need to remove it in this patch is:

  1. We can define records, invoke class-based subroutines inside a multiclass.
  2. When parsing the name of named arguments in ParseTemplateArgValueList, we need to construct the qualified name to find if there is an argument with that name.
  3. CurMultiClass may not be null, so the qualified name woule be like MultiClass::Class:argname, which doesn't exist.
  4. Then we fail to find the argument which exists actually.
3161

For the first named argument, we are actually parsing the name value (which is a StringInit) here, so the type doesn't matter.
I set nullptr to ItemType explictly here for non-first named arguments.

3170

When resolving arguments, we can only see Inits and Records. We will lose exact error location information if we move the error checking to later parts.

wangpc marked 3 inline comments as done.Jul 12 2023, 8:41 AM
wangpc updated this revision to Diff 539833.Jul 12 2023, 8:35 PM

clang-format

Ping.
@reames Are there any other issues I need to fix?

reames accepted this revision.Jul 19 2023, 12:39 PM

LGTM w/one required comment

llvm/lib/TableGen/TGParser.cpp
119–120

Please separate this diff, and commit it separately. Your explanation is sufficient, and you don't need separate review. You should take the time to construct a commit comment which explains which this is fully NFC (without this patch).

This revision is now accepted and ready to land.Jul 19 2023, 12:39 PM
wangpc marked 2 inline comments as done.Jul 20 2023, 1:04 AM
This revision was landed with ongoing or failed builds.Jul 20 2023, 1:05 AM
This revision was automatically updated to reflect the committed changes.
DavidSpickett added inline comments.
llvm/lib/TableGen/TGParser.cpp
598

I noticed this working on my Tablegen notebooks, the following example gives the error, but is not itself a multiclass at least not from the user's point of view:

class C <int a, int b> {
    int c = a;
    int d = b;
}
def X: C<0> {}
$ ./bin/llvm-tblgen /tmp/test.td
/tmp/test.td:5:8: error: value not specified for template argument (C:b) of multiclass 'C'
def X: C<0> {}
       ^

Do you have enough information in this context to be able to make the error message more accurate?

wangpc added inline comments.Aug 2 2023, 8:22 AM
llvm/lib/TableGen/TGParser.cpp
598

Oops, it is my mistake. I will fix it and print accurate location of unspecified argument.

wangpc marked an inline comment as done.Aug 3 2023, 12:01 AM
wangpc added inline comments.
llvm/lib/TableGen/TGParser.cpp
598

Should be fixed in D156966.