re PR ipa/64801 (kernel build failure due to ICF)
authorJan Hubicka <hubicka@ucw.cz>
Thu, 29 Jan 2015 07:43:14 +0000 (08:43 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 29 Jan 2015 07:43:14 +0000 (07:43 +0000)
PR ipa/64801
* gcc.dg/tree-ssa/pr64801.c: New testcase.
* cgraphunit.c (init_lowered_empty_function): Add CoUNT parameter;
make sane BB profile.
(cgraph_node::expand_thunk): Make sane BB profile.
(cgraph_node::create_wrapper): Do not set call_stmt_cannot_inline_p.
* cgraph.h (init_lowered_empty_function): Update prototype.
* config/i386/i386.c (make_resolver_func): Update call.
* predict.c (gate): Disable branch prediction pass if
profile is already there.

From-SVN: r220230

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphunit.c
gcc/config/i386/i386.c
gcc/predict.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr64801.c [new file with mode: 0644]

index f46d755b595ff3d5eee693237e35961e6cb40e2c..1471b218cf03e0fa3cb1cc171bd7b19bfb51357d 100644 (file)
@@ -1,3 +1,15 @@
+2015-01-29  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/64801
+       * cgraphunit.c (init_lowered_empty_function): Add CoUNT parameter;
+       make sane BB profile.
+       (cgraph_node::expand_thunk): Make sane BB profile.
+       (cgraph_node::create_wrapper): Do not set call_stmt_cannot_inline_p.
+       * cgraph.h (init_lowered_empty_function): Update prototype.
+       * config/i386/i386.c (make_resolver_func): Update call.
+       * predict.c (gate): Disable branch prediction pass if
+       profile is already there.
+
 2015-01-29  Jan Hubicka  <hubicka@ucw.cz>
 
        * optc-save-gen.awk: flag_fp_contract_mode is no longer speical.
index e3e29d0be5c033f2b59bebee061ba30f732c11a2..40e6c6c767c51513ff9d009d7028d9ab6cb889b0 100644 (file)
@@ -2194,7 +2194,7 @@ void cgraphunit_c_finalize (void);
 
 /*  Initialize datastructures so DECL is a function in lowered gimple form.
     IN_SSA is true if the gimple is in SSA.  */
-basic_block init_lowered_empty_function (tree, bool);
+basic_block init_lowered_empty_function (tree, bool, gcov_type);
 
 /* In cgraphclones.c  */
 
index bde3e420a7130fea58b1dffa7d148adb8fa22e01..a2650f724c1db9476fbebff4f6d5a231ecfa91c2 100644 (file)
@@ -1325,9 +1325,10 @@ mark_functions_to_output (void)
    return basic block in the function body.  */
 
 basic_block
-init_lowered_empty_function (tree decl, bool in_ssa)
+init_lowered_empty_function (tree decl, bool in_ssa, gcov_type count)
 {
   basic_block bb;
+  edge e;
 
   current_function_decl = decl;
   allocate_struct_function (decl, false);
@@ -1353,9 +1354,19 @@ init_lowered_empty_function (tree decl, bool in_ssa)
   loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
 
   /* Create BB for body of the function and connect it properly.  */
+  ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = count;
+  ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency = REG_BR_PROB_BASE;
+  EXIT_BLOCK_PTR_FOR_FN (cfun)->count = count;
+  EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency = REG_BR_PROB_BASE;
   bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR_FOR_FN (cfun));
-  make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
-  make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+  bb->count = count;
+  bb->frequency = BB_FREQ_MAX;
+  e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
+  e->count = count;
+  e->probability = REG_BR_PROB_BASE;
+  e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+  e->count = count;
+  e->probability = REG_BR_PROB_BASE;
   add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
 
   return bb;
@@ -1578,7 +1589,8 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
       else
        resdecl = DECL_RESULT (thunk_fndecl);
 
-      bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
+      bb = then_bb = else_bb = return_bb
+       = init_lowered_empty_function (thunk_fndecl, true, count);
 
       bsi = gsi_start_bb (bb);
 
@@ -1654,13 +1666,20 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
              if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
                {
                  gimple stmt;
+                 edge e;
                  /* If the return type is a pointer, we need to
                     protect against NULL.  We know there will be an
                     adjustment, because that's why we're emitting a
                     thunk.  */
                  then_bb = create_basic_block (NULL, (void *) 0, bb);
+                 then_bb->count = count - count / 16;
+                 then_bb->frequency = BB_FREQ_MAX - BB_FREQ_MAX / 16;
                  return_bb = create_basic_block (NULL, (void *) 0, then_bb);
+                 return_bb->count = count;
+                 return_bb->frequency = BB_FREQ_MAX;
                  else_bb = create_basic_block (NULL, (void *) 0, else_bb);
+                 then_bb->count = count / 16;
+                 then_bb->frequency = BB_FREQ_MAX / 16;
                  add_bb_to_loop (then_bb, bb->loop_father);
                  add_bb_to_loop (return_bb, bb->loop_father);
                  add_bb_to_loop (else_bb, bb->loop_father);
@@ -1670,11 +1689,21 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
                                            build_zero_cst (TREE_TYPE (restmp)),
                                            NULL_TREE, NULL_TREE);
                  gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
-                 make_edge (bb, then_bb, EDGE_TRUE_VALUE);
-                 make_edge (bb, else_bb, EDGE_FALSE_VALUE);
-                 make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
-                 make_edge (then_bb, return_bb, EDGE_FALLTHRU);
-                 make_edge (else_bb, return_bb, EDGE_FALLTHRU);
+                 e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
+                 e->probability = REG_BR_PROB_BASE - REG_BR_PROB_BASE / 16;
+                 e->count = count - count / 16;
+                 e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
+                 e->probability = REG_BR_PROB_BASE / 16;
+                 e->count = count / 16;
+                 e = make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+                 e->probability = REG_BR_PROB_BASE;
+                 e->count = count;
+                 e = make_edge (then_bb, return_bb, EDGE_FALLTHRU);
+                 e->probability = REG_BR_PROB_BASE;
+                 e->count = count - count / 16;
+                 e = make_edge (else_bb, return_bb, EDGE_FALLTHRU);
+                 e->probability = REG_BR_PROB_BASE;
+                 e->count = count / 16;
                  bsi = gsi_last_bb (then_bb);
                }
 
@@ -1708,6 +1737,8 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
        }
 
       cfun->gimple_df->in_ssa_p = true;
+      profile_status_for_fn (cfun)
+        = count ? PROFILE_READ : PROFILE_GUESSED;
       /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks.  */
       TREE_ASM_WRITTEN (thunk_fndecl) = false;
       delete_unreachable_blocks ();
@@ -2415,8 +2446,7 @@ cgraph_node::create_wrapper (cgraph_node *target)
   definition = true;
   thunk.thunk_p = true;
   thunk.this_adjusting = false;
-
-  cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE);
+  create_edge (target, NULL, count, CGRAPH_FREQ_BASE);
 
   tree arguments = DECL_ARGUMENTS (decl);
 
@@ -2427,7 +2457,6 @@ cgraph_node::create_wrapper (cgraph_node *target)
     }
 
   expand_thunk (false, true);
-  e->call_stmt_cannot_inline_p = true;
 
   /* Inline summary set-up.  */
   analyze ();
index 794d8d0fdb17c40bc0db634b6ae7c4f991aec4ec..1db80709bea0ed13244c9898f1df40587799ee22 100644 (file)
@@ -35145,7 +35145,7 @@ make_resolver_func (const tree default_decl,
 
   gimplify_function_tree (decl);
   push_cfun (DECL_STRUCT_FUNCTION (decl));
-  *empty_bb = init_lowered_empty_function (decl, false);
+  *empty_bb = init_lowered_empty_function (decl, false, 0);
 
   cgraph_node::add_new_function (decl, true);
   symtab->call_cgraph_insertion_hooks (cgraph_node::get_create (decl));
index 505c06dc0c86208866c4b0cb041e4d8dc55c98b5..67d5d20102b24d27b5b7c206e5ad3e1e2dd7acaf 100644 (file)
@@ -3050,6 +3050,9 @@ pass_profile::execute (function *fun)
 {
   unsigned nb_loops;
 
+  if (profile_status_for_fn (cfun) == PROFILE_GUESSED)
+    return 0;
+
   loop_optimizer_init (LOOPS_NORMAL);
   if (dump_file && (dump_flags & TDF_DETAILS))
     flow_loops_dump (dump_file, NULL, 0);
index ac215205d9ab583e1d51e981d49d4c611e647edc..a0fbef7c30b20ca5cfe1b6df612073d23bafe02c 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-29  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/64801
+       * gcc.dg/tree-ssa/pr64801.c: New testcase.
+
 2015-01-28  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/64659
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr64801.c b/gcc/testsuite/gcc.dg/tree-ssa/pr64801.c
new file mode 100644 (file)
index 0000000..8d07b30
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+int a;
+int
+elantech_detect (void)
+{
+  return -38;
+}
+inline int
+fsp_detect (void)
+{
+  return -38;
+}
+void
+psmouse_extensions (void)
+{
+  int (*b)() = fsp_detect;
+  a = b ();
+}
+/* { dg-final { scan-tree-dump-not "fsp_detect"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */