diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc index 81b65125409..5869010287c 100644 --- a/gcc/tree-ssa-dse.cc +++ b/gcc/tree-ssa-dse.cc @@ -403,11 +403,11 @@ setup_live_bytes_from_ref (ao_ref *ref, sbitmap live_bytes) return false; } -/* Compute the number of elements that we can trim from the head and - tail of ORIG resulting in a bitmap that is a superset of LIVE. +/* Compute the number of stored bytes that we can trim from the head and + tail of REF. LIVE is the bitmap of stores to REF that are still live. - Store the number of elements trimmed from the head and tail in - TRIM_HEAD and TRIM_TAIL. + Store the number of bytes trimmed from the head and tail in TRIM_HEAD + and TRIM_TAIL respectively. STMT is the statement being trimmed and is used for debugging dump output only. */ @@ -416,10 +416,16 @@ static void 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 - bits 0..ref->size were true. We don't actually need the bitmap, just - the REF to compute the trims. */ + *trim_head = 0; + *trim_tail = 0; + + /* We use bitmaps biased such that ref->offset is contained in bit zero and + the bitmap extends through ref->max_size and we know that in the original + bitmap bits 0 .. ref->max_size were true. But we need to check that this + covers exactly the bytes of REF. */ + const unsigned int align = known_alignment (ref->offset); + if ((align && align < BITS_PER_UNIT) || !known_eq (ref->size, ref->max_size)) + return; /* Now identify how much, if any of the tail we can chop off. */ HOST_WIDE_INT const_size; @@ -444,8 +450,6 @@ compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail, last_orig) <= 0) *trim_tail = 0; } - else - *trim_tail = 0; /* Identify how much, if any of the head we can chop off. */ int first_orig = 0; @@ -503,8 +507,7 @@ compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail, } } - if ((*trim_head || *trim_tail) - && dump_file && (dump_flags & TDF_DETAILS)) + if ((*trim_head || *trim_tail) && dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, " Trimming statement (head = %d, tail = %d): ", *trim_head, *trim_tail); @@ -513,9 +516,9 @@ compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail, } } -/* STMT initializes an object from COMPLEX_CST where one or more of the - bytes written may be dead stores. REF is a representation of the - memory written. LIVE is the bitmap of stores that are actually live. +/* STMT initializes an object from COMPLEX_CST where one or more of the bytes + written may be dead stores. REF is a representation of the memory written. + LIVE is the bitmap of stores to REF that are still live. Attempt to rewrite STMT so that only the real or imaginary part of the object is actually stored. */ @@ -554,11 +557,10 @@ maybe_trim_complex_store (ao_ref *ref, sbitmap live, gimple *stmt) } /* STMT initializes an object using a CONSTRUCTOR where one or more of the - bytes written are dead stores. ORIG is the bitmap of bytes stored by - STMT. LIVE is the bitmap of stores that are actually live. + bytes written are dead stores. REF is a representation of the memory + written. LIVE is the bitmap of stores to REF that are still live. - Attempt to rewrite STMT so that only the real or imaginary part of - the object is actually stored. + Attempt to rewrite STMT so that only the live stores are performed. The most common case for getting here is a CONSTRUCTOR with no elements being used to zero initialize an object. We do not try to handle other @@ -780,9 +782,9 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, gimple *stmt) } } -/* STMT is a memory write where one or more bytes written are dead - stores. ORIG is the bitmap of bytes stored by STMT. LIVE is the - bitmap of stores that are actually live. +/* STMT is a memory write where one or more bytes written are dead stores. + REF is a representation of the memory written. LIVE is the bitmap of + stores to REF that are still live. Attempt to rewrite STMT so that it writes fewer memory locations. Right now we only support trimming at the start or end of the memory region.