* builtins.c (dummy_object, gimplify_va_arg_expr): Move to gimplify.c.
authoramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Oct 2013 19:02:44 +0000 (19:02 +0000)
committeramacleod <amacleod@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 24 Oct 2013 19:02:44 +0000 (19:02 +0000)
* gimplify.c (build_va_arg_indirect_ref, std_gimplify_va_arg_expr):
Move to targhooks.c.
(dummy_object, gimplify_va_arg_expr): Relocate from builtins.c.
* targhooks.c (build_va_arg_indirect_ref, std_gimplify_va_arg_expr):
Relocate from gimplify.c.
* targhooks.h: Add 2 prototypes.
* tree.h. Delete 2 prototypes.

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

gcc/ChangeLog
gcc/builtins.c
gcc/gimplify.c
gcc/targhooks.c
gcc/targhooks.h
gcc/tree.h

index 1b3b1ea..3f23ec6 100644 (file)
@@ -1,3 +1,14 @@
+2013-10-24  Andrew MacLeod  <amacleod@redhat.com>
+
+       * builtins.c (dummy_object, gimplify_va_arg_expr): Move to gimplify.c.
+       * gimplify.c (build_va_arg_indirect_ref, std_gimplify_va_arg_expr):
+       Move to targhooks.c.
+       (dummy_object, gimplify_va_arg_expr): Relocate from builtins.c.
+       * targhooks.c (build_va_arg_indirect_ref, std_gimplify_va_arg_expr):
+       Relocate from gimplify.c.
+       * targhooks.h: Add 2 prototypes.
+       * tree.h: Delete 2 prototypes.
+
 2013-10-24  Igor Shevlyakov  <igor.shevlyakov@gmail.com>
 
        * tree-ssa-loop-ivopts.c (multiplier_allowed_in_address_p ): Check both
index df6f4af..b380c2c 100644 (file)
@@ -4234,110 +4234,6 @@ expand_builtin_va_start (tree exp)
   return const0_rtx;
 }
 
-
-/* Return a dummy expression of type TYPE in order to keep going after an
-   error.  */
-
-static tree
-dummy_object (tree type)
-{
-  tree t = build_int_cst (build_pointer_type (type), 0);
-  return build2 (MEM_REF, type, t, t);
-}
-
-/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
-   builtin function, but a very special sort of operator.  */
-
-enum gimplify_status
-gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
-{
-  tree promoted_type, have_va_type;
-  tree valist = TREE_OPERAND (*expr_p, 0);
-  tree type = TREE_TYPE (*expr_p);
-  tree t;
-  location_t loc = EXPR_LOCATION (*expr_p);
-
-  /* Verify that valist is of the proper type.  */
-  have_va_type = TREE_TYPE (valist);
-  if (have_va_type == error_mark_node)
-    return GS_ERROR;
-  have_va_type = targetm.canonical_va_list_type (have_va_type);
-
-  if (have_va_type == NULL_TREE)
-    {
-      error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
-      return GS_ERROR;
-    }
-
-  /* Generate a diagnostic for requesting data of a type that cannot
-     be passed through `...' due to type promotion at the call site.  */
-  if ((promoted_type = lang_hooks.types.type_promotes_to (type))
-          != type)
-    {
-      static bool gave_help;
-      bool warned;
-
-      /* Unfortunately, this is merely undefined, rather than a constraint
-        violation, so we cannot make this an error.  If this call is never
-        executed, the program is still strictly conforming.  */
-      warned = warning_at (loc, 0,
-                          "%qT is promoted to %qT when passed through %<...%>",
-                          type, promoted_type);
-      if (!gave_help && warned)
-       {
-         gave_help = true;
-         inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
-                 promoted_type, type);
-       }
-
-      /* We can, however, treat "undefined" any way we please.
-        Call abort to encourage the user to fix the program.  */
-      if (warned)
-       inform (loc, "if this code is reached, the program will abort");
-      /* Before the abort, allow the evaluation of the va_list
-        expression to exit or longjmp.  */
-      gimplify_and_add (valist, pre_p);
-      t = build_call_expr_loc (loc,
-                              builtin_decl_implicit (BUILT_IN_TRAP), 0);
-      gimplify_and_add (t, pre_p);
-
-      /* This is dead code, but go ahead and finish so that the
-        mode of the result comes out right.  */
-      *expr_p = dummy_object (type);
-      return GS_ALL_DONE;
-    }
-  else
-    {
-      /* Make it easier for the backends by protecting the valist argument
-        from multiple evaluations.  */
-      if (TREE_CODE (have_va_type) == ARRAY_TYPE)
-       {
-         /* For this case, the backends will be expecting a pointer to
-            TREE_TYPE (abi), but it's possible we've
-            actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
-            So fix it.  */
-         if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
-           {
-             tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
-             valist = fold_convert_loc (loc, p1,
-                                        build_fold_addr_expr_loc (loc, valist));
-           }
-
-         gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
-       }
-      else
-       gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
-
-      if (!targetm.gimplify_va_arg_expr)
-       /* FIXME: Once most targets are converted we should merely
-          assert this is non-null.  */
-       return GS_ALL_DONE;
-
-      *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
-      return GS_OK;
-    }
-}
-
 /* Expand EXP, a call to __builtin_va_end.  */
 
 static rtx
index 8d78440..d5b535d 100644 (file)
@@ -9258,118 +9258,107 @@ force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
                                     var, before, m);
 }
 
-#ifndef PAD_VARARGS_DOWN
-#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
-#endif
+/* Return a dummy expression of type TYPE in order to keep going after an
+   error.  */
 
-/* Build an indirect-ref expression over the given TREE, which represents a
-   piece of a va_arg() expansion.  */
-tree
-build_va_arg_indirect_ref (tree addr)
+static tree
+dummy_object (tree type)
 {
-  addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
-
-  if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
-    mf_mark (addr);
-
-  return addr;
+  tree t = build_int_cst (build_pointer_type (type), 0);
+  return build2 (MEM_REF, type, t, t);
 }
 
-/* The "standard" implementation of va_arg: read the value from the
-   current (padded) address and increment by the (padded) size.  */
+/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
+   builtin function, but a very special sort of operator.  */
 
-tree
-std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
-                         gimple_seq *post_p)
-{
-  tree addr, t, type_size, rounded_size, valist_tmp;
-  unsigned HOST_WIDE_INT align, boundary;
-  bool indirect;
-
-#ifdef ARGS_GROW_DOWNWARD
-  /* All of the alignment and movement below is for args-grow-up machines.
-     As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
-     implement their own specialized gimplify_va_arg_expr routines.  */
-  gcc_unreachable ();
-#endif
-
-  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
-  if (indirect)
-    type = build_pointer_type (type);
+enum gimplify_status
+gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
+{
+  tree promoted_type, have_va_type;
+  tree valist = TREE_OPERAND (*expr_p, 0);
+  tree type = TREE_TYPE (*expr_p);
+  tree t;
+  location_t loc = EXPR_LOCATION (*expr_p);
 
-  align = PARM_BOUNDARY / BITS_PER_UNIT;
-  boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
+  /* Verify that valist is of the proper type.  */
+  have_va_type = TREE_TYPE (valist);
+  if (have_va_type == error_mark_node)
+    return GS_ERROR;
+  have_va_type = targetm.canonical_va_list_type (have_va_type);
 
-  /* When we align parameter on stack for caller, if the parameter
-     alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
-     aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
-     here with caller.  */
-  if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
-    boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
+  if (have_va_type == NULL_TREE)
+    {
+      error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
+      return GS_ERROR;
+    }
 
-  boundary /= BITS_PER_UNIT;
+  /* Generate a diagnostic for requesting data of a type that cannot
+     be passed through `...' due to type promotion at the call site.  */
+  if ((promoted_type = lang_hooks.types.type_promotes_to (type))
+          != type)
+    {
+      static bool gave_help;
+      bool warned;
 
-  /* Hoist the valist value into a temporary for the moment.  */
-  valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
+      /* Unfortunately, this is merely undefined, rather than a constraint
+        violation, so we cannot make this an error.  If this call is never
+        executed, the program is still strictly conforming.  */
+      warned = warning_at (loc, 0,
+                          "%qT is promoted to %qT when passed through %<...%>",
+                          type, promoted_type);
+      if (!gave_help && warned)
+       {
+         gave_help = true;
+         inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
+                 promoted_type, type);
+       }
 
-  /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
-     requires greater alignment, we must perform dynamic alignment.  */
-  if (boundary > align
-      && !integer_zerop (TYPE_SIZE (type)))
-    {
-      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
-                 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
+      /* We can, however, treat "undefined" any way we please.
+        Call abort to encourage the user to fix the program.  */
+      if (warned)
+       inform (loc, "if this code is reached, the program will abort");
+      /* Before the abort, allow the evaluation of the va_list
+        expression to exit or longjmp.  */
+      gimplify_and_add (valist, pre_p);
+      t = build_call_expr_loc (loc,
+                              builtin_decl_implicit (BUILT_IN_TRAP), 0);
       gimplify_and_add (t, pre_p);
 
-      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
-                 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
-                              valist_tmp,
-                              build_int_cst (TREE_TYPE (valist), -boundary)));
-      gimplify_and_add (t, pre_p);
+      /* This is dead code, but go ahead and finish so that the
+        mode of the result comes out right.  */
+      *expr_p = dummy_object (type);
+      return GS_ALL_DONE;
     }
   else
-    boundary = align;
-
-  /* If the actual alignment is less than the alignment of the type,
-     adjust the type accordingly so that we don't assume strict alignment
-     when dereferencing the pointer.  */
-  boundary *= BITS_PER_UNIT;
-  if (boundary < TYPE_ALIGN (type))
     {
-      type = build_variant_type_copy (type);
-      TYPE_ALIGN (type) = boundary;
-    }
+      /* Make it easier for the backends by protecting the valist argument
+        from multiple evaluations.  */
+      if (TREE_CODE (have_va_type) == ARRAY_TYPE)
+       {
+         /* For this case, the backends will be expecting a pointer to
+            TREE_TYPE (abi), but it's possible we've
+            actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
+            So fix it.  */
+         if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
+           {
+             tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
+             valist = fold_convert_loc (loc, p1,
+                                        build_fold_addr_expr_loc (loc, valist));
+           }
 
-  /* Compute the rounded size of the type.  */
-  type_size = size_in_bytes (type);
-  rounded_size = round_up (type_size, align);
+         gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
+       }
+      else
+       gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
 
-  /* Reduce rounded_size so it's sharable with the postqueue.  */
-  gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
+      if (!targetm.gimplify_va_arg_expr)
+       /* FIXME: Once most targets are converted we should merely
+          assert this is non-null.  */
+       return GS_ALL_DONE;
 
-  /* Get AP.  */
-  addr = valist_tmp;
-  if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
-    {
-      /* Small args are padded downward.  */
-      t = fold_build2_loc (input_location, GT_EXPR, sizetype,
-                      rounded_size, size_int (align));
-      t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
-                      size_binop (MINUS_EXPR, rounded_size, type_size));
-      addr = fold_build_pointer_plus (addr, t);
+      *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
+      return GS_OK;
     }
-
-  /* Compute new value for AP.  */
-  t = fold_build_pointer_plus (valist_tmp, rounded_size);
-  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
-  gimplify_and_add (t, pre_p);
-
-  addr = fold_convert (build_pointer_type (type), addr);
-
-  if (indirect)
-    addr = build_va_arg_indirect_ref (addr);
-
-  return build_va_arg_indirect_ref (addr);
 }
 
 #include "gt-gimplify.h"
index 2504436..bee404d 100644 (file)
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssanames.h"
 #include "tree-ssa-alias.h"
 #include "insn-codes.h"
+#include "tree-mudflap.h"
 
 
 bool
@@ -1565,4 +1566,119 @@ default_canonicalize_comparison (int *, rtx *, rtx *, bool)
 {
 }
 
+#ifndef PAD_VARARGS_DOWN
+#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
+#endif
+
+/* Build an indirect-ref expression over the given TREE, which represents a
+   piece of a va_arg() expansion.  */
+tree
+build_va_arg_indirect_ref (tree addr)
+{
+  addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
+
+  if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
+    mf_mark (addr);
+
+  return addr;
+}
+
+/* The "standard" implementation of va_arg: read the value from the
+   current (padded) address and increment by the (padded) size.  */
+
+tree
+std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+                         gimple_seq *post_p)
+{
+  tree addr, t, type_size, rounded_size, valist_tmp;
+  unsigned HOST_WIDE_INT align, boundary;
+  bool indirect;
+
+#ifdef ARGS_GROW_DOWNWARD
+  /* All of the alignment and movement below is for args-grow-up machines.
+     As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
+     implement their own specialized gimplify_va_arg_expr routines.  */
+  gcc_unreachable ();
+#endif
+
+  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
+  if (indirect)
+    type = build_pointer_type (type);
+
+  align = PARM_BOUNDARY / BITS_PER_UNIT;
+  boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
+
+  /* When we align parameter on stack for caller, if the parameter
+     alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
+     aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
+     here with caller.  */
+  if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
+    boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
+
+  boundary /= BITS_PER_UNIT;
+
+  /* Hoist the valist value into a temporary for the moment.  */
+  valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
+
+  /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
+     requires greater alignment, we must perform dynamic alignment.  */
+  if (boundary > align
+      && !integer_zerop (TYPE_SIZE (type)))
+    {
+      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+                 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
+      gimplify_and_add (t, pre_p);
+
+      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+                 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
+                              valist_tmp,
+                              build_int_cst (TREE_TYPE (valist), -boundary)));
+      gimplify_and_add (t, pre_p);
+    }
+  else
+    boundary = align;
+
+  /* If the actual alignment is less than the alignment of the type,
+     adjust the type accordingly so that we don't assume strict alignment
+     when dereferencing the pointer.  */
+  boundary *= BITS_PER_UNIT;
+  if (boundary < TYPE_ALIGN (type))
+    {
+      type = build_variant_type_copy (type);
+      TYPE_ALIGN (type) = boundary;
+    }
+
+  /* Compute the rounded size of the type.  */
+  type_size = size_in_bytes (type);
+  rounded_size = round_up (type_size, align);
+
+  /* Reduce rounded_size so it's sharable with the postqueue.  */
+  gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
+
+  /* Get AP.  */
+  addr = valist_tmp;
+  if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
+    {
+      /* Small args are padded downward.  */
+      t = fold_build2_loc (input_location, GT_EXPR, sizetype,
+                      rounded_size, size_int (align));
+      t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
+                      size_binop (MINUS_EXPR, rounded_size, type_size));
+      addr = fold_build_pointer_plus (addr, t);
+    }
+
+  /* Compute new value for AP.  */
+  t = fold_build_pointer_plus (valist_tmp, rounded_size);
+  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
+  gimplify_and_add (t, pre_p);
+
+  addr = fold_convert (build_pointer_type (type), addr);
+
+  if (indirect)
+    addr = build_va_arg_indirect_ref (addr);
+
+  return build_va_arg_indirect_ref (addr);
+}
+
+
 #include "gt-targhooks.h"
index b3bd155..48de2a8 100644 (file)
@@ -202,3 +202,5 @@ extern void default_asm_output_ident_directive (const char*);
 
 extern enum machine_mode default_cstore_mode (enum insn_code);
 extern bool default_member_type_forces_blk (const_tree, enum machine_mode);
+extern tree build_va_arg_indirect_ref (tree);
+extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
index 2f4514d..7732d69 100644 (file)
@@ -4508,8 +4508,6 @@ extern tree build_call_expr_loc (location_t, tree, int, ...);
 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 std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
-extern tree build_va_arg_indirect_ref (tree);
 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);