Hi Jeff,
On 17 January 2017 at 00:44, Jeff Law <l...@redhat.com> wrote: > > > ACATS already had a test covering the Ada issue, Eric also added a test to > the gnat.dg testsuite. So that's well covered. > > The test for the bootstrap comparison failure was (as expected) trivial to > construct (ssa-dse-29.c). The test for the ppc64 big endian failures was > easy to extract from sel-sched.c (ssa-dse-2.C) What was more interesting > was the scanning. > > I finally decided to enhance the dumps a bit to facilitate testing. If we > have a trimmable store, we now dump the trimming information. The test then > verifies two things. First that we don't get a negative trim, second that > the dead memmove call gets deleted. > > Bootstrapped and regression tested on x86_64-linux-gnu. Installing on the > trunk. > > Again folks, sorry for the breakage over the weekend. > > Jeff > > commit b241d3db9d195bdffa4349cea077ee0e94985435 > Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4> > Date: Mon Jan 16 23:43:05 2017 +0000 > > 2017-01-16 Jeff Law <l...@redhat.com> > > PR tree-optimization/79090 > PR tree-optimization/33562 > PR tree-optimization/61912 > PR tree-optimization/77485 > * tree-ssa-dse.c (compute_trims): Accept STMT argument. Dump STMT > and computed trims into the dump file. > > PR tree-optimization/79090 > PR tree-optimization/33562 > PR tree-optimization/61912 > PR tree-optimization/77485 > * tree-ssa-dse.c (compute_trims): Accept STMT argument. Dump STMT > and computed trims into the dump file. > > git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@244509 > 138bc75d-0d04-0410-961f-82ee72b054a4 > > diff --git a/gcc/ChangeLog b/gcc/ChangeLog > index 265e3a5..8507528 100644 > --- a/gcc/ChangeLog > +++ b/gcc/ChangeLog > @@ -1,3 +1,12 @@ > +2017-01-16 Jeff Law <l...@redhat.com> > + > + PR tree-optimization/79090 > + PR tree-optimization/33562 > + PR tree-optimization/61912 > + PR tree-optimization/77485 > + * tree-ssa-dse.c (compute_trims): Accept STMT argument. Dump STMT > + and computed trims into the dump file. > + > 2017-01-17 Uros Bizjak <ubiz...@gmail.com> > > * config/i386/i386.h (LIMIT_RELOAD_CLASS): Remove. > diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog > index ef1fea5..09c5d52 100644 > --- a/gcc/testsuite/ChangeLog > +++ b/gcc/testsuite/ChangeLog > @@ -1,3 +1,12 @@ > +2017-01-16 Jeff Law <l...@redhat.com> > + > + PR tree-optimization/33562 > + PR tree-optimization/61912 > + PR tree-optimization/77485 > + PR tree-optimization/79090 > + * gcc.dg/tree-ssa/ssa-dse-29.c: New test. > + * g++.dg/tree-ssa/ssa-dse-2.C: New test. > + The new ssa-dse-2.C test fails on arm because: warning: declaration of 'void* memmove(void*, const void*, size_t)' conflicts with built-in declaration 'void* memmove(void*, const void*, unsigned int)' [-Wbuiltin-declaration-mismatch] Christophe > 2017-01-16 Jakub Jelinek <ja...@redhat.com> > > PR c/79089 > diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-2.C > b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-2.C > new file mode 100644 > index 0000000..d69edd2 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-2.C > @@ -0,0 +1,59 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-dse2-details" } */ > + > +typedef long unsigned int size_t; > +extern "C" > +{ > + extern void *memmove (void *__dest, const void *__src, size_t __n) throw > () > + __attribute__ ((__nonnull__ (1, 2))); > +} > +extern void abort () __attribute__ ((__noreturn__)); > +struct vec_prefix { unsigned m_num; }; > +struct vl_embed { }; > +struct vl_ptr { }; > +struct va_heap { typedef vl_ptr default_layout; }; > +template < typename T, typename A = va_heap, typename L = typename > A::default_layout > struct vec { }; > +template < typename T, typename A > struct vec < T, A, vl_embed > > +{ > + unsigned length (void) const { return m_vecpfx. m_num; } > + bool is_empty (void) const { return m_vecpfx. m_num == 0; } > + void block_remove (unsigned, unsigned); > + vec_prefix m_vecpfx; > + T m_vecdata[1]; > +}; > +template < typename T, typename A > inline void vec < T, A, vl_embed >>::block_remove (unsigned ix, unsigned len) > +{ > + T * slot = &m_vecdata[ix]; > + m_vecpfx.m_num -= len; > + memmove (slot, slot + len, (m_vecpfx.m_num - ix) * sizeof (T)); > +} > + > +template < typename T > struct vec < T, va_heap, vl_ptr > > +{ > + bool is_empty (void) const { return m_vec ? m_vec-> is_empty () : true; > } > + unsigned length (void) const { return m_vec ? m_vec-> length () : 0; } > + void block_remove (unsigned, unsigned); > + vec < T, va_heap, vl_embed > * m_vec; > +}; > +template < typename T > inline void vec < T, va_heap, vl_ptr >>::block_remove (unsigned ix, unsigned len) > +{ > + m_vec->block_remove (ix, len); > +} > + > +typedef struct _list_node * _list_t; > +typedef struct _expr expr_def; > +typedef expr_def * expr_t; > +typedef _list_t av_set_t; > +static vec < expr_t > vec_av_set; > +bool > +fill_vec_av_set (av_set_t av) > +{ > + if (vec_av_set.length () > 0) > + vec_av_set.block_remove (0, vec_av_set.length ()); > + ((!(vec_av_set.is_empty ())? abort () , 0 : 0)); > +} > + > +/* { dg-final { scan-tree-dump-not "Trimming statement .head = -" "dse2" } > } */ > +/* { dg-final { scan-tree-dump "Deleted dead call: " "dse2" } } */ > + > + > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c > b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c > new file mode 100644 > index 0000000..31529e7 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c > @@ -0,0 +1,26 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-dse-details" } */ > + > +struct z { > + int a; > + int b; > + int c; > +}; > + > +int > +foo(int cond, struct z *s) > +{ > + > + if (cond) > + { > + s->a = 1; > + s->b = 2; > + s->c = 3; > + } > + __builtin_memset (s, 0, sizeof (struct z)); > +} > + > +/* { dg-final { scan-tree-dump-times "Deleted dead store" 3 "dse1"} } */ > +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse2"} } */ > +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse3"} } */ > + > diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c > index 65dcb12..84c0b11 100644 > --- a/gcc/tree-ssa-dse.c > +++ b/gcc/tree-ssa-dse.c > @@ -212,10 +212,14 @@ setup_live_bytes_from_ref (ao_ref *ref, sbitmap > live_bytes) > tail of ORIG resulting in a bitmap that is a superset of LIVE. > > Store the number of elements trimmed from the head and tail in > - TRIM_HEAD and TRIM_TAIL. */ > + TRIM_HEAD and TRIM_TAIL. > + > + STMT is the statement being trimmed and is used for debugging dump > + output only. */ > > static void > -compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail) > +compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail, > + gimple *stmt) > { > /* We use sbitmaps biased such that ref->offset is bit zero and the > bitmap > extends through ref->size. So we know that in the original bitmap > @@ -231,6 +235,15 @@ compute_trims (ao_ref *ref, sbitmap live, int > *trim_head, int *trim_tail) > int first_orig = 0; > int first_live = bitmap_first_set_bit (live); > *trim_head = (first_live - first_orig) & ~0x1; > + > + if ((*trim_head || *trim_tail) > + && dump_file && (dump_flags & TDF_DETAILS)) > + { > + fprintf (dump_file, " Trimming statement (head = %d, tail = %d): ", > + *trim_head, *trim_tail); > + print_gimple_stmt (dump_file, stmt, dump_flags, 0); > + fprintf (dump_file, "\n"); > + } > } > > /* STMT initializes an object from COMPLEX_CST where one or more of the > @@ -244,7 +257,7 @@ static void > maybe_trim_complex_store (ao_ref *ref, sbitmap live, gimple *stmt) > { > int trim_head, trim_tail; > - compute_trims (ref, live, &trim_head, &trim_tail); > + compute_trims (ref, live, &trim_head, &trim_tail, stmt); > > /* The amount of data trimmed from the head or tail must be at > least half the size of the object to ensure we're trimming > @@ -296,7 +309,7 @@ maybe_trim_constructor_store (ao_ref *ref, sbitmap live, > gimple *stmt) > > int head_trim = 0; > int tail_trim = 0; > - compute_trims (ref, live, &head_trim, &tail_trim); > + compute_trims (ref, live, &head_trim, &tail_trim, stmt); > > /* Now we want to replace the constructor initializer > with memset (object + head_trim, 0, size - head_trim - tail_trim). */ > @@ -384,7 +397,7 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, > gimple *stmt) > case BUILT_IN_MEMMOVE: > { > int head_trim, tail_trim; > - compute_trims (ref, live, &head_trim, &tail_trim); > + compute_trims (ref, live, &head_trim, &tail_trim, stmt); > > /* Tail trimming is easy, we can just reduce the count. */ > if (tail_trim) > @@ -405,7 +418,7 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, > gimple *stmt) > case BUILT_IN_MEMSET: > { > int head_trim, tail_trim; > - compute_trims (ref, live, &head_trim, &tail_trim); > + compute_trims (ref, live, &head_trim, &tail_trim, stmt); > > /* Tail trimming is easy, we can just reduce the count. */ > if (tail_trim) >