]> gcc.gnu.org Git - gcc.git/commitdiff
ipa-inline-analysis.c (find_foldable_builtin_expect): Find the candidate of builtin_e...
authorRong Xu <xur@google.com>
Thu, 3 Oct 2013 17:15:56 +0000 (17:15 +0000)
committerRong Xu <xur@gcc.gnu.org>
Thu, 3 Oct 2013 17:15:56 +0000 (17:15 +0000)
        * ipa-inline-analysis.c (find_foldable_builtin_expect): Find
        the candidate of builtin_expect such that we should fix the
        size/time estimation.
        (estimate_function_body_sizes): Do the acutally size/time fix-up
        for builtin_expect.

From-SVN: r203168

gcc/ChangeLog
gcc/ipa-inline-analysis.c

index c5ffb64ff05e91171e566df8f8155f0054875468..f6c57ff0b9865801be3ba8d9465cda52aaec2dc2 100644 (file)
@@ -1,3 +1,11 @@
+2013-10-03  Rong Xu  <xur@google.com>
+
+        * ipa-inline-analysis.c (find_foldable_builtin_expect): Find
+        the candidate of builtin_expect such that we should fix the 
+        size/time estimation.
+        (estimate_function_body_sizes): Do the acutally size/time fix-up
+        for builtin_expect.
+
 2013-10-03  Rong Xu  <xur@google.com>
 
         * predict.c (tree_predict_by_opcode): Get the probability
index 7ca09ad0b916043a9fab0d297d64d96ff82067ec..304f9f5d7cc8a03c8fc16187cb049c6bc3a21df2 100644 (file)
@@ -2257,6 +2257,77 @@ array_index_predicate (struct inline_summary *info,
   return p;
 }
 
+/* For a typical usage of __builtin_expect (a<b, 1), we
+   may introduce an extra relation stmt:
+   With the builtin, we have
+     t1 = a <= b;
+     t2 = (long int) t1;
+     t3 = __builtin_expect (t2, 1);
+     if (t3 != 0)
+       goto ...
+   Without the builtin, we have
+     if (a<=b)
+       goto...
+   This affects the size/time estimation and may have
+   an impact on the earlier inlining.
+   Here find this pattern and fix it up later.  */
+
+static gimple
+find_foldable_builtin_expect (basic_block bb)
+{
+  gimple_stmt_iterator bsi;
+
+  for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+    {
+      gimple stmt = gsi_stmt (bsi);
+      if (gimple_call_builtin_p (stmt, BUILT_IN_EXPECT))
+        {
+          tree var = gimple_call_lhs (stmt);
+          tree arg = gimple_call_arg (stmt, 0);
+          use_operand_p use_p;
+          gimple use_stmt;
+          bool match = false;
+          bool done = false;
+
+          if (!var || !arg)
+            continue;
+          gcc_assert (TREE_CODE (var) == SSA_NAME);
+
+          while (TREE_CODE (arg) == SSA_NAME)
+            {
+              gimple stmt_tmp = SSA_NAME_DEF_STMT (arg);
+              if (!is_gimple_assign (stmt_tmp))
+                break;
+              switch (gimple_assign_rhs_code (stmt_tmp))
+                {
+                  case LT_EXPR:
+                  case LE_EXPR:
+                  case GT_EXPR:
+                  case GE_EXPR:
+                  case EQ_EXPR:
+                  case NE_EXPR:
+                    match = true;
+                    done = true;
+                    break;
+                  case NOP_EXPR:
+                    break;
+                  default:
+                    done = true;
+                    break;
+                }
+              if (done)
+                break;
+              arg = gimple_assign_rhs1 (stmt_tmp);
+            }
+
+          if (match && single_imm_use (var, &use_p, &use_stmt)
+              && gimple_code (use_stmt) == GIMPLE_COND)
+            return use_stmt;
+        }
+    }
+  return NULL;
+}
+
 /* Compute function body size parameters for NODE.
    When EARLY is true, we compute only simple summaries without
    non-trivial predicates to drive the early inliner.  */
@@ -2280,6 +2351,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
   int nblocks, n;
   int *order;
   predicate array_index = true_predicate ();
+  gimple fix_builtin_expect_stmt;
 
   info->conds = NULL;
   info->entry = NULL;
@@ -2360,6 +2432,8 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
            }
        }
 
+      fix_builtin_expect_stmt = find_foldable_builtin_expect (bb);
+
       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
        {
          gimple stmt = gsi_stmt (bsi);
@@ -2368,6 +2442,14 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
          int prob;
          struct predicate will_be_nonconstant;
 
+          /* This relation stmt should be folded after we remove
+             buildin_expect call. Adjust the cost here.  */
+         if (stmt == fix_builtin_expect_stmt)
+            {
+              this_size--;
+              this_time--;
+            }
+
          if (dump_file && (dump_flags & TDF_DETAILS))
            {
              fprintf (dump_file, "  ");
This page took 0.077979 seconds and 5 git commands to generate.