OSDN Git Service

2012-01-04 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index e9876dd..76488f7 100644 (file)
@@ -247,7 +247,9 @@ unsigned const char omp_clause_num_ops[] =
   0, /* OMP_CLAUSE_ORDERED  */
   0, /* OMP_CLAUSE_DEFAULT  */
   3, /* OMP_CLAUSE_COLLAPSE  */
-  0  /* OMP_CLAUSE_UNTIED   */
+  0, /* OMP_CLAUSE_UNTIED   */
+  1, /* OMP_CLAUSE_FINAL  */
+  0  /* OMP_CLAUSE_MERGEABLE  */
 };
 
 const char * const omp_clause_code_name[] =
@@ -267,7 +269,9 @@ const char * const omp_clause_code_name[] =
   "ordered",
   "default",
   "collapse",
-  "untied"
+  "untied",
+  "final",
+  "mergeable"
 };
 
 
@@ -1521,6 +1525,7 @@ build_real_from_int_cst (tree type, const_tree i)
 
 /* Return a newly constructed STRING_CST node whose value is
    the LEN characters at STR.
+   Note that for a C string literal, LEN should include the trailing NUL.
    The TREE_TYPE is not initialized.  */
 
 tree
@@ -1759,9 +1764,7 @@ integer_all_onesp (const_tree expr)
   if (!uns)
     return 0;
 
-  /* Note that using TYPE_PRECISION here is wrong.  We care about the
-     actual bits, not the (arbitrary) range of the type.  */
-  prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)));
+  prec = TYPE_PRECISION (TREE_TYPE (expr));
   if (prec >= HOST_BITS_PER_WIDE_INT)
     {
       HOST_WIDE_INT high_value;
@@ -3782,8 +3785,7 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
 
   if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
     gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
-               && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-               && useless_type_conversion_p (sizetype, TREE_TYPE (arg1)));
+               && ptrofftype_p (TREE_TYPE (arg1)));
 
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
@@ -4396,7 +4398,7 @@ free_lang_data_in_one_sizepos (tree *expr_p)
 
 
 /* Reset all the fields in a binfo node BINFO.  We only keep
-   BINFO_VIRTUALS, which is used by gimple_fold_obj_type_ref.  */
+   BINFO_VTABLE, which is used by gimple_fold_obj_type_ref.  */
 
 static void
 free_lang_data_in_binfo (tree binfo)
@@ -4406,7 +4408,7 @@ free_lang_data_in_binfo (tree binfo)
 
   gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
 
-  BINFO_VTABLE (binfo) = NULL_TREE;
+  BINFO_VIRTUALS (binfo) = NULL_TREE;
   BINFO_BASE_ACCESSES (binfo) = NULL;
   BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
   BINFO_SUBVTT_INDEX (binfo) = NULL_TREE;
@@ -4475,7 +4477,8 @@ free_lang_data_in_type (tree type)
       member = TYPE_FIELDS (type);
       while (member)
        {
-         if (TREE_CODE (member) == FIELD_DECL)
+         if (TREE_CODE (member) == FIELD_DECL
+             || TREE_CODE (member) == TYPE_DECL)
            {
              if (prev)
                TREE_CHAIN (prev) = member;
@@ -4519,9 +4522,6 @@ free_lang_data_in_type (tree type)
          && TREE_CODE (TYPE_CONTEXT (type)) != FUNCTION_DECL
          && TREE_CODE (TYPE_CONTEXT (type)) != NAMESPACE_DECL))
     TYPE_CONTEXT (type) = NULL_TREE;
-
-  if (debug_info_level < DINFO_LEVEL_TERSE)
-    TYPE_STUB_DECL (type) = NULL_TREE;
 }
 
 
@@ -4598,11 +4598,6 @@ free_lang_data_in_decl (tree decl)
   if (TREE_CODE (decl) == FIELD_DECL)
     free_lang_data_in_one_sizepos (&DECL_FIELD_OFFSET (decl));
 
- /* DECL_FCONTEXT is only used for debug info generation.  */
- if (TREE_CODE (decl) == FIELD_DECL
-     && debug_info_level < DINFO_LEVEL_TERSE)
-   DECL_FCONTEXT (decl) = NULL_TREE;
-
  if (TREE_CODE (decl) == FUNCTION_DECL)
     {
       if (gimple_has_body_p (decl))
@@ -4649,16 +4644,16 @@ free_lang_data_in_decl (tree decl)
          || (decl_function_context (decl) && !TREE_STATIC (decl)))
        DECL_INITIAL (decl) = NULL_TREE;
     }
-  else if (TREE_CODE (decl) == TYPE_DECL)
+  else if (TREE_CODE (decl) == TYPE_DECL
+          || TREE_CODE (decl) == FIELD_DECL)
     DECL_INITIAL (decl) = NULL_TREE;
   else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL
            && DECL_INITIAL (decl)
            && TREE_CODE (DECL_INITIAL (decl)) == BLOCK)
     {
-      /* Strip builtins from the translation-unit BLOCK.  We still have
-        targets without builtin_decl support and also builtins are
-        shared nodes and thus we can't use TREE_CHAIN in multiple
-        lists.  */
+      /* Strip builtins from the translation-unit BLOCK.  We still have targets
+        without builtin_decl_explicit support and also builtins are shared
+        nodes and thus we can't use TREE_CHAIN in multiple lists.  */
       tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl));
       while (*nextp)
         {
@@ -4799,6 +4794,7 @@ find_decls_types_r (tree *tp, int *ws, void *data)
        {
          fld_worklist_push (DECL_ARGUMENT_FLD (t), fld);
          fld_worklist_push (DECL_VINDEX (t), fld);
+         fld_worklist_push (DECL_ORIGINAL_TYPE (t), fld);
        }
       else if (TREE_CODE (t) == FIELD_DECL)
        {
@@ -4877,13 +4873,14 @@ find_decls_types_r (tree *tp, int *ws, void *data)
          tem = TYPE_FIELDS (t);
          while (tem)
            {
-             if (TREE_CODE (tem) == FIELD_DECL)
+             if (TREE_CODE (tem) == FIELD_DECL
+                 || TREE_CODE (tem) == TYPE_DECL)
                fld_worklist_push (tem, fld);
              tem = TREE_CHAIN (tem);
            }
        }
 
-      fld_worklist_push (TREE_CHAIN (t), fld);
+      fld_worklist_push (TYPE_STUB_DECL (t), fld);
       *ws = 0;
     }
   else if (TREE_CODE (t) == BLOCK)
@@ -6350,7 +6347,8 @@ attribute_list_contained (const_tree l1, const_tree l2)
        t1 != 0 && t2 != 0
         && TREE_PURPOSE (t1) == TREE_PURPOSE (t2)
         && TREE_VALUE (t1) == TREE_VALUE (t2);
-       t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2));
+       t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
+    ;
 
   /* Maybe the lists are equal.  */
   if (t1 == 0 && t2 == 0)
@@ -6511,21 +6509,34 @@ tree_low_cst (const_tree t, int pos)
   return TREE_INT_CST_LOW (t);
 }
 
-/* Return the most significant bit of the integer constant T.  */
+/* Return the HOST_WIDE_INT least significant bits of T, a sizetype
+   kind INTEGER_CST.  This makes sure to properly sign-extend the
+   constant.  */
+
+HOST_WIDE_INT
+size_low_cst (const_tree t)
+{
+  double_int d = tree_to_double_int (t);
+  return double_int_sext (d, TYPE_PRECISION (TREE_TYPE (t))).low;
+}
+
+/* Return the most significant (sign) bit of T.  */
 
 int
-tree_int_cst_msb (const_tree t)
+tree_int_cst_sign_bit (const_tree t)
 {
-  int prec;
-  HOST_WIDE_INT h;
-  unsigned HOST_WIDE_INT l;
+  unsigned bitno = TYPE_PRECISION (TREE_TYPE (t)) - 1;
+  unsigned HOST_WIDE_INT w;
+
+  if (bitno < HOST_BITS_PER_WIDE_INT)
+    w = TREE_INT_CST_LOW (t);
+  else
+    {
+      w = TREE_INT_CST_HIGH (t);
+      bitno -= HOST_BITS_PER_WIDE_INT;
+    }
 
-  /* Note that using TYPE_PRECISION here is wrong.  We care about the
-     actual bits, not the (arbitrary) range of the type.  */
-  prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (t))) - 1;
-  rshift_double (TREE_INT_CST_LOW (t), TREE_INT_CST_HIGH (t), prec,
-                2 * HOST_BITS_PER_WIDE_INT, &l, &h, 0);
-  return (l & 1) == 1;
+  return (w >> bitno) & 1;
 }
 
 /* Return an indication of the sign of the integer constant T.
@@ -6938,9 +6949,9 @@ iterative_hash_expr (const_tree t, hashval_t val)
         or front end builtins, since the function code is overloaded in those
         cases.  */
       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
-         && built_in_decls[DECL_FUNCTION_CODE (t)])
+         && builtin_decl_explicit_p (DECL_FUNCTION_CODE (t)))
        {
-         t = built_in_decls[DECL_FUNCTION_CODE (t)];
+         t = builtin_decl_explicit (DECL_FUNCTION_CODE (t));
          code = TREE_CODE (t);
        }
       /* FALL THROUGH */
@@ -6990,7 +7001,6 @@ iterative_hash_expr (const_tree t, hashval_t val)
              val = iterative_hash_expr (TREE_OPERAND (t, i), val);
        }
       return val;
-      break;
     }
 }
 
@@ -8745,11 +8755,11 @@ get_file_function_name (const char *type)
        file = input_filename;
 
       len = strlen (file);
-      q = (char *) alloca (9 * 2 + len + 1);
+      q = (char *) alloca (9 + 17 + len + 1);
       memcpy (q, file, len + 1);
 
-      sprintf (q + len, "_%08X_%08X", crc32_string (0, name),
-              crc32_string (0, get_random_seed (false)));
+      snprintf (q + len, 9 + 17 + 1, "_%08X_" HOST_WIDE_INT_PRINT_HEX, 
+               crc32_string (0, name), get_random_seed (false));
 
       p = q;
     }
@@ -9229,6 +9239,8 @@ build_common_tree_nodes (bool signed_char, bool short_double)
     size_type_node = long_unsigned_type_node;
   else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
     size_type_node = long_long_unsigned_type_node;
+  else if (strcmp (SIZE_TYPE, "short unsigned int") == 0)
+    size_type_node = short_unsigned_type_node;
   else
     gcc_unreachable ();
 
@@ -9422,9 +9434,10 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
   if (ecf_flags & ECF_LEAF)
     DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
                                        NULL, DECL_ATTRIBUTES (decl));
+  if ((ecf_flags & ECF_TM_PURE) && flag_tm)
+    apply_tm_attr (decl, get_identifier ("transaction_pure"));
 
-  built_in_decls[code] = decl;
-  implicit_built_in_decls[code] = decl;
+  set_builtin_decl (code, decl, true);
 }
 
 /* Call this function after instantiating all builtins that the language
@@ -9435,23 +9448,24 @@ void
 build_common_builtin_nodes (void)
 {
   tree tmp, ftype;
+  int ecf_flags;
 
-  if (built_in_decls[BUILT_IN_MEMCPY] == NULL
-      || built_in_decls[BUILT_IN_MEMMOVE] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)
+      || !builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
     {
       ftype = build_function_type_list (ptr_type_node,
                                        ptr_type_node, const_ptr_type_node,
                                        size_type_node, NULL_TREE);
 
-      if (built_in_decls[BUILT_IN_MEMCPY] == NULL)
+      if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY))
        local_define_builtin ("__builtin_memcpy", ftype, BUILT_IN_MEMCPY,
                              "memcpy", ECF_NOTHROW | ECF_LEAF);
-      if (built_in_decls[BUILT_IN_MEMMOVE] == NULL)
+      if (!builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
        local_define_builtin ("__builtin_memmove", ftype, BUILT_IN_MEMMOVE,
                              "memmove", ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_MEMCMP] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_MEMCMP))
     {
       ftype = build_function_type_list (integer_type_node, const_ptr_type_node,
                                        const_ptr_type_node, size_type_node,
@@ -9460,7 +9474,7 @@ build_common_builtin_nodes (void)
                            "memcmp", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_MEMSET] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_MEMSET))
     {
       ftype = build_function_type_list (ptr_type_node,
                                        ptr_type_node, integer_type_node,
@@ -9469,7 +9483,7 @@ build_common_builtin_nodes (void)
                            "memset", ECF_NOTHROW | ECF_LEAF);
     }
 
-  if (built_in_decls[BUILT_IN_ALLOCA] == NULL)
+  if (!builtin_decl_explicit_p (BUILT_IN_ALLOCA))
     {
       ftype = build_function_type_list (ptr_type_node,
                                        size_type_node, NULL_TREE);
@@ -9477,9 +9491,18 @@ build_common_builtin_nodes (void)
                            "alloca", ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
     }
 
+  ftype = build_function_type_list (ptr_type_node, size_type_node,
+                                   size_type_node, NULL_TREE);
+  local_define_builtin ("__builtin_alloca_with_align", ftype,
+                       BUILT_IN_ALLOCA_WITH_ALIGN, "alloca",
+                       ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
+
   /* If we're checking the stack, `alloca' can throw.  */
   if (flag_stack_check)
-    TREE_NOTHROW (built_in_decls[BUILT_IN_ALLOCA]) = 0;
+    {
+      TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA)) = 0;
+      TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN)) = 0;
+    }
 
   ftype = build_function_type_list (void_type_node,
                                    ptr_type_node, ptr_type_node,
@@ -9545,6 +9568,31 @@ build_common_builtin_nodes (void)
                         ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
                        ECF_NORETURN);
 
+  if (builtin_decl_explicit (BUILT_IN_RETURN_ADDRESS) == NULL_TREE)
+    {
+      ftype = build_function_type_list (ptr_type_node, integer_type_node,
+                                       NULL_TREE);
+      local_define_builtin ("__builtin_return_address", ftype,
+                           BUILT_IN_RETURN_ADDRESS,
+                           "__builtin_return_address",
+                           ECF_NOTHROW);
+    }
+
+  if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER)
+      || !builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
+    {
+      ftype = build_function_type_list (void_type_node, ptr_type_node,
+                                       ptr_type_node, NULL_TREE);
+      if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_ENTER))
+       local_define_builtin ("__cyg_profile_func_enter", ftype,
+                             BUILT_IN_PROFILE_FUNC_ENTER,
+                             "__cyg_profile_func_enter", 0);
+      if (!builtin_decl_explicit_p (BUILT_IN_PROFILE_FUNC_EXIT))
+       local_define_builtin ("__cyg_profile_func_exit", ftype,
+                             BUILT_IN_PROFILE_FUNC_EXIT,
+                             "__cyg_profile_func_exit", 0);
+    }
+
   /* The exception object and filter values from the runtime.  The argument
      must be zero before exception lowering, i.e. from the front end.  After
      exception lowering, it will be the region number for the exception
@@ -9553,8 +9601,12 @@ build_common_builtin_nodes (void)
      its value in the landing pad.  */
   ftype = build_function_type_list (ptr_type_node,
                                    integer_type_node, NULL_TREE);
+  ecf_flags = ECF_PURE | ECF_NOTHROW | ECF_LEAF;
+  /* Only use TM_PURE if we we have TM language support.  */
+  if (builtin_decl_explicit_p (BUILT_IN_TM_LOAD_1))
+    ecf_flags |= ECF_TM_PURE;
   local_define_builtin ("__builtin_eh_pointer", ftype, BUILT_IN_EH_POINTER,
-                       "__builtin_eh_pointer", ECF_PURE | ECF_NOTHROW | ECF_LEAF);
+                       "__builtin_eh_pointer", ecf_flags);
 
   tmp = lang_hooks.types.type_for_mode (targetm.eh_return_filter_mode (), 0);
   ftype = build_function_type_list (tmp, integer_type_node, NULL_TREE);
@@ -9721,17 +9773,29 @@ build_vector_type (tree innertype, int nunits)
   return make_vector_type (innertype, nunits, VOIDmode);
 }
 
-/* Similarly, but takes the inner type and number of units, which must be
-   a power of two.  */
+/* Similarly, but builds a variant type with TYPE_VECTOR_OPAQUE set.  */
 
 tree
 build_opaque_vector_type (tree innertype, int nunits)
 {
-  tree t;
-  innertype = build_distinct_type_copy (innertype);
-  t = make_vector_type (innertype, nunits, VOIDmode);
-  TYPE_VECTOR_OPAQUE (t) = true;
-  return t;
+  tree t = make_vector_type (innertype, nunits, VOIDmode);
+  tree cand;
+  /* We always build the non-opaque variant before the opaque one,
+     so if it already exists, it is TYPE_NEXT_VARIANT of this one.  */
+  cand = TYPE_NEXT_VARIANT (t);
+  if (cand
+      && TYPE_VECTOR_OPAQUE (cand)
+      && check_qualified_type (cand, t, TYPE_QUALS (t)))
+    return cand;
+  /* Othewise build a variant type and make sure to queue it after
+     the non-opaque type.  */
+  cand = build_distinct_type_copy (t);
+  TYPE_VECTOR_OPAQUE (cand) = true;
+  TYPE_CANONICAL (cand) = TYPE_CANONICAL (t);
+  TYPE_NEXT_VARIANT (cand) = TYPE_NEXT_VARIANT (t);
+  TYPE_NEXT_VARIANT (t) = cand;
+  TYPE_MAIN_VARIANT (cand) = TYPE_MAIN_VARIANT (t);
+  return cand;
 }
 
 
@@ -10520,6 +10584,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_FIRSTPRIVATE:
        case OMP_CLAUSE_COPYIN:
        case OMP_CLAUSE_COPYPRIVATE:
+       case OMP_CLAUSE_FINAL:
        case OMP_CLAUSE_IF:
        case OMP_CLAUSE_NUM_THREADS:
        case OMP_CLAUSE_SCHEDULE:
@@ -10530,6 +10595,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_DEFAULT:
        case OMP_CLAUSE_UNTIED:
+       case OMP_CLAUSE_MERGEABLE:
          WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
 
        case OMP_CLAUSE_LASTPRIVATE:
@@ -10595,9 +10661,14 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
          if (result || !walk_subtrees)
            return result;
 
-         result = walk_type_fields (*type_p, func, data, pset, lh);
-         if (result)
-           return result;
+         /* But do not walk a pointed-to type since it may itself need to
+            be walked in the declaration case if it isn't anonymous.  */
+         if (!POINTER_TYPE_P (*type_p))
+           {
+             result = walk_type_fields (*type_p, func, data, pset, lh);
+             if (result)
+               return result;
+           }
 
          /* If this is a record type, also walk the fields.  */
          if (RECORD_OR_UNION_TYPE_P (*type_p))
@@ -11084,6 +11155,37 @@ tree_strip_sign_nop_conversions (tree exp)
   return exp;
 }
 
+/* Strip out all handled components that produce invariant
+   offsets.  */
+
+const_tree
+strip_invariant_refs (const_tree op)
+{
+  while (handled_component_p (op))
+    {
+      switch (TREE_CODE (op))
+       {
+       case ARRAY_REF:
+       case ARRAY_RANGE_REF:
+         if (!is_gimple_constant (TREE_OPERAND (op, 1))
+             || TREE_OPERAND (op, 2) != NULL_TREE
+             || TREE_OPERAND (op, 3) != NULL_TREE)
+           return NULL;
+         break;
+
+       case COMPONENT_REF:
+         if (TREE_OPERAND (op, 2) != NULL_TREE)
+           return NULL;
+         break;
+
+       default:;
+       }
+      op = TREE_OPERAND (op, 0);
+    }
+
+  return op;
+}
+
 static GTY(()) tree gcc_eh_personality_decl;
 
 /* Return the GCC personality function decl.  */