Re-factor tree.h - Part 1.
authorDiego Novillo <dnovillo@google.com>
Fri, 8 Nov 2013 22:46:16 +0000 (17:46 -0500)
committerDiego Novillo <dnovillo@gcc.gnu.org>
Fri, 8 Nov 2013 22:46:16 +0000 (17:46 -0500)
This is the first patch in a series of patches to cleanup tree.h to
reduce the exposure it has all over the compiler.

In this patch, I'm moving functions that are used once into the files
that use them, and make them private to that file. These functions
were declared extern in tree.h and called from exactly one place.

The patch does not move EVERY function. This usually happens
when the function uses private state from its original file, and
moving that private state would mean moving other functions that made
no sense to move.

Additionally, the patch removes functions that were never used.

In subsequent patches, I will be moving out of tree.h extern definitions
that should be grouped in other files (e.g., all functions defined in
some FOO.c will be moved to the corresponding FOO.h). This will allow
me to remove the inclusion of tree.h from some files.

    * attribs.c (lookup_scoped_attribute_spec): Make static.
    (get_attribute_namespace): Likewise.
    * builtins.c (more_const_call_expr_args_p): Move from
    tree.h.
    (validate_arglist): Move earlier in the file. Make static.
    (expand_stack_restore): Move from stmt.c
    (expand_stack_save): Move from stmt.c
    (rewrite_call_expr_array): Move earlier in the file.
    (rewrite_call_expr_valist): Likewise.
    * cfgexpand.c: Include hard-reg-set.h before tree.h
    Include recog.h.
    Include output.h.
    (expand_asm_loc): Move from stmt.c.
    (n_occurrences): Move from stmt.c.
    (check_operand_nalternatives): Move from stmt.c.
    (tree_conflicts_with_clobbers_p): Move from stmt.c.
    (expand_asm_operands): Move from stmt.c
    (expand_asm_stmt): Move from stmt.c
    (expand_computed_goto): Move from stmt.c
    (expand_goto): Move from stmt.c
    (expand_null_return_1): Move from stmt.c
    (expand_null_return): Move from stmt.c
    (expand_value_return): Move from stmt.c
    (expand_return): Move from stmt.c
    (expand_main_function): Move from function.c
    (stack_protect_prologue): Move from function.c
    * cgraphclones.c (build_function_type_skip_args): Move from tree.c.
    (build_function_decl_skip_args): Move from tree.c.
    * explow.c (tree_expr_size): Move from tree.c.
    * expr.c (addr_expr_of_non_mem_decl_p): Remove.
    (fields_length): Move from tree.c.
    * fold-const.c (size_low_cst): Move from tree.c.
    (tree_expr_nonzero_warnv_p): Make static. Move earlier in the file.
    (tree_expr_nonzero_p): Make static. Move earlier in the file.
    (fold_build3_initializer_loc): Remove.
    (tree_invalid_nonnegative_warnv_p): Make static.
    * function.c (expand_main_function): Move to cfgexpand.c.
    (stack_protect_prologue): Move to cfgexpand.c.
    (set_insn_locations): Move earlier in the file.
    * gimple-fold.c: Include langhooks.h.
    (truth_type_for): Move from tree.c.
    * print-tree.c (print_vec_tree): Remove.
    * stmt.c (expand_computed_goto): Move to cfgexpand.c.
    (expand_goto): Move to cfgexpand.c.
    (n_occurrences): Move to cfgexpand.c.
    (expand_asm_loc): Move to cfgexpand.c
    (tree_conflicts_with_clobbers_p): Move to cfgexpand.c.
    (expand_asm_operands): Move to cfgexpand.c.
    (expand_asm_stmt): Move to cfgexpand.c.
    (check_operand_nalternatives): Move to cfgexpand.c
    (expand_null_return): Move to cfgexpand.c.
    (expand_value_return): Move to cfgexpand.c.
    (expand_null_return_1): Move to cfgexpand.c.
    (expand_return): Move to cfgexpand.c.
    (expand_stack_save): Move to builtins.c.
    (expand_stack_restore): Move to builtins.c
    * symtab.c: Include output.h.
    (decl_assembler_name_hash): Move from tree.c.
    (decl_assembler_name_equal): Move from tree.c.
    * trans-mem.c (is_tm_safe_or_pure): Move from tree.h.
    * tree-eh.c (in_array_bounds_p): Move from tree.c.
    (range_in_array_bounds_p): Move from tree.c.
    * tree-object-size.c (fini_object_sizes): Make static.
    * tree-ssa-dom.c (iterative_hash_exprs_commutative): Move from tree.h.
    * tree-vrp.c (ssa_name_nonnegative_p): Remove.
    * tree.c (decl_assembler_name_equal): Move to symtab.c.
    (tree_expr_size): Move to explow.c.
    (decl_assembler_name_hash): Move to symtab.c.
    (real_twop): Remove.
    (tree_expr_size): Move to explow.c.
    (stabilize_reference_1): Move earlier in the file. Make static.
    (omp_remove_redundant_declare_simd_attrs): Remove.
    (simple_cst_list_equal): Move earlier in the file. Make static.
    (size_low_cst): Move to fold-const.c.
    (build_type_no_quals): Remove.
    (build_function_type_skip_args): Move to cgraphclones.c.
    (build_function_decl_skip_args): Move to cgraphclones.c.
    (in_array_bounds_p): Move to tree-eh.c.
    (range_in_array_bounds_p): Move to tree-eh.c.
    (truth_type_for): Move to gimple-fold.c.
    (list_equal_p): remove.
    * tree.h (decl_assembler_name_equal): Remove.
    (decl_assembler_name_hash): Remove.
    (truth_type_for): Remove.
    (build_type_no_quals): Remove.
    (build_function_decl_skip_args): Remove.
    (in_array_bounds_p): Remove.
    (range_in_array_bounds_p): Remove.
    (size_low_cst): Remove.
    (omp_remove_redundant_declare_simd_attrs): Remove.
    (tree_expr_size): Remove.
    (fields_length): Remove.
    (stabilize_reference_1): Remove.
    (expand_goto): Remove.
    (expand_stack_save): Remove.
    (expand_stack_restore): Remove.
    (expand_return): Remove.
    (fold_build3_initializer_loc): Remove.
    (tree_expr_nonzero_p): Remove.
    (tree_invalid_nonnegative_warnv_p): Remove.
    (tree_expr_nonzero_warnv_p): Remove.
    (fold_builtin_snprintf_chk): Remove.
    (validate_arglist): Remove.
    (iterative_hash_exprs_commutative): Move to tree-ssa-dom.c.
    (simple_cst_list_equal): Remove.
    (real_twop): Remove.
    (expand_main_function): Remove.
    (stack_protect_prologue): Remove.
    (print_vec_tree): Remove.
    (lookup_scoped_attribute_spec): Remove.
    (get_attribute_namespace): Remove.
    (expand_computed_goto): Remove.
    (expand_asm_stmt): Remove.
    (list_equal_p): Remove.
    (ssa_name_nonnegative_p): Remove.
    (fini_object_sizes): Remove.
    (addr_expr_of_non_mem_decl_p): Remove.
    (is_tm_safe_or_pure): Move to trans-mem.c.
    (more_const_call_expr_args_p): Remove.
    (save_vtable_map_decl): Remove.

From-SVN: r204606

20 files changed:
gcc/ChangeLog
gcc/attribs.c
gcc/builtins.c
gcc/cfgexpand.c
gcc/cgraphclones.c
gcc/explow.c
gcc/expr.c
gcc/fold-const.c
gcc/function.c
gcc/gimple-fold.c
gcc/print-tree.c
gcc/stmt.c
gcc/symtab.c
gcc/trans-mem.c
gcc/tree-eh.c
gcc/tree-object-size.c
gcc/tree-ssa-dom.c
gcc/tree-vrp.c
gcc/tree.c
gcc/tree.h

index 2f224a42da2ded178454d2d87b28e8a7aab7c6c1..9387646a7a0294bdebafa939b432a0c8837f89d4 100644 (file)
        No longer check if we have __builtin_trap, assume it's
        available.
 
+2013-11-07  Diego Novillo  <dnovillo@google.com>
+
+       * attribs.c (lookup_scoped_attribute_spec): Make static.
+       (get_attribute_namespace): Likewise.
+       * builtins.c (more_const_call_expr_args_p): Move from
+       tree.h.
+       (validate_arglist): Move earlier in the file. Make static.
+       (expand_stack_restore): Move from stmt.c
+       (expand_stack_save): Move from stmt.c
+       (rewrite_call_expr_array): Move earlier in the file.
+       (rewrite_call_expr_valist): Likewise.
+       * cfgexpand.c: Include hard-reg-set.h before tree.h
+       Include recog.h.
+       Include output.h.
+       (expand_asm_loc): Move from stmt.c.
+       (n_occurrences): Move from stmt.c.
+       (check_operand_nalternatives): Move from stmt.c.
+       (tree_conflicts_with_clobbers_p): Move from stmt.c.
+       (expand_asm_operands): Move from stmt.c
+       (expand_asm_stmt): Move from stmt.c
+       (expand_computed_goto): Move from stmt.c
+       (expand_goto): Move from stmt.c
+       (expand_null_return_1): Move from stmt.c
+       (expand_null_return): Move from stmt.c
+       (expand_value_return): Move from stmt.c
+       (expand_return): Move from stmt.c
+       (expand_main_function): Move from function.c
+       (stack_protect_prologue): Move from function.c
+       * cgraphclones.c (build_function_type_skip_args): Move from tree.c.
+       (build_function_decl_skip_args): Move from tree.c.
+       * explow.c (tree_expr_size): Move from tree.c.
+       * expr.c (addr_expr_of_non_mem_decl_p): Remove.
+       (fields_length): Move from tree.c.
+       * fold-const.c (size_low_cst): Move from tree.c.
+       (tree_expr_nonzero_warnv_p): Make static. Move earlier in the file.
+       (tree_expr_nonzero_p): Make static. Move earlier in the file.
+       (fold_build3_initializer_loc): Remove.
+       (tree_invalid_nonnegative_warnv_p): Make static.
+       * function.c (expand_main_function): Move to cfgexpand.c.
+       (stack_protect_prologue): Move to cfgexpand.c.
+       (set_insn_locations): Move earlier in the file.
+       * gimple-fold.c: Include langhooks.h.
+       (truth_type_for): Move from tree.c.
+       * print-tree.c (print_vec_tree): Remove.
+       * stmt.c (expand_computed_goto): Move to cfgexpand.c.
+       (expand_goto): Move to cfgexpand.c.
+       (n_occurrences): Move to cfgexpand.c.
+       (expand_asm_loc): Move to cfgexpand.c
+       (tree_conflicts_with_clobbers_p): Move to cfgexpand.c.
+       (expand_asm_operands): Move to cfgexpand.c.
+       (expand_asm_stmt): Move to cfgexpand.c.
+       (check_operand_nalternatives): Move to cfgexpand.c
+       (expand_null_return): Move to cfgexpand.c.
+       (expand_value_return): Move to cfgexpand.c.
+       (expand_null_return_1): Move to cfgexpand.c.
+       (expand_return): Move to cfgexpand.c.
+       (expand_stack_save): Move to builtins.c.
+       (expand_stack_restore): Move to builtins.c
+       * symtab.c: Include output.h.
+       (decl_assembler_name_hash): Move from tree.c.
+       (decl_assembler_name_equal): Move from tree.c.
+       * trans-mem.c (is_tm_safe_or_pure): Move from tree.h.
+       * tree-eh.c (in_array_bounds_p): Move from tree.c.
+       (range_in_array_bounds_p): Move from tree.c.
+       * tree-object-size.c (fini_object_sizes): Make static.
+       * tree-ssa-dom.c (iterative_hash_exprs_commutative): Move from tree.h.
+       * tree-vrp.c (ssa_name_nonnegative_p): Remove.
+       * tree.c (decl_assembler_name_equal): Move to symtab.c.
+       (tree_expr_size): Move to explow.c.
+       (decl_assembler_name_hash): Move to symtab.c.
+       (real_twop): Remove.
+       (tree_expr_size): Move to explow.c.
+       (stabilize_reference_1): Move earlier in the file. Make static.
+       (omp_remove_redundant_declare_simd_attrs): Remove.
+       (simple_cst_list_equal): Move earlier in the file. Make static.
+       (size_low_cst): Move to fold-const.c.
+       (build_type_no_quals): Remove.
+       (build_function_type_skip_args): Move to cgraphclones.c.
+       (build_function_decl_skip_args): Move to cgraphclones.c.
+       (in_array_bounds_p): Move to tree-eh.c.
+       (range_in_array_bounds_p): Move to tree-eh.c.
+       (truth_type_for): Move to gimple-fold.c.
+       (list_equal_p): remove.
+       * tree.h (decl_assembler_name_equal): Remove.
+       (decl_assembler_name_hash): Remove.
+       (truth_type_for): Remove.
+       (build_type_no_quals): Remove.
+       (build_function_decl_skip_args): Remove.
+       (in_array_bounds_p): Remove.
+       (range_in_array_bounds_p): Remove.
+       (size_low_cst): Remove.
+       (omp_remove_redundant_declare_simd_attrs): Remove.
+       (tree_expr_size): Remove.
+       (fields_length): Remove.
+       (stabilize_reference_1): Remove.
+       (expand_goto): Remove.
+       (expand_stack_save): Remove.
+       (expand_stack_restore): Remove.
+       (expand_return): Remove.
+       (fold_build3_initializer_loc): Remove.
+       (tree_expr_nonzero_p): Remove.
+       (tree_invalid_nonnegative_warnv_p): Remove.
+       (tree_expr_nonzero_warnv_p): Remove.
+       (fold_builtin_snprintf_chk): Remove.
+       (validate_arglist): Remove.
+       (iterative_hash_exprs_commutative): Move to tree-ssa-dom.c.
+       (simple_cst_list_equal): Remove.
+       (real_twop): Remove.
+       (expand_main_function): Remove.
+       (stack_protect_prologue): Remove.
+       (print_vec_tree): Remove.
+       (lookup_scoped_attribute_spec): Remove.
+       (get_attribute_namespace): Remove.
+       (expand_computed_goto): Remove.
+       (expand_asm_stmt): Remove.
+       (list_equal_p): Remove.
+       (ssa_name_nonnegative_p): Remove.
+       (fini_object_sizes): Remove.
+       (addr_expr_of_non_mem_decl_p): Remove.
+       (is_tm_safe_or_pure): Move to trans-mem.c.
+       (more_const_call_expr_args_p): Remove.
+       (save_vtable_map_decl): Remove.
+
 2013-11-07  Thomas Schwinge  <thomas@codesourcery.com>
 
        * doc/sourcebuild.texi (Top Level) <lto-plugin>: GNU ld can use
index 164385b2b3c4598d11c729b4543ee67fbd693518..296bcd6eb740bc0a5bb215ab8417b0678a49d74c 100644 (file)
@@ -297,7 +297,7 @@ register_scoped_attribute (const struct attribute_spec *attr,
 /* Return the spec for the scoped attribute with namespace NS and
    name NAME.   */
 
-const struct attribute_spec *
+static const struct attribute_spec *
 lookup_scoped_attribute_spec (const_tree ns, const_tree name)
 {
   struct substring attr;
@@ -334,7 +334,23 @@ lookup_attribute_spec (const_tree name)
   return lookup_scoped_attribute_spec (ns, name);
 }
 
-\f
+
+/* Return the namespace of the attribute ATTR.  This accessor works on
+   GNU and C++11 (scoped) attributes.  On GNU attributes,
+   it returns an identifier tree for the string "gnu".
+
+   Please read the comments of cxx11_attribute_p to understand the
+   format of attributes.  */
+
+static tree
+get_attribute_namespace (const_tree attr)
+{
+  if (cxx11_attribute_p (attr))
+    return TREE_PURPOSE (TREE_PURPOSE (attr));
+  return get_identifier ("gnu");
+}
+
+
 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
    it should be modified in place; if a TYPE, a copy should be created
@@ -659,21 +675,6 @@ get_attribute_name (const_tree attr)
   return TREE_PURPOSE (attr);
 }
 
-/* Return the namespace of the attribute ATTR.  This accessor works on
-   GNU and C++11 (scoped) attributes.  On GNU attributes,
-   it returns an identifier tree for the string "gnu".
-
-   Please read the comments of cxx11_attribute_p to understand the
-   format of attributes.  */
-
-tree
-get_attribute_namespace (const_tree attr)
-{
-  if (cxx11_attribute_p (attr))
-    return TREE_PURPOSE (TREE_PURPOSE (attr));
-  return get_identifier ("gnu");
-}
-
 /* Subroutine of set_method_tm_attributes.  Apply TM attribute ATTR
    to the method FNDECL.  */
 
index f84789e6a59f3d27acf7e6dab4e1e017dff82bd8..7a04664c9099ced6ed1437af25047a0e05499fdf 100644 (file)
@@ -1050,6 +1050,63 @@ expand_builtin_longjmp (rtx buf_addr, rtx value)
     }
 }
 
+static inline bool
+more_const_call_expr_args_p (const const_call_expr_arg_iterator *iter)
+{
+  return (iter->i < iter->n);
+}
+
+/* This function validates the types of a function call argument list
+   against a specified list of tree_codes.  If the last specifier is a 0,
+   that represents an ellipses, otherwise the last specifier must be a
+   VOID_TYPE.  */
+
+static bool
+validate_arglist (const_tree callexpr, ...)
+{
+  enum tree_code code;
+  bool res = 0;
+  va_list ap;
+  const_call_expr_arg_iterator iter;
+  const_tree arg;
+
+  va_start (ap, callexpr);
+  init_const_call_expr_arg_iterator (callexpr, &iter);
+
+  do
+    {
+      code = (enum tree_code) va_arg (ap, int);
+      switch (code)
+       {
+       case 0:
+         /* This signifies an ellipses, any further arguments are all ok.  */
+         res = true;
+         goto end;
+       case VOID_TYPE:
+         /* This signifies an endlink, if no arguments remain, return
+            true, otherwise return false.  */
+         res = !more_const_call_expr_args_p (&iter);
+         goto end;
+       default:
+         /* If no parameters remain or the parameter's code does not
+            match the specified code, return false.  Otherwise continue
+            checking any remaining arguments.  */
+         arg = next_const_call_expr_arg (&iter);
+         if (!validate_arg (arg, code))
+           goto end;
+         break;
+       }
+    }
+  while (1);
+
+  /* We need gotos here since we can only have one VA_CLOSE in a
+     function.  */
+ end: ;
+  va_end (ap);
+
+  return res;
+}
+
 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
    and the address of the save area.  */
 
@@ -5581,6 +5638,33 @@ expand_builtin_set_thread_pointer (tree exp)
 }
 
 \f
+/* Emit code to restore the current value of stack.  */
+
+static void
+expand_stack_restore (tree var)
+{
+  rtx prev, sa = expand_normal (var);
+
+  sa = convert_memory_address (Pmode, sa);
+
+  prev = get_last_insn ();
+  emit_stack_restore (SAVE_BLOCK, sa);
+  fixup_args_size_notes (prev, get_last_insn (), 0);
+}
+
+
+/* Emit code to save the current value of stack.  */
+
+static rtx
+expand_stack_save (void)
+{
+  rtx ret = NULL_RTX;
+
+  do_pending_stack_adjust ();
+  emit_stack_save (SAVE_BLOCK, &ret);
+  return ret;
+}
+
 /* Expand an expression EXP that calls a built-in function,
    with result going to TARGET if that's convenient
    (and in mode MODE if that's convenient).
@@ -10962,47 +11046,51 @@ fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
   return NULL_TREE;
 }
 
-/* Builtins with folding operations that operate on "..." arguments
-   need special handling; we need to store the arguments in a convenient
-   data structure before attempting any folding.  Fortunately there are
-   only a few builtins that fall into this category.  FNDECL is the
-   function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
-   result of the function call is ignored.  */
+/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
+   list ARGS along with N new arguments in NEWARGS.  SKIP is the number
+   of arguments in ARGS to be omitted.  OLDNARGS is the number of
+   elements in ARGS.  */
 
 static tree
-fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
-                     bool ignore ATTRIBUTE_UNUSED)
+rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
+                         int skip, tree fndecl, int n, va_list newargs)
 {
-  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
-  tree ret = NULL_TREE;
+  int nargs = oldnargs - skip + n;
+  tree *buffer;
 
-  switch (fcode)
+  if (n > 0)
     {
-    case BUILT_IN_SPRINTF_CHK:
-    case BUILT_IN_VSPRINTF_CHK:
-      ret = fold_builtin_sprintf_chk (loc, exp, fcode);
-      break;
+      int i, j;
 
-    case BUILT_IN_SNPRINTF_CHK:
-    case BUILT_IN_VSNPRINTF_CHK:
-      ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
-      break;
+      buffer = XALLOCAVEC (tree, nargs);
+      for (i = 0; i < n; i++)
+       buffer[i] = va_arg (newargs, tree);
+      for (j = skip; j < oldnargs; j++, i++)
+       buffer[i] = args[j];
+    }
+  else
+    buffer = args + skip;
 
-    case BUILT_IN_FPCLASSIFY:
-      ret = fold_builtin_fpclassify (loc, exp);
-      break;
+  return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
+}
 
-    default:
-      break;
-    }
-  if (ret)
-    {
-      ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
-      SET_EXPR_LOCATION (ret, loc);
-      TREE_NO_WARNING (ret) = 1;
-      return ret;
-    }
-  return NULL_TREE;
+/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
+   list ARGS along with N new arguments specified as the "..."
+   parameters.  SKIP is the number of arguments in ARGS to be omitted.
+   OLDNARGS is the number of elements in ARGS.  */
+
+static tree
+rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
+                        int skip, tree fndecl, int n, ...)
+{
+  va_list ap;
+  tree t;
+
+  va_start (ap, n);
+  t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
+  va_end (ap);
+
+  return t;
 }
 
 /* Return true if FNDECL shouldn't be folded right now.
@@ -11193,53 +11281,6 @@ fold_builtin_call_array (location_t loc, tree type,
   return build_call_array_loc (loc, type, fn, n, argarray);
 }
 
-/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
-   list ARGS along with N new arguments in NEWARGS.  SKIP is the number
-   of arguments in ARGS to be omitted.  OLDNARGS is the number of
-   elements in ARGS.  */
-
-static tree
-rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
-                         int skip, tree fndecl, int n, va_list newargs)
-{
-  int nargs = oldnargs - skip + n;
-  tree *buffer;
-
-  if (n > 0)
-    {
-      int i, j;
-
-      buffer = XALLOCAVEC (tree, nargs);
-      for (i = 0; i < n; i++)
-       buffer[i] = va_arg (newargs, tree);
-      for (j = skip; j < oldnargs; j++, i++)
-       buffer[i] = args[j];
-    }
-  else
-    buffer = args + skip;
-
-  return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
-}
-
-/* Construct a new CALL_EXPR to FNDECL using the tail of the argument
-   list ARGS along with N new arguments specified as the "..."
-   parameters.  SKIP is the number of arguments in ARGS to be omitted.
-   OLDNARGS is the number of elements in ARGS.  */
-
-static tree
-rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
-                        int skip, tree fndecl, int n, ...)
-{
-  va_list ap;
-  tree t;
-
-  va_start (ap, n);
-  t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
-  va_end (ap);
-
-  return t;
-}
-
 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
    along with N new arguments specified as the "..." parameters.  SKIP
    is the number of arguments in EXP to be omitted.  This function is used
@@ -11329,57 +11370,6 @@ validate_gimple_arglist (const_gimple call, ...)
   return res;
 }
 
-/* This function validates the types of a function call argument list
-   against a specified list of tree_codes.  If the last specifier is a 0,
-   that represents an ellipses, otherwise the last specifier must be a
-   VOID_TYPE.  */
-
-bool
-validate_arglist (const_tree callexpr, ...)
-{
-  enum tree_code code;
-  bool res = 0;
-  va_list ap;
-  const_call_expr_arg_iterator iter;
-  const_tree arg;
-
-  va_start (ap, callexpr);
-  init_const_call_expr_arg_iterator (callexpr, &iter);
-
-  do
-    {
-      code = (enum tree_code) va_arg (ap, int);
-      switch (code)
-       {
-       case 0:
-         /* This signifies an ellipses, any further arguments are all ok.  */
-         res = true;
-         goto end;
-       case VOID_TYPE:
-         /* This signifies an endlink, if no arguments remain, return
-            true, otherwise return false.  */
-         res = !more_const_call_expr_args_p (&iter);
-         goto end;
-       default:
-         /* If no parameters remain or the parameter's code does not
-            match the specified code, return false.  Otherwise continue
-            checking any remaining arguments.  */
-         arg = next_const_call_expr_arg (&iter);
-         if (!validate_arg (arg, code))
-           goto end;
-         break;
-       }
-    }
-  while (1);
-
-  /* We need gotos here since we can only have one VA_CLOSE in a
-     function.  */
- end: ;
-  va_end (ap);
-
-  return res;
-}
-
 /* Default target-specific builtin expander that does nothing.  */
 
 rtx
@@ -13151,7 +13141,7 @@ fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
    passed as second argument.  */
 
-tree
+static tree
 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
                           enum built_in_function fcode)
 {
@@ -13159,6 +13149,49 @@ fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
                                      CALL_EXPR_ARGP (exp), maxlen, fcode);
 }
 
+/* Builtins with folding operations that operate on "..." arguments
+   need special handling; we need to store the arguments in a convenient
+   data structure before attempting any folding.  Fortunately there are
+   only a few builtins that fall into this category.  FNDECL is the
+   function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
+   result of the function call is ignored.  */
+
+static tree
+fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
+                     bool ignore ATTRIBUTE_UNUSED)
+{
+  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+  tree ret = NULL_TREE;
+
+  switch (fcode)
+    {
+    case BUILT_IN_SPRINTF_CHK:
+    case BUILT_IN_VSPRINTF_CHK:
+      ret = fold_builtin_sprintf_chk (loc, exp, fcode);
+      break;
+
+    case BUILT_IN_SNPRINTF_CHK:
+    case BUILT_IN_VSNPRINTF_CHK:
+      ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
+      break;
+
+    case BUILT_IN_FPCLASSIFY:
+      ret = fold_builtin_fpclassify (loc, exp);
+      break;
+
+    default:
+      break;
+    }
+  if (ret)
+    {
+      ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
+      SET_EXPR_LOCATION (ret, loc);
+      TREE_NO_WARNING (ret) = 1;
+      return ret;
+    }
+  return NULL_TREE;
+}
+
 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
    FMT and ARG are the arguments to the call; we don't fold cases with
    more than 2 arguments, and ARG may be null if this is a 1-argument case.
index fb05ce7a05d3dadb1d2bd8b7e6d9856e1dc5a4e5..8faf48ad4f8d557165fad7523667e36f92633df8 100644 (file)
@@ -21,8 +21,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "tree.h"
 #include "rtl.h"
+#include "hard-reg-set.h"
+#include "tree.h"
 #include "tm_p.h"
 #include "basic-block.h"
 #include "function.h"
@@ -57,6 +58,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-attr.h" /* For INSN_SCHEDULING.  */
 #include "asan.h"
 #include "tree-ssa-address.h"
+#include "recog.h"
+#include "output.h"
 
 /* This variable holds information helping the rewriting of SSA trees
    into RTL.  */
@@ -2194,6 +2197,866 @@ expand_call_stmt (gimple stmt)
   mark_transaction_restart_calls (stmt);
 }
 
+
+/* Generate RTL for an asm statement (explicit assembler code).
+   STRING is a STRING_CST node containing the assembler code text,
+   or an ADDR_EXPR containing a STRING_CST.  VOL nonzero means the
+   insn is volatile; don't optimize it.  */
+
+static void
+expand_asm_loc (tree string, int vol, location_t locus)
+{
+  rtx body;
+
+  if (TREE_CODE (string) == ADDR_EXPR)
+    string = TREE_OPERAND (string, 0);
+
+  body = gen_rtx_ASM_INPUT_loc (VOIDmode,
+                               ggc_strdup (TREE_STRING_POINTER (string)),
+                               locus);
+
+  MEM_VOLATILE_P (body) = vol;
+
+  emit_insn (body);
+}
+
+/* Return the number of times character C occurs in string S.  */
+static int
+n_occurrences (int c, const char *s)
+{
+  int n = 0;
+  while (*s)
+    n += (*s++ == c);
+  return n;
+}
+
+/* A subroutine of expand_asm_operands.  Check that all operands have
+   the same number of alternatives.  Return true if so.  */
+
+static bool
+check_operand_nalternatives (tree outputs, tree inputs)
+{
+  if (outputs || inputs)
+    {
+      tree tmp = TREE_PURPOSE (outputs ? outputs : inputs);
+      int nalternatives
+       = n_occurrences (',', TREE_STRING_POINTER (TREE_VALUE (tmp)));
+      tree next = inputs;
+
+      if (nalternatives + 1 > MAX_RECOG_ALTERNATIVES)
+       {
+         error ("too many alternatives in %<asm%>");
+         return false;
+       }
+
+      tmp = outputs;
+      while (tmp)
+       {
+         const char *constraint
+           = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tmp)));
+
+         if (n_occurrences (',', constraint) != nalternatives)
+           {
+             error ("operand constraints for %<asm%> differ "
+                    "in number of alternatives");
+             return false;
+           }
+
+         if (TREE_CHAIN (tmp))
+           tmp = TREE_CHAIN (tmp);
+         else
+           tmp = next, next = 0;
+       }
+    }
+
+  return true;
+}
+
+/* Check for overlap between registers marked in CLOBBERED_REGS and
+   anything inappropriate in T.  Emit error and return the register
+   variable definition for error, NULL_TREE for ok.  */
+
+static bool
+tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
+{
+  /* Conflicts between asm-declared register variables and the clobber
+     list are not allowed.  */
+  tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs);
+
+  if (overlap)
+    {
+      error ("asm-specifier for variable %qE conflicts with asm clobber list",
+            DECL_NAME (overlap));
+
+      /* Reset registerness to stop multiple errors emitted for a single
+        variable.  */
+      DECL_REGISTER (overlap) = 0;
+      return true;
+    }
+
+  return false;
+}
+
+/* Generate RTL for an asm statement with arguments.
+   STRING is the instruction template.
+   OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
+   Each output or input has an expression in the TREE_VALUE and
+   a tree list in TREE_PURPOSE which in turn contains a constraint
+   name in TREE_VALUE (or NULL_TREE) and a constraint string
+   in TREE_PURPOSE.
+   CLOBBERS is a list of STRING_CST nodes each naming a hard register
+   that is clobbered by this insn.
+
+   LABELS is a list of labels, and if LABELS is non-NULL, FALLTHRU_BB
+   should be the fallthru basic block of the asm goto.
+
+   Not all kinds of lvalue that may appear in OUTPUTS can be stored directly.
+   Some elements of OUTPUTS may be replaced with trees representing temporary
+   values.  The caller should copy those temporary values to the originally
+   specified lvalues.
+
+   VOL nonzero means the insn is volatile; don't optimize it.  */
+
+static void
+expand_asm_operands (tree string, tree outputs, tree inputs,
+                    tree clobbers, tree labels, basic_block fallthru_bb,
+                    int vol, location_t locus)
+{
+  rtvec argvec, constraintvec, labelvec;
+  rtx body;
+  int ninputs = list_length (inputs);
+  int noutputs = list_length (outputs);
+  int nlabels = list_length (labels);
+  int ninout;
+  int nclobbers;
+  HARD_REG_SET clobbered_regs;
+  int clobber_conflict_found = 0;
+  tree tail;
+  tree t;
+  int i;
+  /* Vector of RTX's of evaluated output operands.  */
+  rtx *output_rtx = XALLOCAVEC (rtx, noutputs);
+  int *inout_opnum = XALLOCAVEC (int, noutputs);
+  rtx *real_output_rtx = XALLOCAVEC (rtx, noutputs);
+  enum machine_mode *inout_mode = XALLOCAVEC (enum machine_mode, noutputs);
+  const char **constraints = XALLOCAVEC (const char *, noutputs + ninputs);
+  int old_generating_concat_p = generating_concat_p;
+  rtx fallthru_label = NULL_RTX;
+
+  /* An ASM with no outputs needs to be treated as volatile, for now.  */
+  if (noutputs == 0)
+    vol = 1;
+
+  if (! check_operand_nalternatives (outputs, inputs))
+    return;
+
+  string = resolve_asm_operand_names (string, outputs, inputs, labels);
+
+  /* Collect constraints.  */
+  i = 0;
+  for (t = outputs; t ; t = TREE_CHAIN (t), i++)
+    constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+  for (t = inputs; t ; t = TREE_CHAIN (t), i++)
+    constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+
+  /* Sometimes we wish to automatically clobber registers across an asm.
+     Case in point is when the i386 backend moved from cc0 to a hard reg --
+     maintaining source-level compatibility means automatically clobbering
+     the flags register.  */
+  clobbers = targetm.md_asm_clobbers (outputs, inputs, clobbers);
+
+  /* Count the number of meaningful clobbered registers, ignoring what
+     we would ignore later.  */
+  nclobbers = 0;
+  CLEAR_HARD_REG_SET (clobbered_regs);
+  for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
+    {
+      const char *regname;
+      int nregs;
+
+      if (TREE_VALUE (tail) == error_mark_node)
+       return;
+      regname = TREE_STRING_POINTER (TREE_VALUE (tail));
+
+      i = decode_reg_name_and_count (regname, &nregs);
+      if (i == -4)
+       ++nclobbers;
+      else if (i == -2)
+       error ("unknown register name %qs in %<asm%>", regname);
+
+      /* Mark clobbered registers.  */
+      if (i >= 0)
+        {
+         int reg;
+
+         for (reg = i; reg < i + nregs; reg++)
+           {
+             ++nclobbers;
+
+             /* Clobbering the PIC register is an error.  */
+             if (reg == (int) PIC_OFFSET_TABLE_REGNUM)
+               {
+                 error ("PIC register clobbered by %qs in %<asm%>", regname);
+                 return;
+               }
+
+             SET_HARD_REG_BIT (clobbered_regs, reg);
+           }
+       }
+    }
+
+  /* First pass over inputs and outputs checks validity and sets
+     mark_addressable if needed.  */
+
+  ninout = 0;
+  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
+    {
+      tree val = TREE_VALUE (tail);
+      tree type = TREE_TYPE (val);
+      const char *constraint;
+      bool is_inout;
+      bool allows_reg;
+      bool allows_mem;
+
+      /* If there's an erroneous arg, emit no insn.  */
+      if (type == error_mark_node)
+       return;
+
+      /* Try to parse the output constraint.  If that fails, there's
+        no point in going further.  */
+      constraint = constraints[i];
+      if (!parse_output_constraint (&constraint, i, ninputs, noutputs,
+                                   &allows_mem, &allows_reg, &is_inout))
+       return;
+
+      if (! allows_reg
+         && (allows_mem
+             || is_inout
+             || (DECL_P (val)
+                 && REG_P (DECL_RTL (val))
+                 && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type))))
+       mark_addressable (val);
+
+      if (is_inout)
+       ninout++;
+    }
+
+  ninputs += ninout;
+  if (ninputs + noutputs > MAX_RECOG_OPERANDS)
+    {
+      error ("more than %d operands in %<asm%>", MAX_RECOG_OPERANDS);
+      return;
+    }
+
+  for (i = 0, tail = inputs; tail; i++, tail = TREE_CHAIN (tail))
+    {
+      bool allows_reg, allows_mem;
+      const char *constraint;
+
+      /* If there's an erroneous arg, emit no insn, because the ASM_INPUT
+        would get VOIDmode and that could cause a crash in reload.  */
+      if (TREE_TYPE (TREE_VALUE (tail)) == error_mark_node)
+       return;
+
+      constraint = constraints[i + noutputs];
+      if (! parse_input_constraint (&constraint, i, ninputs, noutputs, ninout,
+                                   constraints, &allows_mem, &allows_reg))
+       return;
+
+      if (! allows_reg && allows_mem)
+       mark_addressable (TREE_VALUE (tail));
+    }
+
+  /* Second pass evaluates arguments.  */
+
+  /* Make sure stack is consistent for asm goto.  */
+  if (nlabels > 0)
+    do_pending_stack_adjust ();
+
+  ninout = 0;
+  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
+    {
+      tree val = TREE_VALUE (tail);
+      tree type = TREE_TYPE (val);
+      bool is_inout;
+      bool allows_reg;
+      bool allows_mem;
+      rtx op;
+      bool ok;
+
+      ok = parse_output_constraint (&constraints[i], i, ninputs,
+                                   noutputs, &allows_mem, &allows_reg,
+                                   &is_inout);
+      gcc_assert (ok);
+
+      /* If an output operand is not a decl or indirect ref and our constraint
+        allows a register, make a temporary to act as an intermediate.
+        Make the asm insn write into that, then our caller will copy it to
+        the real output operand.  Likewise for promoted variables.  */
+
+      generating_concat_p = 0;
+
+      real_output_rtx[i] = NULL_RTX;
+      if ((TREE_CODE (val) == INDIRECT_REF
+          && allows_mem)
+         || (DECL_P (val)
+             && (allows_mem || REG_P (DECL_RTL (val)))
+             && ! (REG_P (DECL_RTL (val))
+                   && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
+         || ! allows_reg
+         || is_inout)
+       {
+         op = expand_expr (val, NULL_RTX, VOIDmode,
+                           !allows_reg ? EXPAND_MEMORY : EXPAND_WRITE);
+         if (MEM_P (op))
+           op = validize_mem (op);
+
+         if (! allows_reg && !MEM_P (op))
+           error ("output number %d not directly addressable", i);
+         if ((! allows_mem && MEM_P (op))
+             || GET_CODE (op) == CONCAT)
+           {
+             real_output_rtx[i] = op;
+             op = gen_reg_rtx (GET_MODE (op));
+             if (is_inout)
+               emit_move_insn (op, real_output_rtx[i]);
+           }
+       }
+      else
+       {
+         op = assign_temp (type, 0, 1);
+         op = validize_mem (op);
+         if (!MEM_P (op) && TREE_CODE (TREE_VALUE (tail)) == SSA_NAME)
+           set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (TREE_VALUE (tail)), op);
+         TREE_VALUE (tail) = make_tree (type, op);
+       }
+      output_rtx[i] = op;
+
+      generating_concat_p = old_generating_concat_p;
+
+      if (is_inout)
+       {
+         inout_mode[ninout] = TYPE_MODE (type);
+         inout_opnum[ninout++] = i;
+       }
+
+      if (tree_conflicts_with_clobbers_p (val, &clobbered_regs))
+       clobber_conflict_found = 1;
+    }
+
+  /* Make vectors for the expression-rtx, constraint strings,
+     and named operands.  */
+
+  argvec = rtvec_alloc (ninputs);
+  constraintvec = rtvec_alloc (ninputs);
+  labelvec = rtvec_alloc (nlabels);
+
+  body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode
+                               : GET_MODE (output_rtx[0])),
+                              ggc_strdup (TREE_STRING_POINTER (string)),
+                              empty_string, 0, argvec, constraintvec,
+                              labelvec, locus);
+
+  MEM_VOLATILE_P (body) = vol;
+
+  /* Eval the inputs and put them into ARGVEC.
+     Put their constraints into ASM_INPUTs and store in CONSTRAINTS.  */
+
+  for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), ++i)
+    {
+      bool allows_reg, allows_mem;
+      const char *constraint;
+      tree val, type;
+      rtx op;
+      bool ok;
+
+      constraint = constraints[i + noutputs];
+      ok = parse_input_constraint (&constraint, i, ninputs, noutputs, ninout,
+                                  constraints, &allows_mem, &allows_reg);
+      gcc_assert (ok);
+
+      generating_concat_p = 0;
+
+      val = TREE_VALUE (tail);
+      type = TREE_TYPE (val);
+      /* EXPAND_INITIALIZER will not generate code for valid initializer
+        constants, but will still generate code for other types of operand.
+        This is the behavior we want for constant constraints.  */
+      op = expand_expr (val, NULL_RTX, VOIDmode,
+                       allows_reg ? EXPAND_NORMAL
+                       : allows_mem ? EXPAND_MEMORY
+                       : EXPAND_INITIALIZER);
+
+      /* Never pass a CONCAT to an ASM.  */
+      if (GET_CODE (op) == CONCAT)
+       op = force_reg (GET_MODE (op), op);
+      else if (MEM_P (op))
+       op = validize_mem (op);
+
+      if (asm_operand_ok (op, constraint, NULL) <= 0)
+       {
+         if (allows_reg && TYPE_MODE (type) != BLKmode)
+           op = force_reg (TYPE_MODE (type), op);
+         else if (!allows_mem)
+           warning (0, "asm operand %d probably doesn%'t match constraints",
+                    i + noutputs);
+         else if (MEM_P (op))
+           {
+             /* We won't recognize either volatile memory or memory
+                with a queued address as available a memory_operand
+                at this point.  Ignore it: clearly this *is* a memory.  */
+           }
+         else
+           gcc_unreachable ();
+       }
+
+      generating_concat_p = old_generating_concat_p;
+      ASM_OPERANDS_INPUT (body, i) = op;
+
+      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, i)
+       = gen_rtx_ASM_INPUT (TYPE_MODE (type),
+                            ggc_strdup (constraints[i + noutputs]));
+
+      if (tree_conflicts_with_clobbers_p (val, &clobbered_regs))
+       clobber_conflict_found = 1;
+    }
+
+  /* Protect all the operands from the queue now that they have all been
+     evaluated.  */
+
+  generating_concat_p = 0;
+
+  /* For in-out operands, copy output rtx to input rtx.  */
+  for (i = 0; i < ninout; i++)
+    {
+      int j = inout_opnum[i];
+      char buffer[16];
+
+      ASM_OPERANDS_INPUT (body, ninputs - ninout + i)
+       = output_rtx[j];
+
+      sprintf (buffer, "%d", j);
+      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, ninputs - ninout + i)
+       = gen_rtx_ASM_INPUT (inout_mode[i], ggc_strdup (buffer));
+    }
+
+  /* Copy labels to the vector.  */
+  for (i = 0, tail = labels; i < nlabels; ++i, tail = TREE_CHAIN (tail))
+    {
+      rtx r;
+      /* If asm goto has any labels in the fallthru basic block, use
+        a label that we emit immediately after the asm goto.  Expansion
+        may insert further instructions into the same basic block after
+        asm goto and if we don't do this, insertion of instructions on
+        the fallthru edge might misbehave.  See PR58670.  */
+      if (fallthru_bb
+         && label_to_block_fn (cfun, TREE_VALUE (tail)) == fallthru_bb)
+       {
+         if (fallthru_label == NULL_RTX)
+           fallthru_label = gen_label_rtx ();
+         r = fallthru_label;
+       }
+      else
+       r = label_rtx (TREE_VALUE (tail));
+      ASM_OPERANDS_LABEL (body, i) = gen_rtx_LABEL_REF (Pmode, r);
+    }
+
+  generating_concat_p = old_generating_concat_p;
+
+  /* Now, for each output, construct an rtx
+     (set OUTPUT (asm_operands INSN OUTPUTCONSTRAINT OUTPUTNUMBER
+                              ARGVEC CONSTRAINTS OPNAMES))
+     If there is more than one, put them inside a PARALLEL.  */
+
+  if (nlabels > 0 && nclobbers == 0)
+    {
+      gcc_assert (noutputs == 0);
+      emit_jump_insn (body);
+    }
+  else if (noutputs == 0 && nclobbers == 0)
+    {
+      /* No output operands: put in a raw ASM_OPERANDS rtx.  */
+      emit_insn (body);
+    }
+  else if (noutputs == 1 && nclobbers == 0)
+    {
+      ASM_OPERANDS_OUTPUT_CONSTRAINT (body) = ggc_strdup (constraints[0]);
+      emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
+    }
+  else
+    {
+      rtx obody = body;
+      int num = noutputs;
+
+      if (num == 0)
+       num = 1;
+
+      body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num + nclobbers));
+
+      /* For each output operand, store a SET.  */
+      for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
+       {
+         XVECEXP (body, 0, i)
+           = gen_rtx_SET (VOIDmode,
+                          output_rtx[i],
+                          gen_rtx_ASM_OPERANDS
+                          (GET_MODE (output_rtx[i]),
+                           ggc_strdup (TREE_STRING_POINTER (string)),
+                           ggc_strdup (constraints[i]),
+                           i, argvec, constraintvec, labelvec, locus));
+
+         MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
+       }
+
+      /* If there are no outputs (but there are some clobbers)
+        store the bare ASM_OPERANDS into the PARALLEL.  */
+
+      if (i == 0)
+       XVECEXP (body, 0, i++) = obody;
+
+      /* Store (clobber REG) for each clobbered register specified.  */
+
+      for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
+       {
+         const char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
+         int reg, nregs;
+         int j = decode_reg_name_and_count (regname, &nregs);
+         rtx clobbered_reg;
+
+         if (j < 0)
+           {
+             if (j == -3)      /* `cc', which is not a register */
+               continue;
+
+             if (j == -4)      /* `memory', don't cache memory across asm */
+               {
+                 XVECEXP (body, 0, i++)
+                   = gen_rtx_CLOBBER (VOIDmode,
+                                      gen_rtx_MEM
+                                      (BLKmode,
+                                       gen_rtx_SCRATCH (VOIDmode)));
+                 continue;
+               }
+
+             /* Ignore unknown register, error already signaled.  */
+             continue;
+           }
+
+         for (reg = j; reg < j + nregs; reg++)
+           {
+             /* Use QImode since that's guaranteed to clobber just
+              * one reg.  */
+             clobbered_reg = gen_rtx_REG (QImode, reg);
+
+             /* Do sanity check for overlap between clobbers and
+                respectively input and outputs that hasn't been
+                handled.  Such overlap should have been detected and
+                reported above.  */
+             if (!clobber_conflict_found)
+               {
+                 int opno;
+
+                 /* We test the old body (obody) contents to avoid
+                    tripping over the under-construction body.  */
+                 for (opno = 0; opno < noutputs; opno++)
+                   if (reg_overlap_mentioned_p (clobbered_reg,
+                                                output_rtx[opno]))
+                     internal_error
+                       ("asm clobber conflict with output operand");
+
+                 for (opno = 0; opno < ninputs - ninout; opno++)
+                   if (reg_overlap_mentioned_p (clobbered_reg,
+                                                ASM_OPERANDS_INPUT (obody,
+                                                                    opno)))
+                     internal_error
+                       ("asm clobber conflict with input operand");
+               }
+
+             XVECEXP (body, 0, i++)
+               = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
+           }
+       }
+
+      if (nlabels > 0)
+       emit_jump_insn (body);
+      else
+       emit_insn (body);
+    }
+
+  if (fallthru_label)
+    emit_label (fallthru_label);
+
+  /* For any outputs that needed reloading into registers, spill them
+     back to where they belong.  */
+  for (i = 0; i < noutputs; ++i)
+    if (real_output_rtx[i])
+      emit_move_insn (real_output_rtx[i], output_rtx[i]);
+
+  crtl->has_asm_statement = 1;
+  free_temp_slots ();
+}
+
+
+static void
+expand_asm_stmt (gimple stmt)
+{
+  int noutputs;
+  tree outputs, tail, t;
+  tree *o;
+  size_t i, n;
+  const char *s;
+  tree str, out, in, cl, labels;
+  location_t locus = gimple_location (stmt);
+  basic_block fallthru_bb = NULL;
+
+  /* Meh... convert the gimple asm operands into real tree lists.
+     Eventually we should make all routines work on the vectors instead
+     of relying on TREE_CHAIN.  */
+  out = NULL_TREE;
+  n = gimple_asm_noutputs (stmt);
+  if (n > 0)
+    {
+      t = out = gimple_asm_output_op (stmt, 0);
+      for (i = 1; i < n; i++)
+       t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
+    }
+
+  in = NULL_TREE;
+  n = gimple_asm_ninputs (stmt);
+  if (n > 0)
+    {
+      t = in = gimple_asm_input_op (stmt, 0);
+      for (i = 1; i < n; i++)
+       t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
+    }
+
+  cl = NULL_TREE;
+  n = gimple_asm_nclobbers (stmt);
+  if (n > 0)
+    {
+      t = cl = gimple_asm_clobber_op (stmt, 0);
+      for (i = 1; i < n; i++)
+       t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
+    }
+
+  labels = NULL_TREE;
+  n = gimple_asm_nlabels (stmt);
+  if (n > 0)
+    {
+      edge fallthru = find_fallthru_edge (gimple_bb (stmt)->succs);
+      if (fallthru)
+       fallthru_bb = fallthru->dest;
+      t = labels = gimple_asm_label_op (stmt, 0);
+      for (i = 1; i < n; i++)
+       t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
+    }
+
+  s = gimple_asm_string (stmt);
+  str = build_string (strlen (s), s);
+
+  if (gimple_asm_input_p (stmt))
+    {
+      expand_asm_loc (str, gimple_asm_volatile_p (stmt), locus);
+      return;
+    }
+
+  outputs = out;
+  noutputs = gimple_asm_noutputs (stmt);
+  /* o[I] is the place that output number I should be written.  */
+  o = (tree *) alloca (noutputs * sizeof (tree));
+
+  /* Record the contents of OUTPUTS before it is modified.  */
+  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
+    o[i] = TREE_VALUE (tail);
+
+  /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
+     OUTPUTS some trees for where the values were actually stored.  */
+  expand_asm_operands (str, outputs, in, cl, labels, fallthru_bb,
+                      gimple_asm_volatile_p (stmt), locus);
+
+  /* Copy all the intermediate outputs into the specified outputs.  */
+  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
+    {
+      if (o[i] != TREE_VALUE (tail))
+       {
+         expand_assignment (o[i], TREE_VALUE (tail), false);
+         free_temp_slots ();
+
+         /* Restore the original value so that it's correct the next
+            time we expand this function.  */
+         TREE_VALUE (tail) = o[i];
+       }
+    }
+}
+
+/* Emit code to jump to the address
+   specified by the pointer expression EXP.  */
+
+static void
+expand_computed_goto (tree exp)
+{
+  rtx x = expand_normal (exp);
+
+  x = convert_memory_address (Pmode, x);
+
+  do_pending_stack_adjust ();
+  emit_indirect_jump (x);
+}
+
+/* Generate RTL code for a `goto' statement with target label LABEL.
+   LABEL should be a LABEL_DECL tree node that was or will later be
+   defined with `expand_label'.  */
+
+static void
+expand_goto (tree label)
+{
+#ifdef ENABLE_CHECKING
+  /* Check for a nonlocal goto to a containing function.  Should have
+     gotten translated to __builtin_nonlocal_goto.  */
+  tree context = decl_function_context (label);
+  gcc_assert (!context || context == current_function_decl);
+#endif
+
+  emit_jump (label_rtx (label));
+}
+
+/* Output a return with no value.  */
+
+static void
+expand_null_return_1 (void)
+{
+  clear_pending_stack_adjust ();
+  do_pending_stack_adjust ();
+  emit_jump (return_label);
+}
+
+/* Generate RTL to return from the current function, with no value.
+   (That is, we do not do anything about returning any value.)  */
+
+void
+expand_null_return (void)
+{
+  /* If this function was declared to return a value, but we
+     didn't, clobber the return registers so that they are not
+     propagated live to the rest of the function.  */
+  clobber_return_register ();
+
+  expand_null_return_1 ();
+}
+
+/* Generate RTL to return from the current function, with value VAL.  */
+
+static void
+expand_value_return (rtx val)
+{
+  /* Copy the value to the return location unless it's already there.  */
+
+  tree decl = DECL_RESULT (current_function_decl);
+  rtx return_reg = DECL_RTL (decl);
+  if (return_reg != val)
+    {
+      tree funtype = TREE_TYPE (current_function_decl);
+      tree type = TREE_TYPE (decl);
+      int unsignedp = TYPE_UNSIGNED (type);
+      enum machine_mode old_mode = DECL_MODE (decl);
+      enum machine_mode mode;
+      if (DECL_BY_REFERENCE (decl))
+        mode = promote_function_mode (type, old_mode, &unsignedp, funtype, 2);
+      else
+        mode = promote_function_mode (type, old_mode, &unsignedp, funtype, 1);
+
+      if (mode != old_mode)
+       val = convert_modes (mode, old_mode, val, unsignedp);
+
+      if (GET_CODE (return_reg) == PARALLEL)
+       emit_group_load (return_reg, val, type, int_size_in_bytes (type));
+      else
+       emit_move_insn (return_reg, val);
+    }
+
+  expand_null_return_1 ();
+}
+
+/* Generate RTL to evaluate the expression RETVAL and return it
+   from the current function.  */
+
+static void
+expand_return (tree retval)
+{
+  rtx result_rtl;
+  rtx val = 0;
+  tree retval_rhs;
+
+  /* If function wants no value, give it none.  */
+  if (TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl))) == VOID_TYPE)
+    {
+      expand_normal (retval);
+      expand_null_return ();
+      return;
+    }
+
+  if (retval == error_mark_node)
+    {
+      /* Treat this like a return of no value from a function that
+        returns a value.  */
+      expand_null_return ();
+      return;
+    }
+  else if ((TREE_CODE (retval) == MODIFY_EXPR
+           || TREE_CODE (retval) == INIT_EXPR)
+          && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
+    retval_rhs = TREE_OPERAND (retval, 1);
+  else
+    retval_rhs = retval;
+
+  result_rtl = DECL_RTL (DECL_RESULT (current_function_decl));
+
+  /* If we are returning the RESULT_DECL, then the value has already
+     been stored into it, so we don't have to do anything special.  */
+  if (TREE_CODE (retval_rhs) == RESULT_DECL)
+    expand_value_return (result_rtl);
+
+  /* If the result is an aggregate that is being returned in one (or more)
+     registers, load the registers here.  */
+
+  else if (retval_rhs != 0
+          && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
+          && REG_P (result_rtl))
+    {
+      val = copy_blkmode_to_reg (GET_MODE (result_rtl), retval_rhs);
+      if (val)
+       {
+         /* Use the mode of the result value on the return register.  */
+         PUT_MODE (result_rtl, GET_MODE (val));
+         expand_value_return (val);
+       }
+      else
+       expand_null_return ();
+    }
+  else if (retval_rhs != 0
+          && !VOID_TYPE_P (TREE_TYPE (retval_rhs))
+          && (REG_P (result_rtl)
+              || (GET_CODE (result_rtl) == PARALLEL)))
+    {
+      /* Calculate the return value into a temporary (usually a pseudo
+         reg).  */
+      tree ot = TREE_TYPE (DECL_RESULT (current_function_decl));
+      tree nt = build_qualified_type (ot, TYPE_QUALS (ot) | TYPE_QUAL_CONST);
+
+      val = assign_temp (nt, 0, 1);
+      val = expand_expr (retval_rhs, val, GET_MODE (val), EXPAND_NORMAL);
+      val = force_not_mem (val);
+      /* Return the calculated value.  */
+      expand_value_return (val);
+    }
+  else
+    {
+      /* No hard reg used; calculate value into hard return reg.  */
+      expand_expr (retval, const0_rtx, VOIDmode, EXPAND_NORMAL);
+      expand_value_return (result_rtl);
+    }
+}
+
 /* A subroutine of expand_gimple_stmt, expanding one gimple statement
    STMT that doesn't require special handling for outgoing edges.  That
    is no tailcalls and no GIMPLE_COND.  */
@@ -4534,6 +5397,52 @@ expand_stack_alignment (void)
       fixup_tail_calls ();
     }
 }
+\f
+
+static void
+expand_main_function (void)
+{
+#if (defined(INVOKE__main)                             \
+     || (!defined(HAS_INIT_SECTION)                    \
+        && !defined(INIT_SECTION_ASM_OP)               \
+        && !defined(INIT_ARRAY_SECTION_ASM_OP)))
+  emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
+#endif
+}
+\f
+
+/* Expand code to initialize the stack_protect_guard.  This is invoked at
+   the beginning of a function to be protected.  */
+
+#ifndef HAVE_stack_protect_set
+# define HAVE_stack_protect_set                0
+# define gen_stack_protect_set(x,y)    (gcc_unreachable (), NULL_RTX)
+#endif
+
+static void
+stack_protect_prologue (void)
+{
+  tree guard_decl = targetm.stack_protect_guard ();
+  rtx x, y;
+
+  x = expand_normal (crtl->stack_protect_guard);
+  y = expand_normal (guard_decl);
+
+  /* Allow the target to copy from Y to X without leaking Y into a
+     register.  */
+  if (HAVE_stack_protect_set)
+    {
+      rtx insn = gen_stack_protect_set (x, y);
+      if (insn)
+       {
+         emit_insn (insn);
+         return;
+       }
+    }
+
+  /* Otherwise do a straight move.  */
+  emit_move_insn (x, y);
+}
 
 /* Translate the intermediate representation contained in the CFG
    from GIMPLE trees to RTL.
index 373f5013d26b6e8ad63e2b5ee327621f0054fdf2..9bb5656fb078e64cf71637e56c969542308f3b8a 100644 (file)
@@ -277,6 +277,111 @@ clone_function_name (tree decl, const char *suffix)
   return get_identifier (tmp_name);
 }
 
+/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
+   return value if SKIP_RETURN is true.  */
+
+static tree
+build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
+                              bool skip_return)
+{
+  tree new_type = NULL;
+  tree args, new_args = NULL, t;
+  tree new_reversed;
+  int i = 0;
+
+  for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node;
+       args = TREE_CHAIN (args), i++)
+    if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
+      new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args);
+
+  new_reversed = nreverse (new_args);
+  if (args)
+    {
+      if (new_reversed)
+        TREE_CHAIN (new_args) = void_list_node;
+      else
+       new_reversed = void_list_node;
+    }
+
+  /* Use copy_node to preserve as much as possible from original type
+     (debug info, attribute lists etc.)
+     Exception is METHOD_TYPEs must have THIS argument.
+     When we are asked to remove it, we need to build new FUNCTION_TYPE
+     instead.  */
+  if (TREE_CODE (orig_type) != METHOD_TYPE
+      || !args_to_skip
+      || !bitmap_bit_p (args_to_skip, 0))
+    {
+      new_type = build_distinct_type_copy (orig_type);
+      TYPE_ARG_TYPES (new_type) = new_reversed;
+    }
+  else
+    {
+      new_type
+        = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
+                                                        new_reversed));
+      TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
+    }
+
+  if (skip_return)
+    TREE_TYPE (new_type) = void_type_node;
+
+  /* This is a new type, not a copy of an old type.  Need to reassociate
+     variants.  We can handle everything except the main variant lazily.  */
+  t = TYPE_MAIN_VARIANT (orig_type);
+  if (t != orig_type)
+    {
+      t = build_function_type_skip_args (t, args_to_skip, skip_return);
+      TYPE_MAIN_VARIANT (new_type) = t;
+      TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
+      TYPE_NEXT_VARIANT (t) = new_type;
+    }
+  else
+    {
+      TYPE_MAIN_VARIANT (new_type) = new_type;
+      TYPE_NEXT_VARIANT (new_type) = NULL;
+    }
+
+  return new_type;
+}
+
+/* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the
+   return value if SKIP_RETURN is true.
+
+   Arguments from DECL_ARGUMENTS list can't be removed now, since they are
+   linked by TREE_CHAIN directly.  The caller is responsible for eliminating
+   them when they are being duplicated (i.e. copy_arguments_for_versioning).  */
+
+static tree
+build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
+                              bool skip_return)
+{
+  tree new_decl = copy_node (orig_decl);
+  tree new_type;
+
+  new_type = TREE_TYPE (orig_decl);
+  if (prototype_p (new_type)
+      || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type))))
+    new_type
+      = build_function_type_skip_args (new_type, args_to_skip, skip_return);
+  TREE_TYPE (new_decl) = new_type;
+
+  /* For declarations setting DECL_VINDEX (i.e. methods)
+     we expect first argument to be THIS pointer.   */
+  if (args_to_skip && bitmap_bit_p (args_to_skip, 0))
+    DECL_VINDEX (new_decl) = NULL_TREE;
+
+  /* When signature changes, we need to clear builtin info.  */
+  if (DECL_BUILT_IN (new_decl)
+      && args_to_skip
+      && !bitmap_empty_p (args_to_skip))
+    {
+      DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN;
+      DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0;
+    }
+  return new_decl;
+}
+
 /* Create callgraph node clone with new declaration.  The actual body will
    be copied later at compilation stage.
 
index f278e29b78e057ff8f2d6dc205c0c1bfb4e233d4..bf5742de89652103bde81e386d62409322f68742 100644 (file)
@@ -235,6 +235,18 @@ eliminate_constant_term (rtx x, rtx *constptr)
   return x;
 }
 
+/* Returns a tree for the size of EXP in bytes.  */
+
+static tree
+tree_expr_size (const_tree exp)
+{
+  if (DECL_P (exp)
+      && DECL_SIZE_UNIT (exp) != 0)
+    return DECL_SIZE_UNIT (exp);
+  else
+    return size_in_bytes (TREE_TYPE (exp));
+}
+
 /* Return an rtx for the size in bytes of the value of EXP.  */
 
 rtx
index 4c64489976f1af0f6a86d8a87a3f13d719903bf6..28b43320798c196f42b1e60f24bdc6575c96d580 100644 (file)
@@ -4630,17 +4630,6 @@ mem_ref_refers_to_non_mem_p (tree ref)
   return addr_expr_of_non_mem_decl_p_1 (base, false);
 }
 
-/* Return TRUE iff OP is an ADDR_EXPR of a DECL that's not
-   addressable.  This is very much like mem_ref_refers_to_non_mem_p,
-   but instead of the MEM_REF, it takes its base, and it doesn't
-   assume a DECL is in memory just because its RTL is not set yet.  */
-
-bool
-addr_expr_of_non_mem_decl_p (tree op)
-{
-  return addr_expr_of_non_mem_decl_p_1 (op, true);
-}
-
 /* Expand an assignment that stores the value of FROM into TO.  If NONTEMPORAL
    is true, try generating a nontemporal store.  */
 
@@ -5753,6 +5742,23 @@ store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
     store_field (target, bitsize, bitpos, 0, 0, mode, exp, alias_set, false);
 }
 
+
+/* Returns the number of FIELD_DECLs in TYPE.  */
+
+static int
+fields_length (const_tree type)
+{
+  tree t = TYPE_FIELDS (type);
+  int count = 0;
+
+  for (; t; t = DECL_CHAIN (t))
+    if (TREE_CODE (t) == FIELD_DECL)
+      ++count;
+
+  return count;
+}
+
+
 /* Store the value of constructor EXP into the rtx TARGET.
    TARGET is either a REG or a MEM; we know it cannot conflict, since
    safe_from_p has been called.
index c346063f925d9fe61d9eef871ce14eabd3ed6853..3e6f15887dbbce00aca9a7dc7776795f68e96110 100644 (file)
@@ -8944,6 +8944,17 @@ pointer_may_wrap_p (tree base, tree offset, HOST_WIDE_INT bitpos)
   return total.low > (unsigned HOST_WIDE_INT) size;
 }
 
+/* Return the HOST_WIDE_INT least significant bits of T, a sizetype
+   kind INTEGER_CST.  This makes sure to properly sign-extend the
+   constant.  */
+
+static HOST_WIDE_INT
+size_low_cst (const_tree t)
+{
+  double_int d = tree_to_double_int (t);
+  return d.sext (TYPE_PRECISION (TREE_TYPE (t))).low;
+}
+
 /* Subroutine of fold_binary.  This routine performs all of the
    transformations that are common to the equality/inequality
    operators (EQ_EXPR and NE_EXPR) and the ordering operators
@@ -9951,6 +9962,117 @@ mask_with_tz (tree type, double_int x, double_int y)
   return x;
 }
 
+/* Return true when T is an address and is known to be nonzero.
+   For floating point we further ensure that T is not denormal.
+   Similar logic is present in nonzero_address in rtlanal.h.
+
+   If the return value is based on the assumption that signed overflow
+   is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't
+   change *STRICT_OVERFLOW_P.  */
+
+static bool
+tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
+{
+  tree type = TREE_TYPE (t);
+  enum tree_code code;
+
+  /* Doing something useful for floating point would need more work.  */
+  if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
+    return false;
+
+  code = TREE_CODE (t);
+  switch (TREE_CODE_CLASS (code))
+    {
+    case tcc_unary:
+      return tree_unary_nonzero_warnv_p (code, type, TREE_OPERAND (t, 0),
+                                             strict_overflow_p);
+    case tcc_binary:
+    case tcc_comparison:
+      return tree_binary_nonzero_warnv_p (code, type,
+                                              TREE_OPERAND (t, 0),
+                                              TREE_OPERAND (t, 1),
+                                              strict_overflow_p);
+    case tcc_constant:
+    case tcc_declaration:
+    case tcc_reference:
+      return tree_single_nonzero_warnv_p (t, strict_overflow_p);
+
+    default:
+      break;
+    }
+
+  switch (code)
+    {
+    case TRUTH_NOT_EXPR:
+      return tree_unary_nonzero_warnv_p (code, type, TREE_OPERAND (t, 0),
+                                             strict_overflow_p);
+
+    case TRUTH_AND_EXPR:
+    case TRUTH_OR_EXPR:
+    case TRUTH_XOR_EXPR:
+      return tree_binary_nonzero_warnv_p (code, type,
+                                              TREE_OPERAND (t, 0),
+                                              TREE_OPERAND (t, 1),
+                                              strict_overflow_p);
+
+    case COND_EXPR:
+    case CONSTRUCTOR:
+    case OBJ_TYPE_REF:
+    case ASSERT_EXPR:
+    case ADDR_EXPR:
+    case WITH_SIZE_EXPR:
+    case SSA_NAME:
+      return tree_single_nonzero_warnv_p (t, strict_overflow_p);
+
+    case COMPOUND_EXPR:
+    case MODIFY_EXPR:
+    case BIND_EXPR:
+      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
+                                       strict_overflow_p);
+
+    case SAVE_EXPR:
+      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
+                                       strict_overflow_p);
+
+    case CALL_EXPR:
+      {
+       tree fndecl = get_callee_fndecl (t);
+       if (!fndecl) return false;
+       if (flag_delete_null_pointer_checks && !flag_check_new
+           && DECL_IS_OPERATOR_NEW (fndecl)
+           && !TREE_NOTHROW (fndecl))
+         return true;
+       if (flag_delete_null_pointer_checks
+           && lookup_attribute ("returns_nonnull",
+                TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+         return true;
+       return alloca_call_p (t);
+      }
+
+    default:
+      break;
+    }
+  return false;
+}
+
+/* Return true when T is an address and is known to be nonzero.
+   Handle warnings about undefined signed overflow.  */
+
+static bool
+tree_expr_nonzero_p (tree t)
+{
+  bool ret, strict_overflow_p;
+
+  strict_overflow_p = false;
+  ret = tree_expr_nonzero_warnv_p (t, &strict_overflow_p);
+  if (strict_overflow_p)
+    fold_overflow_warning (("assuming signed overflow does not occur when "
+                           "determining that expression is always "
+                           "non-zero"),
+                          WARN_STRICT_OVERFLOW_MISC);
+  return ret;
+}
+
 /* Fold a binary expression of code CODE and type TYPE with operands
    OP0 and OP1.  LOC is the location of the resulting expression.
    Return the folded expression if folding is successful.  Otherwise,
@@ -15243,19 +15365,6 @@ fold_build2_initializer_loc (location_t loc, enum tree_code code,
   return result;
 }
 
-tree
-fold_build3_initializer_loc (location_t loc, enum tree_code code,
-                            tree type, tree op0, tree op1, tree op2)
-{
-  tree result;
-  START_FOLD_INIT;
-
-  result = fold_build3_loc (loc, code, type, op0, op1, op2);
-
-  END_FOLD_INIT;
-  return result;
-}
-
 tree
 fold_build_call_array_initializer_loc (location_t loc, tree type, tree fn,
                                       int nargs, tree *argarray)
@@ -15777,7 +15886,7 @@ tree_call_nonnegative_warnv_p (tree type, tree fndecl,
    set *STRICT_OVERFLOW_P to true; otherwise, don't change
    *STRICT_OVERFLOW_P.  */
 
-bool
+static bool
 tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
 {
   enum tree_code code = TREE_CODE (t);
@@ -16146,117 +16255,6 @@ tree_single_nonzero_warnv_p (tree t, bool *strict_overflow_p)
   return false;
 }
 
-/* Return true when T is an address and is known to be nonzero.
-   For floating point we further ensure that T is not denormal.
-   Similar logic is present in nonzero_address in rtlanal.h.
-
-   If the return value is based on the assumption that signed overflow
-   is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't
-   change *STRICT_OVERFLOW_P.  */
-
-bool
-tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
-{
-  tree type = TREE_TYPE (t);
-  enum tree_code code;
-
-  /* Doing something useful for floating point would need more work.  */
-  if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
-    return false;
-
-  code = TREE_CODE (t);
-  switch (TREE_CODE_CLASS (code))
-    {
-    case tcc_unary:
-      return tree_unary_nonzero_warnv_p (code, type, TREE_OPERAND (t, 0),
-                                             strict_overflow_p);
-    case tcc_binary:
-    case tcc_comparison:
-      return tree_binary_nonzero_warnv_p (code, type,
-                                              TREE_OPERAND (t, 0),
-                                              TREE_OPERAND (t, 1),
-                                              strict_overflow_p);
-    case tcc_constant:
-    case tcc_declaration:
-    case tcc_reference:
-      return tree_single_nonzero_warnv_p (t, strict_overflow_p);
-
-    default:
-      break;
-    }
-
-  switch (code)
-    {
-    case TRUTH_NOT_EXPR:
-      return tree_unary_nonzero_warnv_p (code, type, TREE_OPERAND (t, 0),
-                                             strict_overflow_p);
-
-    case TRUTH_AND_EXPR:
-    case TRUTH_OR_EXPR:
-    case TRUTH_XOR_EXPR:
-      return tree_binary_nonzero_warnv_p (code, type,
-                                              TREE_OPERAND (t, 0),
-                                              TREE_OPERAND (t, 1),
-                                              strict_overflow_p);
-
-    case COND_EXPR:
-    case CONSTRUCTOR:
-    case OBJ_TYPE_REF:
-    case ASSERT_EXPR:
-    case ADDR_EXPR:
-    case WITH_SIZE_EXPR:
-    case SSA_NAME:
-      return tree_single_nonzero_warnv_p (t, strict_overflow_p);
-
-    case COMPOUND_EXPR:
-    case MODIFY_EXPR:
-    case BIND_EXPR:
-      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
-                                       strict_overflow_p);
-
-    case SAVE_EXPR:
-      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
-                                       strict_overflow_p);
-
-    case CALL_EXPR:
-      {
-       tree fndecl = get_callee_fndecl (t);
-       if (!fndecl) return false;
-       if (flag_delete_null_pointer_checks && !flag_check_new
-           && DECL_IS_OPERATOR_NEW (fndecl)
-           && !TREE_NOTHROW (fndecl))
-         return true;
-       if (flag_delete_null_pointer_checks
-           && lookup_attribute ("returns_nonnull",
-                TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
-         return true;
-       return alloca_call_p (t);
-      }
-
-    default:
-      break;
-    }
-  return false;
-}
-
-/* Return true when T is an address and is known to be nonzero.
-   Handle warnings about undefined signed overflow.  */
-
-bool
-tree_expr_nonzero_p (tree t)
-{
-  bool ret, strict_overflow_p;
-
-  strict_overflow_p = false;
-  ret = tree_expr_nonzero_warnv_p (t, &strict_overflow_p);
-  if (strict_overflow_p)
-    fold_overflow_warning (("assuming signed overflow does not occur when "
-                           "determining that expression is always "
-                           "non-zero"),
-                          WARN_STRICT_OVERFLOW_MISC);
-  return ret;
-}
-
 /* Given the components of a binary expression CODE, TYPE, OP0 and OP1,
    attempt to fold the expression to a constant without modifying TYPE,
    OP0 or OP1.
index 21ab691c586a43d86f629d9c71e4f5ba3d3c1611..ba881c9744ed30511878f402dc6758cbcb513ed0 100644 (file)
@@ -130,7 +130,6 @@ static bool contains (const_rtx, htab_t);
 static void prepare_function_start (void);
 static void do_clobber_return_reg (rtx, void *);
 static void do_use_return_reg (rtx, void *);
-static void set_insn_locations (rtx, int) ATTRIBUTE_UNUSED;
 \f
 /* Stack of nested functions.  */
 /* Keep track of the cfun stack.  */
@@ -4644,51 +4643,6 @@ init_function_start (tree subr)
     warning (OPT_Waggregate_return, "function returns an aggregate");
 }
 
-
-void
-expand_main_function (void)
-{
-#if (defined(INVOKE__main)                             \
-     || (!defined(HAS_INIT_SECTION)                    \
-        && !defined(INIT_SECTION_ASM_OP)               \
-        && !defined(INIT_ARRAY_SECTION_ASM_OP)))
-  emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
-#endif
-}
-\f
-/* Expand code to initialize the stack_protect_guard.  This is invoked at
-   the beginning of a function to be protected.  */
-
-#ifndef HAVE_stack_protect_set
-# define HAVE_stack_protect_set                0
-# define gen_stack_protect_set(x,y)    (gcc_unreachable (), NULL_RTX)
-#endif
-
-void
-stack_protect_prologue (void)
-{
-  tree guard_decl = targetm.stack_protect_guard ();
-  rtx x, y;
-
-  x = expand_normal (crtl->stack_protect_guard);
-  y = expand_normal (guard_decl);
-
-  /* Allow the target to copy from Y to X without leaking Y into a
-     register.  */
-  if (HAVE_stack_protect_set)
-    {
-      rtx insn = gen_stack_protect_set (x, y);
-      if (insn)
-       {
-         emit_insn (insn);
-         return;
-       }
-    }
-
-  /* Otherwise do a straight move.  */
-  emit_move_insn (x, y);
-}
-
 /* Expand code to verify the stack_protect_guard.  This is invoked at
    the end of a function to be protected.  */
 
@@ -5006,6 +4960,19 @@ do_warn_unused_parameter (tree fn)
       warning (OPT_Wunused_parameter, "unused parameter %q+D", decl);
 }
 
+/* Set the location of the insn chain starting at INSN to LOC.  */
+
+static void
+set_insn_locations (rtx insn, int loc)
+{
+  while (insn != NULL_RTX)
+    {
+      if (INSN_P (insn))
+       INSN_LOCATION (insn) = loc;
+      insn = NEXT_INSN (insn);
+    }
+}
+
 /* Generate RTL for the end of the current function.  */
 
 void
@@ -5335,18 +5302,6 @@ maybe_copy_prologue_epilogue_insn (rtx insn, rtx copy)
   *slot = copy;
 }
 
-/* Set the location of the insn chain starting at INSN to LOC.  */
-static void
-set_insn_locations (rtx insn, int loc)
-{
-  while (insn != NULL_RTX)
-    {
-      if (INSN_P (insn))
-       INSN_LOCATION (insn) = loc;
-      insn = NEXT_INSN (insn);
-    }
-}
-
 /* Determine if any INSNs in HASH are, or are part of, INSN.  Because
    we can be running after reorg, SEQUENCE rtl is possible.  */
 
index a4be3aae4d554c183ee9ef6190b3fc6d386e91d1..89d1ac993f6de78e07da3fa3675d0d592f7059cf 100644 (file)
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-utils.h"
 #include "gimple-pretty-print.h"
 #include "tree-ssa-address.h"
+#include "langhooks.h"
 
 /* Return true when DECL can be referenced from current unit.
    FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
index 08af30d7f19ad78b5757ae793ac896c04ac5a904..5916c523f9d4af0189ce35db351dece919a3ed01 100644 (file)
@@ -962,30 +962,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
   fprintf (file, ">");
 }
 
-/* Print the tree vector VEC in full on file FILE, preceded by PREFIX,
-   starting in column INDENT.  */
-
-void
-print_vec_tree (FILE *file, const char *prefix, vec<tree, va_gc> *vec, int indent)
-{
-  tree elt;
-  unsigned ix;
-
-  /* Indent to the specified column, since this is the long form.  */
-  indent_to (file, indent);
-
-  /* Print the slot this node is in, and its code, and address.  */
-  fprintf (file, "%s <VEC", prefix);
-  dump_addr (file, " ", vec->address ());
-
-  FOR_EACH_VEC_ELT (*vec, ix, elt)
-    {
-      char temp[10];
-      sprintf (temp, "elt %d", ix);
-      print_node (file, temp, elt, indent + 4);
-    }
-}
-
 
 /* Print the node NODE on standard error, for debugging.
    Most nodes referred to by this one are printed recursively
index b3fd25510abe7509ff07ef00f4f8dc47582233ca..947dca9e8b89d42c6e2823aeabaeb288d7d4f3d7 100644 (file)
@@ -102,13 +102,8 @@ typedef struct case_node *case_node_ptr;
 
 extern basic_block label_to_block_fn (struct function *, tree);
 \f
-static int n_occurrences (int, const char *);
-static bool tree_conflicts_with_clobbers_p (tree, HARD_REG_SET *);
-static bool check_operand_nalternatives (tree, tree);
 static bool check_unique_operand_names (tree, tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree, tree);
-static void expand_null_return_1 (void);
-static void expand_value_return (rtx);
 static void balance_case_nodes (case_node_ptr *, case_node_ptr);
 static int node_has_low_bound (case_node_ptr, tree);
 static int node_has_high_bound (case_node_ptr, tree);
@@ -157,20 +152,6 @@ emit_jump (rtx label)
   emit_jump_insn (gen_jump (label));
   emit_barrier ();
 }
-
-/* Emit code to jump to the address
-   specified by the pointer expression EXP.  */
-
-void
-expand_computed_goto (tree exp)
-{
-  rtx x = expand_normal (exp);
-
-  x = convert_memory_address (Pmode, x);
-
-  do_pending_stack_adjust ();
-  emit_indirect_jump (x);
-}
 \f
 /* Handle goto statements and the labels that they can go to.  */
 
@@ -209,56 +190,7 @@ expand_label (tree label)
   if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
     maybe_set_first_label_num (label_r);
 }
-
-/* Generate RTL code for a `goto' statement with target label LABEL.
-   LABEL should be a LABEL_DECL tree node that was or will later be
-   defined with `expand_label'.  */
-
-void
-expand_goto (tree label)
-{
-#ifdef ENABLE_CHECKING
-  /* Check for a nonlocal goto to a containing function.  Should have
-     gotten translated to __builtin_nonlocal_goto.  */
-  tree context = decl_function_context (label);
-  gcc_assert (!context || context == current_function_decl);
-#endif
-
-  emit_jump (label_rtx (label));
-}
-\f
-/* Return the number of times character C occurs in string S.  */
-static int
-n_occurrences (int c, const char *s)
-{
-  int n = 0;
-  while (*s)
-    n += (*s++ == c);
-  return n;
-}
 \f
-/* Generate RTL for an asm statement (explicit assembler code).
-   STRING is a STRING_CST node containing the assembler code text,
-   or an ADDR_EXPR containing a STRING_CST.  VOL nonzero means the
-   insn is volatile; don't optimize it.  */
-
-static void
-expand_asm_loc (tree string, int vol, location_t locus)
-{
-  rtx body;
-
-  if (TREE_CODE (string) == ADDR_EXPR)
-    string = TREE_OPERAND (string, 0);
-
-  body = gen_rtx_ASM_INPUT_loc (VOIDmode,
-                               ggc_strdup (TREE_STRING_POINTER (string)),
-                               locus);
-
-  MEM_VOLATILE_P (body) = vol;
-
-  emit_insn (body);
-}
-
 /* Parse the output constraint pointed to by *CONSTRAINT_P.  It is the
    OPERAND_NUMth output operand, indexed from zero.  There are NINPUTS
    inputs and NOUTPUTS outputs to this extended-asm.  Upon return,
@@ -577,663 +509,6 @@ tree_overlaps_hard_reg_set (tree decl, HARD_REG_SET *regs)
   return walk_tree (&decl, decl_overlaps_hard_reg_set_p, regs, NULL);
 }
 
-/* Check for overlap between registers marked in CLOBBERED_REGS and
-   anything inappropriate in T.  Emit error and return the register
-   variable definition for error, NULL_TREE for ok.  */
-
-static bool
-tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET *clobbered_regs)
-{
-  /* Conflicts between asm-declared register variables and the clobber
-     list are not allowed.  */
-  tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs);
-
-  if (overlap)
-    {
-      error ("asm-specifier for variable %qE conflicts with asm clobber list",
-            DECL_NAME (overlap));
-
-      /* Reset registerness to stop multiple errors emitted for a single
-        variable.  */
-      DECL_REGISTER (overlap) = 0;
-      return true;
-    }
-
-  return false;
-}
-
-/* Generate RTL for an asm statement with arguments.
-   STRING is the instruction template.
-   OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
-   Each output or input has an expression in the TREE_VALUE and
-   a tree list in TREE_PURPOSE which in turn contains a constraint
-   name in TREE_VALUE (or NULL_TREE) and a constraint string
-   in TREE_PURPOSE.
-   CLOBBERS is a list of STRING_CST nodes each naming a hard register
-   that is clobbered by this insn.
-
-   LABELS is a list of labels, and if LABELS is non-NULL, FALLTHRU_BB
-   should be the fallthru basic block of the asm goto.
-
-   Not all kinds of lvalue that may appear in OUTPUTS can be stored directly.
-   Some elements of OUTPUTS may be replaced with trees representing temporary
-   values.  The caller should copy those temporary values to the originally
-   specified lvalues.
-
-   VOL nonzero means the insn is volatile; don't optimize it.  */
-
-static void
-expand_asm_operands (tree string, tree outputs, tree inputs,
-                    tree clobbers, tree labels, basic_block fallthru_bb,
-                    int vol, location_t locus)
-{
-  rtvec argvec, constraintvec, labelvec;
-  rtx body;
-  int ninputs = list_length (inputs);
-  int noutputs = list_length (outputs);
-  int nlabels = list_length (labels);
-  int ninout;
-  int nclobbers;
-  HARD_REG_SET clobbered_regs;
-  int clobber_conflict_found = 0;
-  tree tail;
-  tree t;
-  int i;
-  /* Vector of RTX's of evaluated output operands.  */
-  rtx *output_rtx = XALLOCAVEC (rtx, noutputs);
-  int *inout_opnum = XALLOCAVEC (int, noutputs);
-  rtx *real_output_rtx = XALLOCAVEC (rtx, noutputs);
-  enum machine_mode *inout_mode = XALLOCAVEC (enum machine_mode, noutputs);
-  const char **constraints = XALLOCAVEC (const char *, noutputs + ninputs);
-  int old_generating_concat_p = generating_concat_p;
-  rtx fallthru_label = NULL_RTX;
-
-  /* An ASM with no outputs needs to be treated as volatile, for now.  */
-  if (noutputs == 0)
-    vol = 1;
-
-  if (! check_operand_nalternatives (outputs, inputs))
-    return;
-
-  string = resolve_asm_operand_names (string, outputs, inputs, labels);
-
-  /* Collect constraints.  */
-  i = 0;
-  for (t = outputs; t ; t = TREE_CHAIN (t), i++)
-    constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
-  for (t = inputs; t ; t = TREE_CHAIN (t), i++)
-    constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
-
-  /* Sometimes we wish to automatically clobber registers across an asm.
-     Case in point is when the i386 backend moved from cc0 to a hard reg --
-     maintaining source-level compatibility means automatically clobbering
-     the flags register.  */
-  clobbers = targetm.md_asm_clobbers (outputs, inputs, clobbers);
-
-  /* Count the number of meaningful clobbered registers, ignoring what
-     we would ignore later.  */
-  nclobbers = 0;
-  CLEAR_HARD_REG_SET (clobbered_regs);
-  for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
-    {
-      const char *regname;
-      int nregs;
-
-      if (TREE_VALUE (tail) == error_mark_node)
-       return;
-      regname = TREE_STRING_POINTER (TREE_VALUE (tail));
-
-      i = decode_reg_name_and_count (regname, &nregs);
-      if (i == -4)
-       ++nclobbers;
-      else if (i == -2)
-       error ("unknown register name %qs in %<asm%>", regname);
-
-      /* Mark clobbered registers.  */
-      if (i >= 0)
-        {
-         int reg;
-
-         for (reg = i; reg < i + nregs; reg++)
-           {
-             ++nclobbers;
-
-             /* Clobbering the PIC register is an error.  */
-             if (reg == (int) PIC_OFFSET_TABLE_REGNUM)
-               {
-                 error ("PIC register clobbered by %qs in %<asm%>", regname);
-                 return;
-               }
-
-             SET_HARD_REG_BIT (clobbered_regs, reg);
-           }
-       }
-    }
-
-  /* First pass over inputs and outputs checks validity and sets
-     mark_addressable if needed.  */
-
-  ninout = 0;
-  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
-    {
-      tree val = TREE_VALUE (tail);
-      tree type = TREE_TYPE (val);
-      const char *constraint;
-      bool is_inout;
-      bool allows_reg;
-      bool allows_mem;
-
-      /* If there's an erroneous arg, emit no insn.  */
-      if (type == error_mark_node)
-       return;
-
-      /* Try to parse the output constraint.  If that fails, there's
-        no point in going further.  */
-      constraint = constraints[i];
-      if (!parse_output_constraint (&constraint, i, ninputs, noutputs,
-                                   &allows_mem, &allows_reg, &is_inout))
-       return;
-
-      if (! allows_reg
-         && (allows_mem
-             || is_inout
-             || (DECL_P (val)
-                 && REG_P (DECL_RTL (val))
-                 && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type))))
-       mark_addressable (val);
-
-      if (is_inout)
-       ninout++;
-    }
-
-  ninputs += ninout;
-  if (ninputs + noutputs > MAX_RECOG_OPERANDS)
-    {
-      error ("more than %d operands in %<asm%>", MAX_RECOG_OPERANDS);
-      return;
-    }
-
-  for (i = 0, tail = inputs; tail; i++, tail = TREE_CHAIN (tail))
-    {
-      bool allows_reg, allows_mem;
-      const char *constraint;
-
-      /* If there's an erroneous arg, emit no insn, because the ASM_INPUT
-        would get VOIDmode and that could cause a crash in reload.  */
-      if (TREE_TYPE (TREE_VALUE (tail)) == error_mark_node)
-       return;
-
-      constraint = constraints[i + noutputs];
-      if (! parse_input_constraint (&constraint, i, ninputs, noutputs, ninout,
-                                   constraints, &allows_mem, &allows_reg))
-       return;
-
-      if (! allows_reg && allows_mem)
-       mark_addressable (TREE_VALUE (tail));
-    }
-
-  /* Second pass evaluates arguments.  */
-
-  /* Make sure stack is consistent for asm goto.  */
-  if (nlabels > 0)
-    do_pending_stack_adjust ();
-
-  ninout = 0;
-  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
-    {
-      tree val = TREE_VALUE (tail);
-      tree type = TREE_TYPE (val);
-      bool is_inout;
-      bool allows_reg;
-      bool allows_mem;
-      rtx op;
-      bool ok;
-
-      ok = parse_output_constraint (&constraints[i], i, ninputs,
-                                   noutputs, &allows_mem, &allows_reg,
-                                   &is_inout);
-      gcc_assert (ok);
-
-      /* If an output operand is not a decl or indirect ref and our constraint
-        allows a register, make a temporary to act as an intermediate.
-        Make the asm insn write into that, then our caller will copy it to
-        the real output operand.  Likewise for promoted variables.  */
-
-      generating_concat_p = 0;
-
-      real_output_rtx[i] = NULL_RTX;
-      if ((TREE_CODE (val) == INDIRECT_REF
-          && allows_mem)
-         || (DECL_P (val)
-             && (allows_mem || REG_P (DECL_RTL (val)))
-             && ! (REG_P (DECL_RTL (val))
-                   && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
-         || ! allows_reg
-         || is_inout)
-       {
-         op = expand_expr (val, NULL_RTX, VOIDmode,
-                           !allows_reg ? EXPAND_MEMORY : EXPAND_WRITE);
-         if (MEM_P (op))
-           op = validize_mem (op);
-
-         if (! allows_reg && !MEM_P (op))
-           error ("output number %d not directly addressable", i);
-         if ((! allows_mem && MEM_P (op))
-             || GET_CODE (op) == CONCAT)
-           {
-             real_output_rtx[i] = op;
-             op = gen_reg_rtx (GET_MODE (op));
-             if (is_inout)
-               emit_move_insn (op, real_output_rtx[i]);
-           }
-       }
-      else
-       {
-         op = assign_temp (type, 0, 1);
-         op = validize_mem (op);
-         if (!MEM_P (op) && TREE_CODE (TREE_VALUE (tail)) == SSA_NAME)
-           set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (TREE_VALUE (tail)), op);
-         TREE_VALUE (tail) = make_tree (type, op);
-       }
-      output_rtx[i] = op;
-
-      generating_concat_p = old_generating_concat_p;
-
-      if (is_inout)
-       {
-         inout_mode[ninout] = TYPE_MODE (type);
-         inout_opnum[ninout++] = i;
-       }
-
-      if (tree_conflicts_with_clobbers_p (val, &clobbered_regs))
-       clobber_conflict_found = 1;
-    }
-
-  /* Make vectors for the expression-rtx, constraint strings,
-     and named operands.  */
-
-  argvec = rtvec_alloc (ninputs);
-  constraintvec = rtvec_alloc (ninputs);
-  labelvec = rtvec_alloc (nlabels);
-
-  body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode
-                               : GET_MODE (output_rtx[0])),
-                              ggc_strdup (TREE_STRING_POINTER (string)),
-                              empty_string, 0, argvec, constraintvec,
-                              labelvec, locus);
-
-  MEM_VOLATILE_P (body) = vol;
-
-  /* Eval the inputs and put them into ARGVEC.
-     Put their constraints into ASM_INPUTs and store in CONSTRAINTS.  */
-
-  for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), ++i)
-    {
-      bool allows_reg, allows_mem;
-      const char *constraint;
-      tree val, type;
-      rtx op;
-      bool ok;
-
-      constraint = constraints[i + noutputs];
-      ok = parse_input_constraint (&constraint, i, ninputs, noutputs, ninout,
-                                  constraints, &allows_mem, &allows_reg);
-      gcc_assert (ok);
-
-      generating_concat_p = 0;
-
-      val = TREE_VALUE (tail);
-      type = TREE_TYPE (val);
-      /* EXPAND_INITIALIZER will not generate code for valid initializer
-        constants, but will still generate code for other types of operand.
-        This is the behavior we want for constant constraints.  */
-      op = expand_expr (val, NULL_RTX, VOIDmode,
-                       allows_reg ? EXPAND_NORMAL
-                       : allows_mem ? EXPAND_MEMORY
-                       : EXPAND_INITIALIZER);
-
-      /* Never pass a CONCAT to an ASM.  */
-      if (GET_CODE (op) == CONCAT)
-       op = force_reg (GET_MODE (op), op);
-      else if (MEM_P (op))
-       op = validize_mem (op);
-
-      if (asm_operand_ok (op, constraint, NULL) <= 0)
-       {
-         if (allows_reg && TYPE_MODE (type) != BLKmode)
-           op = force_reg (TYPE_MODE (type), op);
-         else if (!allows_mem)
-           warning (0, "asm operand %d probably doesn%'t match constraints",
-                    i + noutputs);
-         else if (MEM_P (op))
-           {
-             /* We won't recognize either volatile memory or memory
-                with a queued address as available a memory_operand
-                at this point.  Ignore it: clearly this *is* a memory.  */
-           }
-         else
-           gcc_unreachable ();
-       }
-
-      generating_concat_p = old_generating_concat_p;
-      ASM_OPERANDS_INPUT (body, i) = op;
-
-      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, i)
-       = gen_rtx_ASM_INPUT (TYPE_MODE (type),
-                            ggc_strdup (constraints[i + noutputs]));
-
-      if (tree_conflicts_with_clobbers_p (val, &clobbered_regs))
-       clobber_conflict_found = 1;
-    }
-
-  /* Protect all the operands from the queue now that they have all been
-     evaluated.  */
-
-  generating_concat_p = 0;
-
-  /* For in-out operands, copy output rtx to input rtx.  */
-  for (i = 0; i < ninout; i++)
-    {
-      int j = inout_opnum[i];
-      char buffer[16];
-
-      ASM_OPERANDS_INPUT (body, ninputs - ninout + i)
-       = output_rtx[j];
-
-      sprintf (buffer, "%d", j);
-      ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, ninputs - ninout + i)
-       = gen_rtx_ASM_INPUT (inout_mode[i], ggc_strdup (buffer));
-    }
-
-  /* Copy labels to the vector.  */
-  for (i = 0, tail = labels; i < nlabels; ++i, tail = TREE_CHAIN (tail))
-    {
-      rtx r;
-      /* If asm goto has any labels in the fallthru basic block, use
-        a label that we emit immediately after the asm goto.  Expansion
-        may insert further instructions into the same basic block after
-        asm goto and if we don't do this, insertion of instructions on
-        the fallthru edge might misbehave.  See PR58670.  */
-      if (fallthru_bb
-         && label_to_block_fn (cfun, TREE_VALUE (tail)) == fallthru_bb)
-       {
-         if (fallthru_label == NULL_RTX)
-           fallthru_label = gen_label_rtx ();
-         r = fallthru_label;
-       }
-      else
-       r = label_rtx (TREE_VALUE (tail));
-      ASM_OPERANDS_LABEL (body, i) = gen_rtx_LABEL_REF (Pmode, r);
-    }
-
-  generating_concat_p = old_generating_concat_p;
-
-  /* Now, for each output, construct an rtx
-     (set OUTPUT (asm_operands INSN OUTPUTCONSTRAINT OUTPUTNUMBER
-                              ARGVEC CONSTRAINTS OPNAMES))
-     If there is more than one, put them inside a PARALLEL.  */
-
-  if (nlabels > 0 && nclobbers == 0)
-    {
-      gcc_assert (noutputs == 0);
-      emit_jump_insn (body);
-    }
-  else if (noutputs == 0 && nclobbers == 0)
-    {
-      /* No output operands: put in a raw ASM_OPERANDS rtx.  */
-      emit_insn (body);
-    }
-  else if (noutputs == 1 && nclobbers == 0)
-    {
-      ASM_OPERANDS_OUTPUT_CONSTRAINT (body) = ggc_strdup (constraints[0]);
-      emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
-    }
-  else
-    {
-      rtx obody = body;
-      int num = noutputs;
-
-      if (num == 0)
-       num = 1;
-
-      body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num + nclobbers));
-
-      /* For each output operand, store a SET.  */
-      for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
-       {
-         XVECEXP (body, 0, i)
-           = gen_rtx_SET (VOIDmode,
-                          output_rtx[i],
-                          gen_rtx_ASM_OPERANDS
-                          (GET_MODE (output_rtx[i]),
-                           ggc_strdup (TREE_STRING_POINTER (string)),
-                           ggc_strdup (constraints[i]),
-                           i, argvec, constraintvec, labelvec, locus));
-
-         MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
-       }
-
-      /* If there are no outputs (but there are some clobbers)
-        store the bare ASM_OPERANDS into the PARALLEL.  */
-
-      if (i == 0)
-       XVECEXP (body, 0, i++) = obody;
-
-      /* Store (clobber REG) for each clobbered register specified.  */
-
-      for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
-       {
-         const char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
-         int reg, nregs;
-         int j = decode_reg_name_and_count (regname, &nregs);
-         rtx clobbered_reg;
-
-         if (j < 0)
-           {
-             if (j == -3)      /* `cc', which is not a register */
-               continue;
-
-             if (j == -4)      /* `memory', don't cache memory across asm */
-               {
-                 XVECEXP (body, 0, i++)
-                   = gen_rtx_CLOBBER (VOIDmode,
-                                      gen_rtx_MEM
-                                      (BLKmode,
-                                       gen_rtx_SCRATCH (VOIDmode)));
-                 continue;
-               }
-
-             /* Ignore unknown register, error already signaled.  */
-             continue;
-           }
-
-         for (reg = j; reg < j + nregs; reg++)
-           {
-             /* Use QImode since that's guaranteed to clobber just
-              * one reg.  */
-             clobbered_reg = gen_rtx_REG (QImode, reg);
-
-             /* Do sanity check for overlap between clobbers and
-                respectively input and outputs that hasn't been
-                handled.  Such overlap should have been detected and
-                reported above.  */
-             if (!clobber_conflict_found)
-               {
-                 int opno;
-
-                 /* We test the old body (obody) contents to avoid
-                    tripping over the under-construction body.  */
-                 for (opno = 0; opno < noutputs; opno++)
-                   if (reg_overlap_mentioned_p (clobbered_reg,
-                                                output_rtx[opno]))
-                     internal_error
-                       ("asm clobber conflict with output operand");
-
-                 for (opno = 0; opno < ninputs - ninout; opno++)
-                   if (reg_overlap_mentioned_p (clobbered_reg,
-                                                ASM_OPERANDS_INPUT (obody,
-                                                                    opno)))
-                     internal_error
-                       ("asm clobber conflict with input operand");
-               }
-
-             XVECEXP (body, 0, i++)
-               = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
-           }
-       }
-
-      if (nlabels > 0)
-       emit_jump_insn (body);
-      else
-       emit_insn (body);
-    }
-
-  if (fallthru_label)
-    emit_label (fallthru_label);
-
-  /* For any outputs that needed reloading into registers, spill them
-     back to where they belong.  */
-  for (i = 0; i < noutputs; ++i)
-    if (real_output_rtx[i])
-      emit_move_insn (real_output_rtx[i], output_rtx[i]);
-
-  crtl->has_asm_statement = 1;
-  free_temp_slots ();
-}
-
-void
-expand_asm_stmt (gimple stmt)
-{
-  int noutputs;
-  tree outputs, tail, t;
-  tree *o;
-  size_t i, n;
-  const char *s;
-  tree str, out, in, cl, labels;
-  location_t locus = gimple_location (stmt);
-  basic_block fallthru_bb = NULL;
-
-  /* Meh... convert the gimple asm operands into real tree lists.
-     Eventually we should make all routines work on the vectors instead
-     of relying on TREE_CHAIN.  */
-  out = NULL_TREE;
-  n = gimple_asm_noutputs (stmt);
-  if (n > 0)
-    {
-      t = out = gimple_asm_output_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
-    }
-
-  in = NULL_TREE;
-  n = gimple_asm_ninputs (stmt);
-  if (n > 0)
-    {
-      t = in = gimple_asm_input_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
-    }
-
-  cl = NULL_TREE;
-  n = gimple_asm_nclobbers (stmt);
-  if (n > 0)
-    {
-      t = cl = gimple_asm_clobber_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
-    }
-
-  labels = NULL_TREE;
-  n = gimple_asm_nlabels (stmt);
-  if (n > 0)
-    {
-      edge fallthru = find_fallthru_edge (gimple_bb (stmt)->succs);
-      if (fallthru)
-       fallthru_bb = fallthru->dest;
-      t = labels = gimple_asm_label_op (stmt, 0);
-      for (i = 1; i < n; i++)
-       t = TREE_CHAIN (t) = gimple_asm_label_op (stmt, i);
-    }
-
-  s = gimple_asm_string (stmt);
-  str = build_string (strlen (s), s);
-
-  if (gimple_asm_input_p (stmt))
-    {
-      expand_asm_loc (str, gimple_asm_volatile_p (stmt), locus);
-      return;
-    }
-
-  outputs = out;
-  noutputs = gimple_asm_noutputs (stmt);
-  /* o[I] is the place that output number I should be written.  */
-  o = (tree *) alloca (noutputs * sizeof (tree));
-
-  /* Record the contents of OUTPUTS before it is modified.  */
-  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
-    o[i] = TREE_VALUE (tail);
-
-  /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
-     OUTPUTS some trees for where the values were actually stored.  */
-  expand_asm_operands (str, outputs, in, cl, labels, fallthru_bb,
-                      gimple_asm_volatile_p (stmt), locus);
-
-  /* Copy all the intermediate outputs into the specified outputs.  */
-  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
-    {
-      if (o[i] != TREE_VALUE (tail))
-       {
-         expand_assignment (o[i], TREE_VALUE (tail), false);
-         free_temp_slots ();
-
-         /* Restore the original value so that it's correct the next
-            time we expand this function.  */
-         TREE_VALUE (tail) = o[i];
-       }
-    }
-}
-
-/* A subroutine of expand_asm_operands.  Check that all operands have
-   the same number of alternatives.  Return true if so.  */
-
-static bool
-check_operand_nalternatives (tree outputs, tree inputs)
-{
-  if (outputs || inputs)
-    {
-      tree tmp = TREE_PURPOSE (outputs ? outputs : inputs);
-      int nalternatives
-       = n_occurrences (',', TREE_STRING_POINTER (TREE_VALUE (tmp)));
-      tree next = inputs;
-
-      if (nalternatives + 1 > MAX_RECOG_ALTERNATIVES)
-       {
-         error ("too many alternatives in %<asm%>");
-         return false;
-       }
-
-      tmp = outputs;
-      while (tmp)
-       {
-         const char *constraint
-           = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tmp)));
-
-         if (n_occurrences (',', constraint) != nalternatives)
-           {
-             error ("operand constraints for %<asm%> differ "
-                    "in number of alternatives");
-             return false;
-           }
-
-         if (TREE_CHAIN (tmp))
-           tmp = TREE_CHAIN (tmp);
-         else
-           tmp = next, next = 0;
-       }
-    }
-
-  return true;
-}
 
 /* A subroutine of expand_asm_operands.  Check that all operand names
    are unique.  Return true if so.  We rely on the fact that these names
@@ -1427,19 +702,6 @@ resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
   return p;
 }
 \f
-/* Generate RTL to return from the current function, with no value.
-   (That is, we do not do anything about returning any value.)  */
-
-void
-expand_null_return (void)
-{
-  /* If this function was declared to return a value, but we
-     didn't, clobber the return registers so that they are not
-     propagated live to the rest of the function.  */
-  clobber_return_register ();
-
-  expand_null_return_1 ();
-}
 
 /* Generate RTL to return directly from the current function.
    (That is, we bypass any return value.)  */
@@ -1459,154 +721,6 @@ expand_naked_return (void)
   emit_jump (end_label);
 }
 
-/* Generate RTL to return from the current function, with value VAL.  */
-
-static void
-expand_value_return (rtx val)
-{
-  /* Copy the value to the return location unless it's already there.  */
-
-  tree decl = DECL_RESULT (current_function_decl);
-  rtx return_reg = DECL_RTL (decl);
-  if (return_reg != val)
-    {
-      tree funtype = TREE_TYPE (current_function_decl);
-      tree type = TREE_TYPE (decl);
-      int unsignedp = TYPE_UNSIGNED (type);
-      enum machine_mode old_mode = DECL_MODE (decl);
-      enum machine_mode mode;
-      if (DECL_BY_REFERENCE (decl))
-        mode = promote_function_mode (type, old_mode, &unsignedp, funtype, 2);
-      else
-        mode = promote_function_mode (type, old_mode, &unsignedp, funtype, 1);
-
-      if (mode != old_mode)
-       val = convert_modes (mode, old_mode, val, unsignedp);
-
-      if (GET_CODE (return_reg) == PARALLEL)
-       emit_group_load (return_reg, val, type, int_size_in_bytes (type));
-      else
-       emit_move_insn (return_reg, val);
-    }
-
-  expand_null_return_1 ();
-}
-
-/* Output a return with no value.  */
-
-static void
-expand_null_return_1 (void)
-{
-  clear_pending_stack_adjust ();
-  do_pending_stack_adjust ();
-  emit_jump (return_label);
-}
-\f
-/* Generate RTL to evaluate the expression RETVAL and return it
-   from the current function.  */
-
-void
-expand_return (tree retval)
-{
-  rtx result_rtl;
-  rtx val = 0;
-  tree retval_rhs;
-
-  /* If function wants no value, give it none.  */
-  if (TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl))) == VOID_TYPE)
-    {
-      expand_normal (retval);
-      expand_null_return ();
-      return;
-    }
-
-  if (retval == error_mark_node)
-    {
-      /* Treat this like a return of no value from a function that
-        returns a value.  */
-      expand_null_return ();
-      return;
-    }
-  else if ((TREE_CODE (retval) == MODIFY_EXPR
-           || TREE_CODE (retval) == INIT_EXPR)
-          && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
-    retval_rhs = TREE_OPERAND (retval, 1);
-  else
-    retval_rhs = retval;
-
-  result_rtl = DECL_RTL (DECL_RESULT (current_function_decl));
-
-  /* If we are returning the RESULT_DECL, then the value has already
-     been stored into it, so we don't have to do anything special.  */
-  if (TREE_CODE (retval_rhs) == RESULT_DECL)
-    expand_value_return (result_rtl);
-
-  /* If the result is an aggregate that is being returned in one (or more)
-     registers, load the registers here.  */
-
-  else if (retval_rhs != 0
-          && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
-          && REG_P (result_rtl))
-    {
-      val = copy_blkmode_to_reg (GET_MODE (result_rtl), retval_rhs);
-      if (val)
-       {
-         /* Use the mode of the result value on the return register.  */
-         PUT_MODE (result_rtl, GET_MODE (val));
-         expand_value_return (val);
-       }
-      else
-       expand_null_return ();
-    }
-  else if (retval_rhs != 0
-          && !VOID_TYPE_P (TREE_TYPE (retval_rhs))
-          && (REG_P (result_rtl)
-              || (GET_CODE (result_rtl) == PARALLEL)))
-    {
-      /* Calculate the return value into a temporary (usually a pseudo
-         reg).  */
-      tree ot = TREE_TYPE (DECL_RESULT (current_function_decl));
-      tree nt = build_qualified_type (ot, TYPE_QUALS (ot) | TYPE_QUAL_CONST);
-
-      val = assign_temp (nt, 0, 1);
-      val = expand_expr (retval_rhs, val, GET_MODE (val), EXPAND_NORMAL);
-      val = force_not_mem (val);
-      /* Return the calculated value.  */
-      expand_value_return (val);
-    }
-  else
-    {
-      /* No hard reg used; calculate value into hard return reg.  */
-      expand_expr (retval, const0_rtx, VOIDmode, EXPAND_NORMAL);
-      expand_value_return (result_rtl);
-    }
-}
-\f
-\f
-/* Emit code to save the current value of stack.  */
-rtx
-expand_stack_save (void)
-{
-  rtx ret = NULL_RTX;
-
-  do_pending_stack_adjust ();
-  emit_stack_save (SAVE_BLOCK, &ret);
-  return ret;
-}
-
-/* Emit code to restore the current value of stack.  */
-void
-expand_stack_restore (tree var)
-{
-  rtx prev, sa = expand_normal (var);
-
-  sa = convert_memory_address (Pmode, sa);
-
-  prev = get_last_insn ();
-  emit_stack_restore (SAVE_BLOCK, sa);
-  fixup_args_size_notes (prev, get_last_insn (), 0);
-}
-
 /* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE. PROB
    is the probability of jumping to LABEL.  */
 static void
index 90924c3180365ffeec490914cb809199638bd4f8..9310dfd21ec9eac517614280667866d34dc21329 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "lto-streamer.h"
 #include "rtl.h"
+#include "output.h"
 
 const char * const ld_plugin_symbol_resolution_names[]=
 {
@@ -81,6 +82,28 @@ eq_node (const void *p1, const void *p2)
   return DECL_UID (n1->decl) == DECL_UID (n2->decl);
 }
 
+/* Hash asmnames ignoring the user specified marks.  */
+
+static hashval_t
+decl_assembler_name_hash (const_tree asmname)
+{
+  if (IDENTIFIER_POINTER (asmname)[0] == '*')
+    {
+      const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
+      size_t ulp_len = strlen (user_label_prefix);
+
+      if (ulp_len == 0)
+       ;
+      else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
+       decl_str += ulp_len;
+
+      return htab_hash_string (decl_str);
+    }
+
+  return htab_hash_string (IDENTIFIER_POINTER (asmname));
+}
+
+
 /* Returns a hash code for P.  */
 
 static hashval_t
@@ -90,6 +113,62 @@ hash_node_by_assembler_name (const void *p)
   return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
 }
 
+/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
+
+static bool
+decl_assembler_name_equal (tree decl, const_tree asmname)
+{
+  tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
+  const char *decl_str;
+  const char *asmname_str;
+  bool test = false;
+
+  if (decl_asmname == asmname)
+    return true;
+
+  decl_str = IDENTIFIER_POINTER (decl_asmname);
+  asmname_str = IDENTIFIER_POINTER (asmname);
+
+
+  /* If the target assembler name was set by the user, things are trickier.
+     We have a leading '*' to begin with.  After that, it's arguable what
+     is the correct thing to do with -fleading-underscore.  Arguably, we've
+     historically been doing the wrong thing in assemble_alias by always
+     printing the leading underscore.  Since we're not changing that, make
+     sure user_label_prefix follows the '*' before matching.  */
+  if (decl_str[0] == '*')
+    {
+      size_t ulp_len = strlen (user_label_prefix);
+
+      decl_str ++;
+
+      if (ulp_len == 0)
+       test = true;
+      else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
+       decl_str += ulp_len, test=true;
+      else
+       decl_str --;
+    }
+  if (asmname_str[0] == '*')
+    {
+      size_t ulp_len = strlen (user_label_prefix);
+
+      asmname_str ++;
+
+      if (ulp_len == 0)
+       test = true;
+      else if (strncmp (asmname_str, user_label_prefix, ulp_len) == 0)
+       asmname_str += ulp_len, test=true;
+      else
+       asmname_str --;
+    }
+
+  if (!test)
+    return false;
+  return strcmp (decl_str, asmname_str) == 0;
+}
+
+
 /* Returns nonzero if P1 and P2 are equal.  */
 
 static int
index d74455d2bbcfaf545e402b7fe4fa4d2302e2485c..784ff247e9d752d126c39f9a1704c79c6170eb7b 100644 (file)
@@ -592,6 +592,12 @@ diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
   return NULL_TREE;
 }
 
+static inline bool
+is_tm_safe_or_pure (const_tree x)
+{
+  return is_tm_safe (x) || is_tm_pure (x);
+}
+
 static tree
 diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
                    struct walk_stmt_info *wi)
index a91542d56aa7913dcb593d104c2be1702860c001..a489b61c3f246f10546c701e64fd5631f88ccd46 100644 (file)
@@ -2506,6 +2506,68 @@ operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv,
                                        &handled);
 }
 
+
+/* Returns true if it is possible to prove that the index of
+   an array access REF (an ARRAY_REF expression) falls into the
+   array bounds.  */
+
+static bool
+in_array_bounds_p (tree ref)
+{
+  tree idx = TREE_OPERAND (ref, 1);
+  tree min, max;
+
+  if (TREE_CODE (idx) != INTEGER_CST)
+    return false;
+
+  min = array_ref_low_bound (ref);
+  max = array_ref_up_bound (ref);
+  if (!min
+      || !max
+      || TREE_CODE (min) != INTEGER_CST
+      || TREE_CODE (max) != INTEGER_CST)
+    return false;
+
+  if (tree_int_cst_lt (idx, min)
+      || tree_int_cst_lt (max, idx))
+    return false;
+
+  return true;
+}
+
+/* Returns true if it is possible to prove that the range of
+   an array access REF (an ARRAY_RANGE_REF expression) falls
+   into the array bounds.  */
+
+static bool
+range_in_array_bounds_p (tree ref)
+{
+  tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref));
+  tree range_min, range_max, min, max;
+
+  range_min = TYPE_MIN_VALUE (domain_type);
+  range_max = TYPE_MAX_VALUE (domain_type);
+  if (!range_min
+      || !range_max
+      || TREE_CODE (range_min) != INTEGER_CST
+      || TREE_CODE (range_max) != INTEGER_CST)
+    return false;
+
+  min = array_ref_low_bound (ref);
+  max = array_ref_up_bound (ref);
+  if (!min
+      || !max
+      || TREE_CODE (min) != INTEGER_CST
+      || TREE_CODE (max) != INTEGER_CST)
+    return false;
+
+  if (tree_int_cst_lt (range_min, min)
+      || tree_int_cst_lt (max, range_max))
+    return false;
+
+  return true;
+}
+
 /* Return true if EXPR can trap, as in dereferencing an invalid pointer
    location or floating point arithmetic.  C.f. the rtl version, may_trap_p.
    This routine expects only GIMPLE lhs or rhs input.  */
index 2d7ebfd764f009faa8a4bdc58d4a70f3e3fdc5f9..576dcb786ede05e0ff282ce7d718e827e6873a26 100644 (file)
@@ -1181,7 +1181,7 @@ init_object_sizes (void)
 
 /* Destroy data structures after the object size computation.  */
 
-void
+static void
 fini_object_sizes (void)
 {
   int object_size_type;
index 211bfcf5cc4e7787af154643e0f30ebe82cdeed4..6a6f027e90cc62ace942ca0ba7104ea95654b95d 100644 (file)
@@ -536,6 +536,29 @@ hashable_expr_equal_p (const struct hashable_expr *expr0,
     }
 }
 
+/* Generate a hash value for a pair of expressions.  This can be used
+   iteratively by passing a previous result as the VAL argument.
+
+   The same hash value is always returned for a given pair of expressions,
+   regardless of the order in which they are presented.  This is useful in
+   hashing the operands of commutative functions.  */
+
+static hashval_t
+iterative_hash_exprs_commutative (const_tree t1,
+                                  const_tree t2, hashval_t val)
+{
+  hashval_t one = iterative_hash_expr (t1, 0);
+  hashval_t two = iterative_hash_expr (t2, 0);
+  hashval_t t;
+
+  if (one > two)
+    t = one, one = two, two = t;
+  val = iterative_hash_hashval_t (one, val);
+  val = iterative_hash_hashval_t (two, val);
+
+  return val;
+}
+
 /* Compute a hash value for a hashable_expr value EXPR and a
    previously accumulated hash value VAL.  If two hashable_expr
    values compare equal with hashable_expr_equal_p, they must
index c1ff4752cb040c3a40a60540b0c94a0e5987851a..8f8b5ebada78af27a953e167da9fb7d510b2e748 100644 (file)
@@ -1464,24 +1464,6 @@ value_range_nonnegative_p (value_range_t *vr)
   return false;
 }
 
-/* Return true if T, an SSA_NAME, is known to be nonnegative.  Return
-   false otherwise or if no value range information is available.  */
-
-bool
-ssa_name_nonnegative_p (const_tree t)
-{
-  value_range_t *vr = get_value_range (t);
-
-  if (INTEGRAL_TYPE_P (t)
-      && TYPE_UNSIGNED (t))
-    return true;
-
-  if (!vr)
-    return false;
-
-  return value_range_nonnegative_p (vr);
-}
-
 /* If *VR has a value rante that is a single constant value return that,
    otherwise return NULL_TREE.  */
 
index 21b790a5de06a2639967421505f92c2e569c3a6d..686a680f94c698ffa63f55390c3ed4088aefe9ec 100644 (file)
@@ -588,82 +588,6 @@ decl_assembler_name (tree decl)
   return DECL_WITH_VIS_CHECK (decl)->decl_with_vis.assembler_name;
 }
 
-/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
-
-bool
-decl_assembler_name_equal (tree decl, const_tree asmname)
-{
-  tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
-  const char *decl_str;
-  const char *asmname_str;
-  bool test = false;
-
-  if (decl_asmname == asmname)
-    return true;
-
-  decl_str = IDENTIFIER_POINTER (decl_asmname);
-  asmname_str = IDENTIFIER_POINTER (asmname);
-
-
-  /* If the target assembler name was set by the user, things are trickier.
-     We have a leading '*' to begin with.  After that, it's arguable what
-     is the correct thing to do with -fleading-underscore.  Arguably, we've
-     historically been doing the wrong thing in assemble_alias by always
-     printing the leading underscore.  Since we're not changing that, make
-     sure user_label_prefix follows the '*' before matching.  */
-  if (decl_str[0] == '*')
-    {
-      size_t ulp_len = strlen (user_label_prefix);
-
-      decl_str ++;
-
-      if (ulp_len == 0)
-       test = true;
-      else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
-       decl_str += ulp_len, test=true;
-      else
-       decl_str --;
-    }
-  if (asmname_str[0] == '*')
-    {
-      size_t ulp_len = strlen (user_label_prefix);
-
-      asmname_str ++;
-
-      if (ulp_len == 0)
-       test = true;
-      else if (strncmp (asmname_str, user_label_prefix, ulp_len) == 0)
-       asmname_str += ulp_len, test=true;
-      else
-       asmname_str --;
-    }
-
-  if (!test)
-    return false;
-  return strcmp (decl_str, asmname_str) == 0;
-}
-
-/* Hash asmnames ignoring the user specified marks.  */
-
-hashval_t
-decl_assembler_name_hash (const_tree asmname)
-{
-  if (IDENTIFIER_POINTER (asmname)[0] == '*')
-    {
-      const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
-      size_t ulp_len = strlen (user_label_prefix);
-
-      if (ulp_len == 0)
-       ;
-      else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
-       decl_str += ulp_len;
-
-      return htab_hash_string (decl_str);
-    }
-
-  return htab_hash_string (IDENTIFIER_POINTER (asmname));
-}
-
 /* Compute the number of bytes occupied by a tree with code CODE.
    This function cannot be used for nodes that have variable sizes,
    including TREE_VEC, STRING_CST, and CALL_EXPR.  */
@@ -2386,35 +2310,6 @@ real_onep (const_tree expr)
     }
 }
 
-/* Return 1 if EXPR is the real constant two.  Trailing zeroes matter
-   for decimal float constants, so don't return 1 for them.  */
-
-int
-real_twop (const_tree expr)
-{
-  STRIP_NOPS (expr);
-
-  switch (TREE_CODE (expr))
-    {
-    case REAL_CST:
-      return REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2)
-            && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
-    case COMPLEX_CST:
-      return real_twop (TREE_REALPART (expr))
-            && real_zerop (TREE_IMAGPART (expr));
-    case VECTOR_CST:
-      {
-       unsigned i;
-       for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
-         if (!real_twop (VECTOR_CST_ELT (expr, i)))
-           return false;
-       return true;
-      }
-    default:
-      return false;
-    }
-}
-
 /* Return 1 if EXPR is the real constant minus one.  Trailing zeroes
    matter for decimal float constants, so don't return 1 for them.  */
 
@@ -2552,21 +2447,6 @@ list_length (const_tree t)
   return len;
 }
 
-/* Returns the number of FIELD_DECLs in TYPE.  */
-
-int
-fields_length (const_tree type)
-{
-  tree t = TYPE_FIELDS (type);
-  int count = 0;
-
-  for (; t; t = DECL_CHAIN (t))
-    if (TREE_CODE (t) == FIELD_DECL)
-      ++count;
-
-  return count;
-}
-
 /* Returns the first FIELD_DECL in the TYPE_FIELDS of the RECORD_TYPE or
    UNION_TYPE TYPE, or NULL_TREE if none.  */
 
@@ -2787,18 +2667,6 @@ max_int_size_in_bytes (const_tree type)
 
   return size;
 }
-
-/* Returns a tree for the size of EXP in bytes.  */
-
-tree
-tree_expr_size (const_tree exp)
-{
-  if (DECL_P (exp)
-      && DECL_SIZE_UNIT (exp) != 0)
-    return DECL_SIZE_UNIT (exp);
-  else
-    return size_in_bytes (TREE_TYPE (exp));
-}
 \f
 /* Return the bit position of FIELD, in bits from the start of the record.
    This is a tree of type bitsizetype.  */
@@ -3902,6 +3770,88 @@ substitute_placeholder_in_expr (tree exp, tree obj)
   return new_tree;
 }
 \f
+
+/* Subroutine of stabilize_reference; this is called for subtrees of
+   references.  Any expression with side-effects must be put in a SAVE_EXPR
+   to ensure that it is only evaluated once.
+
+   We don't put SAVE_EXPR nodes around everything, because assigning very
+   simple expressions to temporaries causes us to miss good opportunities
+   for optimizations.  Among other things, the opportunity to fold in the
+   addition of a constant into an addressing mode often gets lost, e.g.
+   "y[i+1] += x;".  In general, we take the approach that we should not make
+   an assignment unless we are forced into it - i.e., that any non-side effect
+   operator should be allowed, and that cse should take care of coalescing
+   multiple utterances of the same expression should that prove fruitful.  */
+
+static tree
+stabilize_reference_1 (tree e)
+{
+  tree result;
+  enum tree_code code = TREE_CODE (e);
+
+  /* We cannot ignore const expressions because it might be a reference
+     to a const array but whose index contains side-effects.  But we can
+     ignore things that are actual constant or that already have been
+     handled by this function.  */
+
+  if (tree_invariant_p (e))
+    return e;
+
+  switch (TREE_CODE_CLASS (code))
+    {
+    case tcc_exceptional:
+    case tcc_type:
+    case tcc_declaration:
+    case tcc_comparison:
+    case tcc_statement:
+    case tcc_expression:
+    case tcc_reference:
+    case tcc_vl_exp:
+      /* If the expression has side-effects, then encase it in a SAVE_EXPR
+        so that it will only be evaluated once.  */
+      /* The reference (r) and comparison (<) classes could be handled as
+        below, but it is generally faster to only evaluate them once.  */
+      if (TREE_SIDE_EFFECTS (e))
+       return save_expr (e);
+      return e;
+
+    case tcc_constant:
+      /* Constants need no processing.  In fact, we should never reach
+        here.  */
+      return e;
+
+    case tcc_binary:
+      /* Division is slow and tends to be compiled with jumps,
+        especially the division by powers of 2 that is often
+        found inside of an array reference.  So do it just once.  */
+      if (code == TRUNC_DIV_EXPR || code == TRUNC_MOD_EXPR
+         || code == FLOOR_DIV_EXPR || code == FLOOR_MOD_EXPR
+         || code == CEIL_DIV_EXPR || code == CEIL_MOD_EXPR
+         || code == ROUND_DIV_EXPR || code == ROUND_MOD_EXPR)
+       return save_expr (e);
+      /* Recursively stabilize each operand.  */
+      result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)),
+                        stabilize_reference_1 (TREE_OPERAND (e, 1)));
+      break;
+
+    case tcc_unary:
+      /* Recursively stabilize each operand.  */
+      result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)));
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  TREE_TYPE (result) = TREE_TYPE (e);
+  TREE_READONLY (result) = TREE_READONLY (e);
+  TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
+  TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
+
+  return result;
+}
+
 /* Stabilize a reference so that we can use it any number of times
    without causing its operands to be evaluated more than once.
    Returns the stabilized reference.  This works by means of save_expr,
@@ -3983,87 +3933,6 @@ stabilize_reference (tree ref)
 
   return result;
 }
-
-/* Subroutine of stabilize_reference; this is called for subtrees of
-   references.  Any expression with side-effects must be put in a SAVE_EXPR
-   to ensure that it is only evaluated once.
-
-   We don't put SAVE_EXPR nodes around everything, because assigning very
-   simple expressions to temporaries causes us to miss good opportunities
-   for optimizations.  Among other things, the opportunity to fold in the
-   addition of a constant into an addressing mode often gets lost, e.g.
-   "y[i+1] += x;".  In general, we take the approach that we should not make
-   an assignment unless we are forced into it - i.e., that any non-side effect
-   operator should be allowed, and that cse should take care of coalescing
-   multiple utterances of the same expression should that prove fruitful.  */
-
-tree
-stabilize_reference_1 (tree e)
-{
-  tree result;
-  enum tree_code code = TREE_CODE (e);
-
-  /* We cannot ignore const expressions because it might be a reference
-     to a const array but whose index contains side-effects.  But we can
-     ignore things that are actual constant or that already have been
-     handled by this function.  */
-
-  if (tree_invariant_p (e))
-    return e;
-
-  switch (TREE_CODE_CLASS (code))
-    {
-    case tcc_exceptional:
-    case tcc_type:
-    case tcc_declaration:
-    case tcc_comparison:
-    case tcc_statement:
-    case tcc_expression:
-    case tcc_reference:
-    case tcc_vl_exp:
-      /* If the expression has side-effects, then encase it in a SAVE_EXPR
-        so that it will only be evaluated once.  */
-      /* The reference (r) and comparison (<) classes could be handled as
-        below, but it is generally faster to only evaluate them once.  */
-      if (TREE_SIDE_EFFECTS (e))
-       return save_expr (e);
-      return e;
-
-    case tcc_constant:
-      /* Constants need no processing.  In fact, we should never reach
-        here.  */
-      return e;
-
-    case tcc_binary:
-      /* Division is slow and tends to be compiled with jumps,
-        especially the division by powers of 2 that is often
-        found inside of an array reference.  So do it just once.  */
-      if (code == TRUNC_DIV_EXPR || code == TRUNC_MOD_EXPR
-         || code == FLOOR_DIV_EXPR || code == FLOOR_MOD_EXPR
-         || code == CEIL_DIV_EXPR || code == CEIL_MOD_EXPR
-         || code == ROUND_DIV_EXPR || code == ROUND_MOD_EXPR)
-       return save_expr (e);
-      /* Recursively stabilize each operand.  */
-      result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)),
-                        stabilize_reference_1 (TREE_OPERAND (e, 1)));
-      break;
-
-    case tcc_unary:
-      /* Recursively stabilize each operand.  */
-      result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)));
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  TREE_TYPE (result) = TREE_TYPE (e);
-  TREE_READONLY (result) = TREE_READONLY (e);
-  TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
-  TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
-
-  return result;
-}
 \f
 /* Low-level constructors for expressions.  */
 
@@ -4758,43 +4627,22 @@ omp_declare_simd_clauses_equal (tree clauses1, tree clauses2)
   return true;
 }
 
-/* Remove duplicate "omp declare simd" attributes.  */
+/* Compare two constructor-element-type constants.  Return 1 if the lists
+   are known to be equal; otherwise return 0.  */
 
-void
-omp_remove_redundant_declare_simd_attrs (tree fndecl)
+static bool
+simple_cst_list_equal (const_tree l1, const_tree l2)
 {
-  tree attr, end_attr = NULL_TREE, last_attr = NULL_TREE;
-  for (attr = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (fndecl));
-       attr;
-       attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr)))
+  while (l1 != NULL_TREE && l2 != NULL_TREE)
     {
-      tree *pc;
-      for (pc = &TREE_CHAIN (attr); *pc && *pc != end_attr; )
-       {
-         if (is_attribute_p ("omp declare simd", TREE_PURPOSE (*pc)))
-           {
-             last_attr = TREE_CHAIN (*pc);
-             if (TREE_VALUE (attr) == NULL_TREE)
-               {
-                 if (TREE_VALUE (*pc) == NULL_TREE)
-                   {
-                     *pc = TREE_CHAIN (*pc);
-                     continue;
-                   }
-               }
-             else if (TREE_VALUE (*pc) != NULL_TREE
-                      && omp_declare_simd_clauses_equal
-                               (TREE_VALUE (TREE_VALUE (*pc)),
-                                TREE_VALUE (TREE_VALUE (attr))))
-               {
-                 *pc = TREE_CHAIN (*pc);
-                 continue;
-               }
-           }
-         pc = &TREE_CHAIN (*pc);
-       }
-      end_attr = last_attr;
+      if (simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)) != 1)
+       return false;
+
+      l1 = TREE_CHAIN (l1);
+      l2 = TREE_CHAIN (l2);
     }
+
+  return l1 == l2;
 }
 
 /* Compare two attributes for their value identity.  Return true if the
@@ -7129,17 +6977,6 @@ tree_low_cst (const_tree t, int pos)
   return TREE_INT_CST_LOW (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 d.sext (TYPE_PRECISION (TREE_TYPE (t))).low;
-}
-
 /* Return the most significant (sign) bit of T.  */
 
 int
@@ -7201,24 +7038,6 @@ tree_int_cst_min_precision (tree value, bool unsignedp)
     return tree_floor_log2 (value) + 1 + !unsignedp;
 }
 
-/* Compare two constructor-element-type constants.  Return 1 if the lists
-   are known to be equal; otherwise return 0.  */
-
-int
-simple_cst_list_equal (const_tree l1, const_tree l2)
-{
-  while (l1 != NULL_TREE && l2 != NULL_TREE)
-    {
-      if (simple_cst_equal (TREE_VALUE (l1), TREE_VALUE (l2)) != 1)
-       return 0;
-
-      l1 = TREE_CHAIN (l1);
-      l2 = TREE_CHAIN (l2);
-    }
-
-  return l1 == l2;
-}
-
 /* Return truthvalue of whether T1 is the same tree structure as T2.
    Return 1 if they are the same.
    Return 0 if they are understandably different.
@@ -7644,29 +7463,6 @@ iterative_hash_expr (const_tree t, hashval_t val)
     }
 }
 
-/* Generate a hash value for a pair of expressions.  This can be used
-   iteratively by passing a previous result as the VAL argument.
-
-   The same hash value is always returned for a given pair of expressions,
-   regardless of the order in which they are presented.  This is useful in
-   hashing the operands of commutative functions.  */
-
-hashval_t
-iterative_hash_exprs_commutative (const_tree t1,
-                                  const_tree t2, hashval_t val)
-{
-  hashval_t one = iterative_hash_expr (t1, 0);
-  hashval_t two = iterative_hash_expr (t2, 0);
-  hashval_t t;
-
-  if (one > two)
-    t = one, one = two, two = t;
-  val = iterative_hash_hashval_t (one, val);
-  val = iterative_hash_hashval_t (two, val);
-
-  return val;
-}
-\f
 /* Constructors for pointer, array and function types.
    (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
    constructed by language-dependent code, not here.)  */
@@ -7808,30 +7604,6 @@ build_reference_type (tree to_type)
   return build_reference_type_for_mode (to_type, pointer_mode, false);
 }
 
-/* Build a type that is compatible with t but has no cv quals anywhere
-   in its type, thus
-
-   const char *const *const *  ->  char ***.  */
-
-tree
-build_type_no_quals (tree t)
-{
-  switch (TREE_CODE (t))
-    {
-    case POINTER_TYPE:
-      return build_pointer_type_for_mode (build_type_no_quals (TREE_TYPE (t)),
-                                         TYPE_MODE (t),
-                                         TYPE_REF_CAN_ALIAS_ALL (t));
-    case REFERENCE_TYPE:
-      return
-       build_reference_type_for_mode (build_type_no_quals (TREE_TYPE (t)),
-                                      TYPE_MODE (t),
-                                      TYPE_REF_CAN_ALIAS_ALL (t));
-    default:
-      return TYPE_MAIN_VARIANT (t);
-    }
-}
-
 #define MAX_INT_CACHED_PREC \
   (HOST_BITS_PER_WIDE_INT > 64 ? HOST_BITS_PER_WIDE_INT : 64)
 static GTY(()) tree nonstandard_integer_type_cache[2 * MAX_INT_CACHED_PREC + 2];
@@ -8207,111 +7979,6 @@ build_function_type (tree value_type, tree arg_types)
   return t;
 }
 
-/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
-   return value if SKIP_RETURN is true.  */
-
-static tree
-build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
-                              bool skip_return)
-{
-  tree new_type = NULL;
-  tree args, new_args = NULL, t;
-  tree new_reversed;
-  int i = 0;
-
-  for (args = TYPE_ARG_TYPES (orig_type); args && args != void_list_node;
-       args = TREE_CHAIN (args), i++)
-    if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
-      new_args = tree_cons (NULL_TREE, TREE_VALUE (args), new_args);
-
-  new_reversed = nreverse (new_args);
-  if (args)
-    {
-      if (new_reversed)
-        TREE_CHAIN (new_args) = void_list_node;
-      else
-       new_reversed = void_list_node;
-    }
-
-  /* Use copy_node to preserve as much as possible from original type
-     (debug info, attribute lists etc.)
-     Exception is METHOD_TYPEs must have THIS argument.
-     When we are asked to remove it, we need to build new FUNCTION_TYPE
-     instead.  */
-  if (TREE_CODE (orig_type) != METHOD_TYPE
-      || !args_to_skip
-      || !bitmap_bit_p (args_to_skip, 0))
-    {
-      new_type = build_distinct_type_copy (orig_type);
-      TYPE_ARG_TYPES (new_type) = new_reversed;
-    }
-  else
-    {
-      new_type
-        = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
-                                                        new_reversed));
-      TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
-    }
-
-  if (skip_return)
-    TREE_TYPE (new_type) = void_type_node;
-
-  /* This is a new type, not a copy of an old type.  Need to reassociate
-     variants.  We can handle everything except the main variant lazily.  */
-  t = TYPE_MAIN_VARIANT (orig_type);
-  if (t != orig_type)
-    {
-      t = build_function_type_skip_args (t, args_to_skip, skip_return);
-      TYPE_MAIN_VARIANT (new_type) = t;
-      TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
-      TYPE_NEXT_VARIANT (t) = new_type;
-    }
-  else
-    {
-      TYPE_MAIN_VARIANT (new_type) = new_type;
-      TYPE_NEXT_VARIANT (new_type) = NULL;
-    }
-
-  return new_type;
-}
-
-/* Build variant of function decl ORIG_DECL skipping ARGS_TO_SKIP and the
-   return value if SKIP_RETURN is true.
-
-   Arguments from DECL_ARGUMENTS list can't be removed now, since they are
-   linked by TREE_CHAIN directly.  The caller is responsible for eliminating
-   them when they are being duplicated (i.e. copy_arguments_for_versioning).  */
-
-tree
-build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
-                              bool skip_return)
-{
-  tree new_decl = copy_node (orig_decl);
-  tree new_type;
-
-  new_type = TREE_TYPE (orig_decl);
-  if (prototype_p (new_type)
-      || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type))))
-    new_type
-      = build_function_type_skip_args (new_type, args_to_skip, skip_return);
-  TREE_TYPE (new_decl) = new_type;
-
-  /* For declarations setting DECL_VINDEX (i.e. methods)
-     we expect first argument to be THIS pointer.   */
-  if (args_to_skip && bitmap_bit_p (args_to_skip, 0))
-    DECL_VINDEX (new_decl) = NULL_TREE;
-
-  /* When signature changes, we need to clear builtin info.  */
-  if (DECL_BUILT_IN (new_decl)
-      && args_to_skip
-      && !bitmap_empty_p (args_to_skip))
-    {
-      DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN;
-      DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0;
-    }
-  return new_decl;
-}
-
 /* Build a function type.  The RETURN_TYPE is the type returned by the
    function.  If VAARGS is set, no void_type_node is appended to the
    the list.  ARGP must be always be terminated be a NULL_TREE.  */
@@ -10781,68 +10448,6 @@ build_call_vec (tree return_type, tree fn, vec<tree, va_gc> *args)
   return ret;
 }
 
-
-/* Returns true if it is possible to prove that the index of
-   an array access REF (an ARRAY_REF expression) falls into the
-   array bounds.  */
-
-bool
-in_array_bounds_p (tree ref)
-{
-  tree idx = TREE_OPERAND (ref, 1);
-  tree min, max;
-
-  if (TREE_CODE (idx) != INTEGER_CST)
-    return false;
-
-  min = array_ref_low_bound (ref);
-  max = array_ref_up_bound (ref);
-  if (!min
-      || !max
-      || TREE_CODE (min) != INTEGER_CST
-      || TREE_CODE (max) != INTEGER_CST)
-    return false;
-
-  if (tree_int_cst_lt (idx, min)
-      || tree_int_cst_lt (max, idx))
-    return false;
-
-  return true;
-}
-
-/* Returns true if it is possible to prove that the range of
-   an array access REF (an ARRAY_RANGE_REF expression) falls
-   into the array bounds.  */
-
-bool
-range_in_array_bounds_p (tree ref)
-{
-  tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref));
-  tree range_min, range_max, min, max;
-
-  range_min = TYPE_MIN_VALUE (domain_type);
-  range_max = TYPE_MAX_VALUE (domain_type);
-  if (!range_min
-      || !range_max
-      || TREE_CODE (range_min) != INTEGER_CST
-      || TREE_CODE (range_max) != INTEGER_CST)
-    return false;
-
-  min = array_ref_low_bound (ref);
-  max = array_ref_up_bound (ref);
-  if (!min
-      || !max
-      || TREE_CODE (min) != INTEGER_CST
-      || TREE_CODE (max) != INTEGER_CST)
-    return false;
-
-  if (tree_int_cst_lt (range_min, min)
-      || tree_int_cst_lt (max, range_max))
-    return false;
-
-  return true;
-}
-
 /* Return true if T (assumed to be a DECL) must be assigned a memory
    location.  */
 
@@ -11910,17 +11515,6 @@ block_ultimate_origin (const_tree block)
     }
 }
 
-/* Return true if T1 and T2 are equivalent lists.  */
-
-bool
-list_equal_p (const_tree t1, const_tree t2)
-{
-  for (; t1 && t2; t1 = TREE_CHAIN (t1) , t2 = TREE_CHAIN (t2))
-    if (TREE_VALUE (t1) != TREE_VALUE (t2))
-      return false;
-  return !t1 && !t2;
-}
-
 /* Return true iff conversion in EXP generates no instruction.  Mark
    it inline so that we fully inline into the stripping functions even
    though we have two uses of this function.  */
index 96948f152a576f3d9fbcc1770e58449e537b7c70..c4b23d0864ab906355c166d8e56acd5c45935d38 100644 (file)
@@ -3385,8 +3385,6 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i,
    || ((NODE) && TREE_TYPE ((NODE)) == error_mark_node))
 
 extern tree decl_assembler_name (tree);
-extern bool decl_assembler_name_equal (tree decl, const_tree asmname);
-extern hashval_t decl_assembler_name_hash (const_tree asmname);
 
 /* Compute the number of bytes occupied by 'node'.  This routine only
    looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH.  */
@@ -3619,14 +3617,12 @@ extern tree build_reference_type (tree);
 extern tree build_vector_type_for_mode (tree, enum machine_mode);
 extern tree build_vector_type (tree innertype, int nunits);
 extern tree build_opaque_vector_type (tree innertype, int nunits);
-extern tree build_type_no_quals (tree);
 extern tree build_index_type (tree);
 extern tree build_array_type (tree, tree);
 extern tree build_nonshared_array_type (tree, tree);
 extern tree build_array_type_nelts (tree, unsigned HOST_WIDE_INT);
 extern tree build_function_type (tree, tree);
 extern tree build_function_type_list (tree, ...);
-extern tree build_function_decl_skip_args (tree, bitmap, bool);
 extern tree build_varargs_function_type_list (tree, ...);
 extern tree build_function_type_array (tree, int, tree *);
 extern tree build_varargs_function_type_array (tree, int, tree *);
@@ -3640,8 +3636,6 @@ extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);
 extern tree build_complex_type (tree);
 extern tree array_type_nelts (const_tree);
-extern bool in_array_bounds_p (tree);
-extern bool range_in_array_bounds_p (tree);
 
 extern tree value_member (tree, tree);
 extern tree purpose_member (const_tree, tree);
@@ -3667,7 +3661,6 @@ tree_low_cst (const_tree t, int pos)
   return TREE_INT_CST_LOW (t);
 }
 #endif
-extern HOST_WIDE_INT size_low_cst (const_tree);
 extern int tree_int_cst_sgn (const_tree);
 extern int tree_int_cst_sign_bit (const_tree);
 extern unsigned int tree_int_cst_min_precision (tree, bool);
@@ -3726,9 +3719,6 @@ extern tree build_type_attribute_variant (tree, tree);
 extern tree build_decl_attribute_variant (tree, tree);
 extern tree build_type_attribute_qual_variant (tree, tree, int);
 
-/* Remove redundant "omp declare simd" attributes from fndecl.  */
-extern void omp_remove_redundant_declare_simd_attrs (tree);
-
 /* Return 0 if the attributes for two types are incompatible, 1 if they
    are compatible, and 2 if they are nearly compatible (which causes a
    warning to be generated).  */
@@ -3902,7 +3892,6 @@ extern tree expr_last (tree);
 extern tree size_in_bytes (const_tree);
 extern HOST_WIDE_INT int_size_in_bytes (const_tree);
 extern HOST_WIDE_INT max_int_size_in_bytes (const_tree);
-extern tree tree_expr_size (const_tree);
 extern tree bit_position (const_tree);
 extern HOST_WIDE_INT int_bit_position (const_tree);
 extern tree byte_position (const_tree);
@@ -3963,10 +3952,6 @@ extern tree nreverse (tree);
 
 extern int list_length (const_tree);
 
-/* Returns the number of FIELD_DECLs in a type.  */
-
-extern int fields_length (const_tree);
-
 /* Returns the first FIELD_DECL in a type.  */
 
 extern tree first_field (const_tree);
@@ -4127,12 +4112,6 @@ extern tree variable_size (tree);
 
 extern tree stabilize_reference (tree);
 
-/* Subroutine of stabilize_reference; this is called for subtrees of
-   references.  Any expression with side-effects must be put in a SAVE_EXPR
-   to ensure that it is only evaluated once.  */
-
-extern tree stabilize_reference_1 (tree);
-
 /* Return EXP, stripped of any conversions to wider types
    in such a way that the result of converting to type FOR_TYPE
    is the same as if EXP were converted to FOR_TYPE.
@@ -4315,11 +4294,6 @@ extern tree unshare_expr_without_location (tree);
 /* In stmt.c */
 
 extern void expand_label (tree);
-extern void expand_goto (tree);
-
-extern rtx expand_stack_save (void);
-extern void expand_stack_restore (tree);
-extern void expand_return (tree);
 
 /* Compare and hash for any structure which begins with a canonical
    pointer.  Assumes all pointers are interchangeable, which is sort
@@ -4389,7 +4363,6 @@ extern tree fold_build3_stat_loc (location_t, enum tree_code, tree, tree, tree,
                                  tree MEM_STAT_DECL);
 extern tree fold_build1_initializer_loc (location_t, enum tree_code, tree, tree);
 extern tree fold_build2_initializer_loc (location_t, enum tree_code, tree, tree, tree);
-extern tree fold_build3_initializer_loc (location_t, enum tree_code, tree, tree, tree, tree);
 #define fold_build_call_array(T1,T2,N,T4)\
    fold_build_call_array_loc (UNKNOWN_LOCATION, T1, T2, N, T4)
 extern tree fold_build_call_array_loc (location_t, tree, tree, int, tree *);
@@ -4452,7 +4425,6 @@ extern enum tree_code swap_tree_comparison (enum tree_code);
 extern bool ptr_difference_const (tree, tree, HOST_WIDE_INT *);
 extern enum tree_code invert_tree_comparison (enum tree_code, bool);
 
-extern bool tree_expr_nonzero_p (tree);
 extern bool tree_unary_nonzero_warnv_p (enum tree_code, tree, tree, bool *);
 extern bool tree_binary_nonzero_warnv_p (enum tree_code, tree, tree, tree op1,
                                          bool *);
@@ -4461,11 +4433,8 @@ extern bool tree_unary_nonnegative_warnv_p (enum tree_code, tree, tree, bool *);
 extern bool tree_binary_nonnegative_warnv_p (enum tree_code, tree, tree, tree,
                                              bool *);
 extern bool tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p);
-extern bool tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p);
 extern bool tree_call_nonnegative_warnv_p (tree, tree, tree, tree, bool *);
 
-extern bool tree_expr_nonzero_warnv_p (tree, bool *);
-
 extern bool fold_real_zero_addition_p (const_tree, const_tree, int);
 extern tree combine_comparisons (location_t, enum tree_code, enum tree_code,
                                 enum tree_code, tree, tree, tree);
@@ -4536,7 +4505,6 @@ extern tree fold_builtin_stxcpy_chk (location_t, tree, tree, tree, tree, tree, b
                                     enum built_in_function);
 extern tree fold_builtin_stxncpy_chk (location_t, tree, tree, tree, tree, tree, bool,
                                      enum built_in_function);
-extern tree fold_builtin_snprintf_chk (location_t, tree, tree, enum built_in_function);
 extern bool fold_builtin_next_arg (tree, bool);
 extern enum built_in_function builtin_mathfn_code (const_tree);
 extern tree fold_builtin_call_array (location_t, tree, tree, int, tree *);
@@ -4547,7 +4515,6 @@ extern tree build_call_expr (tree, int, ...);
 extern tree mathfn_built_in (tree, enum built_in_function fn);
 extern tree c_strlen (tree, int);
 extern tree build_string_literal (int, const char *);
-extern bool validate_arglist (const_tree, ...);
 extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
 extern bool is_builtin_fn (tree);
 extern bool get_object_alignment_1 (tree, unsigned int *,
@@ -4585,22 +4552,18 @@ extern int tree_floor_log2 (const_tree);
 extern unsigned int tree_ctz (const_tree);
 extern int simple_cst_equal (const_tree, const_tree);
 extern hashval_t iterative_hash_expr (const_tree, hashval_t);
-extern hashval_t iterative_hash_exprs_commutative (const_tree,
-                                                   const_tree, hashval_t);
 extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
 extern hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);
 extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
 extern int compare_tree_int (const_tree, unsigned HOST_WIDE_INT);
 extern int type_list_equal (const_tree, const_tree);
 extern int chain_member (const_tree, const_tree);
-extern int simple_cst_list_equal (const_tree, const_tree);
 extern void dump_tree_statistics (void);
 extern void recompute_tree_invariant_for_addr_expr (tree);
 extern bool needs_to_live_in_memory (const_tree);
 extern tree reconstruct_complex_type (tree, tree);
 
 extern int real_onep (const_tree);
-extern int real_twop (const_tree);
 extern int real_minus_onep (const_tree);
 extern void init_ttree (void);
 extern void build_common_tree_nodes (bool, bool);
@@ -4635,10 +4598,8 @@ extern const char *get_tree_code_name (enum tree_code);
 extern tree build_addr (tree, tree);
 
 /* In function.c */
-extern void expand_main_function (void);
 extern void expand_function_end (void);
 extern void expand_function_start (tree);
-extern void stack_protect_prologue (void);
 extern void stack_protect_epilogue (void);
 extern void init_dummy_function_start (void);
 extern void expand_dummy_function_end (void);
@@ -4682,7 +4643,6 @@ extern void debug_raw (vec<tree, va_gc> *ptr);
 #ifdef BUFSIZ
 extern void dump_addr (FILE*, const char *, const void *);
 extern void print_node (FILE *, const char *, tree, int);
-extern void print_vec_tree (FILE *, const char *, vec<tree, va_gc> *, int);
 extern void print_node_brief (FILE *, const char *, const_tree, int);
 extern void indent_to (FILE *, int);
 #endif
@@ -4707,9 +4667,6 @@ extern bool must_pass_in_stack_var_size_or_pad (enum machine_mode, const_tree);
 /* In attribs.c.  */
 
 extern const struct attribute_spec *lookup_attribute_spec (const_tree);
-extern const struct attribute_spec *lookup_scoped_attribute_spec (const_tree,
-                                                                 const_tree);
-
 extern void init_attributes (void);
 
 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
@@ -4726,8 +4683,6 @@ extern bool cxx11_attribute_p (const_tree);
 
 extern tree get_attribute_name (const_tree);
 
-extern tree get_attribute_namespace (const_tree);
-
 extern void apply_tm_attr (tree, tree);
 
 /* In stor-layout.c */
@@ -4783,12 +4738,10 @@ extern bool initializer_constant_valid_for_bitfield_p (tree);
 extern bool constructor_static_from_elts_p (const_tree);
 
 /* In stmt.c */
-extern void expand_computed_goto (tree);
 extern bool parse_output_constraint (const char **, int, int, int,
                                     bool *, bool *, bool *);
 extern bool parse_input_constraint (const char **, int, int, int, int,
                                    const char * const *, bool *, bool *);
-extern void expand_asm_stmt (gimple);
 extern tree resolve_asm_operand_names (tree, tree, tree, tree);
 #ifdef HARD_CONST
 /* Silly ifdef to avoid having all includers depend on hard-reg-set.h.  */
@@ -4822,7 +4775,6 @@ extern tree drop_tree_overflow (tree);
 extern int tree_map_base_eq (const void *, const void *);
 extern unsigned int tree_map_base_hash (const void *);
 extern int tree_map_base_marked_p (const void *);
-extern bool list_equal_p (const_tree, const_tree);
 
 #define tree_map_eq tree_map_base_eq
 extern unsigned int tree_map_hash (const void *);
@@ -4844,12 +4796,8 @@ extern unsigned int tree_decl_map_hash (const void *);
 #define tree_vec_map_hash tree_decl_map_hash
 #define tree_vec_map_marked_p tree_map_base_marked_p
 
-/* In tree-vrp.c */
-extern bool ssa_name_nonnegative_p (const_tree);
-
 /* In tree-object-size.c.  */
 extern void init_object_sizes (void);
-extern void fini_object_sizes (void);
 extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
 
 /* In expr.c.  */
@@ -4859,9 +4807,6 @@ extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
    succeed.  */
 extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
 
-/* Is it an ADDR_EXPR of a DECL that's not in memory?  */
-extern bool addr_expr_of_non_mem_decl_p (tree);
-
 extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
 extern tree build_personality_function (const char *);
 
@@ -4874,12 +4819,6 @@ extern bool is_tm_ending_fndecl (tree);
 extern void record_tm_replacement (tree, tree);
 extern void tm_malloc_replacement (tree);
 
-static inline bool
-is_tm_safe_or_pure (const_tree x)
-{
-  return is_tm_safe (x) || is_tm_pure (x);
-}
-
 /* In tree-inline.c.  */
 
 void init_inline_once (void);
@@ -4952,12 +4891,6 @@ more_call_expr_args_p (const call_expr_arg_iterator *iter)
   return (iter->i < iter->n);
 }
 
-static inline bool
-more_const_call_expr_args_p (const const_call_expr_arg_iterator *iter)
-{
-  return (iter->i < iter->n);
-}
-
 /* Iterate through each argument ARG of CALL_EXPR CALL, using variable ITER
    (of type call_expr_arg_iterator) to hold the iteration state.  */
 #define FOR_EACH_CALL_EXPR_ARG(arg, iter, call)                        \
@@ -4975,9 +4908,6 @@ is_lang_specific (tree t)
   return TREE_CODE (t) == LANG_TYPE || TREE_CODE (t) >= NUM_TREE_CODES;
 }
 
-/* In vtable-verify.c.  */
-extern void save_vtable_map_decl (tree);
-
 /* Valid builtin number.  */
 #define BUILTIN_VALID_P(FNCODE) \
   (IN_RANGE ((int)FNCODE, ((int)BUILT_IN_NONE) + 1, ((int) END_BUILTINS) - 1))