OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index c39bccd..8bf2b77 100644 (file)
@@ -177,7 +177,7 @@ unsigned const char omp_clause_num_ops[] =
   1, /* OMP_CLAUSE_PRIVATE  */
   1, /* OMP_CLAUSE_SHARED  */
   1, /* OMP_CLAUSE_FIRSTPRIVATE  */
-  1, /* OMP_CLAUSE_LASTPRIVATE  */
+  2, /* OMP_CLAUSE_LASTPRIVATE  */
   4, /* OMP_CLAUSE_REDUCTION  */
   1, /* OMP_CLAUSE_COPYIN  */
   1, /* OMP_CLAUSE_COPYPRIVATE  */
@@ -186,7 +186,9 @@ unsigned const char omp_clause_num_ops[] =
   1, /* OMP_CLAUSE_SCHEDULE  */
   0, /* OMP_CLAUSE_NOWAIT  */
   0, /* OMP_CLAUSE_ORDERED  */
-  0  /* OMP_CLAUSE_DEFAULT  */
+  0, /* OMP_CLAUSE_DEFAULT  */
+  3, /* OMP_CLAUSE_COLLAPSE  */
+  0  /* OMP_CLAUSE_UNTIED   */
 };
 
 const char * const omp_clause_code_name[] =
@@ -204,7 +206,9 @@ const char * const omp_clause_code_name[] =
   "schedule",
   "nowait",
   "ordered",
-  "default"
+  "default",
+  "collapse",
+  "untied"
 };
 \f
 /* Init tree.c.  */
@@ -263,17 +267,14 @@ init_ttree (void)
   tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_MINIMAL] = 1;
   tree_contains_struct[LABEL_DECL][TS_DECL_MINIMAL] = 1;
   tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[STRUCT_FIELD_TAG][TS_DECL_MINIMAL] = 1;
   tree_contains_struct[NAME_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
   tree_contains_struct[SYMBOL_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
   tree_contains_struct[MEMORY_PARTITION_TAG][TS_DECL_MINIMAL] = 1;
 
-  tree_contains_struct[STRUCT_FIELD_TAG][TS_MEMORY_TAG] = 1;
   tree_contains_struct[NAME_MEMORY_TAG][TS_MEMORY_TAG] = 1;
   tree_contains_struct[SYMBOL_MEMORY_TAG][TS_MEMORY_TAG] = 1;
   tree_contains_struct[MEMORY_PARTITION_TAG][TS_MEMORY_TAG] = 1;
 
-  tree_contains_struct[STRUCT_FIELD_TAG][TS_STRUCT_FIELD_TAG] = 1;
   tree_contains_struct[MEMORY_PARTITION_TAG][TS_MEMORY_PARTITION_TAG] = 1;
 
   tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS] = 1;
@@ -370,8 +371,6 @@ tree_code_size (enum tree_code code)
          case NAME_MEMORY_TAG:
          case SYMBOL_MEMORY_TAG:
            return sizeof (struct tree_memory_tag);
-         case STRUCT_FIELD_TAG:
-           return sizeof (struct tree_struct_field_tag);
          case MEMORY_PARTITION_TAG:
            return sizeof (struct tree_memory_partition_tag);
          default:
@@ -621,7 +620,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
 
     case tcc_constant:
       TREE_CONSTANT (t) = 1;
-      TREE_INVARIANT (t) = 1;
       break;
 
     case tcc_expression:
@@ -1192,7 +1190,6 @@ build_string (int len, const char *str)
   memset (s, 0, sizeof (struct tree_common));
   TREE_SET_CODE (s, STRING_CST);
   TREE_CONSTANT (s) = 1;
-  TREE_INVARIANT (s) = 1;
   TREE_STRING_LENGTH (s) = len;
   memcpy (s->string.str, str, len);
   s->string.str[len] = '\0';
@@ -1605,8 +1602,7 @@ int
 really_constant_p (const_tree exp)
 {
   /* This is not quite the same as STRIP_NOPS.  It does more.  */
-  while (TREE_CODE (exp) == NOP_EXPR
-        || TREE_CODE (exp) == CONVERT_EXPR
+  while (CONVERT_EXPR_P (exp)
         || TREE_CODE (exp) == NON_LVALUE_EXPR)
     exp = TREE_OPERAND (exp, 0);
   return TREE_CONSTANT (exp);
@@ -1925,7 +1921,7 @@ expr_align (const_tree t)
 
   switch (TREE_CODE (t))
     {
-    case NOP_EXPR:  case CONVERT_EXPR:  case NON_LVALUE_EXPR:
+    CASE_CONVERT:  case NON_LVALUE_EXPR:
       /* If we have conversions, we know that the alignment of the
         object must meet each of the alignments of the types.  */
       align0 = expr_align (TREE_OPERAND (t, 0));
@@ -2056,7 +2052,111 @@ staticp (tree arg)
        return NULL;
     }
 }
+
 \f
+
+
+/* Return whether OP is a DECL whose address is function-invariant.  */
+
+bool
+decl_address_invariant_p (const_tree op)
+{
+  /* The conditions below are slightly less strict than the one in
+     staticp.  */
+
+  switch (TREE_CODE (op))
+    {
+    case PARM_DECL:
+    case RESULT_DECL:
+    case LABEL_DECL:
+    case FUNCTION_DECL:
+      return true;
+
+    case VAR_DECL:
+      if (((TREE_STATIC (op) || DECL_EXTERNAL (op))
+           && !DECL_DLLIMPORT_P (op))
+          || DECL_THREAD_LOCAL_P (op)
+          || DECL_CONTEXT (op) == current_function_decl
+          || decl_function_context (op) == current_function_decl)
+        return true;
+      break;
+
+    case CONST_DECL:
+      if ((TREE_STATIC (op) || DECL_EXTERNAL (op))
+          || decl_function_context (op) == current_function_decl)
+        return true;
+      break;
+
+    default:
+      break;
+    }
+
+  return false;
+}
+
+
+/* Return true if T is function-invariant (internal function, does
+   not handle arithmetic; that's handled in skip_simple_arithmetic and
+   tree_invariant_p).  */
+
+static bool tree_invariant_p (tree t);
+
+static bool
+tree_invariant_p_1 (tree t)
+{
+  tree op;
+
+  if (TREE_CONSTANT (t)
+      || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t)))
+    return true;
+
+  switch (TREE_CODE (t))
+    {
+    case SAVE_EXPR:
+      return true;
+
+    case ADDR_EXPR:
+      op = TREE_OPERAND (t, 0);
+      while (handled_component_p (op))
+       {
+         switch (TREE_CODE (op))
+           {
+           case ARRAY_REF:
+           case ARRAY_RANGE_REF:
+             if (!tree_invariant_p (TREE_OPERAND (op, 1))
+                 || TREE_OPERAND (op, 2) != NULL_TREE
+                 || TREE_OPERAND (op, 3) != NULL_TREE)
+               return false;
+             break;
+
+           case COMPONENT_REF:
+             if (TREE_OPERAND (op, 2) != NULL_TREE)
+               return false;
+             break;
+
+           default:;
+           }
+         op = TREE_OPERAND (op, 0);
+       }
+
+      return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
+
+    default:
+      break;
+    }
+
+  return false;
+}
+
+/* Return true if T is function-invariant.  */
+
+static bool
+tree_invariant_p (tree t)
+{
+  tree inner = skip_simple_arithmetic (t);
+  return tree_invariant_p_1 (inner);
+}
+
 /* Wrap a SAVE_EXPR around EXPR, if appropriate.
    Do this to any expression which may be used in more than one place,
    but must be evaluated only once.
@@ -2091,11 +2191,10 @@ save_expr (tree expr)
      Since it is no problem to reevaluate literals, we just return the
      literal node.  */
   inner = skip_simple_arithmetic (t);
+  if (TREE_CODE (inner) == ERROR_MARK)
+    return inner;
 
-  if (TREE_INVARIANT (inner)
-      || (TREE_READONLY (inner) && ! TREE_SIDE_EFFECTS (inner))
-      || TREE_CODE (inner) == SAVE_EXPR
-      || TREE_CODE (inner) == ERROR_MARK)
+  if (tree_invariant_p_1 (inner))
     return t;
 
   /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
@@ -2116,7 +2215,6 @@ save_expr (tree expr)
      value was computed on both sides of the jump.  So make sure it isn't
      eliminated as dead.  */
   TREE_SIDE_EFFECTS (t) = 1;
-  TREE_INVARIANT (t) = 1;
   return t;
 }
 
@@ -2144,9 +2242,9 @@ skip_simple_arithmetic (tree expr)
        inner = TREE_OPERAND (inner, 0);
       else if (BINARY_CLASS_P (inner))
        {
-         if (TREE_INVARIANT (TREE_OPERAND (inner, 1)))
+         if (tree_invariant_p (TREE_OPERAND (inner, 1)))
            inner = TREE_OPERAND (inner, 0);
-         else if (TREE_INVARIANT (TREE_OPERAND (inner, 0)))
+         else if (tree_invariant_p (TREE_OPERAND (inner, 0)))
            inner = TREE_OPERAND (inner, 1);
          else
            break;
@@ -2189,7 +2287,6 @@ tree_node_structure (const_tree t)
            return TS_FUNCTION_DECL;
          case SYMBOL_MEMORY_TAG:
          case NAME_MEMORY_TAG:
-         case STRUCT_FIELD_TAG:
          case MEMORY_PARTITION_TAG:
            return TS_MEMORY_TAG;
          default:
@@ -2423,8 +2520,7 @@ substitute_in_expr (tree exp, tree f, tree r)
 {
   enum tree_code code = TREE_CODE (exp);
   tree op0, op1, op2, op3;
-  tree new;
-  tree inner;
+  tree new, inner;
 
   /* We handle TREE_LIST and COMPONENT_REF separately.  */
   if (code == TREE_LIST)
@@ -2534,13 +2630,15 @@ substitute_in_expr (tree exp, tree f, tree r)
          for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
            {
              tree op = TREE_OPERAND (exp, i);
-             tree newop = SUBSTITUTE_IN_EXPR (op, f, r);
-             if (newop != op)
+             tree new_op = SUBSTITUTE_IN_EXPR (op, f, r);
+             if (new_op != op)
                {
-                 copy = copy_node (exp);
-                 TREE_OPERAND (copy, i) = newop;
+                 if (!copy)
+                   copy = copy_node (exp);
+                 TREE_OPERAND (copy, i) = new_op;
                }
            }
+
          if (copy)
            new = fold (copy);
          else
@@ -2684,18 +2782,19 @@ substitute_placeholder_in_expr (tree exp, tree obj)
        {
          tree copy = NULL_TREE;
          int i;
-         int n = TREE_OPERAND_LENGTH (exp);
-         for (i = 1; i < n; i++)
+
+         for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)
            {
              tree op = TREE_OPERAND (exp, i);
-             tree newop = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
-             if (newop != op)
+             tree new_op = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
+             if (new_op != op)
                {
                  if (!copy)
                    copy = copy_node (exp);
-                 TREE_OPERAND (copy, i) = newop;
+                 TREE_OPERAND (copy, i) = new_op;
                }
            }
+
          if (copy)
            return fold (copy);
          else
@@ -2729,8 +2828,7 @@ stabilize_reference (tree ref)
       /* No action is needed in this case.  */
       return ref;
 
-    case NOP_EXPR:
-    case CONVERT_EXPR:
+    CASE_CONVERT:
     case FLOAT_EXPR:
     case FIX_TRUNC_EXPR:
       result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
@@ -2815,7 +2913,7 @@ stabilize_reference_1 (tree e)
      ignore things that are actual constant or that already have been
      handled by this function.  */
 
-  if (TREE_INVARIANT (e))
+  if (tree_invariant_p (e))
     return e;
 
   switch (TREE_CODE_CLASS (code))
@@ -2868,7 +2966,6 @@ stabilize_reference_1 (tree e)
   TREE_READONLY (result) = TREE_READONLY (e);
   TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
   TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
-  TREE_INVARIANT (result) = 1;
 
   return result;
 }
@@ -2876,13 +2973,13 @@ stabilize_reference_1 (tree e)
 /* Low-level constructors for expressions.  */
 
 /* A helper function for build1 and constant folders.  Set TREE_CONSTANT,
-   TREE_INVARIANT, and TREE_SIDE_EFFECTS for an ADDR_EXPR.  */
+   and TREE_SIDE_EFFECTS for an ADDR_EXPR.  */
 
 void
 recompute_tree_invariant_for_addr_expr (tree t)
 {
   tree node;
-  bool tc = true, ti = true, se = false;
+  bool tc = true, se = false;
 
   /* We started out assuming this address is both invariant and constant, but
      does not have side effects.  Now go down any handled components and see if
@@ -2892,9 +2989,8 @@ recompute_tree_invariant_for_addr_expr (tree t)
      ??? Note that this code makes no attempt to deal with the case where
      taking the address of something causes a copy due to misalignment.  */
 
-#define UPDATE_TITCSE(NODE)  \
+#define UPDATE_FLAGS(NODE)  \
 do { tree _node = (NODE); \
-     if (_node && !TREE_INVARIANT (_node)) ti = false; \
      if (_node && !TREE_CONSTANT (_node)) tc = false; \
      if (_node && TREE_SIDE_EFFECTS (_node)) se = true; } while (0)
 
@@ -2908,11 +3004,11 @@ do { tree _node = (NODE); \
           || TREE_CODE (node) == ARRAY_RANGE_REF)
          && TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
        {
-         UPDATE_TITCSE (TREE_OPERAND (node, 1));
+         UPDATE_FLAGS (TREE_OPERAND (node, 1));
          if (TREE_OPERAND (node, 2))
-           UPDATE_TITCSE (TREE_OPERAND (node, 2));
+           UPDATE_FLAGS (TREE_OPERAND (node, 2));
          if (TREE_OPERAND (node, 3))
-           UPDATE_TITCSE (TREE_OPERAND (node, 3));
+           UPDATE_FLAGS (TREE_OPERAND (node, 3));
        }
       /* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
         FIELD_DECL, apparently.  The G++ front end can put something else
@@ -2921,46 +3017,35 @@ do { tree _node = (NODE); \
               && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
        {
          if (TREE_OPERAND (node, 2))
-           UPDATE_TITCSE (TREE_OPERAND (node, 2));
+           UPDATE_FLAGS (TREE_OPERAND (node, 2));
        }
       else if (TREE_CODE (node) == BIT_FIELD_REF)
-       UPDATE_TITCSE (TREE_OPERAND (node, 2));
+       UPDATE_FLAGS (TREE_OPERAND (node, 2));
     }
 
-  node = lang_hooks.expr_to_decl (node, &tc, &ti, &se);
+  node = lang_hooks.expr_to_decl (node, &tc, &se);
 
   /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
-     the address, since &(*a)->b is a form of addition.  If it's a decl, it's
-     invariant and constant if the decl is static.  It's also invariant if it's
-     a decl in the current function.  Taking the address of a volatile variable
-     is not volatile.  If it's a constant, the address is both invariant and
-     constant.  Otherwise it's neither.  */
+     the address, since &(*a)->b is a form of addition.  If it's a constant, the
+     address is constant too.  If it's a decl, its address is constant if the
+     decl is static.  Everything else is not constant and, furthermore,
+     taking the address of a volatile variable is not volatile.  */
   if (TREE_CODE (node) == INDIRECT_REF)
-    UPDATE_TITCSE (TREE_OPERAND (node, 0));
-  else if (DECL_P (node))
-    {
-      if (staticp (node))
-       ;
-      else if (decl_function_context (node) == current_function_decl
-              /* Addresses of thread-local variables are invariant.  */
-              || (TREE_CODE (node) == VAR_DECL
-                  && DECL_THREAD_LOCAL_P (node)))
-       tc = false;
-      else
-       ti = tc = false;
-    }
+    UPDATE_FLAGS (TREE_OPERAND (node, 0));
   else if (CONSTANT_CLASS_P (node))
     ;
+  else if (DECL_P (node))
+    tc &= (staticp (node) != NULL_TREE);
   else
     {
-      ti = tc = false;
+      tc = false;
       se |= TREE_SIDE_EFFECTS (node);
     }
 
+
   TREE_CONSTANT (t) = tc;
-  TREE_INVARIANT (t) = ti;
   TREE_SIDE_EFFECTS (t) = se;
-#undef UPDATE_TITCSE
+#undef UPDATE_FLAGS
 }
 
 /* Build an expression of code CODE, data type TYPE, and operands as
@@ -3057,9 +3142,6 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
          && node && !TYPE_P (node)
          && TREE_CONSTANT (node))
        TREE_CONSTANT (t) = 1;
-      if ((TREE_CODE_CLASS (code) == tcc_unary || code == VIEW_CONVERT_EXPR)
-         && node && TREE_INVARIANT (node))
-       TREE_INVARIANT (t) = 1;
       if (TREE_CODE_CLASS (code) == tcc_reference
          && node && TREE_THIS_VOLATILE (node))
        TREE_THIS_VOLATILE (t) = 1;
@@ -3080,15 +3162,13 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
          read_only = 0;                \
         if (!TREE_CONSTANT (arg##N))   \
          constant = 0;                 \
-       if (!TREE_INVARIANT (arg##N))   \
-         invariant = 0;                \
       }                                        \
   } while (0)
 
 tree
 build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
 {
-  bool constant, read_only, side_effects, invariant;
+  bool constant, read_only, side_effects;
   tree t;
 
   gcc_assert (TREE_CODE_LENGTH (code) == 2);
@@ -3125,14 +3205,12 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
              || TREE_CODE_CLASS (code) == tcc_binary);
   read_only = 1;
   side_effects = TREE_SIDE_EFFECTS (t);
-  invariant = constant;
 
   PROCESS_ARG(0);
   PROCESS_ARG(1);
 
   TREE_READONLY (t) = read_only;
   TREE_CONSTANT (t) = constant;
-  TREE_INVARIANT (t) = invariant;
   TREE_SIDE_EFFECTS (t) = side_effects;
   TREE_THIS_VOLATILE (t)
     = (TREE_CODE_CLASS (code) == tcc_reference
@@ -3161,7 +3239,7 @@ tree
 build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
             tree arg2 MEM_STAT_DECL)
 {
-  bool constant, read_only, side_effects, invariant;
+  bool constant, read_only, side_effects;
   tree t;
 
   gcc_assert (TREE_CODE_LENGTH (code) == 3);
@@ -3197,7 +3275,7 @@ tree
 build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
             tree arg2, tree arg3 MEM_STAT_DECL)
 {
-  bool constant, read_only, side_effects, invariant;
+  bool constant, read_only, side_effects;
   tree t;
 
   gcc_assert (TREE_CODE_LENGTH (code) == 4);
@@ -3224,7 +3302,7 @@ tree
 build5_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
             tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
 {
-  bool constant, read_only, side_effects, invariant;
+  bool constant, read_only, side_effects;
   tree t;
 
   gcc_assert (TREE_CODE_LENGTH (code) == 5);
@@ -3253,7 +3331,7 @@ build7_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
             tree arg2, tree arg3, tree arg4, tree arg5,
             tree arg6 MEM_STAT_DECL)
 {
-  bool constant, read_only, side_effects, invariant;
+  bool constant, read_only, side_effects;
   tree t;
 
   gcc_assert (code == TARGET_MEM_REF);
@@ -3872,7 +3950,7 @@ merge_dllimport_decl_attributes (tree old, tree new)
     }
   else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new))
     {
-      /* Warn about overriding a symbol that has already been used. eg:
+      /* Warn about overriding a symbol that has already been used, e.g.:
            extern int __attribute__ ((dllimport)) foo;
           int* bar () {return &foo;}
           int foo;
@@ -3883,8 +3961,7 @@ merge_dllimport_decl_attributes (tree old, tree new)
                   "after being referenced with dll linkage", new);
          /* If we have used a variable's address with dllimport linkage,
              keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the
-             decl may already have had TREE_INVARIANT and TREE_CONSTANT
-             computed.
+             decl may already have had TREE_CONSTANT computed.
              We still remove the attribute so that assembler code refers
              to '&foo rather than '_imp__foo'.  */
          if (TREE_CODE (old) == VAR_DECL && TREE_ADDRESSABLE (old))
@@ -5609,14 +5686,12 @@ build_array_type (tree elt_type, tree index_type)
   return t;
 }
 
-/* Return the TYPE of the elements comprising
-   the innermost dimension of ARRAY.  */
+/* Recursively examines the array elements of TYPE, until a non-array
+   element type is found.  */
 
 tree
-get_inner_array_type (const_tree array)
+strip_array_types (tree type)
 {
-  tree type = TREE_TYPE (array);
-
   while (TREE_CODE (type) == ARRAY_TYPE)
     type = TREE_TYPE (type);
 
@@ -5956,11 +6031,6 @@ build_complex_type (tree component_type)
    If FOR_TYPE is nonzero, we return a value which, if converted to
    type FOR_TYPE, would be equivalent to converting OP to type FOR_TYPE.
 
-   If FOR_TYPE is nonzero, unaligned bit-field references may be changed to the
-   narrowest type that can hold the value, even if they don't exactly fit.
-   Otherwise, bit-field references are changed to a narrower type
-   only if they can be fetched directly from memory in that type.
-
    OP must have integer, real or enumeral type.  Pointers are not allowed!
 
    There are some cases where the obvious value we could return
@@ -5986,8 +6056,7 @@ get_unwidened (tree op, tree for_type)
        && TYPE_UNSIGNED (type));
   tree win = op;
 
-  while (TREE_CODE (op) == NOP_EXPR
-        || TREE_CODE (op) == CONVERT_EXPR)
+  while (CONVERT_EXPR_P (op))
     {
       int bitschange;
 
@@ -6025,8 +6094,7 @@ get_unwidened (tree op, tree for_type)
             Let's avoid computing it if it does not affect WIN
             and if UNS will not be needed again.  */
          if ((uns
-              || TREE_CODE (op) == NOP_EXPR
-              || TREE_CODE (op) == CONVERT_EXPR)
+              || CONVERT_EXPR_P (op))
              && TYPE_UNSIGNED (TREE_TYPE (op)))
            {
              uns = 1;
@@ -6035,38 +6103,6 @@ get_unwidened (tree op, tree for_type)
        }
     }
 
-  if (TREE_CODE (op) == COMPONENT_REF
-      /* Since type_for_size always gives an integer type.  */
-      && TREE_CODE (type) != REAL_TYPE
-      && TREE_CODE (type) != FIXED_POINT_TYPE
-      /* Don't crash if field not laid out yet.  */
-      && DECL_SIZE (TREE_OPERAND (op, 1)) != 0
-      && host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
-    {
-      unsigned int innerprec
-       = tree_low_cst (DECL_SIZE (TREE_OPERAND (op, 1)), 1);
-      int unsignedp = (DECL_UNSIGNED (TREE_OPERAND (op, 1))
-                      || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 1))));
-      type = lang_hooks.types.type_for_size (innerprec, unsignedp);
-
-      /* We can get this structure field in the narrowest type it fits in.
-        If FOR_TYPE is 0, do this only for a field that matches the
-        narrower type exactly and is aligned for it
-        The resulting extension to its nominal type (a fullword type)
-        must fit the same conditions as for other extensions.  */
-
-      if (type != 0
-         && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (op)))
-         && (for_type || ! DECL_BIT_FIELD (TREE_OPERAND (op, 1)))
-         && (! uns || final_prec <= innerprec || unsignedp))
-       {
-         win = build3 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
-                       TREE_OPERAND (op, 1), NULL_TREE);
-         TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
-         TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
-       }
-    }
-
   return win;
 }
 \f
@@ -7331,7 +7367,9 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
   if (ecf_flags & ECF_CONST)
     TREE_READONLY (decl) = 1;
   if (ecf_flags & ECF_PURE)
-    DECL_IS_PURE (decl) = 1;
+    DECL_PURE_P (decl) = 1;
+  if (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
+    DECL_LOOPING_CONST_OR_PURE_P (decl) = 1;
   if (ecf_flags & ECF_NORETURN)
     TREE_THIS_VOLATILE (decl) = 1;
   if (ecf_flags & ECF_NOTHROW)
@@ -7724,7 +7762,7 @@ process_call_operands (tree t)
       /* Calls have side-effects, except those to const or
         pure functions.  */
       i = call_expr_flags (t);
-      if (!(i & (ECF_CONST | ECF_PURE)))
+      if ((i & ECF_LOOPING_CONST_OR_PURE) || !(i & (ECF_CONST | ECF_PURE)))
        side_effects = 1;
     }
   TREE_SIDE_EFFECTS (t) = side_effects;
@@ -8418,7 +8456,6 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_PRIVATE:
        case OMP_CLAUSE_SHARED:
        case OMP_CLAUSE_FIRSTPRIVATE:
-       case OMP_CLAUSE_LASTPRIVATE:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
        case OMP_CLAUSE_IF:
@@ -8430,8 +8467,22 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_NOWAIT:
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_DEFAULT:
+       case OMP_CLAUSE_UNTIED:
+         WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+
+       case OMP_CLAUSE_LASTPRIVATE:
+         WALK_SUBTREE (OMP_CLAUSE_DECL (*tp));
+         WALK_SUBTREE (OMP_CLAUSE_LASTPRIVATE_STMT (*tp));
          WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
 
+       case OMP_CLAUSE_COLLAPSE:
+         {
+           int i;
+           for (i = 0; i < 3; i++)
+             WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
+           WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+         }
+
        case OMP_CLAUSE_REDUCTION:
          {
            int i;