ipa-utils.c (ipa_merge_profiles): Fix updating of fnsummary; also handle rescaling...
authorJan Hubicka <hubicka@ucw.cz>
Mon, 24 Dec 2018 01:37:44 +0000 (02:37 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 24 Dec 2018 01:37:44 +0000 (01:37 +0000)
* ipa-utils.c (ipa_merge_profiles): Fix updating of fnsummary;
also handle rescaling of mismatched profiles.
* ipa-fnsummary.c (analyze_function): Handle speculative edges.

From-SVN: r267392

gcc/ChangeLog
gcc/ipa-fnsummary.c
gcc/ipa-utils.c

index cd2a294c583dca4ad5d711eab15b7e2084ba79c4..479083e64830493330dbe2700300bcf9fa32ced9 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-24  Jan Hubicka  <hubicka@ucw.cz>
+
+       * ipa-utils.c (ipa_merge_profiles): Fix updating of fnsummary;
+       also handle rescaling of mismatched profiles.
+       * ipa-fnsummary.c (analyze_function): Handle speculative edges.
+
 2018-12-23  Martin Sebor  <msebor@redhat.com>
            Jeff Law  <law@redhat.com>
 
index 471ec5038516a379a1e158b6df0a64abaa8b1eb8..1c43b31104b88eb8338f3573d0cef2269371efaf 100644 (file)
@@ -2180,6 +2180,17 @@ analyze_function_body (struct cgraph_node *node, bool early)
              es->call_stmt_time = this_time;
              es->loop_depth = bb_loop_depth (bb);
              edge_set_predicate (edge, &bb_predicate);
+             if (edge->speculative)
+               {
+                 cgraph_edge *direct, *indirect;
+                 ipa_ref *ref;
+                 edge->speculative_call_info (direct, indirect, ref);
+                 gcc_assert (direct == edge);
+                 ipa_call_summary *es2
+                        = ipa_call_summaries->get_create (indirect);
+                 ipa_call_summaries->duplicate (edge, indirect,
+                                                es, es2);
+               }
            }
 
          /* TODO: When conditional jump or swithc is known to be constant, but
@@ -2491,7 +2502,8 @@ compute_fn_summary (struct cgraph_node *node, bool early)
      ipa_update_overall_fn_summary but because computation happens in
      different order the roundoff errors result in slight changes.  */
   ipa_update_overall_fn_summary (node);
-  gcc_assert (info->size == info->self_size);
+  /* In LTO mode we may have speculative edges set.  */
+  gcc_assert (in_lto_p || info->size == info->self_size);
 }
 
 
index 422d8d09a0eded1a5ac85e04c71c602a2606768b..f07e3b3eeccca910b338e624024ae288d0a555f4 100644 (file)
@@ -392,6 +392,7 @@ ipa_merge_profiles (struct cgraph_node *dst,
   if (!src->definition
       || !dst->definition)
     return;
+
   if (src->frequency < dst->frequency)
     src->frequency = dst->frequency;
 
@@ -416,6 +417,8 @@ ipa_merge_profiles (struct cgraph_node *dst,
       fprintf (symtab->dump_file, "Merging profiles of %s to %s\n",
               src->dump_name (), dst->dump_name ());
     }
+  profile_count orig_count = dst->count;
+
   if (dst->count.initialized_p () && dst->count.ipa () == dst->count)
     dst->count += src->count.ipa ();
   else 
@@ -644,10 +647,21 @@ ipa_merge_profiles (struct cgraph_node *dst,
       if (!preserve_body)
         src->release_body ();
       /* Update summary.  */
-      symtab->call_cgraph_removal_hooks (dst);
-      symtab->call_cgraph_insertion_hooks (dst);
+      compute_fn_summary (dst, 0);
+    }
+  /* We can't update CFG profile, but we can scale IPA profile. CFG
+     will be scaled according to dst->count after IPA passes.  */
+  else
+    {
+      profile_count to = dst->count;
+      profile_count::adjust_for_ipa_scaling (&to, &orig_count);
+      struct cgraph_edge *e;
+      
+      for (e = dst->callees; e; e = e->next_callee)
+       e->count = e->count.apply_scale (to, orig_count);
+      for (e = dst->indirect_calls; e; e = e->next_callee)
+       e->count = e->count.apply_scale (to, orig_count);
     }
-  /* TODO: if there is no match, we can scale up.  */
   src->decl = oldsrcdecl;
 }