From: John David Anglin Date: Mon, 3 Feb 2003 18:01:38 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-3.2.2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=557ef47ced0eb837c2ed3cb0bf062228734f6ee3;p=thirdparty%2Fgcc.git backport: [multiple changes] 2003-02-03 Eric Botcazou * cfgcleanup.c (try_forward_edges): Check for null insn. 2003-02-03 Franz Sirl Eric Botcazou Backport following patches: 2002-09-16 Richard Henderson * emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust SIZE as well as OFFSET for BITPOS. 2002-09-08 Jan Hubicka * emit-rtl.c (set_mem_attributes_minus_bitpos): Fix array_ref handling. 2002-07-29 Richard Henderson * emit-rtl.c (set_mem_attributes_minus_bitpos): Rename from set_mem_attributes and add BITPOS argument. Subtract it from OFFSET when same is adjusted. (set_mem_attributes): New wrapper function. * expr.c (expand_assignment): Use set_mem_attributes_minus_bitpos; remove offset adjustment hack. * expr.h (set_mem_attributes_minus_bitpos): Declare. 2002-07-25 Richard Henderson * emit-rtl.c (set_mem_attributes): Fix size and alignment thinkos in ARRAY_REF of DECL_P case. 2002-07-21 Richard Henderson * emit-rtl.c (set_mem_attributes): Preserve indirection of PARM_DECL when flag_argument_noalias == 2. * alias.c (nonoverlapping_memrefs_p): Handle that. * print-rtl.c (print_mem_expr): Likewise. 2002-06-03 Dan Nicolaescu * alias.c (nonoverlapping_memrefs_p): Fix off by one error. From-SVN: r62331 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0e2a3b2ccfd4..ff6b5a639e58 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,48 @@ +2003-02-03 Eric Botcazou + + * cfgcleanup.c (try_forward_edges): Check for null insn. + +2003-02-03 Franz Sirl + Eric Botcazou + + Backport following patches: + + 2002-09-16 Richard Henderson + + * emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust SIZE + as well as OFFSET for BITPOS. + + 2002-09-08 Jan Hubicka + + * emit-rtl.c (set_mem_attributes_minus_bitpos): Fix array_ref + handling. + + 2002-07-29 Richard Henderson + + * emit-rtl.c (set_mem_attributes_minus_bitpos): Rename from + set_mem_attributes and add BITPOS argument. Subtract it from + OFFSET when same is adjusted. + (set_mem_attributes): New wrapper function. + * expr.c (expand_assignment): Use set_mem_attributes_minus_bitpos; + remove offset adjustment hack. + * expr.h (set_mem_attributes_minus_bitpos): Declare. + + 2002-07-25 Richard Henderson + + * emit-rtl.c (set_mem_attributes): Fix size and alignment thinkos + in ARRAY_REF of DECL_P case. + + 2002-07-21 Richard Henderson + + * emit-rtl.c (set_mem_attributes): Preserve indirection of PARM_DECL + when flag_argument_noalias == 2. + * alias.c (nonoverlapping_memrefs_p): Handle that. + * print-rtl.c (print_mem_expr): Likewise. + + 2002-06-03 Dan Nicolaescu + + * alias.c (nonoverlapping_memrefs_p): Fix off by one error. + 2003-02-03 Steve Ellcey * config/pa/pa64-hpux.h (INIT_ENVIRONMENT): New. diff --git a/gcc/alias.c b/gcc/alias.c index 15f2d7b86618..db9dc07ed9ee 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -1935,6 +1935,14 @@ nonoverlapping_memrefs_p (x, y) moffsetx = adjust_offset_for_component_ref (exprx, moffsetx); exprx = t; } + else if (TREE_CODE (exprx) == INDIRECT_REF) + { + exprx = TREE_OPERAND (exprx, 0); + if (flag_argument_noalias < 2 + || TREE_CODE (exprx) != PARM_DECL) + return 0; + } + moffsety = MEM_OFFSET (y); if (TREE_CODE (expry) == COMPONENT_REF) { @@ -1944,6 +1952,13 @@ nonoverlapping_memrefs_p (x, y) moffsety = adjust_offset_for_component_ref (expry, moffsety); expry = t; } + else if (TREE_CODE (expry) == INDIRECT_REF) + { + expry = TREE_OPERAND (expry, 0); + if (flag_argument_noalias < 2 + || TREE_CODE (expry) != PARM_DECL) + return 0; + } if (! DECL_P (exprx) || ! DECL_P (expry)) return 0; @@ -2012,7 +2027,7 @@ nonoverlapping_memrefs_p (x, y) /* If we don't know the size of the lower-offset value, we can't tell if they conflict. Otherwise, we do the test. */ - return sizex >= 0 && offsety > offsetx + sizex; + return sizex >= 0 && offsety >= offsetx + sizex; } /* True dependence: X is read after store in MEM takes place. */ diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 12be4f523c6e..9589d1f6a43f 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -469,7 +469,7 @@ try_forward_edges (mode, b) && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG) break; - if (GET_CODE (insn) == NOTE) + if (insn && GET_CODE (insn) == NOTE) break; } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 49ad4e025003..e2bbd85003c6 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1698,19 +1698,22 @@ component_ref_for_mem_expr (ref) /* Given REF, a MEM, and T, either the type of X or the expression corresponding to REF, set the memory attributes. OBJECTP is nonzero - if we are making a new object of this type. */ + if we are making a new object of this type. BITPOS is nonzero if + there is an offset outstanding on T that will be applied later. */ void -set_mem_attributes (ref, t, objectp) +set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos) rtx ref; tree t; int objectp; + HOST_WIDE_INT bitpos; { HOST_WIDE_INT alias = MEM_ALIAS_SET (ref); tree expr = MEM_EXPR (ref); rtx offset = MEM_OFFSET (ref); rtx size = MEM_SIZE (ref); unsigned int align = MEM_ALIGN (ref); + HOST_WIDE_INT apply_bitpos = 0; tree type; /* It can happen that type_for_mode was given a mode for which there @@ -1779,6 +1782,7 @@ set_mem_attributes (ref, t, objectp) { expr = t; offset = const0_rtx; + apply_bitpos = bitpos; size = (DECL_SIZE_UNIT (t) && host_integerp (DECL_SIZE_UNIT (t), 1) ? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0); @@ -1803,6 +1807,7 @@ set_mem_attributes (ref, t, objectp) { expr = component_ref_for_mem_expr (t); offset = const0_rtx; + apply_bitpos = bitpos; /* ??? Any reason the field size would be different than the size we got from the type? */ } @@ -1814,27 +1819,97 @@ set_mem_attributes (ref, t, objectp) do { + tree index = TREE_OPERAND (t, 1); + tree array = TREE_OPERAND (t, 0); + tree domain = TYPE_DOMAIN (TREE_TYPE (array)); + tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0); + tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array))); + + /* We assume all arrays have sizes that are a multiple of a byte. + First subtract the lower bound, if any, in the type of the + index, then convert to sizetype and multiply by the size of the + array element. */ + if (low_bound != 0 && ! integer_zerop (low_bound)) + index = fold (build (MINUS_EXPR, TREE_TYPE (index), + index, low_bound)); + + /* If the index has a self-referential type, pass it to a + WITH_RECORD_EXPR; if the component size is, pass our + component to one. */ + if (! TREE_CONSTANT (index) + && contains_placeholder_p (index)) + index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, t); + if (! TREE_CONSTANT (unit_size) + && contains_placeholder_p (unit_size)) + unit_size = build (WITH_RECORD_EXPR, sizetype, + unit_size, array); + off_tree = fold (build (PLUS_EXPR, sizetype, fold (build (MULT_EXPR, sizetype, - TREE_OPERAND (t, 1), - TYPE_SIZE_UNIT (TREE_TYPE (t)))), + index, + unit_size)), off_tree)); t = TREE_OPERAND (t, 0); } while (TREE_CODE (t) == ARRAY_REF); - if (TREE_CODE (t) == COMPONENT_REF) + if (DECL_P (t)) + { + expr = t; + offset = NULL; + if (host_integerp (off_tree, 1)) + { + HOST_WIDE_INT ioff = tree_low_cst (off_tree, 1); + HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT; + align = DECL_ALIGN (t); + if (aoff && aoff < align) + align = aoff; + offset = GEN_INT (ioff); + apply_bitpos = bitpos; + } + } + else if (TREE_CODE (t) == COMPONENT_REF) { expr = component_ref_for_mem_expr (t); if (host_integerp (off_tree, 1)) - offset = GEN_INT (tree_low_cst (off_tree, 1)); + { + offset = GEN_INT (tree_low_cst (off_tree, 1)); + apply_bitpos = bitpos; + } /* ??? Any reason the field size would be different than the size we got from the type? */ } + else if (flag_argument_noalias > 1 + && TREE_CODE (t) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (t, 0)) == PARM_DECL) + { + expr = t; + offset = NULL; + } + } + + /* If this is a Fortran indirect argument reference, record the + parameter decl. */ + else if (flag_argument_noalias > 1 + && TREE_CODE (t) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (t, 0)) == PARM_DECL) + { + expr = t; + offset = NULL; } } + /* If we modified OFFSET based on T, then subtract the outstanding + bit position offset. Similarly, increase the size of the accessed + object to contain the negative offset. */ + if (apply_bitpos) + { + offset = plus_constant (offset, -(apply_bitpos / BITS_PER_UNIT)); + if (size) + size = plus_constant (size, apply_bitpos / BITS_PER_UNIT); + } + /* Now set the attributes we computed above. */ MEM_ATTRS (ref) = get_mem_attrs (alias, expr, offset, size, align, GET_MODE (ref)); @@ -1851,6 +1926,15 @@ set_mem_attributes (ref, t, objectp) MEM_IN_STRUCT_P (ref) = 1; } +void +set_mem_attributes (ref, t, objectp) + rtx ref; + tree t; + int objectp; +{ + set_mem_attributes_minus_bitpos (ref, t, objectp, 0); +} + /* Set the alias set of MEM to SET. */ void diff --git a/gcc/expr.c b/gcc/expr.c index 104aae67cf92..2a13cd4825f6 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3722,17 +3722,7 @@ expand_assignment (to, from, want_value, suggest_reg) DECL_RTX of the parent struct. Don't munge it. */ to_rtx = shallow_copy_rtx (to_rtx); - set_mem_attributes (to_rtx, to, 0); - - /* If we changed MEM_EXPR, that means we're now referencing - the COMPONENT_REF, which means that MEM_OFFSET must be - relative to that field. But we've not yet reflected BITPOS - in TO_RTX. This will be done in store_field. Adjust for - that by biasing MEM_OFFSET by -bitpos. */ - if (MEM_EXPR (to_rtx) != old_expr && MEM_OFFSET (to_rtx) - && (bitpos / BITS_PER_UNIT) != 0) - set_mem_offset (to_rtx, GEN_INT (INTVAL (MEM_OFFSET (to_rtx)) - - (bitpos / BITS_PER_UNIT))); + set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos); } /* Deal with volatile and readonly fields. The former is only done diff --git a/gcc/expr.h b/gcc/expr.h index 4658a5099c55..fb7c61dcae3b 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -677,6 +677,12 @@ extern void maybe_set_unchanging PARAMS ((rtx, tree)); corresponding to REF, set the memory attributes. OBJECTP is nonzero if we are making a new object of this type. */ extern void set_mem_attributes PARAMS ((rtx, tree, int)); + +/* Similar, except that BITPOS has not yet been applied to REF, so if + we alter MEM_OFFSET according to T then we should subtract BITPOS + expecting that it'll be added back in later. */ +extern void set_mem_attributes_minus_bitpos PARAMS ((rtx, tree, int, + HOST_WIDE_INT)); #endif /* Assemble the static constant template for function entry trampolines. */ diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index a93a99b61a23..28f6066cad0c 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -92,6 +92,12 @@ print_mem_expr (outfile, expr) fprintf (outfile, ".%s", IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (expr, 1)))); } + else if (TREE_CODE (expr) == INDIRECT_REF) + { + fputs (" (*", outfile); + print_mem_expr (outfile, TREE_OPERAND (expr, 0)); + fputs (")", outfile); + } else if (DECL_NAME (expr)) fprintf (outfile, " %s", IDENTIFIER_POINTER (DECL_NAME (expr))); else if (TREE_CODE (expr) == RESULT_DECL)