This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]