annotate gcc/ipa-utils.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Utilities for ipa analysis.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "coretypes.h"
111
kono
parents: 55
diff changeset
24 #include "backend.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "tree.h"
111
kono
parents: 55
diff changeset
26 #include "gimple.h"
kono
parents: 55
diff changeset
27 #include "predict.h"
kono
parents: 55
diff changeset
28 #include "alloc-pool.h"
kono
parents: 55
diff changeset
29 #include "cgraph.h"
kono
parents: 55
diff changeset
30 #include "lto-streamer.h"
kono
parents: 55
diff changeset
31 #include "dumpfile.h"
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
32 #include "splay-tree.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 #include "ipa-utils.h"
111
kono
parents: 55
diff changeset
34 #include "symbol-summary.h"
kono
parents: 55
diff changeset
35 #include "tree-vrp.h"
kono
parents: 55
diff changeset
36 #include "ipa-prop.h"
kono
parents: 55
diff changeset
37 #include "ipa-fnsummary.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 /* Debugging function for postorder and inorder code. NOTE is a string
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 that is printed before the nodes are printed. ORDER is an array of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 cgraph_nodes that has COUNT useful nodes in it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
43 void
111
kono
parents: 55
diff changeset
44 ipa_print_order (FILE* out,
kono
parents: 55
diff changeset
45 const char * note,
kono
parents: 55
diff changeset
46 struct cgraph_node** order,
kono
parents: 55
diff changeset
47 int count)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 fprintf (out, "\n\n ordered call graph: %s\n", note);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
51
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 for (i = count - 1; i >= 0; i--)
111
kono
parents: 55
diff changeset
53 order[i]->dump (out);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 fprintf (out, "\n");
111
kono
parents: 55
diff changeset
55 fflush (out);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
111
kono
parents: 55
diff changeset
58
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 struct searchc_env {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 struct cgraph_node **stack;
111
kono
parents: 55
diff changeset
61 struct cgraph_node **result;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 int stack_size;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 int order_pos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 splay_tree nodes_marked_new;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 bool reduce;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 int count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 /* This is an implementation of Tarjan's strongly connected region
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 finder as reprinted in Aho Hopcraft and Ullman's The Design and
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 Analysis of Computer Programs (1975) pages 192-193. This version
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 has been customized for cgraph_nodes. The env parameter is because
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 it is recursive and there are no nested functions here. This
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 function should only be called from itself or
111
kono
parents: 55
diff changeset
75 ipa_reduced_postorder. ENV is a stack env and would be
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 unnecessary if C had nested functions. V is the node to start
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 searching from. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 static void
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
80 searchc (struct searchc_env* env, struct cgraph_node *v,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
81 bool (*ignore_edge) (struct cgraph_edge *))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 struct cgraph_edge *edge;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 struct ipa_dfs_info *v_info = (struct ipa_dfs_info *) v->aux;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
85
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 /* mark node as old */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 v_info->new_node = false;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88 splay_tree_remove (env->nodes_marked_new, v->get_uid ());
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
89
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 v_info->dfn_number = env->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 v_info->low_link = env->count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 env->count++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 env->stack[(env->stack_size)++] = v;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 v_info->on_stack = true;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
95
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 for (edge = v->callees; edge; edge = edge->next_callee)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 struct ipa_dfs_info * w_info;
111
kono
parents: 55
diff changeset
99 enum availability avail;
kono
parents: 55
diff changeset
100 struct cgraph_node *w = edge->callee->ultimate_alias_target (&avail);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101
111
kono
parents: 55
diff changeset
102 if (!w || (ignore_edge && ignore_edge (edge)))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
103 continue;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
104
111
kono
parents: 55
diff changeset
105 if (w->aux
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
106 && (avail >= AVAIL_INTERPOSABLE))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 w_info = (struct ipa_dfs_info *) w->aux;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
109 if (w_info->new_node)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
111 searchc (env, w, ignore_edge);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 v_info->low_link =
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 (v_info->low_link < w_info->low_link) ?
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 v_info->low_link : w_info->low_link;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
115 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
116 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
117 if ((w_info->dfn_number < v_info->dfn_number)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
118 && (w_info->on_stack))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 v_info->low_link =
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 (w_info->dfn_number < v_info->low_link) ?
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 w_info->dfn_number : v_info->low_link;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
126 if (v_info->low_link == v_info->dfn_number)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 struct cgraph_node *last = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 struct cgraph_node *x;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 struct ipa_dfs_info *x_info;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 do {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 x = env->stack[--(env->stack_size)];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 x_info = (struct ipa_dfs_info *) x->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 x_info->on_stack = false;
111
kono
parents: 55
diff changeset
135 x_info->scc_no = v_info->dfn_number;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
136
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
137 if (env->reduce)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 x_info->next_cycle = last;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 last = x;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
141 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
142 else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 env->result[env->order_pos++] = x;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
144 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 while (v != x);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
146 if (env->reduce)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 env->result[env->order_pos++] = v;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 /* Topsort the call graph by caller relation. Put the result in ORDER.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152
111
kono
parents: 55
diff changeset
153 The REDUCE flag is true if you want the cycles reduced to single nodes.
kono
parents: 55
diff changeset
154 You can use ipa_get_nodes_in_cycle to obtain a vector containing all real
kono
parents: 55
diff changeset
155 call graph nodes in a reduced node.
kono
parents: 55
diff changeset
156
kono
parents: 55
diff changeset
157 Set ALLOW_OVERWRITABLE if nodes with such availability should be included.
kono
parents: 55
diff changeset
158 IGNORE_EDGE, if non-NULL is a hook that may make some edges insignificant
kono
parents: 55
diff changeset
159 for the topological sort. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 int
111
kono
parents: 55
diff changeset
162 ipa_reduced_postorder (struct cgraph_node **order,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
163 bool reduce,
111
kono
parents: 55
diff changeset
164 bool (*ignore_edge) (struct cgraph_edge *))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 struct cgraph_node *node;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 struct searchc_env env;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 splay_tree_node result;
111
kono
parents: 55
diff changeset
169 env.stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 env.stack_size = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 env.result = order;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 env.order_pos = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 env.nodes_marked_new = splay_tree_new (splay_tree_compare_ints, 0, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 env.count = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 env.reduce = reduce;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
176
111
kono
parents: 55
diff changeset
177 FOR_EACH_DEFINED_FUNCTION (node)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 {
111
kono
parents: 55
diff changeset
179 enum availability avail = node->get_availability ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
180
111
kono
parents: 55
diff changeset
181 if (avail > AVAIL_INTERPOSABLE
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
182 || avail == AVAIL_INTERPOSABLE)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 /* Reuse the info if it is already there. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 struct ipa_dfs_info *info = (struct ipa_dfs_info *) node->aux;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 if (!info)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 info = XCNEW (struct ipa_dfs_info);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 info->new_node = true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
189 info->on_stack = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 info->next_cycle = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 node->aux = info;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
192
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 splay_tree_insert (env.nodes_marked_new,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
194 (splay_tree_key)node->get_uid (),
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 (splay_tree_value)node);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
196 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
197 else
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 node->aux = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 result = splay_tree_min (env.nodes_marked_new);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 while (result)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 node = (struct cgraph_node *)result->value;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
204 searchc (&env, node, ignore_edge);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 result = splay_tree_min (env.nodes_marked_new);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207 splay_tree_delete (env.nodes_marked_new);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 free (env.stack);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 return env.order_pos;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212
111
kono
parents: 55
diff changeset
213 /* Deallocate all ipa_dfs_info structures pointed to by the aux pointer of call
kono
parents: 55
diff changeset
214 graph nodes. */
kono
parents: 55
diff changeset
215
kono
parents: 55
diff changeset
216 void
kono
parents: 55
diff changeset
217 ipa_free_postorder_info (void)
kono
parents: 55
diff changeset
218 {
kono
parents: 55
diff changeset
219 struct cgraph_node *node;
kono
parents: 55
diff changeset
220 FOR_EACH_DEFINED_FUNCTION (node)
kono
parents: 55
diff changeset
221 {
kono
parents: 55
diff changeset
222 /* Get rid of the aux information. */
kono
parents: 55
diff changeset
223 if (node->aux)
kono
parents: 55
diff changeset
224 {
kono
parents: 55
diff changeset
225 free (node->aux);
kono
parents: 55
diff changeset
226 node->aux = NULL;
kono
parents: 55
diff changeset
227 }
kono
parents: 55
diff changeset
228 }
kono
parents: 55
diff changeset
229 }
kono
parents: 55
diff changeset
230
kono
parents: 55
diff changeset
231 /* Get the set of nodes for the cycle in the reduced call graph starting
kono
parents: 55
diff changeset
232 from NODE. */
kono
parents: 55
diff changeset
233
kono
parents: 55
diff changeset
234 vec<cgraph_node *>
kono
parents: 55
diff changeset
235 ipa_get_nodes_in_cycle (struct cgraph_node *node)
kono
parents: 55
diff changeset
236 {
kono
parents: 55
diff changeset
237 vec<cgraph_node *> v = vNULL;
kono
parents: 55
diff changeset
238 struct ipa_dfs_info *node_dfs_info;
kono
parents: 55
diff changeset
239 while (node)
kono
parents: 55
diff changeset
240 {
kono
parents: 55
diff changeset
241 v.safe_push (node);
kono
parents: 55
diff changeset
242 node_dfs_info = (struct ipa_dfs_info *) node->aux;
kono
parents: 55
diff changeset
243 node = node_dfs_info->next_cycle;
kono
parents: 55
diff changeset
244 }
kono
parents: 55
diff changeset
245 return v;
kono
parents: 55
diff changeset
246 }
kono
parents: 55
diff changeset
247
kono
parents: 55
diff changeset
248 /* Return true iff the CS is an edge within a strongly connected component as
kono
parents: 55
diff changeset
249 computed by ipa_reduced_postorder. */
kono
parents: 55
diff changeset
250
kono
parents: 55
diff changeset
251 bool
kono
parents: 55
diff changeset
252 ipa_edge_within_scc (struct cgraph_edge *cs)
kono
parents: 55
diff changeset
253 {
kono
parents: 55
diff changeset
254 struct ipa_dfs_info *caller_dfs = (struct ipa_dfs_info *) cs->caller->aux;
kono
parents: 55
diff changeset
255 struct ipa_dfs_info *callee_dfs;
kono
parents: 55
diff changeset
256 struct cgraph_node *callee = cs->callee->function_symbol ();
kono
parents: 55
diff changeset
257
kono
parents: 55
diff changeset
258 callee_dfs = (struct ipa_dfs_info *) callee->aux;
kono
parents: 55
diff changeset
259 return (caller_dfs
kono
parents: 55
diff changeset
260 && callee_dfs
kono
parents: 55
diff changeset
261 && caller_dfs->scc_no == callee_dfs->scc_no);
kono
parents: 55
diff changeset
262 }
kono
parents: 55
diff changeset
263
kono
parents: 55
diff changeset
264 struct postorder_stack
kono
parents: 55
diff changeset
265 {
kono
parents: 55
diff changeset
266 struct cgraph_node *node;
kono
parents: 55
diff changeset
267 struct cgraph_edge *edge;
kono
parents: 55
diff changeset
268 int ref;
kono
parents: 55
diff changeset
269 };
kono
parents: 55
diff changeset
270
kono
parents: 55
diff changeset
271 /* Fill array order with all nodes with output flag set in the reverse
kono
parents: 55
diff changeset
272 topological order. Return the number of elements in the array.
kono
parents: 55
diff changeset
273 FIXME: While walking, consider aliases, too. */
kono
parents: 55
diff changeset
274
kono
parents: 55
diff changeset
275 int
kono
parents: 55
diff changeset
276 ipa_reverse_postorder (struct cgraph_node **order)
kono
parents: 55
diff changeset
277 {
kono
parents: 55
diff changeset
278 struct cgraph_node *node, *node2;
kono
parents: 55
diff changeset
279 int stack_size = 0;
kono
parents: 55
diff changeset
280 int order_pos = 0;
kono
parents: 55
diff changeset
281 struct cgraph_edge *edge;
kono
parents: 55
diff changeset
282 int pass;
kono
parents: 55
diff changeset
283 struct ipa_ref *ref = NULL;
kono
parents: 55
diff changeset
284
kono
parents: 55
diff changeset
285 struct postorder_stack *stack =
kono
parents: 55
diff changeset
286 XCNEWVEC (struct postorder_stack, symtab->cgraph_count);
kono
parents: 55
diff changeset
287
kono
parents: 55
diff changeset
288 /* We have to deal with cycles nicely, so use a depth first traversal
kono
parents: 55
diff changeset
289 output algorithm. Ignore the fact that some functions won't need
kono
parents: 55
diff changeset
290 to be output and put them into order as well, so we get dependencies
kono
parents: 55
diff changeset
291 right through inline functions. */
kono
parents: 55
diff changeset
292 FOR_EACH_FUNCTION (node)
kono
parents: 55
diff changeset
293 node->aux = NULL;
kono
parents: 55
diff changeset
294 for (pass = 0; pass < 2; pass++)
kono
parents: 55
diff changeset
295 FOR_EACH_FUNCTION (node)
kono
parents: 55
diff changeset
296 if (!node->aux
kono
parents: 55
diff changeset
297 && (pass
kono
parents: 55
diff changeset
298 || (!node->address_taken
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
299 && !node->inlined_to
111
kono
parents: 55
diff changeset
300 && !node->alias && !node->thunk.thunk_p
kono
parents: 55
diff changeset
301 && !node->only_called_directly_p ())))
kono
parents: 55
diff changeset
302 {
kono
parents: 55
diff changeset
303 stack_size = 0;
kono
parents: 55
diff changeset
304 stack[stack_size].node = node;
kono
parents: 55
diff changeset
305 stack[stack_size].edge = node->callers;
kono
parents: 55
diff changeset
306 stack[stack_size].ref = 0;
kono
parents: 55
diff changeset
307 node->aux = (void *)(size_t)1;
kono
parents: 55
diff changeset
308 while (stack_size >= 0)
kono
parents: 55
diff changeset
309 {
kono
parents: 55
diff changeset
310 while (true)
kono
parents: 55
diff changeset
311 {
kono
parents: 55
diff changeset
312 node2 = NULL;
kono
parents: 55
diff changeset
313 while (stack[stack_size].edge && !node2)
kono
parents: 55
diff changeset
314 {
kono
parents: 55
diff changeset
315 edge = stack[stack_size].edge;
kono
parents: 55
diff changeset
316 node2 = edge->caller;
kono
parents: 55
diff changeset
317 stack[stack_size].edge = edge->next_caller;
kono
parents: 55
diff changeset
318 /* Break possible cycles involving always-inline
kono
parents: 55
diff changeset
319 functions by ignoring edges from always-inline
kono
parents: 55
diff changeset
320 functions to non-always-inline functions. */
kono
parents: 55
diff changeset
321 if (DECL_DISREGARD_INLINE_LIMITS (edge->caller->decl)
kono
parents: 55
diff changeset
322 && !DECL_DISREGARD_INLINE_LIMITS
kono
parents: 55
diff changeset
323 (edge->callee->function_symbol ()->decl))
kono
parents: 55
diff changeset
324 node2 = NULL;
kono
parents: 55
diff changeset
325 }
kono
parents: 55
diff changeset
326 for (; stack[stack_size].node->iterate_referring (
kono
parents: 55
diff changeset
327 stack[stack_size].ref,
kono
parents: 55
diff changeset
328 ref) && !node2;
kono
parents: 55
diff changeset
329 stack[stack_size].ref++)
kono
parents: 55
diff changeset
330 {
kono
parents: 55
diff changeset
331 if (ref->use == IPA_REF_ALIAS)
kono
parents: 55
diff changeset
332 node2 = dyn_cast <cgraph_node *> (ref->referring);
kono
parents: 55
diff changeset
333 }
kono
parents: 55
diff changeset
334 if (!node2)
kono
parents: 55
diff changeset
335 break;
kono
parents: 55
diff changeset
336 if (!node2->aux)
kono
parents: 55
diff changeset
337 {
kono
parents: 55
diff changeset
338 stack[++stack_size].node = node2;
kono
parents: 55
diff changeset
339 stack[stack_size].edge = node2->callers;
kono
parents: 55
diff changeset
340 stack[stack_size].ref = 0;
kono
parents: 55
diff changeset
341 node2->aux = (void *)(size_t)1;
kono
parents: 55
diff changeset
342 }
kono
parents: 55
diff changeset
343 }
kono
parents: 55
diff changeset
344 order[order_pos++] = stack[stack_size--].node;
kono
parents: 55
diff changeset
345 }
kono
parents: 55
diff changeset
346 }
kono
parents: 55
diff changeset
347 free (stack);
kono
parents: 55
diff changeset
348 FOR_EACH_FUNCTION (node)
kono
parents: 55
diff changeset
349 node->aux = NULL;
kono
parents: 55
diff changeset
350 return order_pos;
kono
parents: 55
diff changeset
351 }
kono
parents: 55
diff changeset
352
kono
parents: 55
diff changeset
353
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 /* Given a memory reference T, will return the variable at the bottom
111
kono
parents: 55
diff changeset
356 of the access. Unlike get_base_address, this will recurse through
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 INDIRECT_REFS. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 get_base_var (tree t)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
362 while (!SSA_VAR_P (t)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 && (!CONSTANT_CLASS_P (t))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
364 && TREE_CODE (t) != LABEL_DECL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 && TREE_CODE (t) != FUNCTION_DECL
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
366 && TREE_CODE (t) != CONST_DECL
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
367 && TREE_CODE (t) != CONSTRUCTOR)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 t = TREE_OPERAND (t, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 return t;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
372 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
374 /* Scale function of calls in NODE by ratio ORIG_COUNT/NODE->count. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
375
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
376 void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
377 scale_ipa_profile_for_fn (struct cgraph_node *node, profile_count orig_count)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
378 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
379 profile_count to = node->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
380 profile_count::adjust_for_ipa_scaling (&to, &orig_count);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
381 struct cgraph_edge *e;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
382
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
383 for (e = node->callees; e; e = e->next_callee)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
384 e->count = e->count.apply_scale (to, orig_count);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
385 for (e = node->indirect_calls; e; e = e->next_callee)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
386 e->count = e->count.apply_scale (to, orig_count);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
387 }
111
kono
parents: 55
diff changeset
388
kono
parents: 55
diff changeset
389 /* SRC and DST are going to be merged. Take SRC's profile and merge it into
kono
parents: 55
diff changeset
390 DST so it is not going to be lost. Possibly destroy SRC's body on the way
kono
parents: 55
diff changeset
391 unless PRESERVE_BODY is set. */
kono
parents: 55
diff changeset
392
kono
parents: 55
diff changeset
393 void
kono
parents: 55
diff changeset
394 ipa_merge_profiles (struct cgraph_node *dst,
kono
parents: 55
diff changeset
395 struct cgraph_node *src,
kono
parents: 55
diff changeset
396 bool preserve_body)
kono
parents: 55
diff changeset
397 {
kono
parents: 55
diff changeset
398 tree oldsrcdecl = src->decl;
kono
parents: 55
diff changeset
399 struct function *srccfun, *dstcfun;
kono
parents: 55
diff changeset
400 bool match = true;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
401 bool copy_counts = false;
111
kono
parents: 55
diff changeset
402
kono
parents: 55
diff changeset
403 if (!src->definition
kono
parents: 55
diff changeset
404 || !dst->definition)
kono
parents: 55
diff changeset
405 return;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
406
111
kono
parents: 55
diff changeset
407 if (src->frequency < dst->frequency)
kono
parents: 55
diff changeset
408 src->frequency = dst->frequency;
kono
parents: 55
diff changeset
409
kono
parents: 55
diff changeset
410 /* Time profiles are merged. */
kono
parents: 55
diff changeset
411 if (dst->tp_first_run > src->tp_first_run && src->tp_first_run)
kono
parents: 55
diff changeset
412 dst->tp_first_run = src->tp_first_run;
kono
parents: 55
diff changeset
413
kono
parents: 55
diff changeset
414 if (src->profile_id && !dst->profile_id)
kono
parents: 55
diff changeset
415 dst->profile_id = src->profile_id;
kono
parents: 55
diff changeset
416
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
417 /* Merging zero profile to dst is no-op. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
418 if (src->count.ipa () == profile_count::zero ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
419 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
420
111
kono
parents: 55
diff changeset
421 /* FIXME when we merge in unknown profile, we ought to set counts as
kono
parents: 55
diff changeset
422 unsafe. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 if (!src->count.initialized_p ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
424 || !(src->count.ipa () == src->count))
111
kono
parents: 55
diff changeset
425 return;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
426 profile_count orig_count = dst->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
427
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
428 /* Either sum the profiles if both are IPA and not global0, or
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
429 pick more informative one (that is nonzero IPA if other is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
430 uninitialized, guessed or global0). */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
431
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
432 if ((dst->count.ipa ().nonzero_p ()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
433 || src->count.ipa ().nonzero_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
434 && dst->count.ipa ().initialized_p ()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
435 && src->count.ipa ().initialized_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
436 dst->count = dst->count.ipa () + src->count.ipa ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
437 else if (dst->count.ipa ().initialized_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
438 ;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
439 else if (src->count.ipa ().initialized_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
440 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
441 copy_counts = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
442 dst->count = src->count.ipa ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
443 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
444
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
445 /* If no updating needed return early. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
446 if (dst->count == orig_count)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
447 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
448
111
kono
parents: 55
diff changeset
449 if (symtab->dump_file)
kono
parents: 55
diff changeset
450 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
451 fprintf (symtab->dump_file, "Merging profiles of %s count:",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
452 src->dump_name ());
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
453 src->count.dump (symtab->dump_file);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
454 fprintf (symtab->dump_file, " to %s count:",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
455 dst->dump_name ());
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
456 orig_count.dump (symtab->dump_file);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
457 fprintf (symtab->dump_file, " resulting count:");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
458 dst->count.dump (symtab->dump_file);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
459 fprintf (symtab->dump_file, "\n");
111
kono
parents: 55
diff changeset
460 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
461
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
462 /* First handle functions with no gimple body. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
463 if (dst->thunk.thunk_p || dst->alias
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
464 || src->thunk.thunk_p || src->alias)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
465 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
466 scale_ipa_profile_for_fn (dst, orig_count);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
467 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
468 }
111
kono
parents: 55
diff changeset
469
kono
parents: 55
diff changeset
470 /* This is ugly. We need to get both function bodies into memory.
kono
parents: 55
diff changeset
471 If declaration is merged, we need to duplicate it to be able
kono
parents: 55
diff changeset
472 to load body that is being replaced. This makes symbol table
kono
parents: 55
diff changeset
473 temporarily inconsistent. */
kono
parents: 55
diff changeset
474 if (src->decl == dst->decl)
kono
parents: 55
diff changeset
475 {
kono
parents: 55
diff changeset
476 struct lto_in_decl_state temp;
kono
parents: 55
diff changeset
477 struct lto_in_decl_state *state;
kono
parents: 55
diff changeset
478
kono
parents: 55
diff changeset
479 /* We are going to move the decl, we want to remove its file decl data.
kono
parents: 55
diff changeset
480 and link these with the new decl. */
kono
parents: 55
diff changeset
481 temp.fn_decl = src->decl;
kono
parents: 55
diff changeset
482 lto_in_decl_state **slot
kono
parents: 55
diff changeset
483 = src->lto_file_data->function_decl_states->find_slot (&temp,
kono
parents: 55
diff changeset
484 NO_INSERT);
kono
parents: 55
diff changeset
485 state = *slot;
kono
parents: 55
diff changeset
486 src->lto_file_data->function_decl_states->clear_slot (slot);
kono
parents: 55
diff changeset
487 gcc_assert (state);
kono
parents: 55
diff changeset
488
kono
parents: 55
diff changeset
489 /* Duplicate the decl and be sure it does not link into body of DST. */
kono
parents: 55
diff changeset
490 src->decl = copy_node (src->decl);
kono
parents: 55
diff changeset
491 DECL_STRUCT_FUNCTION (src->decl) = NULL;
kono
parents: 55
diff changeset
492 DECL_ARGUMENTS (src->decl) = NULL;
kono
parents: 55
diff changeset
493 DECL_INITIAL (src->decl) = NULL;
kono
parents: 55
diff changeset
494 DECL_RESULT (src->decl) = NULL;
kono
parents: 55
diff changeset
495
kono
parents: 55
diff changeset
496 /* Associate the decl state with new declaration, so LTO streamer
kono
parents: 55
diff changeset
497 can look it up. */
kono
parents: 55
diff changeset
498 state->fn_decl = src->decl;
kono
parents: 55
diff changeset
499 slot
kono
parents: 55
diff changeset
500 = src->lto_file_data->function_decl_states->find_slot (state, INSERT);
kono
parents: 55
diff changeset
501 gcc_assert (!*slot);
kono
parents: 55
diff changeset
502 *slot = state;
kono
parents: 55
diff changeset
503 }
kono
parents: 55
diff changeset
504 src->get_untransformed_body ();
kono
parents: 55
diff changeset
505 dst->get_untransformed_body ();
kono
parents: 55
diff changeset
506 srccfun = DECL_STRUCT_FUNCTION (src->decl);
kono
parents: 55
diff changeset
507 dstcfun = DECL_STRUCT_FUNCTION (dst->decl);
kono
parents: 55
diff changeset
508 if (n_basic_blocks_for_fn (srccfun)
kono
parents: 55
diff changeset
509 != n_basic_blocks_for_fn (dstcfun))
kono
parents: 55
diff changeset
510 {
kono
parents: 55
diff changeset
511 if (symtab->dump_file)
kono
parents: 55
diff changeset
512 fprintf (symtab->dump_file,
kono
parents: 55
diff changeset
513 "Giving up; number of basic block mismatch.\n");
kono
parents: 55
diff changeset
514 match = false;
kono
parents: 55
diff changeset
515 }
kono
parents: 55
diff changeset
516 else if (last_basic_block_for_fn (srccfun)
kono
parents: 55
diff changeset
517 != last_basic_block_for_fn (dstcfun))
kono
parents: 55
diff changeset
518 {
kono
parents: 55
diff changeset
519 if (symtab->dump_file)
kono
parents: 55
diff changeset
520 fprintf (symtab->dump_file,
kono
parents: 55
diff changeset
521 "Giving up; last block mismatch.\n");
kono
parents: 55
diff changeset
522 match = false;
kono
parents: 55
diff changeset
523 }
kono
parents: 55
diff changeset
524 else
kono
parents: 55
diff changeset
525 {
kono
parents: 55
diff changeset
526 basic_block srcbb, dstbb;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
527 struct cgraph_edge *e, *e2;
111
kono
parents: 55
diff changeset
528
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
529 for (e = dst->callees, e2 = src->callees; e && e2 && match;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
530 e2 = e2->next_callee, e = e->next_callee)
111
kono
parents: 55
diff changeset
531 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
532 if (gimple_bb (e->call_stmt)->index
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
533 != gimple_bb (e2->call_stmt)->index)
111
kono
parents: 55
diff changeset
534 {
kono
parents: 55
diff changeset
535 if (symtab->dump_file)
kono
parents: 55
diff changeset
536 fprintf (symtab->dump_file,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
537 "Giving up; call stmt mismatch.\n");
111
kono
parents: 55
diff changeset
538 match = false;
kono
parents: 55
diff changeset
539 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
540 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
541 if (e || e2)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
542 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
543 if (symtab->dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
544 fprintf (symtab->dump_file,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
545 "Giving up; number of calls differs.\n");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
546 match = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
547 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
548 for (e = dst->indirect_calls, e2 = src->indirect_calls; e && e2 && match;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
549 e2 = e2->next_callee, e = e->next_callee)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
550 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
551 if (gimple_bb (e->call_stmt)->index
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
552 != gimple_bb (e2->call_stmt)->index)
111
kono
parents: 55
diff changeset
553 {
kono
parents: 55
diff changeset
554 if (symtab->dump_file)
kono
parents: 55
diff changeset
555 fprintf (symtab->dump_file,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
556 "Giving up; indirect call stmt mismatch.\n");
111
kono
parents: 55
diff changeset
557 match = false;
kono
parents: 55
diff changeset
558 }
kono
parents: 55
diff changeset
559 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
560 if (e || e2)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
561 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
562 if (symtab->dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
563 fprintf (symtab->dump_file,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
564 "Giving up; number of indirect calls differs.\n");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
565 match=false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
566 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
567
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
568 if (match)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
569 FOR_ALL_BB_FN (srcbb, srccfun)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
570 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
571 unsigned int i;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
572
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
573 dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
574 if (dstbb == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
575 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
576 if (symtab->dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
577 fprintf (symtab->dump_file,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
578 "No matching block for bb %i.\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
579 srcbb->index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
580 match = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
581 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
582 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
583 if (EDGE_COUNT (srcbb->succs) != EDGE_COUNT (dstbb->succs))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
584 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
585 if (symtab->dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
586 fprintf (symtab->dump_file,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
587 "Edge count mismatch for bb %i.\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
588 srcbb->index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
589 match = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
590 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
591 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
592 for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
593 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
594 edge srce = EDGE_SUCC (srcbb, i);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
595 edge dste = EDGE_SUCC (dstbb, i);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
596 if (srce->dest->index != dste->dest->index)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
597 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
598 if (symtab->dump_file)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
599 fprintf (symtab->dump_file,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
600 "Succ edge mismatch for bb %i.\n",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
601 srce->dest->index);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
602 match = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
603 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
604 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
605 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
606 }
111
kono
parents: 55
diff changeset
607 }
kono
parents: 55
diff changeset
608 if (match)
kono
parents: 55
diff changeset
609 {
kono
parents: 55
diff changeset
610 struct cgraph_edge *e, *e2;
kono
parents: 55
diff changeset
611 basic_block srcbb, dstbb;
kono
parents: 55
diff changeset
612
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
613 /* Function and global profile may be out of sync. First scale it same
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
614 way as fixup_cfg would. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
615 profile_count srcnum = src->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
616 profile_count srcden = ENTRY_BLOCK_PTR_FOR_FN (srccfun)->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
617 bool srcscale = srcnum.initialized_p () && !(srcnum == srcden);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
618 profile_count dstnum = orig_count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
619 profile_count dstden = ENTRY_BLOCK_PTR_FOR_FN (dstcfun)->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
620 bool dstscale = !copy_counts
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
621 && dstnum.initialized_p () && !(dstnum == dstden);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
622
111
kono
parents: 55
diff changeset
623 /* TODO: merge also statement histograms. */
kono
parents: 55
diff changeset
624 FOR_ALL_BB_FN (srcbb, srccfun)
kono
parents: 55
diff changeset
625 {
kono
parents: 55
diff changeset
626 unsigned int i;
kono
parents: 55
diff changeset
627
kono
parents: 55
diff changeset
628 dstbb = BASIC_BLOCK_FOR_FN (dstcfun, srcbb->index);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
629
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
630 profile_count srccount = srcbb->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
631 if (srcscale)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
632 srccount = srccount.apply_scale (srcnum, srcden);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
633 if (dstscale)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
634 dstbb->count = dstbb->count.apply_scale (dstnum, dstden);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
635
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
636 if (copy_counts)
111
kono
parents: 55
diff changeset
637 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
638 dstbb->count = srccount;
111
kono
parents: 55
diff changeset
639 for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
kono
parents: 55
diff changeset
640 {
kono
parents: 55
diff changeset
641 edge srce = EDGE_SUCC (srcbb, i);
kono
parents: 55
diff changeset
642 edge dste = EDGE_SUCC (dstbb, i);
kono
parents: 55
diff changeset
643 if (srce->probability.initialized_p ())
kono
parents: 55
diff changeset
644 dste->probability = srce->probability;
kono
parents: 55
diff changeset
645 }
kono
parents: 55
diff changeset
646 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
647 else
111
kono
parents: 55
diff changeset
648 {
kono
parents: 55
diff changeset
649 for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
kono
parents: 55
diff changeset
650 {
kono
parents: 55
diff changeset
651 edge srce = EDGE_SUCC (srcbb, i);
kono
parents: 55
diff changeset
652 edge dste = EDGE_SUCC (dstbb, i);
kono
parents: 55
diff changeset
653 dste->probability =
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
654 dste->probability * dstbb->count.ipa ().probability_in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
655 (dstbb->count.ipa ()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
656 + srccount.ipa ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
657 + srce->probability * srcbb->count.ipa ().probability_in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
658 (dstbb->count.ipa ()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
659 + srccount.ipa ());
111
kono
parents: 55
diff changeset
660 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
661 dstbb->count = dstbb->count.ipa () + srccount.ipa ();
111
kono
parents: 55
diff changeset
662 }
kono
parents: 55
diff changeset
663 }
kono
parents: 55
diff changeset
664 push_cfun (dstcfun);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
665 update_max_bb_count ();
111
kono
parents: 55
diff changeset
666 compute_function_frequency ();
kono
parents: 55
diff changeset
667 pop_cfun ();
kono
parents: 55
diff changeset
668 for (e = dst->callees; e; e = e->next_callee)
kono
parents: 55
diff changeset
669 {
kono
parents: 55
diff changeset
670 if (e->speculative)
kono
parents: 55
diff changeset
671 continue;
kono
parents: 55
diff changeset
672 e->count = gimple_bb (e->call_stmt)->count;
kono
parents: 55
diff changeset
673 }
kono
parents: 55
diff changeset
674 for (e = dst->indirect_calls, e2 = src->indirect_calls; e;
kono
parents: 55
diff changeset
675 e2 = (e2 ? e2->next_callee : NULL), e = e->next_callee)
kono
parents: 55
diff changeset
676 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
677 if (!e->speculative && !e2->speculative)
111
kono
parents: 55
diff changeset
678 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
679 /* FIXME: we need to also merge ipa-profile histograms
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
680 because with LTO merging happens from lto-symtab before
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
681 these are converted to indirect edges. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
682 e->count = gimple_bb (e->call_stmt)->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
683 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
684 }
111
kono
parents: 55
diff changeset
685
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
686 /* When copying just remove all speuclations on dst and then copy
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
687 one from src. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
688 if (copy_counts)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
689 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
690 while (e->speculative)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
691 cgraph_edge::resolve_speculation (e, NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
692 e->count = gimple_bb (e->call_stmt)->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
693 if (e2->speculative)
111
kono
parents: 55
diff changeset
694 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
695 for (cgraph_edge *e3 = e2->first_speculative_call_target ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
696 e3;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
697 e3 = e3->next_speculative_call_target ())
111
kono
parents: 55
diff changeset
698 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
699 cgraph_edge *ns;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
700 ns = e->make_speculative
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
701 (dyn_cast <cgraph_node *>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
702 (e3->speculative_call_target_ref ()->referred),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
703 e3->count, e3->speculative_id);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
704 /* Target may differ from ref (for example it may be
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
705 redirected to local alias. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
706 ns->redirect_callee (e3->callee);
111
kono
parents: 55
diff changeset
707 }
kono
parents: 55
diff changeset
708 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
709 continue;
111
kono
parents: 55
diff changeset
710 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
711
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
712 /* Iterate all speculations in SRC, see if corresponding ones exist
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
713 int DST and if so, sum the counts. Otherwise create new
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
714 speculation. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
715 int max_spec = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
716 for (cgraph_edge *e3 = e->first_speculative_call_target ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
717 e3;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
718 e3 = e3->next_speculative_call_target ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
719 if (e3->speculative_id > max_spec)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
720 max_spec = e3->speculative_id;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
721 for (cgraph_edge *e3 = e2->first_speculative_call_target ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
722 e3;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
723 e3 = e3->next_speculative_call_target ())
111
kono
parents: 55
diff changeset
724 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
725 cgraph_edge *te
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
726 = e->speculative_call_for_target
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
727 (dyn_cast <cgraph_node *>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
728 (e3->speculative_call_target_ref ()->referred));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
729 if (te)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
730 te->count = te->count + e3->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
731 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
732 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
733 e->count = e->count + e3->count;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
734 cgraph_edge *ns;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
735 ns = e->make_speculative
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
736 (dyn_cast <cgraph_node *>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
737 (e3->speculative_call_target_ref ()
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
738 ->referred),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
739 e3->count,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
740 e3->speculative_id + max_spec + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
741 /* Target may differ from ref (for example it may be
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
742 redirected to local alias. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
743 ns->redirect_callee (e3->callee);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
744 }
111
kono
parents: 55
diff changeset
745 }
kono
parents: 55
diff changeset
746 }
kono
parents: 55
diff changeset
747 if (!preserve_body)
kono
parents: 55
diff changeset
748 src->release_body ();
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
749 /* Update summary. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
750 compute_fn_summary (dst, 0);
111
kono
parents: 55
diff changeset
751 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
752 /* We can't update CFG profile, but we can scale IPA profile. CFG
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
753 will be scaled according to dst->count after IPA passes. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
754 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
755 scale_ipa_profile_for_fn (dst, orig_count);
111
kono
parents: 55
diff changeset
756 src->decl = oldsrcdecl;
kono
parents: 55
diff changeset
757 }
kono
parents: 55
diff changeset
758
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
759 /* Return true if call to DEST is known to be self-recusive
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
760 call withing FUNC. */
111
kono
parents: 55
diff changeset
761
kono
parents: 55
diff changeset
762 bool
kono
parents: 55
diff changeset
763 recursive_call_p (tree func, tree dest)
kono
parents: 55
diff changeset
764 {
kono
parents: 55
diff changeset
765 struct cgraph_node *dest_node = cgraph_node::get_create (dest);
kono
parents: 55
diff changeset
766 struct cgraph_node *cnode = cgraph_node::get_create (func);
kono
parents: 55
diff changeset
767 ipa_ref *alias;
kono
parents: 55
diff changeset
768 enum availability avail;
kono
parents: 55
diff changeset
769
kono
parents: 55
diff changeset
770 gcc_assert (!cnode->alias);
kono
parents: 55
diff changeset
771 if (cnode != dest_node->ultimate_alias_target (&avail))
kono
parents: 55
diff changeset
772 return false;
kono
parents: 55
diff changeset
773 if (avail >= AVAIL_AVAILABLE)
kono
parents: 55
diff changeset
774 return true;
kono
parents: 55
diff changeset
775 if (!dest_node->semantically_equivalent_p (cnode))
kono
parents: 55
diff changeset
776 return false;
kono
parents: 55
diff changeset
777 /* If there is only one way to call the fuction or we know all of them
kono
parents: 55
diff changeset
778 are semantically equivalent, we still can consider call recursive. */
kono
parents: 55
diff changeset
779 FOR_EACH_ALIAS (cnode, alias)
kono
parents: 55
diff changeset
780 if (!dest_node->semantically_equivalent_p (alias->referring))
kono
parents: 55
diff changeset
781 return false;
kono
parents: 55
diff changeset
782 return true;
kono
parents: 55
diff changeset
783 }