This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: live insns deleted by delete_trivially_dead_insns()
On 5/8/07, Paolo Bonzini <paolo.bonzini@lu.unisi.ch> 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