A problem with register allocator

Hi

I have a code pattern like this:

Load value 1 from mem

Load value 2 from mem

For (…) {

Use value 2

Use value 1

}

During register allocations values loaded are spilled and I end up with this pattern:

Load value 1 from mem

Store value 1 to stack

Load value 2 from mem

Store value 2 to stack

For (…) {

Load value 2 from stack

Use value 2

Load value 1 from stack

Use value 1

}

At least for my case, I prefer to load directly from memory inside the loop. From what I have heard, this is a known issue with the register allocator. I have a few questions:

1- Has there been any attempt to fix this? If yes, what was the experience when dealing with tradeoffs (for example if value 1 and value 2 are far apart in memory and loop trip count is high, the current codegen might be better)

2- If I want to experiment with some fixes for this, where in the register allocator code I should look?

Thanks

Ehsan

This is called rematerialization, and the register allocator can already do it but there are various constraints.

For it happen:

  • The instruction needs to be marked as isReMaterializable in the tablegen file

  • TargetInstrInfo::isTriviallyReMaterializable needs to return true for the instruction

  • InlineSpiller and LiveRangeEdit in lib/Codegen are the things that actually do the rematerialization, and it

may be worthwhile looking there

  • The base register of the load needs to be guaranteed to be live at the place where it is rematerialized, e.g.

in lib/Target/ARM/ARMInstrThumb.td the tLDRpci instruction is rematerializable because the base in the

pc register which is always available, but loads in general aren’t.

John