I'm working on my -foutline-masbi-xlouges optimization (targeting 64 bit
Wine) and I've run into a snag with sibling calls. When
-foutline-masbi-xlouges is disabled, the sibling call generates just
fine. But when enabled the call to df_analyze() in the peephole2 pass
deletes the insn that initializes the register that the sibling call
uses. I'm hoping that somebody might be able to look at my epilogue code
and identify what may cause this. My optimization is generating insns
146, 147, 148 and 149. (Actually, 146 and 149 can be merged, I just
haven't gotten to it yet).
The insn that's getting deleted is 75, where RCX is set. I'm starting
to think that maybe df_analyze() presumes that my call (to the stub) is
invalidating RCX, although it does not. Below is the RTL dump from the
compgotos pass. Also, I'm not sure why all of my REG_CFA_RESTORE notes
aren't showing up (xmm10-15 are missing).
(code_label 91 70 73 11 903 "" [6 uses])
(note 73 91 74 11 [bb 11] NOTE_INSN_BASIC_BLOCK)
(debug_insn 74 73 75 11 (var_location:DI data (debug_expr:DI D#64)) -1
(nil))
(insn 75 74 150 11 (set (reg:DI 2 cx)
(symbol_ref:DI ("win_data_section") [flags 0x2] <var_decl
0x7f33746fce10 win_data_section>))
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1826 89
{*movdi_internal}
(expr_list:REG_UNUSED (reg:DI 2 cx)
(nil)))
(note 150 75 146 11 NOTE_INSN_EPILOGUE_BEG)
(insn/f 146 150 147 11 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 48 [0x30])))
(clobber (reg:CC 17 flags))
(clobber (mem:BLK (scratch) [0 A8]))
])
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(expr_list:REG_UNUSED (reg:CC 17 flags)
(expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 48 [0x30])))
(nil))))
(insn 147 146 148 11 (set (reg:DI 4 si)
(plus:DI (reg/f:DI 7 sp)
(const_int 96 [0x60])))
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(nil))
(call_insn/f 148 147 149 11 (parallel [
(call (mem:QI (symbol_ref:DI ("__msabi_restore_15") [flags
0x1]) [0 S1 A8])
(const_int 0 [0]))
(clobber (reg:CC 17 flags))
(set (reg:V4SF 52 xmm15)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -88 [0xffffffffffffffa8])) [0 S16 A8]))
(set (reg:V4SF 51 xmm14)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -72 [0xffffffffffffffb8])) [0 S16 A8]))
(set (reg:V4SF 50 xmm13)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -56 [0xffffffffffffffc8])) [0 S16 A8]))
(set (reg:V4SF 49 xmm12)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -40 [0xffffffffffffffd8])) [0 S16 A8]))
(set (reg:V4SF 48 xmm11)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -24 [0xffffffffffffffe8])) [0 S16 A8]))
(set (reg:V4SF 47 xmm10)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -8 [0xfffffffffffffff8])) [0 S16 A8]))
(set (reg:V4SF 46 xmm9)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 8 [0x8])) [0 S16 A8]))
(set (reg:V4SF 45 xmm8)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 24 [0x18])) [0 S16 A8]))
(set (reg:V4SF 28 xmm7)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 40 [0x28])) [0 S16 A8]))
(set (reg:V4SF 27 xmm6)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 56 [0x38])) [0 S16 A8]))
(set (reg:DI 5 di)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 72 [0x48])) [0 S8 A8]))
(set (reg:DI 3 bx)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 80 [0x50])) [0 S8 A8]))
(set (reg:DI 6 bp)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 88 [0x58])) [0 S8 A8]))
(set (reg:DI 41 r12)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 96 [0x60])) [0 S8 A8]))
(set (reg:DI 4 si)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 64 [0x40])) [0 S8 A8]))
])
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(expr_list:REG_CFA_RESTORE (reg:DI 4 si)
(expr_list:REG_CFA_RESTORE (reg:DI 41 r12)
(expr_list:REG_CFA_RESTORE (reg:DI 6 bp)
(expr_list:REG_CFA_RESTORE (reg:DI 3 bx)
(expr_list:REG_CFA_RESTORE (reg:DI 5 di)
(expr_list:REG_CFA_RESTORE (reg:V4SF 27 xmm6)
(expr_list:REG_CFA_RESTORE (reg:V4SF 28 xmm7)
(expr_list:REG_CFA_RESTORE (reg:V4SF 45
xmm8)
(expr_list:REG_CFA_RESTORE (reg:V4SF 46 xmm9)
(nil))))))))))
(expr_list (use (reg:DI 4 si))
(nil)))
(insn/f 149 148 76 11 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 216 [0xd8])))
(clobber (reg:CC 17 flags))
(clobber (mem:BLK (scratch) [0 A8]))
])
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(expr_list:REG_UNUSED (reg:CC 17 flags)
(expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 216 [0xd8])))
(nil))))
(call_insn/j 76 149 77 11 (call (mem:QI (symbol_ref:DI
("LeaveCriticalSection") [flags 0x43] <function_decl 0x7f33753076c0
LeaveCriticalSection>) [0 LeaveCriticalSection S1 A8])
(const_int 32 [0x20]))
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1826 662
{*sibcall}
(expr_list:REG_DEAD (reg:DI 2 cx)
(expr_list:REG_CALL_DECL (symbol_ref:DI
("LeaveCriticalSection") [flags 0x43] <function_decl 0x7f33753076c0
LeaveCriticalSection>)
(nil)))
(expr_list:DI (use (reg:DI 2 cx))
(nil)))
(barrier 77 76 86)
And from peephole2, this (I believe) is the live reg analysis for the bb
in question:
( 10 12 4 6 9 8 7 )->[11]->( 1 )
;; bb 11 artificial_defs: { }
;; bb 11 artificial_uses: { u-1(7){ }}
;; lr in 7 [sp]
;; lr use 7 [sp]
;; lr def 0 [ax] 1 [dx] 2 [cx] 3 [bx] 4 [si] 5 [di] 6 [bp] 7 [sp]
8 [st] 9 [st(1)] 10 [st(2)] 11 [st(3)] 12 [st(4)] 13 [st(5)] 14 [st(6)]
15 [st(7)] 17 [flags] 18 [fpsr] 19 [fpcr] 21 [xmm0] 22 [xmm1] 23 [xmm2]
24 [xmm3] 25 [xmm4] 26 [xmm5] 27 [xmm6] 28 [xmm7] 29 [mm0] 30 [mm1] 31
[mm2] 32 [mm3] 33 [mm4] 34 [mm5] 35 [mm6] 36 [mm7] 37 [r8] 38 [r9] 39
[r10] 40 [r11] 41 [r12] 45 [xmm8] 46 [xmm9] 47 [xmm10] 48 [xmm11] 49
[xmm12] 50 [xmm13] 51 [xmm14] 52 [xmm15] 53 [] 54 [] 55 [] 56 [] 57 []
58 [] 59 [] 60 [] 61 [] 62 [] 63 [] 64 [] 65 [] 66 [] 67 [] 68 [] 69 []
70 [] 71 [] 72 [] 73 [] 74 [] 75 [] 76 [] 77 [] 78 [] 79 [] 80 []
;; live in 7 [sp]
;; live gen 2 [cx] 3 [bx] 4 [si] 5 [di] 6 [bp] 7 [sp] 27 [xmm6] 28
[xmm7] 41 [r12] 45 [xmm8] 46 [xmm9] 47 [xmm10] 48 [xmm11] 49 [xmm12] 50
[xmm13] 51 [xmm14] 52 [xmm15]
;; live kill 17 [flags]
;; lr out 3 [bx] 4 [si] 5 [di] 6 [bp] 7 [sp] 27 [xmm6] 28 [xmm7]
41 [r12] 45 [xmm8] 46 [xmm9] 47 [xmm10] 48 [xmm11] 49 [xmm12] 50 [xmm13]
51 [xmm14] 52 [xmm15]
;; live out 3 [bx] 4 [si] 5 [di] 6 [bp] 7 [sp] 27 [xmm6] 28 [xmm7]
41 [r12] 45 [xmm8] 46 [xmm9] 47 [xmm10] 48 [xmm11] 49 [xmm12] 50 [xmm13]
51 [xmm14] 52 [xmm15]
...
processing block 11 lr out = 3 [bx] 4 [si] 5 [di] 6 [bp] 7 [sp] 27
[xmm6] 28 [xmm7] 41 [r12] 45 [xmm8] 46 [xmm9] 47 [xmm10] 48 [xmm11] 49
[xmm12] 50 [xmm13] 51 [xmm14] 52 [xmm15]
Adding insn 149 to worklist
Adding insn 147 to worklist
Adding insn 146 to worklist
...
DCE: Deleting insn 75
deleting insn with uid = 75.
This is the bb after peephole2:
(code_label 91 70 73 11 903 "" [6 uses])
(note 73 91 74 11 [bb 11] NOTE_INSN_BASIC_BLOCK)
(debug_insn 74 73 150 11 (var_location:DI data (debug_expr:DI D#64)) -1
(nil))
(note 150 74 146 11 NOTE_INSN_EPILOGUE_BEG)
(insn/f 146 150 147 11 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 48 [0x30])))
(clobber (reg:CC 17 flags))
(clobber (mem:BLK (scratch) [0 A8]))
])
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(expr_list:REG_UNUSED (reg:CC 17 flags)
(expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 48 [0x30])))
(nil))))
(insn 147 146 148 11 (set (reg:DI 4 si)
(plus:DI (reg/f:DI 7 sp)
(const_int 96 [0x60])))
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(nil))
(call_insn/f 148 147 149 11 (parallel [
(call (mem:QI (symbol_ref:DI ("__msabi_restore_15") [flags
0x1]) [0 S1 A8])
(const_int 0 [0]))
(clobber (reg:CC 17 flags))
(set (reg:V4SF 52 xmm15)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -88 [0xffffffffffffffa8])) [0 S16 A8]))
(set (reg:V4SF 51 xmm14)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -72 [0xffffffffffffffb8])) [0 S16 A8]))
(set (reg:V4SF 50 xmm13)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -56 [0xffffffffffffffc8])) [0 S16 A8]))
(set (reg:V4SF 49 xmm12)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -40 [0xffffffffffffffd8])) [0 S16 A8]))
(set (reg:V4SF 48 xmm11)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -24 [0xffffffffffffffe8])) [0 S16 A8]))
(set (reg:V4SF 47 xmm10)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int -8 [0xfffffffffffffff8])) [0 S16 A8]))
(set (reg:V4SF 46 xmm9)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 8 [0x8])) [0 S16 A8]))
(set (reg:V4SF 45 xmm8)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 24 [0x18])) [0 S16 A8]))
(set (reg:V4SF 28 xmm7)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 40 [0x28])) [0 S16 A8]))
(set (reg:V4SF 27 xmm6)
(mem/c:V4SF (plus:DI (reg:DI 4 si)
(const_int 56 [0x38])) [0 S16 A8]))
(set (reg:DI 5 di)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 72 [0x48])) [0 S8 A8]))
(set (reg:DI 3 bx)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 80 [0x50])) [0 S8 A8]))
(set (reg:DI 6 bp)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 88 [0x58])) [0 S8 A8]))
(set (reg:DI 41 r12)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 96 [0x60])) [0 S8 A8]))
(set (reg:DI 4 si)
(mem/c:DI (plus:DI (reg:DI 4 si)
(const_int 64 [0x40])) [0 S8 A8]))
])
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(expr_list:REG_CFA_RESTORE (reg:DI 4 si)
(expr_list:REG_CFA_RESTORE (reg:DI 41 r12)
(expr_list:REG_CFA_RESTORE (reg:DI 6 bp)
(expr_list:REG_CFA_RESTORE (reg:DI 3 bx)
(expr_list:REG_CFA_RESTORE (reg:DI 5 di)
(expr_list:REG_CFA_RESTORE (reg:V4SF 27 xmm6)
(expr_list:REG_CFA_RESTORE (reg:V4SF 28 xmm7)
(expr_list:REG_CFA_RESTORE (reg:V4SF 45
xmm8)
(expr_list:REG_CFA_RESTORE (reg:V4SF 46 xmm9)
(nil))))))))))
(expr_list (use (reg:DI 4 si))
(nil)))
(insn/f 149 148 76 11 (parallel [
(set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 216 [0xd8])))
(clobber (reg:CC 17 flags))
(clobber (mem:BLK (scratch) [0 A8]))
])
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1655 -1
(expr_list:REG_UNUSED (reg:CC 17 flags)
(expr_list:REG_CFA_ADJUST_CFA (set (reg/f:DI 7 sp)
(plus:DI (reg/f:DI 7 sp)
(const_int 216 [0xd8])))
(nil))))
(call_insn/j 76 149 77 11 (call (mem:QI (symbol_ref:DI
("LeaveCriticalSection") [flags 0x43] <function_decl 0x7f034a57f6c0
LeaveCriticalSection>) [0 LeaveCriticalSection S1 A8])
(const_int 32 [0x20]))
/home/daniel/proj/emu/wine/github/dlls/winex11.drv/window.c:1826 662
{*sibcall}
(expr_list:REG_DEAD (reg:DI 2 cx)
(expr_list:REG_CALL_DECL (symbol_ref:DI
("LeaveCriticalSection") [flags 0x43] <function_decl 0x7f034a57f6c0
LeaveCriticalSection>)
(nil)))
(expr_list:DI (use (reg:DI 2 cx))
(nil)))
(barrier 77 76 86)
Any help greatly appreciated!
Daniel