aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-stdarg.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-03-23 16:02:30 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2011-03-23 16:02:30 +0000
commit58da96fef9d3d98154968670f1b15dc5b8e116d9 (patch)
treefe05c89a37d45ba1355ef827a99ed207a13c1599 /gcc/tree-stdarg.c
parentb8beb4d13e5c51a50507cb2be345773fa162fce7 (diff)
downloadgcc-58da96fef9d3d98154968670f1b15dc5b8e116d9.zip
gcc-58da96fef9d3d98154968670f1b15dc5b8e116d9.tar.gz
gcc-58da96fef9d3d98154968670f1b15dc5b8e116d9.tar.bz2
tree-stdarg.c (va_list_counter_bump): Handle bumps via MEM_REF.
2011-03-23 Richard Guenther <rguenther@suse.de> * tree-stdarg.c (va_list_counter_bump): Handle bumps via MEM_REF. (check_va_list_escapes): Likewise. (check_all_va_list_escapes): Likewise. From-SVN: r171353
Diffstat (limited to 'gcc/tree-stdarg.c')
-rw-r--r--gcc/tree-stdarg.c71
1 files changed, 59 insertions, 12 deletions
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 5c9b35c..46fc339 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -133,6 +133,7 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
while (lhs)
{
enum tree_code rhs_code;
+ tree rhs1;
if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
{
@@ -152,21 +153,32 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
return (unsigned HOST_WIDE_INT) -1;
rhs_code = gimple_assign_rhs_code (stmt);
+ rhs1 = gimple_assign_rhs1 (stmt);
if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
|| gimple_assign_cast_p (stmt))
- && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ && TREE_CODE (rhs1) == SSA_NAME)
{
- lhs = gimple_assign_rhs1 (stmt);
+ lhs = rhs1;
continue;
}
if ((rhs_code == POINTER_PLUS_EXPR
|| rhs_code == PLUS_EXPR)
- && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && TREE_CODE (rhs1) == SSA_NAME
&& host_integerp (gimple_assign_rhs2 (stmt), 1))
{
ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1);
- lhs = gimple_assign_rhs1 (stmt);
+ lhs = rhs1;
+ continue;
+ }
+
+ if (rhs_code == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0)) == SSA_NAME
+ && host_integerp (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1))
+ {
+ ret += tree_low_cst (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1);
+ lhs = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
continue;
}
@@ -195,6 +207,7 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
while (lhs)
{
enum tree_code rhs_code;
+ tree rhs1;
if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
break;
@@ -207,21 +220,32 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
stmt = SSA_NAME_DEF_STMT (lhs);
rhs_code = gimple_assign_rhs_code (stmt);
+ rhs1 = gimple_assign_rhs1 (stmt);
if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
|| gimple_assign_cast_p (stmt))
- && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ && TREE_CODE (rhs1) == SSA_NAME)
{
- lhs = gimple_assign_rhs1 (stmt);
+ lhs = rhs1;
continue;
}
if ((rhs_code == POINTER_PLUS_EXPR
|| rhs_code == PLUS_EXPR)
- && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && TREE_CODE (rhs1) == SSA_NAME
&& host_integerp (gimple_assign_rhs2 (stmt), 1))
{
val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1);
- lhs = gimple_assign_rhs1 (stmt);
+ lhs = rhs1;
+ continue;
+ }
+
+ if (rhs_code == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (rhs1, 0)) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0)) == SSA_NAME
+ && host_integerp (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1))
+ {
+ val -= tree_low_cst (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1), 1);
+ lhs = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
continue;
}
@@ -433,9 +457,22 @@ check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs)
if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
return;
- if (TREE_CODE (rhs) != SSA_NAME
- || ! bitmap_bit_p (si->va_list_escape_vars,
- DECL_UID (SSA_NAME_VAR (rhs))))
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ if (! bitmap_bit_p (si->va_list_escape_vars,
+ DECL_UID (SSA_NAME_VAR (rhs))))
+ return;
+ }
+ else if (TREE_CODE (rhs) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)) == SSA_NAME)
+ {
+ if (! bitmap_bit_p (si->va_list_escape_vars,
+ DECL_UID (SSA_NAME_VAR (TREE_OPERAND
+ (TREE_OPERAND (rhs, 0), 0)))))
+ return;
+ }
+ else
return;
if (TREE_CODE (lhs) != SSA_NAME || is_global_var (SSA_NAME_VAR (lhs)))
@@ -512,7 +549,7 @@ check_all_va_list_escapes (struct stdarg_info *si)
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
/* x = *ap_temp; */
- if (gimple_assign_rhs_code (stmt) == MEM_REF
+ if (rhs_code == MEM_REF
&& TREE_OPERAND (rhs, 0) == use
&& TYPE_SIZE_UNIT (TREE_TYPE (rhs))
&& host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
@@ -557,6 +594,16 @@ check_all_va_list_escapes (struct stdarg_info *si)
DECL_UID (lhs)))
continue;
}
+ else if (rhs_code == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF
+ && TREE_OPERAND (TREE_OPERAND (rhs, 0), 0) == use)
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+
+ if (bitmap_bit_p (si->va_list_escape_vars,
+ DECL_UID (SSA_NAME_VAR (lhs))))
+ continue;
+ }
}
if (dump_file && (dump_flags & TDF_DETAILS))