Checking when Register Allocation has been performed

Hi LLVM Devs,

I have some shared code that performs lowering operations that can occur before or after register allocation. When it is pre-RA I want to only use virtual registers for intermediate results, but post-RA I have to use only a very restricted set of physical registers.

Code generation using the restricted set is not as efficient as it is when I can use virtual registers. At the moment I have a clunky implementation for checking whether or not the register allocator has been run, and I am wondering if there is a “correct way” of checking whether the RA pass has been run? Some part of the register info API that I have missed perhaps?

Thanks,

MartinO

Maybe MF.getProperties().hasProperty(MachineFunctionProperties::Property::NoVRegs))?

Thanks Craig,

Is asking if the MF has the NoVRegs property okay? My clunky hack does something similar I must admit, currently I use ‘bool isPostRA = (MF.getRegInfo().getNumVirtRegs() == 0);’ and your suggestion is semantically very similar, though with a more official stamp J

All the best,

MartinO

Please don’t rely on this for checking whether regalloc was run: You can have functions without vregs pre-RA[1].

We don’t need or should track state such as pre/post-RA as part of the function. Instead it really is a property of where a pass was scheduled, so the pass should know and not the function.

I’d recommend simply creating a pre-RA and a post-RA pass instead of scheduling the same pass twice. (Of course you can share most of the pass implementation if they turn out to be similar).

  • Matthias

[1]: While currently we do not set the NoVRrgs flag pre-ra even if there are no vregs used, when loading a .mir file for example the flag is computed from scratch and will be set.

Thanks Matthias,

I have both a pre-RA and a post-RA scheduler, and I had thought that I could track “has RA happened?” by setting a flag in my pre-RA scheduler as it completes - my suspicion (which you have confirmed) was that “#vregs == 0” was not a safe assumption. What I cannot be sure of, is what passes execute after my pre-RA scheduler but before RA, and what passes execute after RA but before my post-RA scheduler since this is largely target-independent. If any of those passes trigger a custom lowering action (frame setup for example), and it requires additional scratch registers, then my code generation strategy needs to change. As it happens, I know that frame lowering always occurs post-RA so that is not a real example, but is it possible that another pass between pre-RA and post-RA scheduling could trigger lowering actions? If not, then setting a flag in my pre-RA scheduler will solve the problem perfectly.

All the best,

MartinO

Do you have a specific callback in TargetInstrInfo or similar in mind? I would expect them to either be used pre-ra or post-ra but not both...

- Matthias

Hi Matthias,

I suspect I am more worried than concerned, meaning that I accept that such calls “might be” possible, but I am also currently aware of none. But because I have no control (other than source editing) over the sequence of passes that occur between “pre-RA” scheduling and “post-RA” scheduling, I guess my concern is about being 100% sure about when RA happens.

I have not observed any current passes (other than frame lowering) that can cause lowering to occur between the two scheduling passes. I am quite happy to handle this with a flag which at the end of my “pre-RA” pass, assumes that RA is run. Worst case, slightly less efficient code. If there was something in TII, my preference is simple: ‘bool isPreRA() const’ and ‘bool isPostRA() const’, or something along those lines; not sure it would be appropriate to TII though, perhaps “MachineFunction”? Or even in the pass manager interface?

All the best,

MartinO