[PATCH][PR66013] Update address_taken after ifn_va_arg expansion

Tom de Vries Tom_deVries@mentor.com
Fri May 8 15:14:00 GMT 2015


Hi,

this patch fixes PR66013.


I.

Consider this test-case, with a va_list passed from f2 to f2_1:
...
#include <stdarg.h>

inline int __attribute__((always_inline))
f2_1 (va_list ap)
{
   return va_arg (ap, int);
}

int
f2 (int i, ...)
{
   int res;
   va_list ap;

   va_start (ap, i);
   res = f2_1 (ap);
   va_end (ap);

   return res;
}
...

When compiling at -O2 with -m32, before pass_stdarg we see that va_start and 
va_arg (in the same function after inlining) use different aps (with the same 
value though):
...
   # .MEM_2 = VDEF <.MEM_1(D)>
   # USE = nonlocal escaped
   # CLB = nonlocal escaped { D.1809 }
   __builtin_va_startD.1021 (&apD.1809, 0);

   # VUSE <.MEM_2>
   # PT = nonlocal
   ap.0_3 = apD.1809;

   # .MEM_4 = VDEF <.MEM_2>
   apD.1820 = ap.0_3;

   # .MEM_8 = VDEF <.MEM_4>
   # USE = nonlocal null { D.1820 } (escaped)
   # CLB = nonlocal null { D.1820 } (escaped)
   _7 = VA_ARG (&apD.1820, 0B, 1);
...

After expand_ifn_va_arg_1, we have this representation, and that's the one the 
pass_stdarg optimization operates on:
...
   # .MEM_2 = VDEF <.MEM_1(D)>
   # USE = nonlocal escaped
   # CLB = nonlocal escaped { D.1809 }
   __builtin_va_startD.1021 (&apD.1809, 0);

   # VUSE <.MEM_2>
   # PT = nonlocal
   ap.0_3 = apD.1809;

   # .MEM_4 = VDEF <.MEM_2>
   apD.1820 = ap.0_3;

   # VUSE <.MEM_4>
   ap.4_9 = apD.1820;

   ap.5_10 = ap.4_9 + 4;

   # .MEM_11 = VDEF <.MEM_4>
   apD.1820 = ap.5_10;

   # VUSE <.MEM_11>
   _7 = MEM[(intD.1 *)ap.4_9];
...

The optimization in pass_stdarg fails:
...
f2: va_list escapes 1, needs to save all GPR units and all FPR units.
...

The optimization fails because this assignment makes the va_list escape:
...
va_list escapes in # .MEM_4 = VDEF <.MEM_2>
apD.1820 = ap.0_3;
...


II.

By recalculating address_taken after expanding the ifn_va_arg, we get instead:
...
   # .MEM_2 = VDEF <.MEM_1(D)>
   # USE = nonlocal escaped
   # CLB = nonlocal escaped { D.1809 }
   __builtin_va_startD.1021 (&apD.1809, 0);

   # VUSE <.MEM_2>
   # PT = nonlocal
   ap.0_3 = apD.1809;

   ap_11 = ap.0_3;

   ap.4_9 = ap_11;

   ap.5_10 = ap.4_9 + 4;

   ap_4 = ap.5_10;

   # VUSE <.MEM_2>
   _7 = MEM[(intD.1 *)ap.4_9];
...

and the pass_stdarg optimization succeeds now:
...
f2: va_list escapes 0, needs to save 4 GPR units and all FPR units.
...

Bootstrapped and reg-tested on x86_64 with and without -m32.

OK for trunk?

Thanks,
- Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Update-address_taken-after-ifn_va_arg-expansion.patch
Type: text/x-patch
Size: 2166 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20150508/3a66cc94/attachment.bin>


More information about the Gcc-patches mailing list