This is an archive of the discontinued LLVM Phabricator instance.

TableGen: Streamline how defs are instantiated
ClosedPublic

Authored by nhaehnle on Mar 14 2018, 8:24 AM.

Details

Summary

Instantiating def's and defm's needs to perform the following steps:

  • for defm's, clone multiclass def prototypes and subsitute template args
  • for def's and defm's, add subclass definitions, substituting template args
  • clone the record based on foreach loops and substitute loop iteration variables
  • override record variables based on the global 'let' stack
  • resolve the record name (this should be simple, but unfortunately it's not due to existing .td files relying on rather silly implementation details)
  • for def(m)s in multiclasses, add the unresolved record as a multiclass prototype
  • for top-level def(m)s, resolve all internal variable references and add them to the record keeper and any active defsets

This change streamlines how we go through these steps, by having both
def's and defm's feed into a single addDef() method that handles foreach,
final resolve, and routing the record to the right place.

This happens to make foreach inside of multiclasses work, as the new
test case demonstrates. Previously, foreach inside multiclasses was not
forbidden by the parser, but it was de facto broken.

Another side effect is that the order of "instantiated from" notes in error
messages is reversed, as the modified test case shows. This is arguably
clearer, since the initial error message ends up pointing directly to
whatever triggered the error, and subsequent notes will point to increasingly
outer layers of multiclasses. This is consistent with how C++ compilers
report nested #includes and nested template instantiations.

Change-Id: Ica146d0db2bc133dd7ed88054371becf24320447

Diff Detail

Repository
rL LLVM

Event Timeline

nhaehnle created this revision.Mar 14 2018, 8:24 AM
nhaehnle updated this revision to Diff 138371.Mar 14 2018, 8:38 AM

Updating with a cleanup that I missed.

tra added a comment.Mar 14 2018, 12:13 PM

Just in time. :-) I've ran into the broken foreach-in-multiclass yesterday.

lib/TableGen/TGParser.cpp
2453 ↗(On Diff #138371)

Nit: /*Anonymous=*/true.

2798 ↗(On Diff #138371)

Number of items in a multiclass is relatively small. Perhaps we could/should use SmallVector here.

2853–2856 ↗(On Diff #138371)

It would be good to have an example or a pointer to something specific so whoever gets to read it later has an ises what needs to be fixed. Perhaps it would make sense to add a disabled test case that would demonstrate the issue.

2867–2868 ↗(On Diff #138371)

Same here.

nhaehnle updated this revision to Diff 138909.Mar 19 2018, 7:13 AM
nhaehnle marked 4 inline comments as done.

Address minor review comments and add a new test case that demonstrates
the inconsistencies in name resolution.

nhaehnle added inline comments.Mar 19 2018, 7:16 AM
lib/TableGen/TGParser.cpp
2453 ↗(On Diff #138371)

Done.

2798 ↗(On Diff #138371)

Done.

2853–2856 ↗(On Diff #138371)

Yeah, that's absolutely true.

I added a new test case that shows some of the surprising stuff that happens, in particular: the resolution of record names referencing template args depends on the nesting level at which the template arg is substituted, and trying to add prefixes inside multiclasses ends up with some surprises as well.

tra accepted this revision.Mar 19 2018, 1:29 PM
This revision is now accepted and ready to land.Mar 19 2018, 1:29 PM
This revision was automatically updated to reflect the committed changes.