This is an archive of the discontinued LLVM Phabricator instance.

TableGen: Allow !cast of records, cleanup conversion machinery
ClosedPublic

Authored by nhaehnle on Feb 26 2018, 12:30 AM.

Details

Summary

Distinguish two relationships between types: is-a and convertible-to.
For example, a bit is not an int or vice versa, but they can be
converted into each other (with range checks that you can think of
as "dynamic": unlike other type checks, those range checks do not
happen during parsing, but only once the final values have been
established).

Actually converting initializers between types is subtle: even
when values of type A can be converted to type B (e.g. int into
string), it may not be possible to do so with a concrete initializer
(e.g., a VarInit that refers to a variable of type int cannot
be immediately converted to a string).

For this reason, distinguish between getCastTo and convertInitializerTo:
the latter implements the actual conversion when appropriate, while
the former will first try to do the actual conversion and fall back
to introducing a !cast operation so that the conversion will be
delayed until variable references have been resolved.

To make the approach of adding !cast operations to work, !cast needs
to fallback to convertInitializerTo when the special string <-> record
logic does not apply.

This enables casting records to a subclass, although that new
functionality is only truly useful together with !isa, which will be
added in a later change.

The test is removed because it uses !srl on a bit sequence,
which cannot really be supported consistently, but luckily
isn't used anywhere either.

Change-Id: I98168bf52649176654ed2ec61a29bdb29970cfe7

Diff Detail

Repository
rL LLVM

Event Timeline

nhaehnle created this revision.Feb 26 2018, 12:30 AM
tra added inline comments.Feb 26 2018, 3:55 PM
docs/TableGen/LangIntro.rst
186 ↗(On Diff #135858)

symbol table may need some disambiguation. I.e. we have more than one kind of symbols (template parameters, class/multiclass names, field names, defined records, temporary variables in !foreach) and not all of them are applicable here.

Does it mean list of all records defined by the time tablegen reaches the end of its input?

190–191 ↗(On Diff #135858)

Is it going to be limited to records only? We currently allow !cast<string> for other types, though not all of them work. E.g. currently int works, bits and lists do not. It may be worth documenting this in more details.

lib/TableGen/Record.cpp
790–795 ↗(On Diff #135858)

What makes getBit(0) special for !cast ops?

nhaehnle updated this revision to Diff 136993.Mar 5 2018, 6:52 AM
nhaehnle marked 2 inline comments as done.

More documentation in LangIntro.rst, handle the bit --> bits<1> conversion
properly in cases where the bit has not been resolved.

docs/TableGen/LangIntro.rst
186 ↗(On Diff #135858)

I've tried to make the rules more explicit.

lib/TableGen/Record.cpp
790–795 ↗(On Diff #135858)

Good point, it shouldn't be special. This was fixing some cases of !cast<bits<1>>(P){0} --> { P }{0} --> P in initializers where P itself was unset.

However, the real fix for this is to handle the case convertInitializerTo(bits<1>) for all inits of type bit. I've added that to TypedInit::convertInitializerTo.

tra accepted this revision.Mar 5 2018, 4:44 PM
tra added inline comments.
docs/TableGen/LangIntro.rst
186 ↗(On Diff #135858)

Nice. That's a huge improvement over the old description.

This revision is now accepted and ready to land.Mar 5 2018, 4:44 PM
This revision was automatically updated to reflect the committed changes.
kosarev added inline comments.
llvm/trunk/test/TableGen/BitsInitOverflow.td
5

How is not folding such explicit casts useful?

Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptOct 11 2023, 5:51 AM