This is an archive of the discontinued LLVM Phabricator instance.

[globalisel] Initialize RegisterBanks with static data. Part 1 of 2.
ClosedPublic

Authored by dsanders on Dec 15 2016, 7:31 AM.

Details

Summary

This patch is the first step in refactoring the RegisterBank to a static
table. This patch marks addRegBankCoverage() as unreachable and requires
GlobalISel implementations to rewrite this call into setRegBankMaxSize()
and setRegBankCoverage() calls. addRegBankCoverage() emits all the information
you need to do this rewrite just before calling llvm_unreachable().

The next patch will drop addRegBankCoverage() and move the data to a
static table.

Event Timeline

dsanders updated this revision to Diff 81579.Dec 15 2016, 7:31 AM
dsanders retitled this revision from to [globalisel] Initialize RegisterBanks with static data. Part 1 of 2..
dsanders updated this object.
dsanders added reviewers: qcolombet, t.p.northover, ab, rovka.
dsanders added a subscriber: llvm-commits.
rovka accepted this revision.Dec 16 2016, 3:55 AM
rovka edited edge metadata.

I like the direction where this is going.
LGTM, but feel free to wait for more feedback from the others before committing this series.

This revision is now accepted and ready to land.Dec 16 2016, 3:55 AM

Thanks. I'll update this patch to cover ARM too (since the addRegBankCoverage change will break it) and get an LGTM for that too before committing

qcolombet requested changes to this revision.Dec 19 2016, 5:29 PM
qcolombet edited edge metadata.

Hi Daniel,

Unless you can find a more elegant way for the intermediate step, I would push the change from BitSet to uint32_t* as part of the TableGen.
That being said, I think we could use intermediate steps:

  1. Provide methods that perform the current add coverage logic, while producing the result in a dynamically allocated uint32_t
  2. Gradually switch the dynamic array to static ones
  3. Generate the static array with TableGen

Step #2 and #3 could be merged.

Cheers,
-Quentin

include/llvm/CodeGen/GlobalISel/RegisterBank.h
38 ↗(On Diff #81579)

What's the use for this indirection?

include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
426

What does CoveredClasses represent?

lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
95

Why not directly use uint32_t *?
In particular, if we have target with more than 64 classes the API falls apart.

lib/Target/AArch64/AArch64RegisterBankInfo.cpp
183

I think I would rather have the change in representation be part of the TableGen change, because the intermediate step is painful to read and write IMO.

223

Indeed, I don't want to check if this is correct :S

This revision now requires changes to proceed.Dec 19 2016, 5:29 PM
dsanders updated this revision to Diff 82068.Dec 20 2016, 12:33 AM
dsanders edited edge metadata.

Rebase and include ARM support (this change would otherwise break the recently-added ARM GlobalISel).

Hi Daniel,

Unless you can find a more elegant way for the intermediate step, I would push the change from BitSet to uint32_t* as part of the TableGen.

(I assume you mean BitVector rather than BitSet)

The problem with this is that BitVector needs to know its size in advance and this information is obtained from the TRI which doesn't exist at initialization-time.

That being said, I think we could use intermediate steps:

  1. Provide methods that perform the current add coverage logic, while producing the result in a dynamically allocated uint32_t
  2. Gradually switch the dynamic array to static ones
  3. Generate the static array with TableGen

Step #2 and #3 could be merged.

Cheers,
-Quentin

That was my first approach but I was asked to create the static tables in advance and follow it with an NFC tablegen patch.

include/llvm/CodeGen/GlobalISel/RegisterBank.h
38 ↗(On Diff #81579)

Tablegen is going to generate a big table of static register bank data and DataTy represents an element of that table. The elements appear in this patch (see GPRData) and the <BankName>Data members are merged into a single table in D27808.

Eventually, RegisterBank::Data will just be a reference to that static table. I was going to do it in the tablegen patch but there's no technical reason I can't make that change in this patch if you prefer.

include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
426

It's the classes that addRegBankCoverage() used to add to the register bank.

lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
95

I wasn't expecting to hit this before the tablegen patch landed and there was no longer a need for an API. However, the ARM target now has GlobalISel and has just under 100 classes so I hit this yesterday while rebasing. It's uint32_t* now.

lib/Target/AArch64/AArch64RegisterBankInfo.cpp
183

I think I'm getting mutually exclusive comments. On the one hand I'm being asked to refactor up front so that the tablegen patch is NFC but on the other hand I'm being asked to defer that refactoring to the tablegen patch.

I agree that this is ugly but it's not needed for long and there are ways to avoid maintaining it manually. If you call addRegBankCoverage() then it will dump the classes before aborting and it's a simple transformation to convert the class list to this expression. I'm happy to maintain the patch series until they're all ready and commit them in quick succession if that helps.

@rovka: I had to rework setRegBankCoverage() to account for the number of register classes in ARM (~100). Are you still ok with the latest version?

rovka added a comment.Dec 20 2016, 6:28 AM

Hi,

Still LGTM, thanks!
For the record, until you can generate everything with TableGen, it's fine by me to handle only a subset of the ARM register classes (i.e. those that we have asserts for in ARMRegisterBankInfo). I can manually add the others as I run into them. I guess now you've already done all the work, but if it ever gets in your way later on feel free to get rid of the clutter.

The problem with this is that BitVector needs to know its size in advance and this information is obtained from the TRI which doesn't exist at initialization-time.

IIRC, we get this information statically when we do the generation of TargetRegisterInfo. I suspect we would need to refactor that code to reuse it here, but in the end, everything should be static and this finishInit should not be here.

That was my first approach but I was asked to create the static tables in advance and follow it with an NFC tablegen patch.

I believe the NFC approach is not incompatible with a change of representation in the same patch.

Unless you can find a more elegant way for the intermediate step, I would push the change from BitSet to uint32_t* as part of the TableGen.

! In D27807#628051, @qcolombet wrote:
The problem with this is that BitVector needs to know its size in advance and this information is obtained from the TRI which doesn't exist at initialization-time.

IIRC, we get this information statically when we do the generation of TargetRegisterInfo. I suspect we would need to refactor that code to reuse it here, but in the end, everything should be static and this finishInit should not be here.

Yes, the information is available to tablegen but we don't have our tablegen pass until later in the patch series so we can't make use of that just yet. At the moment, the number of classes is only available to the backend after <Target>Subtarget has been constructed which is after the point that the table is initialized.

Would you be ok with this patch if I eliminate the finishInit() function in D27338 and make sure they are committed close together so we're not in this halfway state for long?

That being said, I think we could use intermediate steps:

  1. Provide methods that perform the current add coverage logic, while producing the result in a dynamically allocated uint32_t
  2. Gradually switch the dynamic array to static ones
  3. Generate the static array with TableGen

Step #2 and #3 could be merged.

Cheers, -Quentin

That was my first approach but I was asked to create the static tables in advance and follow it with an NFC tablegen patch.

I believe the NFC approach is not incompatible with a change of representation in the same patch.

Sorry, I've been confusing here by mis-using 'NFC'. I meant that the plan was to re-factor into the desired implementation and then have a tablegen patch emit the same implementation.

For reference, the plan Ahmed suggested on D27338 was:

  • introduce an intermediate class, 'AArch64GenRegisterBankInfo'
  • make the RegBanks array a member
  • replace initGeneratedInfo with the ctor
  • remove the AlreadyInit logic
  • consolidate the now-redundant GET_REGBANK_*IFACE* into a single GET_REGBANK_IMPLEMENTATION to avoid having everything in the header

My current patch series isn't completely in line with this at the moment (in particular AlreadyInit hasn't been removed yet) but this is the general direction I've been aiming for.

If we do switch to your plan, how would you construct the BitVectors for ARM. ARM has ~100 classes so I'd add BitVector(unsigned Size, uint32_t *Bits) but that brings us back to converting the BitVectors to uint32_t* before we tablegen the table.

dsanders updated this revision to Diff 83599.Jan 9 2017, 2:19 AM
dsanders edited edge metadata.

Updated to account for comments on later patches in the series.

RegisterBank::DataTy has been removed in favour of passing each value to
setRegBankData() and setRegBankCoverage(). RegisterBank::DataTy would have been
removed in D27809 in order to move to a similar initialization style as
TargetRegisterClass so it makes sense to not add it.

D27809 also requested that the finishInit() call that was added be removed.
This call was needed to use the TRI in the initialization of a BitVector but is
not needed by the end of the patch series. I've therefore hardcoded the number
of register classes as 200 and this will be changed in D27338 to be the number
of register classes defined for the target. This shouldn't be a problem since
D27338 already needs to be commited shortly after this patch to minimize the
maintenance burden of the register class tables.

Added the missing printing code to addRegBankCoverage().

This hasn't been rebased to trunk yet.

qcolombet accepted this revision.Jan 9 2017, 1:48 PM
qcolombet edited edge metadata.

Hi Daniel,

LGTM with a couple of nitpicks.

No need for another room of review.

Cheers,
-Quentin

include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
428

Could we merge these two methods?

Also, add a comment explaining the format of CoveredClasses and the effect on RegBank with ID. E.g., \post getRegBank(\p ID).getSize() == Size, etc.

lib/CodeGen/GlobalISel/RegisterBank.cpp
27

Maybe keep the assert but with >=?

lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
187

Shouldn't we just delete this API instead?

This revision is now accepted and ready to land.Jan 9 2017, 1:48 PM
dsanders added inline comments.Jan 9 2017, 2:08 PM
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
428

Sure. The next patch merges them at the moment but I can move that bit to this patch

lib/CodeGen/GlobalISel/RegisterBank.cpp
27

Ok

lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
187

That's done in the next patch. It's been kept in this patch so that any targets that aren't migrated by this patch yet will dump the information needed to migrate instead of just failing to link.

qcolombet added inline comments.Jan 9 2017, 2:25 PM
lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
187

Let's just squash the two part of this patch.
I expect that people would look at the commit list to understand why this method disappeared. Just add that information in the commit message.

dsanders added inline comments.Jan 9 2017, 2:32 PM
lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
187

Ok. Other targets won't be able to apply a few s///'s to the dump to create the tables like I did but I suppose we can always point them at this version of the patch if we need to.

dsanders updated this revision to Diff 84117.Jan 12 2017, 7:05 AM
dsanders edited edge metadata.

Refresh before commit.

I regenerated the tables from the current trunk to be sure they were correct
and the ARM ones have changed upstream during the review.

dsanders closed this revision.Jan 12 2017, 7:55 AM

Squashed with D27808 in rL291768