Mercurial > hg > CbC > CbC_gcc
diff gcc/value-prof.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/value-prof.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/value-prof.c Tue Mar 22 17:18:12 2011 +0900 @@ -1,5 +1,5 @@ /* Transformations based on profile information for values. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -45,11 +45,8 @@ #include "cgraph.h" #include "timevar.h" #include "tree-pass.h" -#include "toplev.h" #include "pointer-set.h" -static struct value_prof_hooks *value_prof_hooks; - /* In this file value profile based optimizations are placed. Currently the following optimizations are implemented (for more detailed descriptions see comments at value_profile_transformations): @@ -375,7 +372,7 @@ histogram_value hist = *(histogram_value *) slot; if (!pointer_set_contains (visited, hist)) { - error ("Dead histogram"); + error ("dead histogram"); dump_histogram_value (stderr, hist); debug_gimple_stmt (hist->hvalue.stmt); error_found = true; @@ -386,7 +383,7 @@ /* Verify sanity of the histograms. */ -void +DEBUG_FUNCTION void verify_histograms (void) { basic_block bb; @@ -466,7 +463,7 @@ : DECL_SOURCE_LOCATION (current_function_decl); if (flag_profile_correction) { - inform (locus, "Correcting inconsistent value profile: " + inform (locus, "correcting inconsistent value profile: " "%s profiler overall count (%d) does not match BB count " "(%d)", name, (int)*all, (int)bb_count); *all = bb_count; @@ -476,9 +473,13 @@ } else { - error_at (locus, "Corrupted value profile: %s " - "profiler overall count (%d) does not match BB count (%d)", - name, (int)*all, (int)bb_count); + error_at (locus, "corrupted value profile: %s " + "profile counter (%d out of %d) inconsistent with " + "basic-block count (%d)", + name, + (int) *count, + (int) *all, + (int) bb_count); return true; } } @@ -489,7 +490,7 @@ /* GIMPLE based transformations. */ -static bool +bool gimple_value_profile_transformations (void) { basic_block bb; @@ -558,7 +559,7 @@ gcov_type all) { gimple stmt1, stmt2, stmt3; - tree tmp1, tmp2, tmpv; + tree tmp0, tmp1, tmp2, tmpv; gimple bb1end, bb2end, bb3end; basic_block bb, bb2, bb3, bb4; tree optype, op1, op2; @@ -576,19 +577,22 @@ bb = gimple_bb (stmt); gsi = gsi_for_stmt (stmt); - tmpv = create_tmp_var (optype, "PROF"); - tmp1 = create_tmp_var (optype, "PROF"); - stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value)); + tmpv = create_tmp_reg (optype, "PROF"); + tmp0 = make_ssa_name (tmpv, NULL); + tmp1 = make_ssa_name (tmpv, NULL); + stmt1 = gimple_build_assign (tmp0, fold_convert (optype, value)); + SSA_NAME_DEF_STMT (tmp0) = stmt1; stmt2 = gimple_build_assign (tmp1, op2); - stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE); + SSA_NAME_DEF_STMT (tmp1) = stmt2; + stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT); bb1end = stmt3; - tmp2 = create_tmp_var (optype, "PROF"); + tmp2 = make_rename_temp (optype, "PROF"); stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2, - op1, tmpv); + op1, tmp0); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); bb2end = stmt1; @@ -699,6 +703,7 @@ } gimple_assign_set_rhs_from_tree (si, result); + update_stmt (gsi_stmt (*si)); return true; } @@ -711,7 +716,7 @@ gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all) { gimple stmt1, stmt2, stmt3, stmt4; - tree tmp2, tmp3; + tree tmp2, tmp3, tmpv; gimple bb1end, bb2end, bb3end; basic_block bb, bb2, bb3, bb4; tree optype, op1, op2; @@ -729,12 +734,15 @@ bb = gimple_bb (stmt); gsi = gsi_for_stmt (stmt); - result = create_tmp_var (optype, "PROF"); - tmp2 = create_tmp_var (optype, "PROF"); - tmp3 = create_tmp_var (optype, "PROF"); + result = make_rename_temp (optype, "PROF"); + tmpv = create_tmp_var (optype, "PROF"); + tmp2 = make_ssa_name (tmpv, NULL); + tmp3 = make_ssa_name (tmpv, NULL); stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2, build_int_cst (optype, -1)); + SSA_NAME_DEF_STMT (tmp2) = stmt2; stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2); + SSA_NAME_DEF_STMT (tmp3) = stmt3; stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0), NULL_TREE, NULL_TREE); gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); @@ -845,6 +853,7 @@ result = gimple_mod_pow2 (stmt, prob, count, all); gimple_assign_set_rhs_from_tree (si, result); + update_stmt (gsi_stmt (*si)); return true; } @@ -881,10 +890,11 @@ bb = gimple_bb (stmt); gsi = gsi_for_stmt (stmt); - result = create_tmp_var (optype, "PROF"); - tmp1 = create_tmp_var (optype, "PROF"); + result = make_rename_temp (optype, "PROF"); + tmp1 = make_ssa_name (create_tmp_var (optype, "PROF"), NULL); stmt1 = gimple_build_assign (result, op1); stmt2 = gimple_build_assign (tmp1, op2); + SSA_NAME_DEF_STMT (tmp1) = stmt2; stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT); @@ -1044,6 +1054,7 @@ result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all); gimple_assign_set_rhs_from_tree (si, result); + update_stmt (gsi_stmt (*si)); return true; } @@ -1092,7 +1103,7 @@ int prob, gcov_type count, gcov_type all) { gimple dcall_stmt, load_stmt, cond_stmt; - tree tmp1, tmpv, tmp; + tree tmp0, tmp1, tmpv, tmp; basic_block cond_bb, dcall_bb, icall_bb, join_bb; tree optype = build_pointer_type (void_type_node); edge e_cd, e_ci, e_di, e_dj, e_ij; @@ -1102,20 +1113,26 @@ cond_bb = gimple_bb (icall_stmt); gsi = gsi_for_stmt (icall_stmt); - tmpv = create_tmp_var (optype, "PROF"); - tmp1 = create_tmp_var (optype, "PROF"); + tmpv = create_tmp_reg (optype, "PROF"); + tmp0 = make_ssa_name (tmpv, NULL); + tmp1 = make_ssa_name (tmpv, NULL); tmp = unshare_expr (gimple_call_fn (icall_stmt)); - load_stmt = gimple_build_assign (tmpv, tmp); + load_stmt = gimple_build_assign (tmp0, tmp); + SSA_NAME_DEF_STMT (tmp0) = load_stmt; gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); tmp = fold_convert (optype, build_addr (direct_call->decl, current_function_decl)); load_stmt = gimple_build_assign (tmp1, tmp); + SSA_NAME_DEF_STMT (tmp1) = load_stmt; gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); - cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE); + cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); + gimple_set_vdef (icall_stmt, NULL_TREE); + gimple_set_vuse (icall_stmt, NULL_TREE); + update_stmt (icall_stmt); dcall_stmt = gimple_copy (icall_stmt); gimple_call_set_fndecl (dcall_stmt, direct_call->decl); gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT); @@ -1130,7 +1147,16 @@ icall_bb = e_di->dest; icall_bb->count = all - count; - e_ij = split_block (icall_bb, icall_stmt); + /* Do not disturb existing EH edges from the indirect call. */ + if (!stmt_ends_bb_p (icall_stmt)) + e_ij = split_block (icall_bb, icall_stmt); + else + { + e_ij = find_fallthru_edge (icall_bb->succs); + e_ij->probability = REG_BR_PROB_BASE; + e_ij->count = all - count; + e_ij = single_pred_edge (split_edge (e_ij)); + } join_bb = e_ij->dest; join_bb->count = all; @@ -1151,21 +1177,42 @@ e_ij->probability = REG_BR_PROB_BASE; e_ij->count = all - count; - /* Fix eh edges */ + /* Insert PHI node for the call result if necessary. */ + if (gimple_call_lhs (icall_stmt) + && TREE_CODE (gimple_call_lhs (icall_stmt)) == SSA_NAME) + { + tree result = gimple_call_lhs (icall_stmt); + gimple phi = create_phi_node (result, join_bb); + SSA_NAME_DEF_STMT (result) = phi; + gimple_call_set_lhs (icall_stmt, + make_ssa_name (SSA_NAME_VAR (result), icall_stmt)); + add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); + gimple_call_set_lhs (dcall_stmt, + make_ssa_name (SSA_NAME_VAR (result), dcall_stmt)); + add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION); + } + + /* Build an EH edge for the direct call if necessary. */ lp_nr = lookup_stmt_eh_lp (icall_stmt); - if (lp_nr != 0) + if (lp_nr != 0 + && stmt_could_throw_p (dcall_stmt)) { - if (stmt_could_throw_p (dcall_stmt)) + edge e_eh, e; + edge_iterator ei; + gimple_stmt_iterator psi; + + add_stmt_to_eh_lp (dcall_stmt, lp_nr); + FOR_EACH_EDGE (e_eh, ei, icall_bb->succs) + if (e_eh->flags & EDGE_EH) + break; + e = make_edge (dcall_bb, e_eh->dest, EDGE_EH); + for (psi = gsi_start_phis (e_eh->dest); + !gsi_end_p (psi); gsi_next (&psi)) { - add_stmt_to_eh_lp (dcall_stmt, lp_nr); - make_eh_edges (dcall_stmt); + gimple phi = gsi_stmt (psi); + SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), + PHI_ARG_DEF_FROM_EDGE (phi, e_eh)); } - - gcc_assert (stmt_could_throw_p (icall_stmt)); - make_eh_edges (icall_stmt); - - /* The old EH edges are sill on the join BB, purge them. */ - gimple_purge_dead_eh_edges (join_bb); } return dcall_stmt; @@ -1289,7 +1336,7 @@ gcov_type count, gcov_type all) { gimple tmp_stmt, cond_stmt, icall_stmt; - tree tmp1, tmpv, vcall_size, optype; + tree tmp0, tmp1, tmpv, vcall_size, optype; basic_block cond_bb, icall_bb, vcall_bb, join_bb; edge e_ci, e_cv, e_iv, e_ij, e_vj; gimple_stmt_iterator gsi; @@ -1307,16 +1354,22 @@ optype = TREE_TYPE (vcall_size); tmpv = create_tmp_var (optype, "PROF"); - tmp1 = create_tmp_var (optype, "PROF"); - tmp_stmt = gimple_build_assign (tmpv, fold_convert (optype, icall_size)); + tmp0 = make_ssa_name (tmpv, NULL); + tmp1 = make_ssa_name (tmpv, NULL); + tmp_stmt = gimple_build_assign (tmp0, fold_convert (optype, icall_size)); + SSA_NAME_DEF_STMT (tmp0) = tmp_stmt; gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); tmp_stmt = gimple_build_assign (tmp1, vcall_size); + SSA_NAME_DEF_STMT (tmp1) = tmp_stmt; gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT); - cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE); + cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmp0, NULL_TREE, NULL_TREE); gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT); + gimple_set_vdef (vcall_stmt, NULL); + gimple_set_vuse (vcall_stmt, NULL); + update_stmt (vcall_stmt); icall_stmt = gimple_copy (vcall_stmt); gimple_call_set_arg (icall_stmt, size_arg, icall_size); gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT); @@ -1352,6 +1405,21 @@ e_vj->probability = REG_BR_PROB_BASE; e_vj->count = all - count; + /* Insert PHI node for the call result if necessary. */ + if (gimple_call_lhs (vcall_stmt) + && TREE_CODE (gimple_call_lhs (vcall_stmt)) == SSA_NAME) + { + tree result = gimple_call_lhs (vcall_stmt); + gimple phi = create_phi_node (result, join_bb); + SSA_NAME_DEF_STMT (result) = phi; + gimple_call_set_lhs (vcall_stmt, + make_ssa_name (SSA_NAME_VAR (result), vcall_stmt)); + add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION); + gimple_call_set_lhs (icall_stmt, + make_ssa_name (SSA_NAME_VAR (result), icall_stmt)); + add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION); + } + /* Because these are all string op builtins, they're all nothrow. */ gcc_assert (!stmt_could_throw_p (vcall_stmt)); gcc_assert (!stmt_could_throw_p (icall_stmt)); @@ -1494,14 +1562,6 @@ } } -struct value_prof_hooks { - /* Find list of values for which we want to measure histograms. */ - void (*find_values_to_profile) (histogram_values *); - - /* Identify and exploit properties of values that are hard to analyze - statically. See value-prof.c for more detail. */ - bool (*value_profile_transformations) (void); -}; /* Find values inside STMT for that we want to measure histograms for division/modulo optimization. */ @@ -1635,7 +1695,7 @@ } } -static void +void gimple_find_values_to_profile (histogram_values *values) { basic_block bb; @@ -1648,7 +1708,7 @@ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) gimple_values_to_profile (gsi_stmt (gsi), values); - for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++) + FOR_EACH_VEC_ELT (histogram_value, *values, i, hist) { switch (hist->type) { @@ -1692,28 +1752,3 @@ } } -static struct value_prof_hooks gimple_value_prof_hooks = { - gimple_find_values_to_profile, - gimple_value_profile_transformations -}; - -void -gimple_register_value_prof_hooks (void) -{ - gcc_assert (current_ir_type () == IR_GIMPLE); - value_prof_hooks = &gimple_value_prof_hooks; -} - -/* IR-independent entry points. */ -void -find_values_to_profile (histogram_values *values) -{ - (value_prof_hooks->find_values_to_profile) (values); -} - -bool -value_profile_transformations (void) -{ - return (value_prof_hooks->value_profile_transformations) (); -} -