This is an archive of the discontinued LLVM Phabricator instance.

[AArch64][SVE] Asm: Add SVE (Z) Register definitions and parsing support
ClosedPublic

Authored by sdesmalen on Oct 19 2017, 5:02 AM.

Details

Summary

Patch [3/5] in a series to add assembler/disassembler support for AArch64 SVE unpredicated ADD/SUB instructions.

To summarise, this patch adds:

  • SVE register definitions
  • Methods to parse SVE register operands
  • Methods to print SVE register operands
  • RegKind SVEDataVector to distinguish it from other data types like scalar register or Neon vector.
  • k_SVEDataRegister and SVEDataRegOp to describe SVE registers (which will be extended by further patches with e.g. ElementWidth and the shift-extend type).

Diff Detail

Repository
rL LLVM

Event Timeline

sdesmalen created this revision.Oct 19 2017, 5:02 AM
fhahn added a subscriber: fhahn.Oct 19 2017, 9:35 AM
sdesmalen updated this revision to Diff 119663.Oct 20 2017, 8:41 AM
rengolin added inline comments.Oct 23 2017, 2:33 PM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
411 ↗(On Diff #119663)

I'm assuming this will change back, as you're making this an actual k_Register with a different type, so I'll stop reviewing for now.

sdesmalen edited the summary of this revision. (Show Details)

Minor refactoring and updated description of the patch.

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
411 ↗(On Diff #119663)

Not sure I fully understand what you mean with 'changing back' into a k_Register, but to clarify my change, I made it a separate k_SVERegister on purpose since it will be extended in future patches with attributes like shift/extend amount and element width.

rengolin edited edge metadata.Oct 24 2017, 10:25 AM

Overall, this looks pretty straightforward to me.

Apart from the few comments, I think the series is good up to here. Thanks!

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
844 ↗(On Diff #120090)

To @javed.absar comment in D39088, this may be simplified by having all done at the RegKind level, instead of having multiple types of registers on top of multiple types of SVE vectors.

1833 ↗(On Diff #120090)

move this case together with k_Register

411 ↗(On Diff #119663)

The other patch confused me by using k_SVERegister alike. Now I see that you're moving things down the line. Np.

Adding a few AArch64 folks, to make sure we get enough eyes on this, thus avoiding silly problems in the future, if we miss anything.

sdesmalen updated this revision to Diff 120244.Oct 25 2017, 7:01 AM

Merged case 'k_SVERegister' with 'k_Register' in AArch64Operand::print()

sdesmalen marked an inline comment as done.Oct 25 2017, 7:02 AM

Adding a few AArch64 folks, to make sure we get enough eyes on this, thus avoiding silly problems in the future, if we miss anything.

Thanks Renato!

rengolin added inline comments.Oct 25 2017, 7:55 AM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
1953 ↗(On Diff #120244)

Isn't this creating a new temporary string just for the comparison?

You can pass by reference, or depending on how the future usage will be, use a StringRef instead (this can be done later).

sdesmalen updated this revision to Diff 120415.Oct 26 2017, 7:22 AM

Replaced std::string by StringRef (isSVEVectorRegister)

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
1953 ↗(On Diff #120244)

You're right that this should be a StringRef, I'll fix that, thanks.

fhahn added inline comments.Oct 31 2017, 7:07 AM
lib/Target/AArch64/AArch64RegisterInfo.td
37 ↗(On Diff #120415)

Maybe add a quick note WHY it should never be used?

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
85 ↗(On Diff #120415)

Will this function also be used to parse SVE predicate registers? If not, it's probably clearer to use SVEDataVectorRegister in the name?

187 ↗(On Diff #120415)

Will we have a separate kind for predicate registers? Or should this be SVEDataRegister too?

274 ↗(On Diff #120415)

SVEDataRegOp? I think if we go with SVEDataRegister and SVEPredicateRegister, we should be consistent.

3270 ↗(On Diff #120415)

where is this used?

sdesmalen updated this revision to Diff 121002.Oct 31 2017, 9:51 AM
sdesmalen marked 4 inline comments as done.
sdesmalen edited the summary of this revision. (Show Details)
  • Updated comment for zsub_hi
  • Removed isMatchingOrAlias() because it was not used (will be part of a future patch)
  • Renamed k_SVERegister to k_SVEDataRegister
  • Renamed SVERegOp to SVEDataRegOp
sdesmalen added inline comments.Oct 31 2017, 9:53 AM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
187 ↗(On Diff #120415)

There will be a separate SVEPredicateRegister as well.

3270 ↗(On Diff #120415)

Not anywhere in this patch it seems, it is part of a future patch. I have removed it in this one.

Apart from the one comment about identifying the register as SVE specific, the patch looks good.

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
844 ↗(On Diff #120090)

I'm confused now. Why do we need both ways of identifying an SVE register?

I can't see anything in this patch that needs k_SVEDataRegister. All uses of it could very well be together with k_Register and have an additional check for RegKind::SVEDataVector.

sdesmalen added inline comments.Nov 2 2017, 2:22 AM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
844 ↗(On Diff #120090)

Okay, I understand the confusion, and its mostly caused by this patch not containing the complete context of how future patches extend SVEDataRegister. I'll try and provide some more context in my future patches, but let me describe this particular instance here:

k_SVEDataRegister will be extended with more details such as 'ElementWidth' and details about sign/shift extension. In contrast, k_Register and Reg.Kind == RegKind::SVEDataVector describe a vector register as a 'bare' register. At this stage, it is functionally equivalent to using k_Register, so this is more a non-functional change for now to prepare for future patches.

rengolin added inline comments.Nov 2 2017, 3:23 AM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
844 ↗(On Diff #120090)

Right, now I get it. SVEDataRegOp has an RegOp inside it, which composes the structure inside the union.

This is a little confusing, and I'd have just extended RegOp instead. This is an AArch64-only structure/union, and AArch64 registers now are a little more complicated, and I can't see why changing RegOp would break anything, if you just extend it. Something like:

struct RegOp {
  unsigned RegNum;
  RegKind Kind;
  int ElementWidth;
};

then...

Width = isSVEVectorReg(Reg) ? Reg.RegOp.ElementWidth : 1;

current uses of RegOp will not access the new elements.

sdesmalen added inline comments.Nov 2 2017, 5:05 AM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
844 ↗(On Diff #120090)

ElementWidth and any Sign/Shift extend are not necessarily things that apply to any RegOp and is specific to the kind of operand you're parsing, so fiddling both scalar, vector and sign/shift-extend specific information into a generic 'RegOp' even when it does not apply to the operand seems conceptually a bit odd to me. I wonder if it would be better to have this discussion when adding support for element-width/shift-extend, as we then have a better picture what things look like?

rengolin added inline comments.Nov 2 2017, 7:01 AM
lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
844 ↗(On Diff #120090)

Well, you're already adding ElementWidth now, signs and shifts will only complement, not change the idea.

You have added Kind to RegOp, which defines what it is, not only if it's a vector or not. This already makes RegOp a bucket for multiple types of registers. But then you create an SVERegOp which is another bucket, for a slightly different type of vector. Now we have three vector types and two operand types.

We either have one, with a type and extra fields that only make sense to specific types, or we have three operand types, one for each type of register we have.

sdesmalen updated this revision to Diff 121484.Nov 3 2017, 8:17 AM

Removed SVEDataRegOp and merged contents into RegOp (which is now further distinguished by RegKind).

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
844 ↗(On Diff #120090)

Fair enough, I tried this out and found that it would also simplify the code further down the line. Please see the updated patch for the change.

Two nits, and I'm happy. :)

Welcoming any final comments from other reviewers.

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
403 ↗(On Diff #121484)

I wouldn't change this, at least not in this patch. :)

1749 ↗(On Diff #121484)

whitespace change on separate patches.

fhahn added a comment.Nov 3 2017, 8:45 AM

Thanks for updating Sander. This patch uses SVEVector in some places. Could you check/confirm that those shouldn't be SVEDataVector?

Besides that, it looks good to me.

sdesmalen updated this revision to Diff 121493.Nov 3 2017, 9:38 AM

renamed all occurrences of ‘SVEVector’ into ‘SVEDataVector’

sdesmalen updated this revision to Diff 121733.Nov 6 2017, 7:30 AM
sdesmalen marked an inline comment as done.
  • Removed newline
  • Reverted assert -> llvm_unreachable change.
sdesmalen marked an inline comment as done.Nov 6 2017, 7:31 AM
rengolin accepted this revision.Nov 6 2017, 9:26 AM

LGTM, without the extra whitespace change. Thanks!

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
1748 ↗(On Diff #121733)

oops, still whitespace changes... :)

I always check the git diff locally before sending, as those pop up quite often.

This revision is now accepted and ready to land.Nov 6 2017, 9:26 AM
sdesmalen updated this revision to Diff 121877.Nov 7 2017, 5:27 AM

Removed newline.

sdesmalen marked an inline comment as done.Nov 7 2017, 5:28 AM
This revision was automatically updated to reflect the committed changes.