Postpone expanding va_arg until pass_stdarg

Tom de Vries Tom_deVries@mentor.com
Wed Feb 11 18:10:00 GMT 2015


On 10-02-15 17:57, Michael Matz wrote:
> Hi,
>
> On Tue, 10 Feb 2015, Tom de Vries wrote:
>
>> I've added two modifications to gimplify_modify_expr:
>> - the WITH_SIZE_EXPR in which the CALL_TREE is wrapped, is dropped after
>>    gimplification, but we need the size expression at expansion in pass_stdarg.
>>    So I added the size expression as argument to the internal function.
>>    [ And at pass_stdarg::execute, we wrap the result of
>> gimplify_va_arg_internal
>>    in a WITH_SIZE_EXPR before generating the assign to the lhs ]
>
> Hmm, why do you need the WITH_SIZE_EXPR actually?  For variable-sized
> types returned by va_arg?
>

Yep.

>> - we detect after gimplify_arg (&ap) whether it created a copy ap.1 of ap,
>>    rather than use ap itself, and if so, we copy the value back from ap.1 to ap
>>    after va_arg.
>
> My idea was to not generate temporaries and hence copies for
> non-scalar types, but rather construct the "result" of va_arg directly
> into the original LHS (that would then also trivially solve the problem of
> nno-copyable types).
>

The copy mentioned here is of ap, not of the result of va_arg.

In gimplify_modify_expr, we're already doing effort not to generate temporaries 
for call lhs, see comment:
...
      To
      prevent gimplify_expr from trying to create a new temporary for
      foo's LHS, we tell it that it should only gimplify until it
      reaches the CALL_EXPR.  On return from gimplify_expr, the newly
      created GIMPLE_CALL <foo> will be the last statement in *PRE_P
      and all we need to do here is set 'a' to be its LHS
...

>> I'm not really sure yet why std_gimplify_va_arg_expr has a part
>> commented out. Michael, can you comment?
>
> I think I did that because of SSA form.  The old sequence calculated
>
>    vatmp = valist;
>    vatmp = vatmp + boundary-1
>    vatmp = vatmp & -boundary
>
> (where the local variable in that function 'valist_tmp' is the tree
> VAR_DECL 'vatmp') and then continue to use valist_tmp.  When in SSA form
> the gimplifier will rewrite this into:
>
>    vatmp_1 = valist;
>    vatmp_2 = vatmp_1 + boundary-1
>    vatmp_3 = vatmp_2 & -boundary
>
> but the local valist_tmp variable will continue to be the VAR_DECL, not
> the vatmp_3 ssa name.  Basically whenever one gimplifies a MODIFY_EXPR
> while in SSA form it's suspicious.  So the new code simply build the
> expression:
>
>    ((valist + bound-1) & -bound)
>
> gimplifies that into an rvalue (most probably an SSA name) and uses that
> to go on generating code by making valist_tmp be that returned rvalue.
>
> I think you'll find that removing that code will make the SSA verifier
> scream or generate invalid code with -m32 when that hook is used.
>

Thanks for the detailed explanation. I'm not sure I understand the problem well 
enough, so I'll try to trigger it and investigate.

Thanks,
- Tom




More information about the Gcc mailing list