This is an archive of the discontinued LLVM Phabricator instance.

WIP: RegBankSelect: Support some more complex part mappings
ClosedPublic

Authored by arsenm on Dec 21 2018, 1:49 AM.

Details

Reviewers
qcolombet
Summary

Sort of works, but still not entirely clear on what the point of RepairPt is in repairReg. Also currently leaves behind the original dest reg without a regbank

Diff Detail

Event Timeline

arsenm created this revision.Dec 21 2018, 1:49 AM

Hi Matt,

Thanks for pushing this forward.

The general direction looks fine to me. I would expect some changes in the cost modeling too though.

Cheers,
-Quentin

arsenm updated this revision to Diff 179463.Dec 24 2018, 3:26 AM

Cleanup a bit, fix greedy, and support vectors.

I have a few more partial patches to support preserving the original vector types (which I might have use for) and for irregularly sized breakdowns (which I don't). Introducing more instructions makes the current handling for multiple insert points more complicated (and there are no tests in tree which actually hit this, so I still don't understand what it would mean)

qcolombet added inline comments.Jan 7 2019, 2:26 PM
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
628

I feel we miss a register bank in that prototype (what you'd referenced as CurBank).

lib/CodeGen/GlobalISel/RegBankSelect.cpp
139

Could you add a message in the assert (e.g., we need as many new regs as break downs.

205

I wonder if we should make this part target specific with a default implementation being what you added.
Indeed, I would expect some target would have fancy instructions to do it in one go ala REG_SEQUENCE.

208

Yes, if we repair a physical register. In practice I've never seen that happen.

lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
501

We could return true instead of asserting.
Make sure to document in the doxygen the pre-condition if you want to stick with the assert.

arsenm updated this revision to Diff 180616.Jan 7 2019, 10:49 PM
arsenm marked 3 inline comments as done.
arsenm added inline comments.
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
628

I had this initially, but then discovered it will always be null. The array of banks is present in ValMapping

lib/CodeGen/GlobalISel/RegBankSelect.cpp
208

An example would help, since handling this is what makes the more general handling more annoying

qcolombet added inline comments.Jan 8 2019, 10:42 AM
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
628

The banks we have in the value mapping are the one we want to use (destination), not the one the value originates from (source), right?

then discovered it will always be null.

Are you just patching up the destination in your case (i.e., things that are not assigned to any regbank yet)?

I would have expected this information to be here and useful in cases like this:
orig: dest = op src
candidate mapping: dest.low = op.low src.low; dest.high = op.high src.high
Thus src has a regbank at this point, but dest doesn't.

Although I am not a fan of such approach, we could take the convention for now that curbank == null means we are patching a definition and curbank != null means we are patching a source.
E.g.,

  1. dest = op => dest.low = op.low ; dest.high = op.high

vs.

  1. = op src => = op.low src.low ; = op.high src.high

In #1 dest's regbank would be nullptr, in #2 src's regbank would be !nullptr.

lib/CodeGen/GlobalISel/RegBankSelect.cpp
208

Phabricator being great, I don't actually see what this comment was referring too.
I believe it has to do with several insertion point and the answer is I don't have any example either. We could construct fake ones, but I avoided that so far to not be in a situation where we have live code just because our crazy mind can produce such case. I.e., I would rather have something realistic or ensure those never happen with some machine verifier checks.

Having a report_fatal_error would be fine as we figure out a way to build such real example.

arsenm marked an inline comment as done.Jan 8 2019, 11:03 PM
arsenm added inline comments.
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
628

I based this off only seeing null, plus the above assert:

assert((!IsSameNumOfValues || CurRegBank) && "We should not have to repair");
arsenm updated this revision to Diff 180793.Jan 8 2019, 11:08 PM

Error on multiple insertion points

qcolombet added inline comments.Jan 14 2019, 10:50 AM
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
628

That's not exactly what the intent of the assert was.

// If MO does not have a register bank, we should have just been
// able to set one unless we have to break the value down.
assert((!IsSameNumOfValues || CurRegBank) && "We should not have to repair");

This should be refined such that CurRegBank == nullptr is allowed only if MO is a definition.
Essentially what this assert does is making sure that the breakdown == 1 code path will have non-nullptr values.

arsenm marked an inline comment as done.Jan 17 2019, 1:58 AM
arsenm added inline comments.
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
628

I'm not sure I understand exactly what you're saying. For the AMDGPU usage, I don't there would be a case where the destination will have a bank assigned that will require splitting the source in this way, so maybe I'm just not seeing it.

arsenm updated this revision to Diff 182223.Jan 17 2019, 1:58 AM

Change assert, cleanup register splitting into helper function

qcolombet added inline comments.Jan 23 2019, 1:46 PM
include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
628

Yes, the definition should almost never have a regbank, I am thinking about a case where we would decide to split the source because the instruction becomes cheaper.

E.g.,

A <regbank1>= ...
= op A

Where op could be mapped like this:

# Mapping by default
= op A<regbank1> # cost 12
;;;
# Alternative mapping
= op.low A.low<anotherBank> # cost 1
= op.high A.high<anotherBank> # cost 1

In that case, to compute the cost of breaking down A, knowing that A is mapped on <regbank1> could change the cost. That's why I think we need a way to pass that information in the API. The default would be nullptr, because A may not have a regbank yet.

arsenm updated this revision to Diff 183188.Jan 23 2019, 2:56 PM

Pass CurBank to getBreakDownCost

arsenm updated this revision to Diff 183190.Jan 23 2019, 3:00 PM

Assert no CurBank on AMDGPU since I don't think it should be possible

qcolombet accepted this revision.Jan 24 2019, 1:53 PM

LGTM.

Thanks for your patience Matt!

This revision is now accepted and ready to land.Jan 24 2019, 1:53 PM
arsenm closed this revision.Jan 24 2019, 2:47 PM

r352123