diff options
author | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-31 13:48:37 +0000 |
---|---|---|
committer | jamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-31 13:48:37 +0000 |
commit | 326917910938d193fef3434d9ecb527357205d2f (patch) | |
tree | 237d85e081f17a050ed81ade517a55c808bd9163 /gcc/ipa-inline-analysis.c | |
parent | 4b209fe798bc04bcef1ee7b29cf7af29c407931e (diff) | |
download | gcc-326917910938d193fef3434d9ecb527357205d2f.tar.gz |
2012-08-31 Martin Jambor <mjambor@suse.cz>
* ipa-inline-analysis.c (phi_result_unknown_predicate): New function.
(predicate_for_phi_result): Likewise.
(estimate_function_body_sizes): Use the above two functions.
* testsuite/gfortran.dg/pr48636.f90: Add dump scan checks.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190832 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r-- | gcc/ipa-inline-analysis.c | 118 |
1 files changed, 117 insertions, 1 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index a3f0a8eccf9..6da256a614c 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -2070,6 +2070,99 @@ param_change_prob (gimple stmt, int i) return REG_BR_PROB_BASE; } +/* Find whether a basic block BB is the final block of a (half) diamond CFG + sub-graph and if the predicate the condition depends on is known. If so, + return true and store the pointer the predicate in *P. */ + +static bool +phi_result_unknown_predicate (struct ipa_node_params *info, + struct inline_summary *summary, basic_block bb, + struct predicate *p, + VEC (predicate_t, heap) *nonconstant_names) +{ + edge e; + edge_iterator ei; + basic_block first_bb = NULL; + gimple stmt; + + if (single_pred_p (bb)) + { + *p = false_predicate (); + return true; + } + + FOR_EACH_EDGE (e, ei, bb->preds) + { + if (single_succ_p (e->src)) + { + if (!single_pred_p (e->src)) + return false; + if (!first_bb) + first_bb = single_pred (e->src); + else if (single_pred (e->src) != first_bb) + return false; + } + else + { + if (!first_bb) + first_bb = e->src; + else if (e->src != first_bb) + return false; + } + } + + if (!first_bb) + return false; + + stmt = last_stmt (first_bb); + if (!stmt + || gimple_code (stmt) != GIMPLE_COND + || !is_gimple_ip_invariant (gimple_cond_rhs (stmt))) + return false; + + *p = will_be_nonconstant_expr_predicate (info, summary, + gimple_cond_lhs (stmt), + nonconstant_names); + if (true_predicate_p (p)) + return false; + else + return true; +} + +/* Given a PHI statement in a function described by inline properties SUMMARY + and *P being the predicate describing whether the selected PHI argument is + known, store a predicate for the result of the PHI statement into + NONCONSTANT_NAMES, if possible. */ + +static void +predicate_for_phi_result (struct inline_summary *summary, gimple phi, + struct predicate *p, + VEC (predicate_t, heap) *nonconstant_names) +{ + unsigned i; + + for (i = 0; i < gimple_phi_num_args (phi); i++) + { + tree arg = gimple_phi_arg (phi, i)->def; + if (!is_gimple_min_invariant (arg)) + { + gcc_assert (TREE_CODE (arg) == SSA_NAME); + *p = or_predicates (summary->conds, p, + &VEC_index (predicate_t, nonconstant_names, + SSA_NAME_VERSION (arg))); + if (true_predicate_p (p)) + return; + } + } + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "\t\tphi predicate: "); + dump_predicate (dump_file, summary->conds, p); + } + VEC_replace (predicate_t, nonconstant_names, + SSA_NAME_VERSION (gimple_phi_result (phi)), *p); +} /* Compute function body size parameters for NODE. When EARLY is true, we compute only simple summaries without @@ -2143,7 +2236,30 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early) fprintf (dump_file, "\n BB %i predicate:", bb->index); dump_predicate (dump_file, info->conds, &bb_predicate); } - + + if (parms_info && nonconstant_names) + { + struct predicate phi_predicate; + bool first_phi = true; + + for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + { + if (first_phi + && !phi_result_unknown_predicate (parms_info, info, bb, + &phi_predicate, + nonconstant_names)) + break; + first_phi = false; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, " "); + print_gimple_stmt (dump_file, gsi_stmt (bsi), 0, 0); + } + predicate_for_phi_result (info, gsi_stmt (bsi), &phi_predicate, + nonconstant_names); + } + } + for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) { gimple stmt = gsi_stmt (bsi); |