This is an archive of the discontinued LLVM Phabricator instance.

Enable MatchRegisterName to match register altnames
AbandonedPublic

Authored by asb on Nov 25 2015, 12:10 PM.

Details

Summary

Currently Tablegen includes support for alternate register names, as added in r133940. These alternate names are made use of in the AsmWriter, but not in AsmMatcher. A number of in-tree targets have multiple names for register (e.g. ABI and architectural names), but set ShouldEmitMatchRegisterName to false and write their own matching function, duplicating the information already available in Tablegen. This commit will cause the TableGen'ned MatchRegisterName function to match register altnames provided that MatchRegisterNameShouldMatchAltNames is set. This is set to false by default to ensure no unexpected changes to the behaviour of in-tree and out-of-tree targets, but I'd hope to later switch the default to true and remove the option altogether in the future.

This commit also modifies the doc comment for RegAltNameIndices to make it a little clearer, and removes altNameIndex from RegisterClass which is entirely unused.

I wrote this for an out-of-tree target, but so that it can be tested I've optimistically enabled the functionality for the Hexagon backend (given that HexagonRegisterInfo.td specified alternate register names and AsmParsing support was very recently added, it seemed a good target).

Patch by Alex Bradbury.

Diff Detail

Event Timeline

asb updated this revision to Diff 41165.Nov 25 2015, 12:10 PM
asb retitled this revision from to Enable MatchRegisterName to match register altnames.
asb updated this object.
asb added reviewers: stoklund, adasgupt, grosbach.
asb added a subscriber: llvm-commits.
asb updated this revision to Diff 41166.Nov 25 2015, 12:12 PM

Updated diff to include the newly-added test file.

asb edited reviewers, added: kparzysz; removed: adasgupt.Dec 3 2015, 9:47 AM

Adding Krzysztof, the new Hexagon code owner as reviewer.

colinl edited edge metadata.Dec 3 2015, 12:19 PM

Is there a reason to not emit all AltNames as register matches? This way we aren't putting a requirement on the number of altnames for a register.

Maybe in emitMatchRegisterName:

    Matches.emplace_back(Reg.TheDef->getValueAsString("AsmName"),
                         "return " + utostr(Reg.EnumValue) + ";");
+    for (auto &I: Reg.TheDef->getValueAsListOfStrings("AltNames"))
+      Matches.emplace_back(*I, "return " + utostr(Reg.EnumValue) + ";");
asb added a comment.Dec 3 2015, 12:42 PM

Hi Colin, I agree this would be a reasonable way for the AltNames mechanism to work. However, it's not how AltNames are implemented to work in AsmWriterEmitter (which will only print an alternative altname if the appropriate AltNameIndex is associated with the record) and I feel there should be symmetry. See http://reviews.llvm.org/diffusion/L/browse/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp;254644$543

colinl added a comment.EditedDec 3 2015, 1:09 PM

Hmm interesting. That code section seems to be dead, for instance I did:

-                    dag regList, RegAltNameIndex idx = NoRegAltName>
+                    dag regList>
}
-  RegAltNameIndex altNameIndex = idx
+  RegAltNameIndex altNameIndex = NoRegAltName;

And all the targets seem to still build which seems to indicate no target was using the defaulted template parameter.

I'm not sure why it would have been implemented that way. When printing we need to make a one-to-many decision, one register enum maps to multiple register names and it seems like the natural name to pick would have been the primary one. If they wanted to print a different register they would have swapped an alt name for the primary.

In the reverse direction it doesn't seem necessary to make that distinction, it's a many-to-one decision where multiple register names all map to a single register enum.

asb added a comment.EditedDec 3 2015, 1:37 PM

Hmm interesting. That code section seems to be dead, for instance I did:

-                    dag regList, RegAltNameIndex idx = NoRegAltName>
+                    dag regList>
}
-  RegAltNameIndex altNameIndex = idx
+  RegAltNameIndex altNameIndex = NoRegAltName;

And all the targets seem to still build which seems to indicate no target was using the defaulted template parameter.

That is correct, that parameter is dead and this submitted patchset removes it. Do beware when reading the AsmWriterEmitter code that the variable naming surrounding AltName and AltNameIndex can be very confusing.

I'm not sure why it would have been implemented that way. When printing we need to make a one-to-many decision, one register enum maps to multiple register names and it seems like the natural name to pick would have been the primary one. If they wanted to print a different register they would have swapped an alt name for the primary.

Well sometimes you have a distinction between the ABI and the architectural name, and you want to print the ABI name in generated assembly but refer to the architectural name in the backend. See also my bugfix D15044 to AsmWriterEmitter.

You could imagine having multiple different ABI names, and selecting the preferred one (and thus the preferred AltNameIndex) based on the Target, though of course this isn't done currently.

In the reverse direction it doesn't seem necessary to make that distinction, it's a many-to-one decision where multiple register names all map to a single register enum.

The point I think is that that .td description for any register with altnames isn't complete unless there is also a list of RegAltNameIndices which indicates how they can be addressed. This is similar to the SubRegs and SubRegIndices lists.

Perhaps @grosbach, the original author of the altname system could comment on this?

In PowerPC, we have registers with names like rNN, where NN is some number, but when parsing, we accept %rNN and NN by default, and rNN when targeting Darwin systems. Could this system handle that, or would we need some target-dependence in the selection of which altname indices were available?

asb added a comment.Dec 11 2015, 1:34 AM

In PowerPC, we have registers with names like rNN, where NN is some number, but when parsing, we accept %rNN and NN by default, and rNN when targeting Darwin systems. Could this system handle that, or would we need some target-dependence in the selection of which altname indices were available?

As is currently implemented, the AltName indices mechanism doesn't provide that flexibility. The existing code in AsmWriterEmitter just assumes that the altname indicated by the first AltNameIndex is preferred, and this patch will match any listed AltNameIndex. Having some flexibility to prefer or match different register names depending on ABI and target platform would be a logical extension, but remains to be implemented.

Off the top of my head, it seems there are two sensible ways of doing this: 1) by allowing a predicate function to be specified that will filter the AltNameIndex list, or 2) just requiring the user to specify a function that returns the AltNameIndex list in the first place, perhaps have this be a field in RegisterClass.

In D14994#308104, @asb wrote:

In PowerPC, we have registers with names like rNN, where NN is some number, but when parsing, we accept %rNN and NN by default, and rNN when targeting Darwin systems. Could this system handle that, or would we need some target-dependence in the selection of which altname indices were available?

As is currently implemented, the AltName indices mechanism doesn't provide that flexibility. The existing code in AsmWriterEmitter just assumes that the altname indicated by the first AltNameIndex is preferred, and this patch will match any listed AltNameIndex. Having some flexibility to prefer or match different register names depending on ABI and target platform would be a logical extension, but remains to be implemented.

Off the top of my head, it seems there are two sensible ways of doing this: 1) by allowing a predicate function to be specified that will filter the AltNameIndex list, or 2) just requiring the user to specify a function that returns the AltNameIndex list in the first place, perhaps have this be a field in RegisterClass.

I think that, to be useful across a range of targets, we should really generate values for the AltName indices that can form a bitmask. Then, when printing we pick one (as we do now), and when matching, we can provide a bitmask of accepted AltName classes.

sidneym added inline comments.
lib/Target/Hexagon/HexagonRegisterInfo.td
94

If RegAltNameIndices is needed then the registers below will need the same treatment.

lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
37

Shouldn't the primary name always be favored over the alternate?

utils/TableGen/AsmMatcherEmitter.cpp
2214

So this change permits multiple possible alternates? Is that needed, can it just check if !AltNames.empty()?

kparzysz edited edge metadata.Apr 22 2016, 2:53 PM

I think this is fixed already. There is a flag ShouldEmitMatchRegisterAltName in AsmParser now.

kparzysz resigned from this revision.Aug 4 2016, 12:39 PM
kparzysz removed a reviewer: kparzysz.
asb abandoned this revision.Aug 15 2016, 5:58 AM

Since this patch was submitted, a similar patch has been merged upstream (providing MatchRegisterAltName). I'm abandoning this revision in favour of the current upstream support for an equivalent feature.