[llvm-commits] Register allocation in ascending order
Jakob Stoklund Olesen
stoklund at 2pi.dk
Mon Apr 2 13:22:20 PDT 2012
On Apr 2, 2012, at 7:35 AM, Shamil Kurmangaleev <kursh at ispras.ru> wrote:
> Hello,
>
> This is a patch for the greedy register allocator that makes possible to
> allocate registers in ascending order.
> It simply sorts the equal live intervals by their start index and after
> this the register allocation for this live interval happens in the order
> defined in Tablegen.
Hi Shamil,
I think this approach is too fragile to be really useful.
First of all, it only works when the live ranges have the exact same length:
> ldr r12, [r1]
> ldr r3, [r1, #4]
> ldr r2, [r1, #8]
> ldr r1, [r1, 12]
> str r12, [r0]
> str r3, [r0, #4]
> str r2, [r0, #8]
> str r1, [r0, #12]
If something gets scheduled between these instructions, the live ranges won't have the same length, and we fail to form ldm/stm.
Second, it is quite normal for the register allocator to allocate large live ranges to all registers, and then use the eviction mechanism to create available physregs. This will also fail to form the ldm/stm pairs.
I think your patch only works for tiny functions like your test case.
It would be better to use the target-specific hinting mechanism to achieve this. See ARMBaseRegisterInfo::getRawAllocationOrder() and ARMBaseRegisterInfo::ResolveRegAllocHint(). Maybe ARMPreAllocLoadStoreOpt can compute the hints?
That said, your patch points out one silly thing about the current priority queue: Live ranges of the same length get allocated in descending order of virtual register number.
We could fix that very simply:
Queue.push(std::make_pair(Prio, ~Reg));
}
LiveInterval *RAGreedy::dequeue() {
if (Queue.empty())
return 0;
LiveInterval *LI = &LIS->getInterval(~Queue.top().second);
Queue.pop();
return LI;
}
I think that would make sense to do, and as it happens, it handles your test case the same way.
/jakob
More information about the llvm-commits
mailing list