On 5/8/07, Paolo Bonzini <[EMAIL PROTECTED]> wrote:
>>> Because it's the semantics of libcall sequences. My take is that the >>> lower subreg pass breaks it in this case. > > I could "fix" it at -O2 with -fno-split-wide-types or at -O1 with > -fno-move-loop-invariants or -fno-split-wide-types. > >> Can you also check -fno-forward-propagate? > > Yes. It'll have to wait until Wednesday, though. Ok. Still, last time everybody spoke about removing libcall notes, the last reason to keep them was elimination of redundant computation for TLS. This patch should have made it redundant: http://gcc.gnu.org/ml/gcc-patches/2005-11/msg01695.html
Hm, I'm not sure what you mean with "made it redundant" but if you mean "made libcall notes redundant", I'm afraid not. We've always been optimizing away libcall results, but we still need the notes to optimize away the libcall itself. Consider e.g. typedef struct { int a, b; } X; static __thread X *x, *y; int foo (void) { int i; while (i < 128) { i += x->a; i += y->b; } return i; } With the options "-O2 -fno-tree-pre -fno-tree-loop-im -fpic t.c -fdump-rtl-expand-slim" we compile this on x86_64-linux to: ;; Basic block 4 , prev 3, next 5, loop_depth 1, count 0, freq 9100, maybe hot. ;; Predecessors: 4 [91.0%] (dfs_back) 3 [91.0%] (fallthru) 7 NOTE_INSN_BASIC_BLOCK 8 ax:DI=call [`__tls_get_addr'] argc:0x0 REG_LIBCALL: insn REG_EH_REGION: 0xffffffffffffffff 9 r62:DI=ax:DI REG_RETVAL: call_insn REG_EQUAL: expr_list 10 {r63:DI=r62:DI+const(unspec[`y'] 6);clobber flags:CC;} 11 r61:DI=[r63:DI] 12 ax:DI=call [`__tls_get_addr'] argc:0x0 REG_LIBCALL: insn REG_EH_REGION: 0xffffffffffffffff 13 r65:DI=ax:DI REG_RETVAL: call_insn REG_EQUAL: expr_list 14 {r66:DI=r65:DI+const(unspec[`x'] 6);clobber flags:CC;} 15 r64:DI=[r66:DI] 16 r67:SI=[r64:DI] 17 r68:SI=[r61:DI+0x4] 18 {r58:SI=r68:SI+r67:SI;clobber flags:CC;} REG_EQUAL: [r61:DI+0x4]+[r64:DI] 19 {r59:SI=r59:SI+r58:SI;clobber flags:CC;} 21 flags:CCGC=cmp(r59:SI,0x7f) 22 pc={(flags:CCGC<=0x0)?L20:pc} REG_BR_PROB: 0x238c Note the two calls to __tls_get_addr. With the normal RTL optimizations we end up with this in gcse1: ;; Basic block 3 , prev 2, next 4, loop_depth 1, count 0, freq 9100, maybe hot. ;; Predecessors: 3 [91.0%] (dfs_back) 2 [91.0%] (fallthru) 7 NOTE_INSN_BASIC_BLOCK 8 ax:DI=call [`__tls_get_addr'] argc:0x0 REG_LIBCALL: insn REG_EH_REGION: 0xffffffffffffffff 9 r62:DI=ax:DI REG_RETVAL: call_insn REG_EQUAL: expr_list 10 {r63:DI=r62:DI+const(unspec[`y'] 6);clobber flags:CC;} 11 r61:DI=[r63:DI] 12 ax:DI=call [`__tls_get_addr'] argc:0x0 REG_LIBCALL: insn REG_EH_REGION: 0xffffffffffffffff 13 r65:DI=r62:DI REG_RETVAL: call_insn REG_EQUAL: expr_list 14 {r66:DI=r62:DI+const(unspec[`x'] 6);clobber flags:CC;} 15 r64:DI=[r66:DI] 16 r67:SI=[r64:DI] 17 r68:SI=[r61:DI+0x4] 18 {r58:SI=r68:SI+r67:SI;clobber flags:CC;} REG_EQUAL: [r61:DI+0x4]+[r64:DI] 19 {r59:SI=r59:SI+r58:SI;clobber flags:CC;} 21 flags:CCGC=cmp(r59:SI,0x7f) 22 pc={(flags:CCGC<=0x0)?L20:pc} REG_BR_PROB: 0x238c Note how the result of the second __tls_get_addr libcall is now unused (this is done in CSE1 I think). So the second libcall is dead. But without libcall notes, we just see a call_insn and a set to a hard register, and we have no way to tell that the call_insn is dead and can safely be removed. So AFAIK we still need libcall notes to remove dead libcalls. Gr. Steven