[GHC] #13563: Avoid redundant MOVes in generated code

GHC ghc-devs at haskell.org
Tue Apr 11 11:25:44 UTC 2017


#13563: Avoid redundant MOVes in generated code
--------------------------------------+---------------------------------
           Reporter:  alexbiehl       |             Owner:  (none)
               Type:  bug             |            Status:  new
           Priority:  normal          |         Milestone:
          Component:  Compiler        |           Version:  8.0.2
           Keywords:                  |  Operating System:  Windows
       Architecture:  x86_64 (amd64)  |   Type of failure:  None/Unknown
          Test Case:                  |        Blocked By:
           Blocking:                  |   Related Tickets:
Differential Rev(s):                  |         Wiki Page:
--------------------------------------+---------------------------------
 I stumbled upon this generated code:

 Everything is fine, a heap check like many others.

 {{{#!hs
       c2ro:
           Hp = Hp + 16;
           if (Hp > I64[BaseReg + 856]) goto c2rt; else goto c2rs;
       c2rt:
           I64[BaseReg + 904] = 16;
           I64[Sp - 48] = block_c2rp_info;
           I64[Sp - 40] = _s2pI::I64;
           I64[Sp - 32] = _s2pJ::I64;
           I64[Sp - 24] = _s2pK::I64;
           I64[Sp - 16] = _s2pN::I64;
           I64[Sp - 8] = _s2pO::I64;
           Sp = Sp - 48;
           call stg_gc_noregs() returns to c2rp, args: 8, res: 8, upd: 8;
       c2rp:
           _s2pI::I64 = I64[Sp + 8];
           _s2pJ::I64 = I64[Sp + 16];
           _s2pK::I64 = I64[Sp + 24];
           _s2pN::I64 = I64[Sp + 32];
           _s2pO::I64 = I64[Sp + 40];
           Sp = Sp + 48;
           goto c2ro;
       c2rs:
 }}}

 Compiled to assembler:

 {{{#!asm
 _c2ro:
         addq $16,%r12           ; Heap check as usual
         cmpq 856(%r13),%r12
         ja _c2rt
 _c2rs:
         ...
 _c2rt:
         movq $16,904(%r13)
         movq $block_c2rp_info,-48(%rbp)
         movq %r14,-40(%rbp)    ; copy out sequence: move live variables
         movq %rsi,-32(%rbp)    ; to stack
         movq %rax,-24(%rbp)
         movq %rbx,-16(%rbp)
         movq %rdi,-8(%rbp)
         addq $-48,%rbp
         jmp stg_gc_noregs
         ...
 .align 8
         .quad   1989
         .quad   32
 block_c2rp_info:
 _c2rp:
         movq 8(%rbp),%rax   ; we returned from gc land, now copy live
 variables back in
         movq 16(%rbp),%rbx
         movq 24(%rbp),%rcx
         movq 32(%rbp),%rdx
         movq 40(%rbp),%rsi
         addq $48,%rbp
 _n2st:                            ; Oh dear! We are moving our freshly
 moved register again for no obvious reason!
         movq %rsi,%rdi
         movq %rbx,%rsi
         movq %rdx,%rbx
         movq %rax,%r14
         movq %rcx,%rax
         jmp _c2ro
 }}}

 What is happening here that GHC isn't able to directly assign the correct
 registers? Also the label `_n2st` suggest it is inserted at a later stage
 than the generated cmm code (Every other label is named contigously).

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13563>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list