diff mbox

Relocate a couple of va_arg_expr routines.

Message ID 52691B58.30304@redhat.com
State New
Headers show

Commit Message

Andrew MacLeod Oct. 24, 2013, 1:06 p.m. UTC
I originally shuffled std_gimplify_va_arg_expr () to gimplify.c, but i 
believe the suggestion was to eventually move it to targhooks.c.

build_va_arg_indirect_ref seems to  hang around with it, and used by all 
the same things that use  std_gimplify_va_arg_expr, so this patch 
currently lumps it in targhooks.c as well (which means they will get it 
with the same header file).   Really, I suppose it should go elsewhere.. 
and I'd guess tree.c...  but its nots 100% obvious... suggestions 
welcome.   I'd think someday this file will get split into 
gimple-targhooks and rtl-targhooks, but not today i think. :-)

It also seems appropriate to move gimplify_va_arg_expr from builtins.c 
to gimplify.c since its a gimplification routiine.. This showed up as I 
was splitting gimple.h into gimplify.h... the prototype is in gimple.h 
and it made sense to become part of gimplify.h as I try to move towards 
an interface from front-ends that only requires gimplfy.h and not 
gimple.h or other middle end things.

bootstraps on x86_64-unknown-linux-gnu with no new regressions.  OK?

Anrdew

Comments

Richard Biener Oct. 24, 2013, 1:11 p.m. UTC | #1
On Thu, Oct 24, 2013 at 3:06 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
> I originally shuffled std_gimplify_va_arg_expr () to gimplify.c, but i
> believe the suggestion was to eventually move it to targhooks.c.
>
> build_va_arg_indirect_ref seems to  hang around with it, and used by all the
> same things that use  std_gimplify_va_arg_expr, so this patch currently
> lumps it in targhooks.c as well (which means they will get it with the same
> header file).   Really, I suppose it should go elsewhere.. and I'd guess
> tree.c...  but its nots 100% obvious... suggestions welcome.   I'd think
> someday this file will get split into gimple-targhooks and rtl-targhooks,
> but not today i think. :-)
>
> It also seems appropriate to move gimplify_va_arg_expr from builtins.c to
> gimplify.c since its a gimplification routiine.. This showed up as I was
> splitting gimple.h into gimplify.h... the prototype is in gimple.h and it
> made sense to become part of gimplify.h as I try to move towards an
> interface from front-ends that only requires gimplfy.h and not gimple.h or
> other middle end things.
>
> bootstraps on x86_64-unknown-linux-gnu with no new regressions.  OK?

Ok.

Err ...

Index: targhooks.c
===================================================================
*** targhooks.c (revision 203915)
--- targhooks.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 71,76 ****
--- 71,77 ----
  #include "tree-ssa.h"
  #include "tree-ssa-alias.h"
  #include "insn-codes.h"
+ #include "tree-mudflap.h"

we were supposed to remove mudflap for 4.9, no?

Thanks,
Richard.

> Anrdew
>
>
Andrew MacLeod Oct. 24, 2013, 1:38 p.m. UTC | #2
On 10/24/2013 09:11 AM, Richard Biener wrote:
> On Thu, Oct 24, 2013 at 3:06 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
>> I originally shuffled std_gimplify_va_arg_expr () to gimplify.c, but i
>> believe the suggestion was to eventually move it to targhooks.c.
>>
>> build_va_arg_indirect_ref seems to  hang around with it, and used by all the
>> same things that use  std_gimplify_va_arg_expr, so this patch currently
>> lumps it in targhooks.c as well (which means they will get it with the same
>> header file).   Really, I suppose it should go elsewhere.. and I'd guess
>> tree.c...  but its nots 100% obvious... suggestions welcome.   I'd think
>> someday this file will get split into gimple-targhooks and rtl-targhooks,
>> but not today i think. :-)
>>
>> It also seems appropriate to move gimplify_va_arg_expr from builtins.c to
>> gimplify.c since its a gimplification routiine.. This showed up as I was
>> splitting gimple.h into gimplify.h... the prototype is in gimple.h and it
>> made sense to become part of gimplify.h as I try to move towards an
>> interface from front-ends that only requires gimplfy.h and not gimple.h or
>> other middle end things.
>>
>> bootstraps on x86_64-unknown-linux-gnu with no new regressions.  OK?
> Ok.
>
> Err ...
>
> Index: targhooks.c
> ===================================================================
> *** targhooks.c (revision 203915)
> --- targhooks.c (working copy)
> *************** along with GCC; see the file COPYING3.
> *** 71,76 ****
> --- 71,77 ----
>    #include "tree-ssa.h"
>    #include "tree-ssa-alias.h"
>    #include "insn-codes.h"
> + #include "tree-mudflap.h"
>
> we were supposed to remove mudflap for 4.9, no?
>
>
Really?  I guess it hasn't been removed yet since the include is still 
there?  who is doing that?

  so I guess should remove this bit too then..?

   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;
  }
Richard Biener Oct. 24, 2013, 1:40 p.m. UTC | #3
On Thu, Oct 24, 2013 at 3:38 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
> On 10/24/2013 09:11 AM, Richard Biener wrote:
>>
>> On Thu, Oct 24, 2013 at 3:06 PM, Andrew MacLeod <amacleod@redhat.com>
>> wrote:
>>>
>>> I originally shuffled std_gimplify_va_arg_expr () to gimplify.c, but i
>>> believe the suggestion was to eventually move it to targhooks.c.
>>>
>>> build_va_arg_indirect_ref seems to  hang around with it, and used by all
>>> the
>>> same things that use  std_gimplify_va_arg_expr, so this patch currently
>>> lumps it in targhooks.c as well (which means they will get it with the
>>> same
>>> header file).   Really, I suppose it should go elsewhere.. and I'd guess
>>> tree.c...  but its nots 100% obvious... suggestions welcome.   I'd think
>>> someday this file will get split into gimple-targhooks and rtl-targhooks,
>>> but not today i think. :-)
>>>
>>> It also seems appropriate to move gimplify_va_arg_expr from builtins.c to
>>> gimplify.c since its a gimplification routiine.. This showed up as I was
>>> splitting gimple.h into gimplify.h... the prototype is in gimple.h and it
>>> made sense to become part of gimplify.h as I try to move towards an
>>> interface from front-ends that only requires gimplfy.h and not gimple.h
>>> or
>>> other middle end things.
>>>
>>> bootstraps on x86_64-unknown-linux-gnu with no new regressions.  OK?
>>
>> Ok.
>>
>> Err ...
>>
>> Index: targhooks.c
>> ===================================================================
>> *** targhooks.c (revision 203915)
>> --- targhooks.c (working copy)
>> *************** along with GCC; see the file COPYING3.
>> *** 71,76 ****
>> --- 71,77 ----
>>    #include "tree-ssa.h"
>>    #include "tree-ssa-alias.h"
>>    #include "insn-codes.h"
>> + #include "tree-mudflap.h"
>>
>> we were supposed to remove mudflap for 4.9, no?
>>
>>
> Really?  I guess it hasn't been removed yet since the include is still
> there?  who is doing that?

Yeah, nobody has done it yet appearantly :/

Richard.

>  so I guess should remove this bit too then..?
>
>   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;
>  }
>
Andrew MacLeod Oct. 24, 2013, 4:10 p.m. UTC | #4
On 10/24/2013 09:40 AM, Richard Biener wrote:
> On Thu, Oct 24, 2013 at 3:38 PM, Andrew MacLeod <amacleod@redhat.com> wrote:
>> On 10/24/2013 09:11 AM, Richard Biener wrote:
>>> On Thu, Oct 24, 2013 at 3:06 PM, Andrew MacLeod <amacleod@redhat.com>
>>> wrote:
>>>> I originally shuffled std_gimplify_va_arg_expr () to gimplify.c, but i
>>>> believe the suggestion was to eventually move it to targhooks.c.
>>>>
>>>> build_va_arg_indirect_ref seems to  hang around with it, and used by all
>>>> the
>>>> same things that use  std_gimplify_va_arg_expr, so this patch currently
>>>> lumps it in targhooks.c as well (which means they will get it with the
>>>> same
>>>> header file).   Really, I suppose it should go elsewhere.. and I'd guess
>>>> tree.c...  but its nots 100% obvious... suggestions welcome.   I'd think
>>>> someday this file will get split into gimple-targhooks and rtl-targhooks,
>>>> but not today i think. :-)
>>>>
>>>> It also seems appropriate to move gimplify_va_arg_expr from builtins.c to
>>>> gimplify.c since its a gimplification routiine.. This showed up as I was
>>>> splitting gimple.h into gimplify.h... the prototype is in gimple.h and it
>>>> made sense to become part of gimplify.h as I try to move towards an
>>>> interface from front-ends that only requires gimplfy.h and not gimple.h
>>>> or
>>>> other middle end things.
>>>>
>>>> bootstraps on x86_64-unknown-linux-gnu with no new regressions.  OK?
>>> Ok.
>>>
>>> Err ...
>>>
>>> Index: targhooks.c
>>> ===================================================================
>>> *** targhooks.c (revision 203915)
>>> --- targhooks.c (working copy)
>>> *************** along with GCC; see the file COPYING3.
>>> *** 71,76 ****
>>> --- 71,77 ----
>>>     #include "tree-ssa.h"
>>>     #include "tree-ssa-alias.h"
>>>     #include "insn-codes.h"
>>> + #include "tree-mudflap.h"
>>>
>>> we were supposed to remove mudflap for 4.9, no?
>>>
>>>
>> Really?  I guess it hasn't been removed yet since the include is still
>> there?  who is doing that?
> Yeah, nobody has done it yet appearantly :/
>
> Richard.
>
I'll leave it in an let whoever removes mudflap can take the include and 
those lines out, Otherwise we get a dozen regressions.  They woud have 
had to do the same thing where ever it was located.

Andrew
diff mbox

Patch



	* 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.

Index: builtins.c
===================================================================
*** builtins.c	(revision 203915)
--- builtins.c	(working copy)
*************** expand_builtin_va_start (tree exp)
*** 4233,4342 ****
    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
--- 4233,4238 ----
Index: gimplify.c
===================================================================
*** gimplify.c	(revision 203915)
--- gimplify.c	(working copy)
*************** force_gimple_operand_gsi (gimple_stmt_it
*** 9228,9345 ****
  				     var, before, m);
  }
  
! #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-gimplify.h"
--- 9228,9334 ----
  				     var, before, m);
  }
  
! /* 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;
!     }
  }
  
  #include "gt-gimplify.h"
Index: targhooks.c
===================================================================
*** targhooks.c	(revision 203915)
--- targhooks.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 71,76 ****
--- 71,77 ----
  #include "tree-ssa.h"
  #include "tree-ssa-alias.h"
  #include "insn-codes.h"
+ #include "tree-mudflap.h"
  
  
  bool
*************** default_canonicalize_comparison (int *, 
*** 1564,1567 ****
--- 1565,1683 ----
  {
  }
  
+ #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: targhooks.h
===================================================================
*** targhooks.h	(revision 203915)
--- targhooks.h	(working copy)
*************** extern void default_asm_output_ident_dir
*** 202,204 ****
--- 202,206 ----
  
  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: tree.h
===================================================================
*** tree.h	(revision 203915)
--- tree.h	(working copy)
*************** extern tree build_call_expr_loc (locatio
*** 4508,4515 ****
  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);
--- 4508,4513 ----