re PR middle-end/17746 (ICE when building the Ada RTS)
authorEric Botcazou <ebotcazou@libertysurf.fr>
Thu, 23 Dec 2004 13:02:33 +0000 (14:02 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 23 Dec 2004 13:02:33 +0000 (13:02 +0000)
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.

From-SVN: r92549

gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/trans.c
gcc/ada/utils2.c
gcc/dojump.c
gcc/dwarf2out.c
gcc/expr.c
gcc/fold-const.c
gcc/tree-ssa-loop-ivopts.c

index 0872bf6..78879a7 100644 (file)
@@ -1,3 +1,20 @@
+2004-12-23  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.
+
 2004-12-23  Richard Henderson  <rth@redhat.com>
 
        * config/i386/i386.c (override_options): Revert last change
index 479443a..792ddcd 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-23  Eric Botcazou  <ebotcazou@libertysurf.fr>
+       * trans.c (Attribute_to_gnu): Adjust call to get_inner_reference.
+       * utils2.c (build_unary_op): Likewise.
+
 2004-12-22  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * trans.c (mark_visited): Set TYPE_SIZES_GIMPLIFIED.
index 0db1709..a93ff5d 100644 (file)
@@ -932,7 +932,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
                          && 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 3727ce4..04ab0cb 100644 (file)
@@ -1087,7 +1087,7 @@ build_unary_op (enum tree_code op_code, tree result_type, tree operand)
              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 b1e17ec..0dc826b 100644 (file)
@@ -315,7 +315,7 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label)
         /* 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 74303c2..beed56b 100644 (file)
@@ -8965,7 +8965,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
        int volatilep;
 
        obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
-                                  &unsignedp, &volatilep);
+                                  &unsignedp, &volatilep, false);
 
        if (obj == loc)
          return 0;
index d69a8df..f602306 100644 (file)
@@ -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 bitsize, HOST_WIDE_INT bitpos,
 
    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_INT *pbitsize,
                                   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 target, enum machine_mode tmode,
          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;
     }
 
@@ -6908,7 +6923,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        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 d249f75..8f8624c 100644 (file)
@@ -3102,7 +3102,7 @@ optimize_bit_field_compare (enum tree_code code, tree compare_type,
      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_code code, tree compare_type,
      /* 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_WIDE_INT *pbitsize,
     }
 
   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 exp,
   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 6935cf5..d1a1bdd 100644 (file)
@@ -2829,7 +2829,7 @@ split_address_cost (struct ivopts_data *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