diff options
Diffstat (limited to 'gcc/tree-stdarg.c')
-rw-r--r-- | gcc/tree-stdarg.c | 227 |
1 files changed, 110 insertions, 117 deletions
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index f9228872dc2..96a72fad08e 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -112,7 +112,8 @@ static unsigned HOST_WIDE_INT va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs, bool gpr_p) { - tree stmt, lhs, orig_lhs; + tree lhs, orig_lhs; + gimple stmt; unsigned HOST_WIDE_INT ret = 0, val, counter_val; unsigned int max_size; @@ -130,6 +131,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs, orig_lhs = lhs = rhs; while (lhs) { + enum tree_code rhs_code; + if (si->offsets[SSA_NAME_VERSION (lhs)] != -1) { if (counter_val >= max_size) @@ -144,38 +147,32 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs, stmt = SSA_NAME_DEF_STMT (lhs); - if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT - || GIMPLE_STMT_OPERAND (stmt, 0) != lhs) + if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs) return (unsigned HOST_WIDE_INT) -1; - rhs = GIMPLE_STMT_OPERAND (stmt, 1); - if (TREE_CODE (rhs) == WITH_SIZE_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - if (TREE_CODE (rhs) == SSA_NAME) + rhs_code = gimple_assign_rhs_code (stmt); + if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS + || gimple_assign_cast_p (stmt)) + && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME) { - lhs = rhs; + lhs = gimple_assign_rhs1 (stmt); continue; } - if (CONVERT_EXPR_P (rhs) - && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME) + if ((rhs_code == POINTER_PLUS_EXPR + || rhs_code == PLUS_EXPR) + && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME + && host_integerp (gimple_assign_rhs2 (stmt), 1)) { - lhs = TREE_OPERAND (rhs, 0); + ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1); + lhs = gimple_assign_rhs1 (stmt); continue; } - if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR - || TREE_CODE (rhs) == PLUS_EXPR) - && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME - && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST - && host_integerp (TREE_OPERAND (rhs, 1), 1)) - { - ret += tree_low_cst (TREE_OPERAND (rhs, 1), 1); - lhs = TREE_OPERAND (rhs, 0); - continue; - } + if (get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS) + return (unsigned HOST_WIDE_INT) -1; + rhs = gimple_assign_rhs1 (stmt); if (TREE_CODE (counter) != TREE_CODE (rhs)) return (unsigned HOST_WIDE_INT) -1; @@ -196,6 +193,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs, val = ret + counter_val; while (lhs) { + enum tree_code rhs_code; + if (si->offsets[SSA_NAME_VERSION (lhs)] != -1) break; @@ -206,31 +205,22 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs, stmt = SSA_NAME_DEF_STMT (lhs); - rhs = GIMPLE_STMT_OPERAND (stmt, 1); - if (TREE_CODE (rhs) == WITH_SIZE_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - if (TREE_CODE (rhs) == SSA_NAME) + rhs_code = gimple_assign_rhs_code (stmt); + if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS + || gimple_assign_cast_p (stmt)) + && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME) { - lhs = rhs; + lhs = gimple_assign_rhs1 (stmt); continue; } - if (CONVERT_EXPR_P (rhs) - && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME) + if ((rhs_code == POINTER_PLUS_EXPR + || rhs_code == PLUS_EXPR) + && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME + && host_integerp (gimple_assign_rhs2 (stmt), 1)) { - lhs = TREE_OPERAND (rhs, 0); - continue; - } - - if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR - || TREE_CODE (rhs) == PLUS_EXPR) - && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME - && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST - && host_integerp (TREE_OPERAND (rhs, 1), 1)) - { - val -= tree_low_cst (TREE_OPERAND (rhs, 1), 1); - lhs = TREE_OPERAND (rhs, 0); + val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1); + lhs = gimple_assign_rhs1 (stmt); continue; } @@ -247,7 +237,7 @@ static tree find_va_list_reference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data) { - bitmap va_list_vars = (bitmap) data; + bitmap va_list_vars = (bitmap) ((struct walk_stmt_info *) data)->info; tree var = *tp; if (TREE_CODE (var) == SSA_NAME) @@ -442,12 +432,6 @@ check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs) if (! POINTER_TYPE_P (TREE_TYPE (rhs))) return; - if (((TREE_CODE (rhs) == POINTER_PLUS_EXPR - || TREE_CODE (rhs) == PLUS_EXPR) - && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST) - || CONVERT_EXPR_P (rhs)) - rhs = TREE_OPERAND (rhs, 0); - if (TREE_CODE (rhs) != SSA_NAME || ! bitmap_bit_p (si->va_list_escape_vars, DECL_UID (SSA_NAME_VAR (rhs)))) @@ -504,11 +488,12 @@ check_all_va_list_escapes (struct stdarg_info *si) FOR_EACH_BB (bb) { - block_stmt_iterator i; + gimple_stmt_iterator i; - for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i)) + for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) { - tree stmt = bsi_stmt (i), use; + gimple stmt = gsi_stmt (i); + tree use; ssa_op_iter iter; FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES) @@ -517,16 +502,13 @@ check_all_va_list_escapes (struct stdarg_info *si) DECL_UID (SSA_NAME_VAR (use)))) continue; - if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) + if (is_gimple_assign (stmt)) { - tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); - tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); - - if (TREE_CODE (rhs) == WITH_SIZE_EXPR) - rhs = TREE_OPERAND (rhs, 0); + tree rhs = gimple_assign_rhs1 (stmt); + enum tree_code rhs_code = gimple_assign_rhs_code (stmt); /* x = *ap_temp; */ - if (TREE_CODE (rhs) == INDIRECT_REF + if (gimple_assign_rhs_code (stmt) == INDIRECT_REF && TREE_OPERAND (rhs, 0) == use && TYPE_SIZE_UNIT (TREE_TYPE (rhs)) && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1) @@ -550,13 +532,16 @@ check_all_va_list_escapes (struct stdarg_info *si) other_ap_temp = (some_type *) ap_temp; ap = ap_temp; statements. */ - if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR - && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST) - || CONVERT_EXPR_P (rhs)) - rhs = TREE_OPERAND (rhs, 0); - - if (rhs == use) + if (rhs == use + && ((rhs_code == POINTER_PLUS_EXPR + && (TREE_CODE (gimple_assign_rhs2 (stmt)) + == INTEGER_CST)) + || gimple_assign_cast_p (stmt) + || (get_gimple_rhs_class (rhs_code) + == GIMPLE_SINGLE_RHS))) { + tree lhs = gimple_assign_lhs (stmt); + if (TREE_CODE (lhs) == SSA_NAME && bitmap_bit_p (si->va_list_escape_vars, DECL_UID (SSA_NAME_VAR (lhs)))) @@ -572,7 +557,7 @@ check_all_va_list_escapes (struct stdarg_info *si) if (dump_file && (dump_flags & TDF_DETAILS)) { fputs ("va_list escapes in ", dump_file); - print_generic_expr (dump_file, stmt, dump_flags); + print_gimple_stmt (dump_file, stmt, 0, dump_flags); fputc ('\n', dump_file); } return true; @@ -604,6 +589,7 @@ execute_optimize_stdarg (void) bool va_list_escapes = false; bool va_list_simple_ptr; struct stdarg_info si; + struct walk_stmt_info wi; const char *funcname = NULL; tree cfun_va_list; @@ -624,18 +610,17 @@ execute_optimize_stdarg (void) FOR_EACH_BB (bb) { - block_stmt_iterator i; + gimple_stmt_iterator i; - for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i)) + for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) { - tree stmt = bsi_stmt (i); - tree call = get_call_expr_in (stmt), callee; - tree ap; + gimple stmt = gsi_stmt (i); + tree callee, ap; - if (!call) + if (!is_gimple_call (stmt)) continue; - callee = get_callee_fndecl (call); + callee = gimple_call_fndecl (stmt); if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL) continue; @@ -655,7 +640,7 @@ execute_optimize_stdarg (void) } si.va_start_count++; - ap = CALL_EXPR_ARG (call, 0); + ap = gimple_call_arg (stmt, 0); if (TREE_CODE (ap) != ADDR_EXPR) { @@ -731,10 +716,12 @@ execute_optimize_stdarg (void) cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE; calculate_dominance_info (CDI_DOMINATORS); + memset (&wi, 0, sizeof (wi)); + wi.info = si.va_list_vars; FOR_EACH_BB (bb) { - block_stmt_iterator i; + gimple_stmt_iterator i; si.compute_sizes = -1; si.bb = bb; @@ -745,12 +732,13 @@ execute_optimize_stdarg (void) any real data movement. */ if (va_list_simple_ptr) { - tree phi, lhs, rhs; + tree lhs, rhs; use_operand_p uop; ssa_op_iter soi; - for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) + for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i)) { + gimple phi = gsi_stmt (i); lhs = PHI_RESULT (phi); if (!is_gimple_reg (lhs)) @@ -766,14 +754,12 @@ execute_optimize_stdarg (void) else check_va_list_escapes (&si, lhs, rhs); - if (si.va_list_escapes - || walk_tree (&phi, find_va_list_reference, - si.va_list_vars, NULL)) + if (si.va_list_escapes) { if (dump_file && (dump_flags & TDF_DETAILS)) { fputs ("va_list escapes in ", dump_file); - print_generic_expr (dump_file, phi, dump_flags); + print_gimple_stmt (dump_file, phi, 0, dump_flags); fputc ('\n', dump_file); } va_list_escapes = true; @@ -782,18 +768,16 @@ execute_optimize_stdarg (void) } } - for (i = bsi_start (bb); - !bsi_end_p (i) && !va_list_escapes; - bsi_next (&i)) + for (i = gsi_start_bb (bb); + !gsi_end_p (i) && !va_list_escapes; + gsi_next (&i)) { - tree stmt = bsi_stmt (i); - tree call; + gimple stmt = gsi_stmt (i); /* Don't look at __builtin_va_{start,end}, they are ok. */ - call = get_call_expr_in (stmt); - if (call) + if (is_gimple_call (stmt)) { - tree callee = get_callee_fndecl (call); + tree callee = gimple_call_fndecl (stmt); if (callee && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL @@ -802,44 +786,54 @@ execute_optimize_stdarg (void) continue; } - if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT) + if (is_gimple_assign (stmt)) { - tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); - tree rhs = GIMPLE_STMT_OPERAND (stmt, 1); - - if (TREE_CODE (rhs) == WITH_SIZE_EXPR) - rhs = TREE_OPERAND (rhs, 0); + tree lhs = gimple_assign_lhs (stmt); + tree rhs = gimple_assign_rhs1 (stmt); if (va_list_simple_ptr) { - /* Check for tem = ap. */ - if (va_list_ptr_read (&si, rhs, lhs)) - continue; + if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) + == GIMPLE_SINGLE_RHS) + { + /* Check for tem = ap. */ + if (va_list_ptr_read (&si, rhs, lhs)) + continue; - /* Check for the last insn in: - tem1 = ap; - tem2 = tem1 + CST; - ap = tem2; - sequence. */ - else if (va_list_ptr_write (&si, lhs, rhs)) - continue; + /* Check for the last insn in: + tem1 = ap; + tem2 = tem1 + CST; + ap = tem2; + sequence. */ + else if (va_list_ptr_write (&si, lhs, rhs)) + continue; + } - else + if ((gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR + && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST) + || IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)) + || (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) + == GIMPLE_SINGLE_RHS)) check_va_list_escapes (&si, lhs, rhs); } else { - /* Check for ap[0].field = temp. */ - if (va_list_counter_struct_op (&si, lhs, rhs, true)) - continue; + if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) + == GIMPLE_SINGLE_RHS) + { + /* Check for ap[0].field = temp. */ + if (va_list_counter_struct_op (&si, lhs, rhs, true)) + continue; - /* Check for temp = ap[0].field. */ - else if (va_list_counter_struct_op (&si, rhs, lhs, false)) - continue; + /* Check for temp = ap[0].field. */ + else if (va_list_counter_struct_op (&si, rhs, lhs, + false)) + continue; + } /* Do any architecture specific checking. */ - else if (targetm.stdarg_optimize_hook - && targetm.stdarg_optimize_hook (&si, lhs, rhs)) + if (targetm.stdarg_optimize_hook + && targetm.stdarg_optimize_hook (&si, stmt)) continue; } } @@ -851,13 +845,12 @@ execute_optimize_stdarg (void) fully), or some unexpected use of va_list. None of these should happen in a gimplified VA_ARG_EXPR. */ if (si.va_list_escapes - || walk_tree (&stmt, find_va_list_reference, - si.va_list_vars, NULL)) + || walk_gimple_op (stmt, find_va_list_reference, &wi)) { if (dump_file && (dump_flags & TDF_DETAILS)) { fputs ("va_list escapes in ", dump_file); - print_generic_expr (dump_file, stmt, dump_flags); + print_gimple_stmt (dump_file, stmt, 0, dump_flags); fputc ('\n', dump_file); } va_list_escapes = true; |