re PR tree-optimization/79090 (DSE wrongly removes store at variable offset)

2017-01-16  Jeff Law  <law@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.

From-SVN: r244509
This commit is contained in:
Jeff Law 2017-01-16 16:43:05 -07:00 committed by Jeff Law
parent af995bf019
commit a59afbe2fe
5 changed files with 122 additions and 6 deletions

View File

@ -1,3 +1,12 @@
2017-01-16 Jeff Law <law@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 <ubizjak@gmail.com>
* config/i386/i386.h (LIMIT_RELOAD_CLASS): Remove.

View File

@ -1,3 +1,12 @@
2017-01-16 Jeff Law <law@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.
2017-01-16 Jakub Jelinek <jakub@redhat.com>
PR c/79089

View File

@ -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" } } */

View File

@ -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"} } */

View File

@ -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)