[LLVMdev] Backend optimizations

Rinaldini Julien julien.rinaldini at heig-vd.ch
Mon Jan 26 07:10:13 PST 2015



On 01/26/2015 03:52 PM, Tim Northover wrote:
> On 26 January 2015 at 06:18, mats petersson <mats at planetcatfish.com> wrote:
>> From the department of ignorance and stupid suggestions: Run this
>> conversion after other passes that deal with call instructions?
> 
> This is almost certainly the way to do it.
> 
> The immediate problem is probably that the jmp isn't being marked with
> the usual call operands telling LLVM that it uses that
> argument-marshalling registers and defines the result ones. But even
> if you fix that x86's JMP is marked isTerminator, isBarrier and so on;
> that means LLVM's optimisers assume it only comes at the end of a
> basic block. Putting it in the middle is just wrong code waiting to
> happen.

Actually my code is made to work that way, each 'jmp' is at the end of a
basic block. For example this test function:

int main(int argc, char **argv) {
  plop2("PLOP");
  plop(1,2);
  return 0;
}

turn into (before optimisations, that's a dump of the MachineFunction in
the custom inserter):

# Machine code for function main: SSA
Frame Objects:
  fi#0: size=8, align=8, at location [SP+8]
  fi#1: size=8, align=8, at location [SP+8]

BB#0: derived from LLVM BB %entry
        MOV64mi32 <fi#0>, 1, %noreg, 0, %noreg, <ga:@plop>;
mem:ST8[%ptrToFunc1]
        %vreg2<def> = MOV32ri64 <ga:@plop>; GR32:%vreg2
        %vreg3<def> = SUBREG_TO_REG 0, %vreg2<kill>, 4; GR64:%vreg3
GR32:%vreg2
        MOV64mi32 <fi#1>, 1, %noreg, 0, %noreg, <ga:@plop2>;
mem:ST8[%ptrToFunc]
        %vreg4<def> = MOV32ri64 <ga:@plop2>; GR32:%vreg4
        %vreg5<def> = SUBREG_TO_REG 0, %vreg4<kill>, 4; GR64:%vreg5
GR32:%vreg4
        ADJCALLSTACKDOWN64 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>,
%RSP<imp-use>
        %vreg6<def> = MOV32ri64 <ga:@.str2>; GR32:%vreg6
        %vreg7<def> = SUBREG_TO_REG 0, %vreg6<kill>, 4; GR64:%vreg7
GR32:%vreg6
        %RDI<def> = COPY %vreg7; GR64:%vreg7
        %vreg11<def> = MOV64ri <BB#1>; GR64:%vreg11
        PUSH64r %vreg11, %RSP<imp-def>, %RSP<imp-use>; GR64:%vreg11
        JMP64r %vreg5; GR64:%vreg5
    Successors according to CFG: BB#1

BB#1:
    Predecessors according to CFG: BB#0
        ADJCALLSTACKUP64 0, 0, %RSP<imp-def,dead>,
%EFLAGS<imp-def,dead>, %RSP<imp-use>
        ADJCALLSTACKDOWN64 0, %RSP<imp-def,dead>, %EFLAGS<imp-def,dead>,
%RSP<imp-use>
        %vreg8<def> = MOV32ri 1; GR32:%vreg8
        %vreg9<def> = MOV32ri 2; GR32:%vreg9
        %EDI<def> = COPY %vreg8; GR32:%vreg8
        %ESI<def> = COPY %vreg9; GR32:%vreg9
        %vreg12<def> = MOV64ri <BB#2>; GR64:%vreg12
        PUSH64r %vreg12, %RSP<imp-def>, %RSP<imp-use>; GR64:%vreg12
        JMP64r %vreg3; GR64:%vreg3
    Successors according to CFG: BB#2

BB#2:
    Predecessors according to CFG: BB#1
        ADJCALLSTACKUP64 0, 0, %RSP<imp-def,dead>,
%EFLAGS<imp-def,dead>, %RSP<imp-use>
        %vreg10<def> = MOV32r0 %EFLAGS<imp-def,dead>; GR32:%vreg10
        %EAX<def> = COPY %vreg10; GR32:%vreg10
        RETQ %EAX

# End machine code for function main.

So maybe 'just' telling the optimiser that some registers are used is
sufficient?

Cheers



More information about the llvm-dev mailing list