This is an archive of the discontinued LLVM Phabricator instance.

[TableGen][SelectionDAG] Improve efficiency of encoding negative immediates for isel's CheckInteger opcode.
ClosedPublic

Authored by craig.topper on Feb 8 2021, 9:52 PM.

Details

Summary

CheckInteger uses an int64_t encoded using a variable width encoding
that is optimized for encoding a number with a lot of leading zeros.
Negative numbers have no leading zeros so use the largest encoding
requiring 9 bytes.

I believe its most like we want to check for positive and negative
numbers near 0. -1 is quite common due to its use in the 'not'
idiom.

To optimize for this, we can borrow an idea from the bitcode format
and move the sign bit to bit 0 with the magnitude stored in the
upper bits. This will drastically increase the number of leading
zeros for small magnitudes. Then we can run this value through
VBR encoding.

This gives a small reduction in the table size on all in tree
targets except VE where size increased by about 300 bytes due
to intrinsic ids now requiring 3 bytes instead of 2. Since the
intrinsic enum space is shared by all targets this an unfortunate
consquence of where VE is currently located in the range.

Diff Detail

Event Timeline

craig.topper created this revision.Feb 8 2021, 9:52 PM
craig.topper requested review of this revision.Feb 8 2021, 9:52 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 8 2021, 9:52 PM

This gives a small reduction in the table size on all in tree targets except VE where size increased by about 300 bytes due to intrinsic ids now requiring 3 bytes instead of 2. Since the intrinsic enum space is shared by all targets this an unfortunate consquence of where VE is currently located in the range.

I'm not very familiar with this - what options do we have for altering the range to help avoid the VE bloat?

This gives a small reduction in the table size on all in tree targets except VE where size increased by about 300 bytes due to intrinsic ids now requiring 3 bytes instead of 2. Since the intrinsic enum space is shared by all targets this an unfortunate consquence of where VE is currently located in the range.

I'm not very familiar with this - what options do we have for altering the range to help avoid the VE bloat?

Pretty sure the intrinsic IDs are just alphabetized and they are all prefixed by the target name. So I think it's just a function of how many target names come before "VE" and how many intrinsics those targets have.

I've no objection to this but I don't know enough to approve - @Paul-C-Anagnostopoulos ?

I'm only slightly more familiar with it, but it looks fine to me.

I take it that C++ doesn't have a standard rotate function?

I'm only slightly more familiar with it, but it looks fine to me.

I take it that C++ doesn't have a standard rotate function?

I don't think there's a standardized rotate. clang has __builtin_rotateright64. MSVC has its own rotate intrinsics. gcc has some intrinsics in ia32intrin.h. None of them are portable.

RKSimon accepted this revision.Feb 18 2021, 1:47 AM

OK, there seems to be no objections. LGTM.

This revision is now accepted and ready to land.Feb 18 2021, 1:47 AM
This revision was landed with ongoing or failed builds.Feb 18 2021, 8:53 AM
This revision was automatically updated to reflect the committed changes.