aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/cgraphclones.c
diff options
context:
space:
mode:
authorRong Xu <xur@google.com>2014-07-21 16:47:22 -0700
committerRong Xu <xur@google.com>2014-07-29 15:31:03 -0700
commit38a8aecfb882072900434499696b5c32a2274515 (patch)
tree2aac97f0ae24b03cd98c1a06e989c031c173f889 /gcc-4.9/gcc/cgraphclones.c
parentc231900e5dcc14d8296bd9f62b45997a49d4d5e7 (diff)
downloadtoolchain_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.c87
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