This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Allow &va_list[0] in tree-stdarg
- From: Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 20 May 2005 13:56:38 +0200 (CEST)
- Subject: [PATCH] Allow &va_list[0] in tree-stdarg
This patch allows &va_list[0] in tree-stdarg optimization as
it shows up on x86_64 with its va_list type "struct ap[1]"
and the C frontend modified to emit &ap[0] for ap-to-pointer
decay, instead of &ap. I guess this should also show up
with current C++ on that architecture.
Is such change ok with you? Would it even be correct to
omit the integer_zerop check for the array index? I get
some extra failures in this case on i686, namely no longer
thinking that for stdarg-3.c:f4() the va_list escapes.
Bootstrapped on x86_64-unknown-linux-gnu, tested on
i686-pc-linux-gnu and x86_64-unknown-linux-gnu.
Comments?
Richard.
Index: tree-stdarg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-stdarg.c,v
retrieving revision 2.4
diff -c -3 -p -r2.4 tree-stdarg.c
*** tree-stdarg.c 28 Apr 2005 02:25:22 -0000 2.4
--- tree-stdarg.c 20 May 2005 11:31:07 -0000
*************** execute_optimize_stdarg (void)
*** 660,675 ****
si.va_start_count++;
ap = TREE_VALUE (TREE_OPERAND (call, 1));
! if (TREE_CODE (ap) != ADDR_EXPR
! || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ap, 0)))
! != TYPE_MAIN_VARIANT (va_list_type_node)
! || TREE_CODE (TREE_OPERAND (ap, 0)) != VAR_DECL)
{
va_list_escapes = true;
break;
}
-
ap = TREE_OPERAND (ap, 0);
if (is_global_var (ap))
{
va_list_escapes = true;
--- 660,689 ----
si.va_start_count++;
ap = TREE_VALUE (TREE_OPERAND (call, 1));
!
! if (TREE_CODE (ap) != ADDR_EXPR)
{
va_list_escapes = true;
break;
}
ap = TREE_OPERAND (ap, 0);
+ if (TREE_CODE (ap) == ARRAY_REF)
+ {
+ if (! integer_zerop (TREE_OPERAND (ap, 1)))
+ {
+ va_list_escapes = true;
+ break;
+ }
+ ap = TREE_OPERAND (ap, 0);
+ }
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (ap))
+ != TYPE_MAIN_VARIANT (va_list_type_node)
+ || TREE_CODE (ap) != VAR_DECL)
+ {
+ va_list_escapes = true;
+ break;
+ }
+
if (is_global_var (ap))
{
va_list_escapes = true;