OSDN Git Service

* tree.h (contains_placeholder_p): Now returns bool.
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 May 2003 18:44:57 +0000 (18:44 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 May 2003 18:44:57 +0000 (18:44 +0000)
(CONTAINS_PLACEHOLDER_P): New macro.
(type_contains_placeholder_p): New function.
* tree.c (save_expr): Remove code avoiding folding COMPONENT_REF.
(contains_placeholder_p): Now returns bool.
Rework to use CONTAINS_PLACEHOLDER_P macro.
(type_contains_placeholder_p): New function.
* fold-const.c (fold, case COMPONENT_REF): Don't fold if
type_contains_placeholder_p.
(fold_range_test, fold_mathfn_compare, fold_inf_compare, fold):
Use CONTAINS_PLACEHOLDER_P macro.
* builtins.c (fold_builtin): Likewise.
* calls.c (initialize_argument_information): Likewise.
* emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
* explow.c (expr_size): Likewise.
* expr.c (store_constructor, get_inner_reference): Likewise.
* function.c (assign_parms): Likewise.
* stor-layout.c (variable_size): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@67189 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/calls.c
gcc/emit-rtl.c
gcc/explow.c
gcc/expr.c
gcc/fold-const.c
gcc/function.c
gcc/tree.c
gcc/tree.h

index 82911fa..d56b572 100644 (file)
@@ -1,3 +1,24 @@
+2003-05027  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       * tree.h (contains_placeholder_p): Now returns bool.
+       (CONTAINS_PLACEHOLDER_P): New macro.
+       (type_contains_placeholder_p): New function.
+       * tree.c (save_expr): Remove code avoiding folding COMPONENT_REF.
+       (contains_placeholder_p): Now returns bool.
+       Rework to use CONTAINS_PLACEHOLDER_P macro.
+       (type_contains_placeholder_p): New function.
+       * fold-const.c (fold, case COMPONENT_REF): Don't fold if
+       type_contains_placeholder_p.
+       (fold_range_test, fold_mathfn_compare, fold_inf_compare, fold): 
+       Use CONTAINS_PLACEHOLDER_P macro.
+       * builtins.c (fold_builtin): Likewise.
+       * calls.c (initialize_argument_information): Likewise.
+       * emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
+       * explow.c (expr_size): Likewise.
+       * expr.c (store_constructor, get_inner_reference): Likewise.
+       * function.c (assign_parms): Likewise.
+       * stor-layout.c (variable_size): Likewise.
+
 2003-05-25  Gabriel Dos Reis <gdr@integrable-solutions.net>
 
        * diagnostic.h (output_verbatim, verbatim):  Remove  printf
index e2da8b8..eef1cce 100644 (file)
@@ -5242,7 +5242,7 @@ fold_builtin (exp)
              /* Optimize pow(x,2.0) = x*x.  */
              if (REAL_VALUES_EQUAL (c, dconst2)
                  && (*lang_hooks.decls.global_bindings_p) () == 0
-                 && ! contains_placeholder_p (arg0))
+                 && ! CONTAINS_PLACEHOLDER_P (arg0))
                {
                  arg0 = save_expr (arg0);
                  return fold (build (MULT_EXPR, type, arg0, arg0));
@@ -5252,7 +5252,7 @@ fold_builtin (exp)
              if (flag_unsafe_math_optimizations
                  && REAL_VALUES_EQUAL (c, dconstm2)
                  && (*lang_hooks.decls.global_bindings_p) () == 0
-                 && ! contains_placeholder_p (arg0))
+                 && ! CONTAINS_PLACEHOLDER_P (arg0))
                {
                  arg0 = save_expr (arg0);
                  return fold (build (RDIV_EXPR, type,
index a3f2de0..9d7899c 100644 (file)
@@ -1146,8 +1146,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
         with those made by function.c.  */
 
       /* See if this argument should be passed by invisible reference.  */
-      if ((TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
-          && contains_placeholder_p (TYPE_SIZE (type)))
+      if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
          || TREE_ADDRESSABLE (type)
 #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
          || FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type),
index 1df50a7..f568991 100644 (file)
@@ -1986,11 +1986,9 @@ set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
              /* 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))
+             if (CONTAINS_PLACEHOLDER_P (index))
                index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, t);
-             if (! TREE_CONSTANT (unit_size)
-                 && contains_placeholder_p (unit_size))
+             if (CONTAINS_PLACEHOLDER_P (unit_size))
                unit_size = build (WITH_RECORD_EXPR, sizetype,
                                   unit_size, array);
 
index da7e2b7..ec7a69a 100644 (file)
@@ -294,8 +294,7 @@ expr_size (exp)
 {
   tree size = (*lang_hooks.expr_size) (exp);
 
-  if (TREE_CODE (size) != INTEGER_CST
-      && contains_placeholder_p (size))
+  if (CONTAINS_PLACEHOLDER_P (size))
     size = build (WITH_RECORD_EXPR, sizetype, size, exp);
 
   return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
index d251a27..770bef4 100644 (file)
@@ -4982,7 +4982,7 @@ store_constructor (exp, target, cleared, size)
            {
              rtx offset_rtx;
 
-             if (contains_placeholder_p (offset))
+             if (CONTAINS_PLACEHOLDER_P (offset))
                offset = build (WITH_RECORD_EXPR, sizetype,
                                offset, make_tree (TREE_TYPE (exp), target));
 
@@ -5799,7 +5799,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
             made during type construction.  */
          if (this_offset == 0)
            break;
-         else if (contains_placeholder_p (this_offset))
+         else if (CONTAINS_PLACEHOLDER_P (this_offset))
            this_offset = build (WITH_RECORD_EXPR, sizetype, this_offset, exp);
 
          offset = size_binop (PLUS_EXPR, offset, this_offset);
@@ -5829,9 +5829,9 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
          /* 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 (contains_placeholder_p (index))
+         if (CONTAINS_PLACEHOLDER_P (index))
            index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, exp);
-         if (contains_placeholder_p (unit_size))
+         if (CONTAINS_PLACEHOLDER_P (unit_size))
            unit_size = build (WITH_RECORD_EXPR, sizetype, unit_size, array);
 
          offset = size_binop (PLUS_EXPR, offset,
index 6a4e229..381bc9c 100644 (file)
@@ -3470,7 +3470,7 @@ fold_range_test (exp)
                      TREE_OPERAND (exp, 1));
 
       else if ((*lang_hooks.decls.global_bindings_p) () == 0
-              && ! contains_placeholder_p (lhs))
+              && ! CONTAINS_PLACEHOLDER_P (lhs))
        {
          tree common = save_expr (lhs);
 
@@ -4768,7 +4768,7 @@ fold_mathfn_compare (fcode, code, type, arg0, arg1)
 
              /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
              if ((*lang_hooks.decls.global_bindings_p) () != 0
-                 || contains_placeholder_p (arg))
+                 || CONTAINS_PLACEHOLDER_P (arg))
                return NULL_TREE;
 
              arg = save_expr (arg);
@@ -4788,7 +4788,7 @@ fold_mathfn_compare (fcode, code, type, arg0, arg1)
 
          /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
          if ((*lang_hooks.decls.global_bindings_p) () == 0
-             && ! contains_placeholder_p (arg))
+             && ! CONTAINS_PLACEHOLDER_P (arg))
            {
              arg = save_expr (arg);
              return fold (build (TRUTH_ANDIF_EXPR, type,
@@ -4851,7 +4851,7 @@ fold_inf_compare (code, type, arg0, arg1)
 
       /* x <= +Inf is the same as x == x, i.e. isfinite(x).  */
       if ((*lang_hooks.decls.global_bindings_p) () == 0
-         && ! contains_placeholder_p (arg0))
+         && ! CONTAINS_PLACEHOLDER_P (arg0))
        {
          arg0 = save_expr (arg0);
          return fold (build (EQ_EXPR, type, arg0, arg0));
@@ -5119,7 +5119,7 @@ fold (expr)
                   || count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
               && (! TREE_SIDE_EFFECTS (arg0)
                   || ((*lang_hooks.decls.global_bindings_p) () == 0
-                      && ! contains_placeholder_p (arg0))))
+                      && ! CONTAINS_PLACEHOLDER_P (arg0))))
        return
          fold_binary_op_with_conditional_arg (code, type, arg1, arg0,
                                               /*cond_first_p=*/0);
@@ -5133,7 +5133,7 @@ fold (expr)
                   || count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
               && (! TREE_SIDE_EFFECTS (arg1)
                   || ((*lang_hooks.decls.global_bindings_p) () == 0
-                      && ! contains_placeholder_p (arg1))))
+                      && ! CONTAINS_PLACEHOLDER_P (arg1))))
        return
          fold_binary_op_with_conditional_arg (code, type, arg0, arg1,
                                               /*cond_first_p=*/1);
@@ -5313,7 +5313,8 @@ fold (expr)
       return t;
 
     case COMPONENT_REF:
-      if (TREE_CODE (arg0) == CONSTRUCTOR)
+      if (TREE_CODE (arg0) == CONSTRUCTOR
+         && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
        {
          tree m = purpose_member (arg1, CONSTRUCTOR_ELTS (arg0));
          if (m)
@@ -5883,7 +5884,7 @@ fold (expr)
          /* x*2 is x+x */
          if (! wins && real_twop (arg1)
              && (*lang_hooks.decls.global_bindings_p) () == 0
-             && ! contains_placeholder_p (arg0))
+             && ! CONTAINS_PLACEHOLDER_P (arg0))
            {
              tree arg = save_expr (arg0);
              return fold (build (PLUS_EXPR, type, arg, arg));
index 8177952..64d045b 100644 (file)
@@ -4494,8 +4494,7 @@ assign_parms (fndecl)
         object itself or if the machine requires these objects be passed
         that way.  */
 
-      if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
-          && contains_placeholder_p (TYPE_SIZE (passed_type)))
+      if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (passed_type))
          || TREE_ADDRESSABLE (passed_type)
 #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
          || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
index efb4e22..51ff3fa 100644 (file)
@@ -1390,15 +1390,9 @@ tree
 save_expr (expr)
      tree expr;
 {
-  tree t = expr;
+  tree t = fold (expr);
   tree inner;
 
-  /* Don't fold a COMPONENT_EXPR: if the operand was a CONSTRUCTOR (the
-     only time it will fold), it can cause problems with PLACEHOLDER_EXPRs
-     in Ada.  Moreover, it isn't at all clear why we fold here at all.  */
-  if (TREE_CODE (t) != COMPONENT_REF)
-    t = fold (t);
-
   /* If the tree evaluates to a constant, then we don't want to hide that
      fact (i.e. this allows further folding, and direct checks for constants).
      However, a read-only object that has side effects cannot be bypassed.
@@ -1745,7 +1739,7 @@ unsafe_for_reeval (expr)
 /* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
    or offset that depends on a field within a record.  */
 
-int
+bool
 contains_placeholder_p (exp)
      tree exp;
 {
@@ -1770,13 +1764,12 @@ contains_placeholder_p (exp)
         position computations since they will be converted into a
         WITH_RECORD_EXPR involving the reference, which will assume
         here will be valid.  */
-      return contains_placeholder_p (TREE_OPERAND (exp, 0));
+      return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
 
     case 'x':
       if (code == TREE_LIST)
-       return (contains_placeholder_p (TREE_VALUE (exp))
-               || (TREE_CHAIN (exp) != 0
-                   && contains_placeholder_p (TREE_CHAIN (exp))));
+       return (CONTAINS_PLACEHOLDER_P (TREE_VALUE (exp))
+               || CONTAINS_PLACEHOLDER_P (TREE_CHAIN (exp)));
       break;
 
     case '1':
@@ -1786,16 +1779,16 @@ contains_placeholder_p (exp)
        {
        case COMPOUND_EXPR:
          /* Ignoring the first operand isn't quite right, but works best.  */
-         return contains_placeholder_p (TREE_OPERAND (exp, 1));
+         return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
 
        case RTL_EXPR:
        case CONSTRUCTOR:
          return 0;
 
        case COND_EXPR:
-         return (contains_placeholder_p (TREE_OPERAND (exp, 0))
-                 || contains_placeholder_p (TREE_OPERAND (exp, 1))
-                 || contains_placeholder_p (TREE_OPERAND (exp, 2)));
+         return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
+                 || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
+                 || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
 
        case SAVE_EXPR:
          /* If we already know this doesn't have a placeholder, don't
@@ -1804,15 +1797,14 @@ contains_placeholder_p (exp)
            return 0;
 
          SAVE_EXPR_NOPLACEHOLDER (exp) = 1;
-         result = contains_placeholder_p (TREE_OPERAND (exp, 0));
+         result = CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
          if (result)
            SAVE_EXPR_NOPLACEHOLDER (exp) = 0;
 
          return result;
 
        case CALL_EXPR:
-         return (TREE_OPERAND (exp, 1) != 0
-                 && contains_placeholder_p (TREE_OPERAND (exp, 1)));
+         return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
 
        default:
          break;
@@ -1821,10 +1813,10 @@ contains_placeholder_p (exp)
       switch (TREE_CODE_LENGTH (code))
        {
        case 1:
-         return contains_placeholder_p (TREE_OPERAND (exp, 0));
+         return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
        case 2:
-         return (contains_placeholder_p (TREE_OPERAND (exp, 0))
-                 || contains_placeholder_p (TREE_OPERAND (exp, 1)));
+         return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
+                 || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)));
        default:
          return 0;
        }
@@ -1835,6 +1827,109 @@ contains_placeholder_p (exp)
   return 0;
 }
 
+/* Return 1 if any part of the computation of TYPE involves a PLACEHOLDER_EXPR.
+   This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and field
+   positions.  */
+
+bool
+type_contains_placeholder_p (type)
+     tree type;
+{
+  /* If the size contains a placeholder or the parent type (component type in
+     the case of arrays) type involves a placeholder, this type does.  */
+  if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
+      || CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (type))
+      || (TREE_TYPE (type) != 0
+         && type_contains_placeholder_p (TREE_TYPE (type))))
+    return 1;
+
+  /* Now do type-specific checks.  Note that the last part of the check above
+     greatly limits what we have to do below.  */
+  switch (TREE_CODE (type))
+    {
+    case VOID_TYPE:
+    case COMPLEX_TYPE:
+    case VECTOR_TYPE:
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
+    case CHAR_TYPE:
+    case POINTER_TYPE:
+    case OFFSET_TYPE:
+    case REFERENCE_TYPE:
+    case METHOD_TYPE:
+    case FILE_TYPE:
+    case FUNCTION_TYPE:
+      return 0;
+
+    case INTEGER_TYPE:
+    case REAL_TYPE:
+      /* Here we just check the bounds.  */
+      return (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (type))
+             || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));
+
+    case ARRAY_TYPE:
+    case SET_TYPE:
+      /* We're already checked the component type (TREE_TYPE), so just check
+        the index type.  */
+      return type_contains_placeholder_p (TYPE_DOMAIN (type));
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+      {
+       static tree seen_types = 0;
+       tree field;
+       bool ret = 0;
+
+       /* We have to be careful here that we don't end up in infinite
+          recursions due to a field of a type being a pointer to that type
+          or to a mutually-recursive type.  So we store a list of record
+          types that we've seen and see if this type is in them.  To save
+          memory, we don't use a list for just one type.  Here we check
+          whether we've seen this type before and store it if not.  */
+       if (seen_types == 0)
+         seen_types = type;
+       else if (TREE_CODE (seen_types) != TREE_LIST)
+         {
+           if (seen_types == type)
+             return 0;
+
+           seen_types = tree_cons (NULL_TREE, type,
+                                   build_tree_list (NULL_TREE, seen_types));
+         }
+       else
+         {
+           if (value_member (type, seen_types) != 0)
+             return 0;
+
+           seen_types = tree_cons (NULL_TREE, type, seen_types);
+         }
+
+       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+         if (TREE_CODE (field) == FIELD_DECL
+             && (CONTAINS_PLACEHOLDER_P (DECL_FIELD_OFFSET (field))
+                 || (TREE_CODE (type) == QUAL_UNION_TYPE
+                     && CONTAINS_PLACEHOLDER_P (DECL_QUALIFIER (field)))
+                 || type_contains_placeholder_p (TREE_TYPE (field))))
+           {
+             ret = true;
+             break;
+           }
+
+       /* Now remove us from seen_types and return the result.  */
+       if (seen_types == type)
+         seen_types = 0;
+       else
+         seen_types = TREE_CHAIN (seen_types);
+
+       return ret;
+      }
+
+    default:
+      abort ();
+    }
+}
+
 /* Return 1 if EXP contains any expressions that produce cleanups for an
    outer scope to deal with.  Used by fold.  */
 
@@ -1960,9 +2055,9 @@ substitute_in_expr (exp, f, r)
 
          op0 = TREE_OPERAND (exp, 0);
          op1 = TREE_OPERAND (exp, 1);
-         if (contains_placeholder_p (op0))
+         if (CONTAINS_PLACEHOLDER_P (op0))
            op0 = substitute_in_expr (op0, f, r);
-         if (contains_placeholder_p (op1))
+         if (CONTAINS_PLACEHOLDER_P (op1))
            op1 = substitute_in_expr (op1, f, r);
 
          if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
@@ -1994,11 +2089,11 @@ substitute_in_expr (exp, f, r)
          op1 = TREE_OPERAND (exp, 1);
          op2 = TREE_OPERAND (exp, 2);
 
-         if (contains_placeholder_p (op0))
+         if (CONTAINS_PLACEHOLDER_P (op0))
            op0 = substitute_in_expr (op0, f, r);
-         if (contains_placeholder_p (op1))
+         if (CONTAINS_PLACEHOLDER_P (op1))
            op1 = substitute_in_expr (op1, f, r);
-         if (contains_placeholder_p (op2))
+         if (CONTAINS_PLACEHOLDER_P (op2))
            op2 = substitute_in_expr (op2, f, r);
 
          if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
index 2c5f2d9..65b7de2 100644 (file)
@@ -2523,7 +2523,19 @@ extern int unsafe_for_reeval             PARAMS ((tree));
    Note that we only allow such expressions within simple arithmetic
    or a COND_EXPR.  */
 
-extern int contains_placeholder_p      PARAMS ((tree));
+extern bool contains_placeholder_p     PARAMS ((tree));
+
+/* This macro calls the above function but short-circuits the common
+   case of a constant to save time.  Also check for null.  */
+
+#define CONTAINS_PLACEHOLDER_P(EXP) \
+  ((EXP) != 0 && ! TREE_CONSTANT (EXP) && contains_placeholder_p (EXP))
+
+/* Return 1 if any part of the computation of TYPE involves a PLACEHOLDER_EXPR.
+   This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and field
+   positions.  */
+
+extern bool type_contains_placeholder_p        PARAMS ((tree));
 
 /* Return 1 if EXP contains any expressions that produce cleanups for an
    outer scope to deal with.  Used by fold.  */