summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-31 13:48:37 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-31 13:48:37 +0000
commit326917910938d193fef3434d9ecb527357205d2f (patch)
tree237d85e081f17a050ed81ade517a55c808bd9163 /gcc/ipa-inline-analysis.c
parent4b209fe798bc04bcef1ee7b29cf7af29c407931e (diff)
downloadgcc-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.c118
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);