[LLVMdev] Subregister coalescing

Jakob Stoklund Olesen stoklund at 2pi.dk
Wed Jul 28 13:42:57 PDT 2010


On Jul 28, 2010, at 12:25 PM, Carlos Sánchez de La Lama wrote:
> Which after register coalescing gets transformed into:
> 
> 36	%reg16404:1<def> = LDWr %reg16384, 0; mem:LD4[<unknown>]
> 76	%reg16394<def> = LDWr %reg16386<kill>, 0; mem:LD4[<unknown>]
> 124	%reg16404<def> = INSERT_SUBREG %reg16404, %reg16394<kill>, 2
> 132	%reg16401<def> = LDWr %reg16390<kill>, 0; mem:LD4[<unknown>]
> 172	%reg16404<def> = INSERT_SUBREG %reg16404, %reg16401<kill>, 3
> 180	%reg16405<def> = LDWr %reg16398<kill>, 0; mem:LD4[<unknown>]
> 220	%reg16404<def> = INSERT_SUBREG %reg16404, %reg16405<kill>, 4
> 
> The code is correct, but not optimal. I would like the loads to go
> directly to the subregisters of %reg16404, avoiding the extra copies.
> But seems Live Range Analisys interprets %reg16404 to be alive in the
> whole range, thus preventing coalescing between its subregs and the load
> destinations.

Right. This is a deficiency in the coalescer. It doesn't deal well with multiple values being inserted into a larger register. As you correctly observed, it doesn't understand that a live interval can be partially defined and so may not interfere.

The opposite direction should be fine - using EXTRACT_SUBREG to get small registers from the larger one. Your stores ought to coalesce properly.

> Is there a way to solve this?

What Bob said. Use REG_SEQUENCE. You may have to use LLVM from Subversion to do that. Your machine code looks like you are using 2.7.

> As an alternate approach, I also tried to do a custom InstrInserter that
> ended with the correct code just after MI emission:
> 
> 68 %reg16392<def> = LDWr %reg16384<kill>, 0; mem:LD4[<unknown>]
> 76 %reg16393<def> = LDWr %reg16386<kill>, 0; mem:LD4[<unknown>]
> 84 %reg16394<def> = LDWr %reg16387<kill>, 0; mem:LD4[<unknown>]
> 92 %reg16395<def> = LDWr %reg16388<kill>, 0; mem:LD4[<unknown>]
> 132 %reg16400:1<def,dead> = MOVI32rr %reg16392<kill>
> 140 %reg16400:2<def> = MOVI32rr %reg16393<kill>
> 148 %reg16400:3<def> = MOVI32rr %reg16394<kill>
> 156 %reg16400:4<def> = MOVI32rr %reg16395<kill>
> 
> but then Live Range Analysis asserts because of multiply defined %
> reg16400.

You can't do it like that because the machine code must be in SSA form until TwoAddressInstructionPass runs. This is why we keep the INSERT_SUBREG instruction around instead of just lowering it to

%reg16404:4<def> = COPY %reg16405<kill>

On the other hand, EXTRACT_SUBREG is translated to a subreg COPY immediately.

/jakob






More information about the llvm-dev mailing list