[LLVMdev] Subregister coalescing

Carlos Sánchez de La Lama carlos.delalama at urjc.es
Wed Jul 28 12:25:02 PDT 2010


Hi all,

We are working on a backend for a machine that has 4-wide vector
register & ops, *but* not vector loads. All the vector register elements
are directly accesible, so VI1 reg (Vector Integer 1) has I4, I5, I6 and
I7 as its (integer) subregisters. Subregisters of same reg *never*
overlap.

Therefore, vector loads are lowered to scalar loads followed by a chain
of INSERT_VECTOR_ELTs. Then we select those to INSERT_SUBREG, everything
fine to that point.

Status before live analisys is (non-related instrs removed):

36 %reg16388<def> = LDWr %reg16384, 0; mem:LD4[<unknown>]
68 %reg16392<def> = INSERT_SUBREG %reg16392<undef>, %reg16388<kill>, 1
76 %reg16394<def> = LDWr %reg16386<kill>, 0; mem:LD4[<unknown>]
116 %reg16400<def> = MOVEV %reg16392<kill>
124 %reg16400<def> = INSERT_SUBREG %reg16400, %reg16394<kill>, 2
132 %reg16401<def> = LDWr %reg16390<kill>, 0; mem:LD4[<unknown>]
164 %reg16404<def> = MOVEV %reg16400<kill>
172 %reg16404<def> = INSERT_SUBREG %reg16404, %reg16401<kill>, 3
180 %reg16405<def> = LDWr %reg16398<kill>, 0; mem:LD4[<unknown>]
212 %reg16408<def> = MOVEV %reg16404<kill>
220 %reg16408<def> = INSERT_SUBREG %reg16408, %reg16405<kill>, 4

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.

Is there a way to solve this?

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.

Can anyone give me a clue on the correct way to handle this situation?

Thanks!

Carlos





More information about the llvm-dev mailing list