diff options
author | Rong Xu <xur@google.com> | 2014-07-21 16:47:22 -0700 |
---|---|---|
committer | Rong Xu <xur@google.com> | 2014-07-29 15:31:03 -0700 |
commit | 38a8aecfb882072900434499696b5c32a2274515 (patch) | |
tree | 2aac97f0ae24b03cd98c1a06e989c031c173f889 /gcc-4.9/gcc/cgraphclones.c | |
parent | c231900e5dcc14d8296bd9f62b45997a49d4d5e7 (diff) | |
download | toolchain_gcc-38a8aecfb882072900434499696b5c32a2274515.tar.gz toolchain_gcc-38a8aecfb882072900434499696b5c32a2274515.tar.bz2 toolchain_gcc-38a8aecfb882072900434499696b5c32a2274515.zip |
[4.9] Switch gcc-4.9 to use google/gcc-4_9 branch.
This source drop uses svn version r212828 of google/gcc-4.9 branch.
We also cherry-picked r213062, r213063 and r213064 to fix windows
build issues.
All gcc-4.9 patches before July 3rd are ported to google/gcc-4.9.
The following prior commits has not been merged to google branch yet.
(They are included in this commit).
e7af147f979e657fe2df00808e5b4319b0e088c6,
baf87df3cb2683649ba7e9872362a7e721117c23, and
c231900e5dcc14d8296bd9f62b45997a49d4d5e7.
Change-Id: I4bea3ea470387ff751c2be4cb0d4a12059b9299b
Diffstat (limited to 'gcc-4.9/gcc/cgraphclones.c')
-rw-r--r-- | gcc-4.9/gcc/cgraphclones.c | 87 |
1 files changed, 45 insertions, 42 deletions
diff --git a/gcc-4.9/gcc/cgraphclones.c b/gcc-4.9/gcc/cgraphclones.c index 257939cb0..9fec2a04d 100644 --- a/gcc-4.9/gcc/cgraphclones.c +++ b/gcc-4.9/gcc/cgraphclones.c @@ -101,6 +101,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-utils.h" #include "lto-streamer.h" #include "except.h" +#include "l-ipo.h" /* Create clone of E in the node N represented by CALL_EXPR the callgraph. */ struct cgraph_edge * @@ -128,7 +129,11 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, via cgraph_resolve_speculation and not here. */ && !e->speculative) { - struct cgraph_node *callee = cgraph_get_node (decl); + struct cgraph_node *callee; + if (L_IPO_COMP_MODE && cgraph_pre_profiling_inlining_done) + callee = cgraph_lipo_get_resolved_node (decl); + else + callee = cgraph_get_node (decl); gcc_checking_assert (callee); new_edge = cgraph_create_edge (n, callee, call_stmt, count, freq); } @@ -302,14 +307,13 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node) thunk is this_adjusting but we are removing this parameter. */ static cgraph_node * -duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, - bitmap args_to_skip) +duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node) { cgraph_node *new_thunk, *thunk_of; thunk_of = cgraph_function_or_thunk_node (thunk->callees->callee); if (thunk_of->thunk.thunk_p) - node = duplicate_thunk_for_node (thunk_of, node, args_to_skip); + node = duplicate_thunk_for_node (thunk_of, node); struct cgraph_edge *cs; for (cs = node->callers; cs; cs = cs->next_caller) @@ -321,17 +325,18 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, return cs->caller; tree new_decl; - if (!args_to_skip) + if (!node->clone.args_to_skip) new_decl = copy_node (thunk->decl); else { /* We do not need to duplicate this_adjusting thunks if we have removed this. */ if (thunk->thunk.this_adjusting - && bitmap_bit_p (args_to_skip, 0)) + && bitmap_bit_p (node->clone.args_to_skip, 0)) return node; - new_decl = build_function_decl_skip_args (thunk->decl, args_to_skip, + new_decl = build_function_decl_skip_args (thunk->decl, + node->clone.args_to_skip, false); } gcc_checking_assert (!DECL_STRUCT_FUNCTION (new_decl)); @@ -349,6 +354,8 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, new_thunk->thunk = thunk->thunk; new_thunk->unique_name = in_lto_p; new_thunk->former_clone_of = thunk->decl; + new_thunk->clone.args_to_skip = node->clone.args_to_skip; + new_thunk->clone.combined_args_to_skip = node->clone.combined_args_to_skip; struct cgraph_edge *e = cgraph_create_edge (new_thunk, node, NULL, 0, CGRAPH_FREQ_BASE); @@ -365,12 +372,11 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node, chain. */ void -redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n, - bitmap args_to_skip) +redirect_edge_duplicating_thunks (struct cgraph_edge *e, struct cgraph_node *n) { cgraph_node *orig_to = cgraph_function_or_thunk_node (e->callee); if (orig_to->thunk.thunk_p) - n = duplicate_thunk_for_node (orig_to, n, args_to_skip); + n = duplicate_thunk_for_node (orig_to, n); cgraph_redirect_edge_callee (e, n); } @@ -422,10 +428,26 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, new_node->global.inlined_to = new_inlined_to; new_node->rtl = n->rtl; new_node->count = count; + new_node->max_bb_count = count; + if (n->count) + new_node->max_bb_count = ((n->max_bb_count + n->count / 2) + / n->count) * count; new_node->frequency = n->frequency; - new_node->clone = n->clone; - new_node->clone.tree_map = NULL; new_node->tp_first_run = n->tp_first_run; + + new_node->clone.tree_map = NULL; + new_node->clone.args_to_skip = args_to_skip; + if (!args_to_skip) + new_node->clone.combined_args_to_skip = n->clone.combined_args_to_skip; + else if (n->clone.combined_args_to_skip) + { + new_node->clone.combined_args_to_skip = BITMAP_GGC_ALLOC (); + bitmap_ior (new_node->clone.combined_args_to_skip, + n->clone.combined_args_to_skip, args_to_skip); + } + else + new_node->clone.combined_args_to_skip = args_to_skip; + if (n->count) { if (new_node->count > n->count) @@ -435,11 +457,19 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, } else count_scale = 0; + /* In AutoFDO, if edge count is larger than callee's entry block + count, we will not update the original callee because it may + mistakenly mark some hot function as cold. */ + if (flag_auto_profile && count >= n->count) + update_original = false; if (update_original) { n->count -= count; if (n->count < 0) - n->count = 0; + n->count = 0; + n->max_bb_count -= new_node->max_bb_count; + if (n->max_bb_count < 0) + n->max_bb_count = 0; } FOR_EACH_VEC_ELT (redirect_callers, i, e) @@ -450,10 +480,9 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq, if (!e->callee || DECL_BUILT_IN_CLASS (e->callee->decl) != BUILT_IN_NORMAL || DECL_FUNCTION_CODE (e->callee->decl) != BUILT_IN_UNREACHABLE) - redirect_edge_duplicating_thunks (e, new_node, args_to_skip); + redirect_edge_duplicating_thunks (e, new_node); } - for (e = n->callees;e; e=e->next_callee) cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid, count_scale, freq, update_original); @@ -562,7 +591,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, DECL_SECTION_NAME (new_node->decl) = NULL; set_new_clone_decl_and_node_flags (new_node); new_node->clone.tree_map = tree_map; - new_node->clone.args_to_skip = args_to_skip; /* Clones of global symbols or symbols with unique names are unique. */ if ((TREE_PUBLIC (old_decl) @@ -574,32 +602,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node, FOR_EACH_VEC_SAFE_ELT (tree_map, i, map) ipa_maybe_record_reference (new_node, map->new_tree, IPA_REF_ADDR, NULL); - if (!args_to_skip) - new_node->clone.combined_args_to_skip = old_node->clone.combined_args_to_skip; - else if (old_node->clone.combined_args_to_skip) - { - int newi = 0, oldi = 0; - tree arg; - bitmap new_args_to_skip = BITMAP_GGC_ALLOC (); - struct cgraph_node *orig_node; - for (orig_node = old_node; orig_node->clone_of; orig_node = orig_node->clone_of) - ; - for (arg = DECL_ARGUMENTS (orig_node->decl); - arg; arg = DECL_CHAIN (arg), oldi++) - { - if (bitmap_bit_p (old_node->clone.combined_args_to_skip, oldi)) - { - bitmap_set_bit (new_args_to_skip, oldi); - continue; - } - if (bitmap_bit_p (args_to_skip, newi)) - bitmap_set_bit (new_args_to_skip, oldi); - newi++; - } - new_node->clone.combined_args_to_skip = new_args_to_skip; - } - else - new_node->clone.combined_args_to_skip = args_to_skip; cgraph_call_node_duplication_hooks (old_node, new_node); @@ -883,6 +885,7 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version, new_version->global = old_version->global; new_version->rtl = old_version->rtl; new_version->count = old_version->count; + new_version->max_bb_count = old_version->max_bb_count; for (e = old_version->callees; e; e=e->next_callee) if (!bbs_to_copy |