This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR middle-end/17746 (take 2)
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 22 Dec 2004 21:03:11 +0100
- Subject: [PATCH] Fix PR middle-end/17746 (take 2)
Hi,
This is the Ada bootstrap failure on the SPARC (and the PA), a problem related
to get_inner_reference and certain kinds of VIEW_CONVERT_EXPR nodes.
Original post: http://gcc.gnu.org/ml/gcc-patches/2004-10/msg01630.html
This patch implements a slightly different approach, although the underlying
idea is still the same. However, to take into account concerns about the
potential discrepancy between handled_component_p and get_inner_reference,
I've added a new parameter to get_inner_reference that controls how the
function handles the problematic nodes; it is almost always set to false so
that the 2 functions almost always agree, it is set to true only at the
low-level in the RTL expanders. I've also heavily commented.
Bootstrapped/regtested on sparc-sun-solaris2.8, with still 18 failures in the
ACATS testsuite.
2004-12-22 Eric Botcazou <ebotcazou@libertysurf.fr>
PR middle-end/17746
* expr.c (get_inner_reference): Add 'keep_aligning' parameter.
Break on aligning VIEW_CONVERT_EXPR nodes on STRICT_ALIGNMENT
platforms only if keep_aligning is true.
(expand_assignment): Adjust call to get_inner_reference.
(expand_expr_addr_expr_1): Likewise.
(expand_expr_real_1): Likewise.
* dojump.c (do_jump): Likewise.
* dwarf2out.c (loc_descriptor_from_tree_1): Likewise.
* fold-const.c (optimize_bit_field_compare): Likewise.
(decode_field_reference): Likewise.
(split_address_to_core_and_offset): Likewise.
* tree-ssa-loop-ivopts.c (split_address_cost): Likewise.
* expr.h (get_inner_reference): Adjust prototype.
ada/
* trans.c (Attribute_to_gnu): Adjust call to get_inner_reference.
* utils2.c (build_unary_op): Likewise.
--
Eric Botcazou
Index: dojump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dojump.c,v
retrieving revision 1.34
diff -u -p -r1.34 dojump.c
--- dojump.c 12 Dec 2004 21:01:17 -0000 1.34
+++ dojump.c 22 Dec 2004 09:14:56 -0000
@@ -315,7 +315,7 @@ do_jump (tree exp, rtx if_false_label, r
/* Get description of this reference. We don't actually care
about the underlying object here. */
get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
- &unsignedp, &volatilep);
+ &unsignedp, &volatilep, false);
type = lang_hooks.types.type_for_size (bitsize, unsignedp);
if (! SLOW_BYTE_ACCESS
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.562
diff -u -p -r1.562 dwarf2out.c
--- dwarf2out.c 9 Dec 2004 10:54:33 -0000 1.562
+++ dwarf2out.c 22 Dec 2004 09:15:02 -0000
@@ -8965,7 +8965,7 @@ loc_descriptor_from_tree_1 (tree loc, in
int volatilep;
obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
- &unsignedp, &volatilep);
+ &unsignedp, &volatilep, false);
if (obj == loc)
return 0;
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.764
diff -u -p -r1.764 expr.c
--- expr.c 21 Dec 2004 07:49:58 -0000 1.764
+++ expr.c 22 Dec 2004 09:15:07 -0000
@@ -3788,7 +3788,7 @@ expand_assignment (tree to, tree from)
push_temp_slots ();
tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
- &unsignedp, &volatilep);
+ &unsignedp, &volatilep, true);
/* If we are going to use store_bit_field and extract_bit_field,
make sure to_rtx will be safe for multiple use. */
@@ -5244,13 +5244,27 @@ store_field (rtx target, HOST_WIDE_INT b
If the field describes a variable-sized object, *PMODE is set to
VOIDmode and *PBITSIZE is set to -1. An access cannot be made in
- this case, but the address of the object can be found. */
+ this case, but the address of the object can be found.
+
+ If KEEP_ALIGNING is true and the target is STRICT_ALIGNMENT, we don't
+ look through nodes that serve as markers of a greater alignment than
+ the one that can be deduced from the expression. These nodes make it
+ possible for front-ends to prevent temporaries from being created by
+ the middle-end on alignment considerations. For that purpose, the
+ normal operating mode at high-level is to always pass FALSE so that
+ the ultimate containing object is really returned; moreover, the
+ associated predicate handled_component_p will always return TRUE
+ on these nodes, thus indicating that they are essentially handled
+ by get_inner_reference. TRUE should only be passed when the caller
+ is scanning the expression in order to build another representation
+ and specifically knows how to handle these nodes; as such, this is
+ the normal operating mode in the RTL expanders. */
tree
get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
HOST_WIDE_INT *pbitpos, tree *poffset,
enum machine_mode *pmode, int *punsignedp,
- int *pvolatilep)
+ int *pvolatilep, bool keep_aligning)
{
tree size_tree = 0;
enum machine_mode mode = VOIDmode;
@@ -5352,14 +5366,10 @@ get_inner_reference (tree exp, HOST_WIDE
bitsize_int (*pbitsize));
break;
- /* We can go inside most conversions: all NON_VALUE_EXPRs, all normal
- conversions that don't change the mode, and all view conversions
- except those that need to "step up" the alignment. */
-
case VIEW_CONVERT_EXPR:
- if ((TYPE_ALIGN (TREE_TYPE (exp))
+ if (keep_aligning && STRICT_ALIGNMENT
+ && (TYPE_ALIGN (TREE_TYPE (exp))
> TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))))
- && STRICT_ALIGNMENT
&& (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
< BIGGEST_ALIGNMENT)
&& (TYPE_ALIGN_OK (TREE_TYPE (exp))
@@ -6082,8 +6092,13 @@ expand_expr_addr_expr_1 (tree exp, rtx t
return result;
}
+ /* Pass FALSE as the last argument to get_inner_reference although
+ we are expanding to RTL. The rationale is that we know how to
+ handle "aligning nodes" here: we can just bypass them because
+ they won't change the final object whose address will be returned
+ (they actually exist only for that purpose). */
inner = get_inner_reference (exp, &bitsize, &bitpos, &offset,
- &mode1, &unsignedp, &volatilep);
+ &mode1, &unsignedp, &volatilep, false);
break;
}
@@ -6885,7 +6900,7 @@ expand_expr_real_1 (tree exp, rtx target
tree offset;
int volatilep = 0;
tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset,
- &mode1, &unsignedp, &volatilep);
+ &mode1, &unsignedp, &volatilep, true);
rtx orig_op0;
/* If we got back the original object, something is wrong. Perhaps
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.486
diff -u -p -r1.486 fold-const.c
--- fold-const.c 18 Dec 2004 19:03:49 -0000 1.486
+++ fold-const.c 22 Dec 2004 09:15:11 -0000
@@ -3102,7 +3102,7 @@ optimize_bit_field_compare (enum tree_co
do anything if the inner expression is a PLACEHOLDER_EXPR since we
then will no longer be able to replace it. */
linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
- &lunsignedp, &lvolatilep);
+ &lunsignedp, &lvolatilep, false);
if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
|| offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR)
return 0;
@@ -3112,7 +3112,7 @@ optimize_bit_field_compare (enum tree_co
/* If this is not a constant, we can only do something if bit positions,
sizes, and signedness are the same. */
rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
- &runsignedp, &rvolatilep);
+ &runsignedp, &rvolatilep, false);
if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
|| lunsignedp != runsignedp || offset != 0
@@ -3288,7 +3288,7 @@ decode_field_reference (tree exp, HOST_W
}
inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
- punsignedp, pvolatilep);
+ punsignedp, pvolatilep, false);
if ((inner == exp && and_mask == 0)
|| *pbitsize < 0 || offset != 0
|| TREE_CODE (inner) == PLACEHOLDER_EXPR)
@@ -11018,7 +11018,8 @@ split_address_to_core_and_offset (tree e
if (TREE_CODE (exp) == ADDR_EXPR)
{
core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
- poffset, &mode, &unsignedp, &volatilep);
+ poffset, &mode, &unsignedp, &volatilep,
+ false);
if (TREE_CODE (core) == INDIRECT_REF)
core = TREE_OPERAND (core, 0);
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v
retrieving revision 2.37
diff -u -p -r2.37 tree-ssa-loop-ivopts.c
--- tree-ssa-loop-ivopts.c 20 Dec 2004 03:11:52 -0000 2.37
+++ tree-ssa-loop-ivopts.c 22 Dec 2004 09:15:13 -0000
@@ -2829,7 +2829,7 @@ split_address_cost (struct ivopts_data *
int unsignedp, volatilep;
core = get_inner_reference (addr, &bitsize, &bitpos, &toffset, &mode,
- &unsignedp, &volatilep);
+ &unsignedp, &volatilep, false);
if (toffset != 0
|| bitpos % BITS_PER_UNIT != 0
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.668
diff -u -p -r1.668 tree.h
--- tree.h 20 Dec 2004 11:26:28 -0000 1.668
+++ tree.h 22 Dec 2004 09:15:15 -0000
@@ -3364,7 +3364,8 @@ extern tree get_narrower (tree, int *);
and find the ultimate containing object, which is returned. */
extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
- tree *, enum machine_mode *, int *, int *);
+ tree *, enum machine_mode *, int *, int *,
+ bool);
/* Return 1 if T is an expression that get_inner_reference handles. */
Index: ada/trans.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/trans.c,v
retrieving revision 1.85
diff -u -p -r1.85 trans.c
--- ada/trans.c 19 Dec 2004 19:59:23 -0000 1.85
+++ ada/trans.c 22 Dec 2004 09:15:20 -0000
@@ -932,7 +932,7 @@ Attribute_to_gnu (Node_Id gnat_node, tre
&& TREE_CODE (gnu_prefix) == FIELD_DECL));
get_inner_reference (gnu_prefix, &bitsize, &bitpos, &gnu_offset,
- &mode, &unsignedp, &volatilep);
+ &mode, &unsignedp, &volatilep, false);
if (TREE_CODE (gnu_prefix) == COMPONENT_REF)
{
Index: ada/utils2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/utils2.c,v
retrieving revision 1.42
diff -u -p -r1.42 utils2.c
--- ada/utils2.c 4 Oct 2004 14:56:03 -0000 1.42
+++ ada/utils2.c 22 Dec 2004 09:15:21 -0000
@@ -1087,7 +1087,7 @@ build_unary_op (enum tree_code op_code,
int unsignedp, volatilep;
inner = get_inner_reference (operand, &bitsize, &bitpos, &offset,
- &mode, &unsignedp, &volatilep);
+ &mode, &unsignedp, &volatilep, false);
/* If INNER is a padding type whose field has a self-referential
size, convert to that inner type. We know the offset is zero