[llvm-commits] Tuning LLVM Greedy Register Allocator to optimize for code size when targeting ARM Thumb 2 instruction set

Jakob Stoklund Olesen stoklund at 2pi.dk
Mon Jan 30 15:28:03 PST 2012


On Jan 25, 2012, at 8:02 PM, Zino Benaissa wrote:

>> Does this negative bias mean that VirtReg.bytes is 0 for most virtual
> registers? How > many get VirtReg.bytes > 0?
> 
> Of course it varies and depends on the compiled code. I have seen that
> VirtReg.bytes =0 (or close) while this VirtReg occurs frequently in the
> function (Which in this case their weight is high). At the same  I have seen
> Candidate that have a very high VirtReg.byte and (they were getting a
> costPerUse register before this heuristic). Some EEMBC benchmarks shrank
> with > 5% and are example of this. 

Alright, so I would expect that the majority of GPR VirtRegs have bytes > 0.

>> As I am reading your changes to the eviction policy, you are completely
>> replacing spill weights with a code size metric for live ranges with
>> Virteg.bytes > 0. Is that the intention?

> It depends why the eviction is invoked. Currently there are three reasons
> for invoking eviction: enabling coalescing, preventing spill/split,
> preventing a costPerUse register. Note all these evections where already put
> in place before my heuristic.
> 1) Both for coalescing or for preventing split/spill: VirtReg.bytes=0 and
> the heuristic is ignored and only the pair <hint,weight> is considered.
> Whatever were put in place is still managing these type of evictions. 
> 2) This heuristic is ON only when a candidate gets a register that has a
> CostPerUse. In this case, When the RA attempts to trade it for a register
> with no cost, Now with this heuristic it has a metric to evaluate whether
> there is a trade worth evicting for. 

Here is the problem: Whenever you do a 'luxury' eviction because you got a physreg with a CostPerUse, you could be evicting virtregs with very high spill weight.  These are the 'used in a hot loop' virtregs you were talking about.  Whenever VirtReg.bytes > 0, you are effectively replacing the spill weights with code size metrics.  That is very heavily biased towards optimizing for code size, and I think it is too aggressive.

Live range splitting is going to save you some of the time. It still uses speed metrics, but the overall behavior of the greedy algorithm becomes very erratic.

Spill weights are used in two different ways when evicting:

1. The shouldEvict() policy function prevents a VirtReg from evicting something with a higher spill weight. (But you are overriding it!)

2. The tryEvict() function selects the eviction candidate that would cause the lowest maximum spill weight to be evicted.

I don't think it is safe to override the shouldEvict() policy. You can get away with changing the candidate selection in 2., though.

Here is what I suggest you do:

- Don't override shouldEvict(). That policy should always stay in place.

- Use code size metrics to select among multiple eviction candidates when evicting from 'cheap' physregs.

- Don't evict from two physregs in selectOrSplit() and then only use one of them. You may be able to use code size metrics for selecting the best eviction candidate, but don't evict two different physregs needlessly.

You should also make sure that the patch works for x86-64. There is a similar code size penalty to using r8-r15 and xmm8-15.

/jakob




More information about the llvm-commits mailing list