This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR47025
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 6 Sep 2011 17:52:40 +0200 (CEST)
- Subject: [PATCH] Fix PR47025
This fixes PR47025, __builtin_va_end is preventing dead store
elimination and __builtin_va_start is an escape point for the
valist.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2011-09-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/47025
* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): BUILT_IN_VA_END
uses nothing.
(call_may_clobber_ref_p_1): BUILT_IN_VA_END is a barrier like
BUILT_IN_FREE.
(stmt_kills_ref_p_1): BUILT_IN_VA_END kills what its argument
definitely points to.
* tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
BUILT_IN_VA_START doesn't let its va_list argument escape.
* tree-ssa-dce.c (propagate_necessity): BUILT_IN_VA_END does
not make any previous stores necessary.
Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig 2011-09-06 16:24:16.000000000 +0200
--- gcc/tree-ssa-alias.c 2011-09-06 16:28:48.000000000 +0200
*************** ref_maybe_used_by_call_p_1 (gimple call,
*** 1254,1259 ****
--- 1254,1260 ----
case BUILT_IN_SINCOSF:
case BUILT_IN_SINCOSL:
case BUILT_IN_ASSUME_ALIGNED:
+ case BUILT_IN_VA_END:
return false;
/* __sync_* builtins and some OpenMP builtins act as threading
barriers. */
*************** call_may_clobber_ref_p_1 (gimple call, a
*** 1518,1523 ****
--- 1519,1525 ----
the call has to serve as a barrier for moving loads and stores
across it. */
case BUILT_IN_FREE:
+ case BUILT_IN_VA_END:
{
tree ptr = gimple_call_arg (call, 0);
return ptr_deref_may_alias_ref_p_1 (ptr, ref);
*************** stmt_kills_ref_p_1 (gimple stmt, ao_ref
*** 1763,1772 ****
/ BITS_PER_UNIT)))
return true;
}
}
default:;
}
-
}
return false;
}
--- 1765,1787 ----
/ BITS_PER_UNIT)))
return true;
}
+ break;
+ }
+
+ case BUILT_IN_VA_END:
+ {
+ tree ptr = gimple_call_arg (stmt, 0);
+ if (TREE_CODE (ptr) == ADDR_EXPR)
+ {
+ tree base = ao_ref_base (ref);
+ if (TREE_OPERAND (ptr, 0) == base)
+ return true;
+ }
+ break;
}
+
default:;
}
}
return false;
}
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig 2011-09-06 16:23:29.000000000 +0200
--- gcc/tree-ssa-structalias.c 2011-09-06 16:24:18.000000000 +0200
*************** find_func_aliases_for_builtin_call (gimp
*** 4187,4213 ****
mode as well. */
case BUILT_IN_VA_START:
{
if (in_ipa_mode)
{
- tree valist = gimple_call_arg (t, 0);
- struct constraint_expr rhs, *lhsp;
- unsigned i;
- /* The va_list gets access to pointers in variadic
- arguments. */
fi = lookup_vi_for_tree (cfun->decl);
- gcc_assert (fi != NULL);
- get_constraint_for (valist, &lhsc);
- do_deref (&lhsc);
rhs = get_function_part_constraint (fi, ~0);
rhs.type = ADDRESSOF;
- FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
- process_constraint (new_constraint (*lhsp, rhs));
- VEC_free (ce_s, heap, lhsc);
- /* va_list is clobbered. */
- make_constraint_to (get_call_clobber_vi (t)->id, valist);
- return true;
}
! break;
}
/* va_end doesn't have any effect that matters. */
case BUILT_IN_VA_END:
--- 4187,4218 ----
mode as well. */
case BUILT_IN_VA_START:
{
+ tree valist = gimple_call_arg (t, 0);
+ struct constraint_expr rhs, *lhsp;
+ unsigned i;
+ get_constraint_for (valist, &lhsc);
+ do_deref (&lhsc);
+ /* The va_list gets access to pointers in variadic
+ arguments. Which we know in the case of IPA analysis
+ and otherwise are just all nonlocal variables. */
if (in_ipa_mode)
{
fi = lookup_vi_for_tree (cfun->decl);
rhs = get_function_part_constraint (fi, ~0);
rhs.type = ADDRESSOF;
}
! else
! {
! rhs.var = nonlocal_id;
! rhs.type = ADDRESSOF;
! rhs.offset = 0;
! }
! FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
! process_constraint (new_constraint (*lhsp, rhs));
! VEC_free (ce_s, heap, lhsc);
! /* va_list is clobbered. */
! make_constraint_to (get_call_clobber_vi (t)->id, valist);
! return true;
}
/* va_end doesn't have any effect that matters. */
case BUILT_IN_VA_END:
Index: gcc/tree-ssa-dce.c
===================================================================
*** gcc/tree-ssa-dce.c.orig 2011-09-06 16:23:29.000000000 +0200
--- gcc/tree-ssa-dce.c 2011-09-06 16:24:18.000000000 +0200
*************** propagate_necessity (struct edge_list *e
*** 836,841 ****
--- 836,842 ----
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE
+ || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE