This is an archive of the discontinued LLVM Phabricator instance.

[GISel]: Process new insts to legalize in the order they were created
AbandonedPublic

Authored by aditya_nandakumar on Sep 22 2017, 3:45 PM.

Details

Summary

Previously, we were legalizing new instructions in the order they were created (using the MIRBuilder). My previous patch to add a clean up combiner ended up chaining the order of how we process the instructions (in the worklist) from top down to bottom up.
While this shouldn't be an issue (legalization should only look at one instruction), there's some out of tree code that looks at other instructions as well, and this is breaking the legalization for that instruction.

This patch reverts the legalization processing order of newly created insts to how they were before the clean up combiner - but still cleans up artifacts.

Diff Detail

Event Timeline

kristof.beyls edited edge metadata.Oct 10 2017, 7:50 AM

While this shouldn't be an issue (legalization should only look at one instruction), there's some out of tree code that looks at other instructions as well, and this is breaking the legalization for that instruction.

I'm a bit confused by the above. Should we allow legalization to look at other instructions, or should we not?

lib/CodeGen/GlobalISel/Legalizer.cpp
55

I don't think I've seen the naming convention of ending type names with "Type" in the LLVM code base - but I also by far haven't looked at all the LLVM code.
Maybe "struct WorkList" would be better.

I find it unfortunate that we would need to create a custom container here for this single specific use case. Is there really not a pre-existing container that is good enough? My guess is that this WorkListType's advantage over a deque is only that it can check quickly if an element is present in the container. Is that really such a frequent operation that that must be fast, but removing that element if present doesn't have to be faster than deque.erase?

94

unordered_set could be used instead of set?

qcolombet edited edge metadata.Oct 10 2017, 9:29 AM

I'm a bit confused by the above. Should we allow legalization to look at other instructions, or should we not?

I believe we shouldn't allow to look at other instructions. I am guessing we need to do that to perform combines at legalization time and I think we shouldn't go in that direction. I would rather have the combines be a separate pass. I.e., we are not taking the same approach as SelectionDAG here.

Aditya, is this really needed to perform legalization?

I'm a bit confused by the above. Should we allow legalization to look at other instructions, or should we not?

I believe we shouldn't allow to look at other instructions. I am guessing we need to do that to perform combines at legalization time and I think we shouldn't go in that direction. I would rather have the combines be a separate pass. I.e., we are not taking the same approach as SelectionDAG here.

Aditya, is this really needed to perform legalization?

Agree, it seems strange for legalisation to need to do this, given that defs could be conceivably hoisted outside of the user's block.

If top-down processing is really necessary, i.e. legalisation really does need to inspect multiple instructions, then the current block iteration strategy will need changing anyway: we're currently doing a linear walk of the blocks when an RPO walk will be needed to ensure defs are processed first.

While this shouldn't be an issue (legalization should only look at one instruction), there's some out of tree code that looks at other instructions as well, and this is breaking the legalization for that instruction.

I'm a bit confused by the above. Should we allow legalization to look at other instructions, or should we not?

I might have not framed that sentence correctly. I meant to say I realized about the dependency on legalization order when I added the LegalizationCombiner. I also think that shouldn't be happening here. I was only trying to revert to the original order in this patch, but I agree that it's a dangerous path to go down.

lib/CodeGen/GlobalISel/Legalizer.cpp
55

Thanks for the naming convention tip. "struct Worklist" does sound better.
I wanted a SetVector's equivalent which lets me do push_back and pop_front . As you said, the advantage over just the deque is quickly lookup if an element already exists. That said, I haven't measured how critical this is or how frequently this operation occurs.

Regarding looking at multiple instructions, One of the use cases I see is something like this.
t = G_ICMP <pred> a, b
s = G_SELECT t, c, d
On targets where selects are not legal, and we want something like the SELECT_CC, we'd need to generate something similar to
CUSTOM_SELECT_CC a, b, c, d, <pred>. This would require looking at the more than the select.
Of course, we can create a select_cc just locally (compare with 0) and let the combiner deal with it later, but that seems wasteful.

volkan edited edge metadata.Nov 15 2017, 3:52 PM

I think this is no longer required, rL318210 fixed this problem.

aditya_nandakumar abandoned this revision.Nov 15 2017, 3:53 PM