diff options
author | Richard Guenther <rguenther@suse.de> | 2011-03-23 16:02:30 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-03-23 16:02:30 +0000 |
commit | 58da96fef9d3d98154968670f1b15dc5b8e116d9 (patch) | |
tree | fe05c89a37d45ba1355ef827a99ed207a13c1599 /gcc/tree-stdarg.c | |
parent | b8beb4d13e5c51a50507cb2be345773fa162fce7 (diff) | |
download | gcc-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.c | 71 |
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)) |