This is an archive of the discontinued LLVM Phabricator instance.

GlobalISel: Do not set observer of MachineIRBuilder in LegalizerHelper
ClosedPublic

Authored by arsenm on Aug 19 2020, 9:44 AM.

Details

Summary

This fixes double printing of insertion debug messages in the
legalizer.

Try to cleanup usage of observers. Currently the use of observers is
pretty hard to follow and it's not clear what is responsible for
them. Observers are referenced in 3 places:

  1. In the MachineFunction
  2. In the MachineIRBuilder
  3. In the LegalizerHelper

The observers in the MachineFunction and MachineIRBuilder are both
called only on insertions, and are redundant with each other. The
source of the double printing was the same observer was added to both
the MachineFunction, and the MachineIRBuilder. One of these references
needs to be removed. Arguably observers in general should be fully
removed from one or the other, but it may be useful to have a local
observer in the MachineIRBuilder that is not added to the function's
observers. Alternatively, the wrapper observer could manage a local
observer in one place.

The LegalizerHelper only ever calls the observer on changing/changed
instructions, and never insertions. Logically these are two different
types of observers, for changes and for insertions.

Additionally, some places used the GISelObserverWrapper when they only
needed a single observer they could use directly.

Setting the observer in the LegalizerHelper constructor is not
flexible enough if the LegalizerHelper is constructed anywhere outside
the one used by the legalizer. AMDGPU calls the LegalizerHelper in
RegBankSelect, and needs to use a local observer to apply the regbank
to newly created instructions. Currently it accomplishes this by
constructing a local MachineIRBuilder. I'm trying to move the
MachineIRBuilder to be owned/maintained by the RegBankSelect pass
itself, but the locally constructed LegalizerHelper would reset the
observer.

Mips also has a special case use of the LegalizationArtifactCombiner
in applyMappingImpl; I think we do need to run the artifact combiner
during RegBankSelect, but in a more consistent way outside of
applyMappingImpl.

Diff Detail

Event Timeline

arsenm created this revision.Aug 19 2020, 9:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 19 2020, 9:44 AM
arsenm requested review of this revision.Aug 19 2020, 9:44 AM

My thought on this Observer ownership is as follows (which I think I mentioned in another review).

  • Each pass will setup an observer(wrapper) and install it to the MF. The MF at this point has the reference to the observer, and the pass owns each observer as it decides what it needs to observe and how.
  • At the end of each pass, just reset the observer (there are RAII helpers for this).
  • Remove the observer in MachineIRBuilder (is there a need for this?).
  • No need to thread observer through APIs. Instead we get it through MF.getObserver().

Thoughts?

My thought on this Observer ownership is as follows (which I think I mentioned in another review).

  • Each pass will setup an observer(wrapper) and install it to the MF. The MF at this point has the reference to the observer, and the pass owns each observer as it decides what it needs to observe and how.
  • At the end of each pass, just reset the observer (there are RAII helpers for this).
  • Remove the observer in MachineIRBuilder (is there a need for this?).
  • No need to thread observer through APIs. Instead we get it through MF.getObserver().

Thoughts?

I'm mostly concerned with the wonky way we set register banks on new instructions with an observer. This isn't pass / function level, and is on an individual instruction we're legalizing.

My thought on this Observer ownership is as follows (which I think I mentioned in another review).

  • Each pass will setup an observer(wrapper) and install it to the MF. The MF at this point has the reference to the observer, and the pass owns each observer as it decides what it needs to observe and how.
  • At the end of each pass, just reset the observer (there are RAII helpers for this).
  • Remove the observer in MachineIRBuilder (is there a need for this?).
  • No need to thread observer through APIs. Instead we get it through MF.getObserver().

Thoughts?

I'm mostly concerned with the wonky way we set register banks on new instructions with an observer. This isn't pass / function level, and is on an individual instruction we're legalizing.

Sure, but what's the observer tracking in these cases (I admit we don't use the regbankselect pass in our out of tree backend and I may be missing the pain points here).

My thought on this Observer ownership is as follows (which I think I mentioned in another review).

  • Each pass will setup an observer(wrapper) and install it to the MF. The MF at this point has the reference to the observer, and the pass owns each observer as it decides what it needs to observe and how.
  • At the end of each pass, just reset the observer (there are RAII helpers for this).
  • Remove the observer in MachineIRBuilder (is there a need for this?).
  • No need to thread observer through APIs. Instead we get it through MF.getObserver().

Thoughts?

I'm mostly concerned with the wonky way we set register banks on new instructions with an observer. This isn't pass / function level, and is on an individual instruction we're legalizing.

Sure, but what's the observer tracking in these cases (I admit we don't use the regbankselect pass in our out of tree backend and I may be missing the pain points here).

It just grabs all the newly created / modified instructions, and then assigning register banks to the registers which haven't been set. This is manageable for the AMDGPU case where the individual opcodes don't really matter, but I would think other targets would struggle using it this way. I don't particularly like using the observer for this. It may be possible to have regbankselect iteratively work on the newly inserted instructions instead, but I haven't tried to do this.

aemerson accepted this revision.Jan 9 2021, 5:52 PM

LGTM. Having looked into this recently we should definitely from the MIRBuilder's observer.

This revision is now accepted and ready to land.Jan 9 2021, 5:52 PM