]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa-inline-analysis.c (phi_result_unknown_predicate): New function.
authorMartin Jambor <mjambor@suse.cz>
Fri, 31 Aug 2012 13:48:37 +0000 (15:48 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Fri, 31 Aug 2012 13:48:37 +0000 (15:48 +0200)
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.

From-SVN: r190832

gcc/ChangeLog
gcc/ipa-inline-analysis.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr48636.f90

index e1413eb19d7430b1bc2d2315f069d3194ec886dd..1797ff6e7f9bf0f76fd4dd7249135b3af190c499 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2012-08-31  Martin Jambor  <mjambor@suse.cz>
 
        PR middle-end/54394
index a3f0a8eccf97678bc93a31ea0cc78df977f4c8ff..6da256a614c625e521bfba03367cf005b445cb71 100644 (file)
@@ -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);
index a7edcef577572f2d078d3dcf988dc00de4ea0770..937ba1a2f0b21b459bbd5d4dbf4a1641aba5b6da 100644 (file)
@@ -1,3 +1,7 @@
+2012-08-31  Martin Jambor  <mjambor@suse.cz>
+
+       * gfortran.dg/pr48636.f90: Add dump scan checks.
+
 2012-08-29  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gcc.target/mips/mips.exp: Work out default -msynci setting.
index 44515ae9ad98aa143aeac3f5b42c2bced4c33b6b..b60dcba47bd28a6c0a1ae520144f9ccca8eae799 100644 (file)
@@ -1,5 +1,5 @@
 ! { dg-do compile }
-! { dg-options "-O3 -fdump-ipa-inline" }
+! { dg-options "-O3 -fdump-ipa-inline-details" }
 
 module foo
   implicit none
@@ -34,4 +34,6 @@ program main
 end program main
 
 ! { dg-final { scan-ipa-dump "bar\[^\\n\]*inline copy in MAIN" "inline" } }
+! { dg-final { scan-ipa-dump-times "phi predicate:" 5 "inline" } }
+! { dg-final { scan-ipa-dump "inline hints: loop_iterations" "inline" } }
 ! { dg-final { cleanup-ipa-dump "inline" } }