This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]