llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.76k stars 11.89k forks source link

Freezing Physical Regs in Machine Frame Info Removes the Manually Resereved Physical Registers in RegAlloc #96979

Open matinraayai opened 4 months ago

matinraayai commented 4 months ago

llvm::MachineRegisterInfo::freezeReservedRegs function copies the default reserved registers of the MF's subtarget into the BitVector of the MRI's reserved register, as seen here: https://github.com/llvm/llvm-project/blob/5b363483cf2461617fbb2449491c9914811c8d53/llvm/lib/CodeGen/MachineRegisterInfo.cpp#L522-L526

From my understanding, this does not take into account the manually-reserved physical registers added via reserveReg: https://github.com/llvm/llvm-project/blob/5b363483cf2461617fbb2449491c9914811c8d53/llvm/include/llvm/CodeGen/MachineRegisterInfo.h#L925-L935

Using reserveReg to manually constrain register allocater from using specific physical registers fails because freezeReservedRegs is called by the register allocator during its initialization, these manually-set registers will be wiped and only the reserved registers designated by the sub target remain: https://github.com/llvm/llvm-project/blob/e55aa027f813679ca63c9b803690ce792a3d7b28/llvm/lib/CodeGen/RegAllocBase.cpp#L57-L66

Is my understanding correct, or does the assignment operation of the BitVector in freezeReservedRegs retains the manually-reserved registers? Is ignoring reserveReg registers expected behavior? If not, is it possible to make the freezing operation take into account manually reserved physical registers?

cc @arsenm

arsenm commented 4 months ago

freezeReservedRegs should be renamed, and also called only once before register allocation. It should really be "initializeReserveRegs".

Right now it's called multiple times, which should be fixed.

matinraayai commented 4 months ago

I agree @arsenm; but the main culprit is reserveReg being called multiple times in SIFrameLowering.cpp

If freezeReservedRegs is to be called only once, then SIFrameLowering must be updated to keep track of its own manually reserved registers, and not rely on updating the MRI's reserved list.

Furthermore, reserveReg should be updated to only work before freezeReservedRegs; I think it is reasonable for a pass to manually reserve registers on top of what TRI reserves for a MF.