Skip to content

Avoid redundant MOVes in generated code

I stumbled upon this generated code:

Everything is fine, a heap check like many others.

      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:

_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).

Trac metadata
Trac field Value
Version 8.0.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information