This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Support vector-of-pointers in LLT
ClosedPublic

Authored by kristof.beyls on Apr 11 2017, 6:36 AM.

Details

Summary

This fixes PR32471.

As comment 10 on that bug report highlights
(https://bugs.llvm.org//show_bug.cgi?id=32471#c10), there are quite a
few different defendable design tradeoffs that could be made, including
not representing pointers at all in LLT.

I decided to go for representing vector-of-pointer as a concept in LLT,
while keeping the size of the LLT type 64 bits (this is an increase from
48 bits before). My rationale for keeping pointers explicit is that on
some targets probably it's very handy to have the distinction between
pointer and non-pointer (e.g. 68K has a different register bank for
pointers IIRC). If we keep a scalar pointer, it probably is easiest to
also have a vector-of-pointers to keep LLT relatively conceptually clean
and orthogonal, while we don't have a very strong reason to break that
orthogonality. Once we gain more experience on the use of LLT, we can
of course reconsider this direction.

Rejecting vector-of-pointer types in the IRTranslator is also an option
to avoid the crash reported in PR32471, but that is only a very
short-term solution; also needs quite a bit of code tweaks in places,
and is probably fragile. Therefore I didn't consider this the best
option.

Diff Detail

Event Timeline

kristof.beyls created this revision.Apr 11 2017, 6:36 AM
ab edited edge metadata.Apr 12 2017, 12:04 PM

You're right, this is probably the best path forward. A few nits inline

include/llvm/Support/LowLevelTypeImpl.h
45–46

Maybe:

return LLT{/*isPointer=*/false, /*isVector=*/false, /*NumElements=*/0, SizeInBits, /*AddressSpace=*/0};

Makes it a bit easier to read IMO

204

Maybe make this 16 bits to match the vector-of-pointer case? I'm a bit worried about it being different.

220

val -> Val (here and elsewhere)

233

Maybe add some static consts for the masks? You could then merge those with the comment explaining the layout.

252

Perhaps:

&& "Invalid type"
lib/Target/AArch64/AArch64RegisterBankInfo.cpp
489

Huh, how does an instruction survive this far with an invalid type?

test/CodeGen/AArch64/GlobalISel/arm64-fallback.ll
159

Immediately stale comment? ;)

update patch taking into account Ahmed's review feedback.

kristof.beyls marked 6 inline comments as done.Apr 13 2017, 6:44 AM

Thanks very much for the review Ahmed! I think I took all feedback into account in the new version of the patch. Please have another look.

include/llvm/Support/LowLevelTypeImpl.h
233

I experimented with a number of different ways to improve this.
The main issue here is that there isn't a way that is both portable and simple to have bitfield unions with full control on bitfield layout in C++ (at least not that I know off).
Apart from resorting to try and create a "union bitfield" ADT, I think either the original code, or the new code here are the most reasonable ways to encode this. I think these *Field descriptors in the new patch is slightly better than the original code I wrote with hard-coded masks etc., but only just.

lib/Target/AArch64/AArch64RegisterBankInfo.cpp
489

I see the following test failing here if this doesn't get changed: CodeGen/AArch64/GlobalISel/regbankselect-dbg-value.mir.
Before this patch, LLT::getSizeInBits() didn't assert on an invalid type, so the invalid type from that test case always seems to have ended up here.
IIRC, it was the following IR line that triggered this, more specifically the operand "debug-use _".

DBG_VALUE debug-use %0(s32), debug-use _, !7, !9, debug-location !10

I didn't investigate further.

ab added inline comments.Apr 13 2017, 9:23 AM
include/llvm/Support/LowLevelTypeImpl.h
233

The [2] are a bit weird, but it does make the bit magic more readable, thanks!

260

Not a big deal, but maybe use getMask() in the asserts too? (and make the message more generic, like 'AddressSpace too large')

lib/Target/AArch64/AArch64RegisterBankInfo.cpp
489

Ah, then I suspect this should ignore %noreg:

if (!MO.getReg())
  continue;

before trying to get the vreg type. Does that help?

540

This would probably also need to check that the vreg isn't 0.

kristof.beyls marked an inline comment as done.

Further tweaks based on Ahmed's feedback.

kristof.beyls marked 7 inline comments as done.Apr 13 2017, 12:48 PM
kristof.beyls added inline comments.
include/llvm/Support/LowLevelTypeImpl.h
233

Yeah, I agree the [2] makes it a bit weird.
I introduced a "typedef int BitFieldInfo[2];", so the [2] doesn't appear in lots of places to make the code read a bit more fluently.
I also renamed the BitFieldInfo variables to end with name "FieldInfo" rather than "Field", as they're not fields, but info about fields.

260

I intended to do that in the previous iteration of the patch, but forgot...
I decided to move this assert to the maskAndShift method, so that I didn't unnecessarily have to copy paste the check.

lib/Target/AArch64/AArch64RegisterBankInfo.cpp
489

Indeed, that was what was needed. Thanks for the pointer!

ab accepted this revision.Apr 14 2017, 10:39 AM

LGTM, thanks for taking care of this!

include/llvm/Support/LowLevelTypeImpl.h
280

Maybe move these up with the other public members?

This revision is now accepted and ready to land.Apr 14 2017, 10:39 AM
kristof.beyls marked 3 inline comments as done.

Move public methods to all be in the same location, as suggested by Ahmed, now that the implementation details are hidden more in private methods.

kristof.beyls marked 4 inline comments as done.Apr 18 2017, 1:10 AM
kristof.beyls closed this revision.Apr 19 2017, 8:26 AM

Committed in r300664