[LLVMdev] subregisters, def-kill

Jonas Paulsson jnspaulsson at hotmail.com
Fri May 20 10:09:24 PDT 2011


If I write



%reg16506<def> = INSERT_SUBREG %reg16506, %reg16445, hi16;   #1
%reg16506<def> = INSERT_SUBREG %reg16506, %reg16468, lo16;   #2
store %reg16506                                                                                    #3


it will not coalesce, as  


LiveVariables:

on
#2: %16506 gets #2 as a kill
#3: %16506 gets #3 as an additional kill

LiveIntervalAnalysis:
The
 common case of a def/kill in same MBB, is missed, as there are two 
kills, one for the store-MI, and one for the last COPY. Thus, two false 
live-ranges are later added, to the end of the block, and from the 
beginning - as it is believed it is not a local live-range.

SimpleRegisterCoalescing:
This ends up as overlapping live-ranges, where the value numbers did not become one, and Interference is reported.



This must then be considered bad code in LLVM.


But if I write



%reg16507<def> = COPY %reg16445;

%reg16508<def> = COPY %reg16468;

%reg16506<def> = REG_SEQUENCE %reg16507, hi16, %reg16508, lo16;

%reg16509<def> = st_2_1_postMod %reg16506, %reg16441, %reg16454, pred:20, pred:%CCReg;



then, there is not an erroneous live-range that interferes, so it coalesces.



I suppose this means that the first version with INSERT_SUBREG's is breaking the SSA-form? Or am I doing it wrong?



In a similar case, the coalescer will not join the %reg16478 into 
%reg16511, although it makes perfect sense [after 
SimpleRegisterCoalescer]:



836L    %reg16511:hi16<def> = COPY %reg16473:lo16<kill>, %reg16511<imp-def>; 

844L    %reg16511:lo16<def> = COPY %reg16478:lo16<kill>; 

852L    %r4<def,dead> = st_postMod %reg16511<kill>, %r4

...

844L    %reg16511:lo16<def> = COPY %reg16478:lo16<kill>; Accum:%reg16511,16478

        Considering merging %reg16478 with reg%16511 to Accum

        RHS = %reg16478,0.000000e+00 = [804d,844d:0)  0 at 804d

        LHS = %reg16511,0.000000e+00 = [836d,844d:1)[844d,852d:0)  0 at 844d 1 at 836d

    Interference!



It seems that there is a Live range from the first COPY  to the store, 
which interferes with the second COPY, which should have been coalesced.
 I find it worrisome that LLVM is not recognizing sub-registers apart 
from the super register. I would like to work with subregisters so as to
 define subregister liveness, but I find that LLVM is only keeping live 
information for the super-register, regardless of which subreg was 
defined. How could I overcome this?



However, if I simply change the order of the COPY's, then I have no problem:



%reg16511:lo16<def> = COPY %reg16482<kill>, %reg16511<imp-def>;

%reg16511:hi16<def> = COPY %reg16479<kill>; 

%r4<def,dead> = st_2_1_postMod %reg16511<kill>, %r4



836L    %reg16511:lo16<def> = COPY %reg16478:lo16<kill>, %reg16511<imp-def>;

    Considering merging %reg16478 with reg%16511 to Accum

        RHS = %reg16478,0.000000e+00 = [804d,836d:0)  0 at 804d

        LHS = %reg16511,0.000000e+00 = [836d,844d:1)[844d,852d:0)  0 at 844d 1 at 836d

        updated: 804L    %reg16511<def> = exz_2_22_right 
%reg16471<kill>, 15, pred:20, pred:%reg0; Accum:%reg16511 
A0_3:%reg16471

    Joined. Result = %reg16511,0.000000e+00 = [804d,844d:1)[844d,852d:0)  0 at 844d 1 at 804d



So what is the story, then? Should the COPY's always be placed in order 
of coalescing probability in the cases of placing COPYs to a 
REG_SEQUENCE? One would have hoped for the coalescer to handle this no 
matter what the order, I guess. I could even omit the COPY after checking that the register classes 
match, but in general it would have been preferred with a strong 
coalescer, so as to not always have to worry about introducing COPY's. 



I tried without any COPY's, and this went all the way through, only to 
find that the register-classes are not used as constraints as in GCC, so
 the register allocator had no problem with allocating to the wrong 
register class. Disappointing, after all, this is defined in the .td 
files and available in the OperandInfo's. 



Jonas

> Subject: Re: [LLVMdev] subregisters, def-kill
> From: stoklund at 2pi.dk
> Date: Thu, 19 May 2011 15:39:40 -0700
> CC: llvmdev at cs.uiuc.edu
> To: jnspaulsson at hotmail.com
> 
> 
> On May 19, 2011, at 7:47 AM, Jonas Paulsson wrote:
> 
> > Hi,
> > 
> > I am combining 16-bit registers to a 32 bit register in order to make a wide store, as per below:
> > 
> > 732 %reg16506:hi16<def,dead> = COPY %reg16445<kill>; 
> > 740 %reg16506:lo16<def> = COPY %reg16468<kill>;
> > 748 %r3<def,dead> = store %reg16506<kill>, %r3, 
> > 
> > As you can see, LiveVariables has marked the high part dead, even though the super-register is used at SlotIndex 748. Why is this? Should I add anything special to the basic BuildMI calls?
> 
> That code is not in SSA form as LiveVariables requires, there can only be one def per virtual register. You need to use INSERT_SUBREG or REG_SEQUENCE to do this.
> 
> /jakob
> 
 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110520/62b3afbf/attachment.html>


More information about the llvm-dev mailing list