This is an archive of the discontinued LLVM Phabricator instance.

MachineFunction: Remove AllVRegsAllocated property
AbandonedPublic

Authored by MatzeB on Jul 22 2016, 8:05 PM.

Details

Summary

Originally I wanted to write some MIRParser code to automatically
determine the correct value for AllVRegsAllocated. Then I realized that
it is equivalent to MachineRegisterInfo::getNumVirtRegs() == 0 so there
is no need to track it in a separate property, we can just assert on the
presence of virtregs instead.

It still catches invalid pass usage, is less code and avoids a line in every .mir file.

Diff Detail

Repository
rL LLVM

Event Timeline

MatzeB updated this revision to Diff 65209.Jul 22 2016, 8:05 PM
MatzeB retitled this revision from to MachineFunction: Remove AllVRegsAllocated property.
MatzeB updated this object.
MatzeB added reviewers: dschuff, qcolombet, hfinkel.
MatzeB set the repository for this revision to rL LLVM.
MatzeB added a subscriber: llvm-commits.
dschuff edited edge metadata.Jul 25 2016, 9:19 AM

Hi Matthias,
This sort of idea (i.e. essentially what you are proposing with this patch) is what we started with, when we began thinking of how to make more existing MI passes handle virtual registers and/or ensure that the right passes are excluded for WebAssembly. @qcolombet and some others really wanted to have something stronger, clearer to readers, and more declarative and/or structural than asserts to ensure there was no confusion. This is in fact the reason that MachineFunctionProperties was invented (the fact that it's now used for isSSA and tracksLiveness was more of a "because it's there" kind of thing).

I would still be amenable to this kind of approach but I'd want Quentin's input first, and we should think a bit about where we might take this in the future either way.
I wouldn't mind helping out either way (and I know I still owe Quentin a cleanup in PEI anyway).

Hi Matthias,
This sort of idea (i.e. essentially what you are proposing with this patch) is what we started with, when we began thinking of how to make more existing MI passes handle virtual registers and/or ensure that the right passes are excluded for WebAssembly. @qcolombet and some others really wanted to have something stronger, clearer to readers, and more declarative and/or structural than asserts to ensure there was no confusion. This is in fact the reason that MachineFunctionProperties was invented (the fact that it's now used for isSSA and tracksLiveness was more of a "because it's there" kind of thing).

I would still be amenable to this kind of approach but I'd want Quentin's input first, and we should think a bit about where we might take this in the future either way.
I wouldn't mind helping out either way (and I know I still owe Quentin a cleanup in PEI anyway).

I did not see what getRequiredProperties() adds over a simple assert, so I went for that in my patch. But that's not my main issue.

My main issue with the current code is that the information in the AllVRegsAllocated property is redundant. So at the very least we should find a way that we do not need to "manually" maintain the AllVRegsAllocated flag.

The AllVRegsAllocated property is a convenient way of determining whether the code runs after register allocation or not. It is possible for post-RA code to temporarily have virtual registers (for example in frame lowering), so just counting the number of virtual registers may not be accurate.

The AllVRegsAllocated property is a convenient way of determining whether the code runs after register allocation or not. It is possible for post-RA code to temporarily have virtual registers (for example in frame lowering), so just counting the number of virtual registers may not be accurate.

Sure passes can temporarily use virtual registers but in between passes there is no reason why virtual registers exist.

On the other hand I would find it very troubling if "AllVRegsAllocated" would just have an abstract meaning of a pass that runs after the register allocator. Why would is be important to run a certain place in the pass pipeline? It is important that the machine function has certain properties like no virtual registers used or no phi instructions being present. An abstract property of being run behind the register allocator seems less useful to me than a concrete property about the machine function.

On the other hand I would find it very troubling if "AllVRegsAllocated" would just have an abstract meaning of a pass that runs after the register allocator. Why would is be important to run a certain place in the pass pipeline?

For a pass, yes, altough there are passes that can run in both scenarios (MachineLICM, IIRC). What I was thinking about were utility routines that can be called at various times. In our internal Hexagon repo we have to maintain super-register liveness via implicit operands. We have a function that updates those and it's called from places like, for example, loadRegFromStackSlot. This function does not know where in the optimization pipleline it was called from. Checking whether the destination register is physical or virtual is not sufficient, because we really only want to do this after RA has completed. Once we get the subregister liveness tracking enabled, this problem will go away, but in general it shows that there can be cases whether the pre- vs post-RA status may be useful to know.

Btw, if you really want to remove this property, that's fine. We will just keep it around in our internal repo until we no longer need it. I'm just indicating that this property may be useful. Ultimately, if it's removed now and the need for it arises later, it may be brought back.

On the other hand I would find it very troubling if "AllVRegsAllocated" would just have an abstract meaning of a pass that runs after the register allocator. Why would is be important to run a certain place in the pass pipeline?

For a pass, yes, altough there are passes that can run in both scenarios (MachineLICM, IIRC). What I was thinking about were utility routines that can be called at various times. In our internal Hexagon repo we have to maintain super-register liveness via implicit operands. We have a function that updates those and it's called from places like, for example, loadRegFromStackSlot. This function does not know where in the optimization pipleline it was called from. Checking whether the destination register is physical or virtual is not sufficient, because we really only want to do this after RA has completed. Once we get the subregister liveness tracking enabled, this problem will go away, but in general it shows that there can be cases whether the pre- vs post-RA status may be useful to know.

I think if you look think about .mir files the it becomes clear why an attribute on a machine function is strange:

file1.mir:
...
name: foo
AllVRegsAllocated: true
body: |
  bb.0:
    RETQ
---
file2.mir
...
name: foo
AllVRegsAllocated: false
body: |
  bb.0:
    RETQ
---

Today those are two different functions, but why is that difference meaningful? Also typing the "AllVRegsAllocated: " seems unnecessary.

On the other hand I would find it very troubling if "AllVRegsAllocated" would just have an abstract meaning of a pass that runs after the register allocator. Why would is be important to run a certain place in the pass pipeline?

For a pass, yes, altough there are passes that can run in both scenarios (MachineLICM, IIRC). What I was thinking about were utility routines that can be called at various times. In our internal Hexagon repo we have to maintain super-register liveness via implicit operands. We have a function that updates those and it's called from places like, for example, loadRegFromStackSlot. This function does not know where in the optimization pipleline it was called from. Checking whether the destination register is physical or virtual is not sufficient, because we really only want to do this after RA has completed.

I find this a minor problem to solve if the function works fine before RA and is just unnecessary. There are so many other function preconditions that we do not explicitely test or that may not be possible to test. I'm not saying checking preconditions isn't useful but I don't find it a convincing argument in this case to keep the AllVRegsAllocated property around.

Yes, it is strange. Whether the RA has already run or not is not really a state of the function, I agree with that. I'm not opposed to this change, I'm just bringing up a potential consideration, that's all.