Mercurial > hg > CbC > CbC_gcc
annotate gcc/ipa-cp.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
rev | line source |
---|---|
0 | 1 /* Interprocedural constant propagation |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
3 Free Software Foundation, Inc. |
0 | 4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
5 |
0 | 6 This file is part of GCC. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
7 |
0 | 8 GCC is free software; you can redistribute it and/or modify it under |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
12 |
0 | 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
17 |
0 | 18 You should have received a copy of the GNU General Public License |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 /* Interprocedural constant propagation. The aim of interprocedural constant | |
23 propagation (IPCP) is to find which function's argument has the same | |
24 constant value in each invocation throughout the whole program. For example, | |
25 consider the following program: | |
26 | |
27 int g (int y) | |
28 { | |
29 printf ("value is %d",y); | |
30 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
31 |
0 | 32 int f (int x) |
33 { | |
34 g (x); | |
35 } | |
36 | |
37 int h (int y) | |
38 { | |
39 g (y); | |
40 } | |
41 | |
42 void main (void) | |
43 { | |
44 f (3); | |
45 h (3); | |
46 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
47 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
48 |
0 | 49 The IPCP algorithm will find that g's formal argument y is always called |
50 with the value 3. | |
51 | |
52 The algorithm used is based on "Interprocedural Constant Propagation", by | |
53 Challahan David, Keith D Cooper, Ken Kennedy, Linda Torczon, Comp86, pg | |
54 152-161 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
55 |
0 | 56 The optimization is divided into three stages: |
57 | |
58 First stage - intraprocedural analysis | |
59 ======================================= | |
60 This phase computes jump_function and modification flags. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
61 |
0 | 62 A jump function for a callsite represents the values passed as an actual |
63 arguments of a given callsite. There are three types of values: | |
64 Pass through - the caller's formal parameter is passed as an actual argument. | |
65 Constant - a constant is passed as an actual argument. | |
66 Unknown - neither of the above. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
67 |
0 | 68 The jump function info, ipa_jump_func, is stored in ipa_edge_args |
69 structure (defined in ipa_prop.h and pointed to by cgraph_node->aux) | |
70 modified_flags are defined in ipa_node_params structure | |
71 (defined in ipa_prop.h and pointed to by cgraph_edge->aux). | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
72 |
0 | 73 -ipcp_init_stage() is the first stage driver. |
74 | |
75 Second stage - interprocedural analysis | |
76 ======================================== | |
77 This phase does the interprocedural constant propagation. | |
78 It computes lattices for all formal parameters in the program | |
79 and their value that may be: | |
80 TOP - unknown. | |
81 BOTTOM - non constant. | |
82 CONSTANT - constant value. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
83 |
0 | 84 Lattice describing a formal parameter p will have a constant value if all |
85 callsites invoking this function have the same constant value passed to p. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
86 |
0 | 87 The lattices are stored in ipcp_lattice which is itself in ipa_node_params |
88 structure (defined in ipa_prop.h and pointed to by cgraph_edge->aux). | |
89 | |
90 -ipcp_iterate_stage() is the second stage driver. | |
91 | |
92 Third phase - transformation of function code | |
93 ============================================ | |
94 Propagates the constant-valued formals into the function. | |
95 For each function whose parameters are constants, we create its clone. | |
96 | |
97 Then we process the clone in two ways: | |
98 1. We insert an assignment statement 'parameter = const' at the beginning | |
99 of the cloned function. | |
100 2. For read-only parameters that do not live in memory, we replace all their | |
101 uses with the constant. | |
102 | |
103 We also need to modify some callsites to call the cloned functions instead | |
104 of the original ones. For a callsite passing an argument found to be a | |
105 constant by IPCP, there are two different cases to handle: | |
106 1. A constant is passed as an argument. In this case the callsite in the | |
107 should be redirected to call the cloned callee. | |
108 2. A parameter (of the caller) passed as an argument (pass through | |
109 argument). In such cases both the caller and the callee have clones and | |
110 only the callsite in the cloned caller is redirected to call to the | |
111 cloned callee. | |
112 | |
113 This update is done in two steps: First all cloned functions are created | |
114 during a traversal of the call graph, during which all callsites are | |
115 redirected to call the cloned function. Then the callsites are traversed | |
116 and many calls redirected back to fit the description above. | |
117 | |
118 -ipcp_insert_stage() is the third phase driver. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
119 |
0 | 120 */ |
121 | |
122 #include "config.h" | |
123 #include "system.h" | |
124 #include "coretypes.h" | |
125 #include "tree.h" | |
126 #include "target.h" | |
127 #include "cgraph.h" | |
128 #include "ipa-prop.h" | |
129 #include "tree-flow.h" | |
130 #include "tree-pass.h" | |
131 #include "flags.h" | |
132 #include "timevar.h" | |
133 #include "diagnostic.h" | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
134 #include "tree-pretty-print.h" |
0 | 135 #include "tree-dump.h" |
136 #include "tree-inline.h" | |
137 #include "fibheap.h" | |
138 #include "params.h" | |
139 | |
140 /* Number of functions identified as candidates for cloning. When not cloning | |
141 we can simplify iterate stage not forcing it to go through the decision | |
142 on what is profitable and what not. */ | |
143 static int n_cloning_candidates; | |
144 | |
145 /* Maximal count found in program. */ | |
146 static gcov_type max_count; | |
147 | |
148 /* Cgraph nodes that has been completely replaced by cloning during iterate | |
149 * stage and will be removed after ipcp is finished. */ | |
150 static bitmap dead_nodes; | |
151 | |
152 static void ipcp_print_profile_data (FILE *); | |
153 static void ipcp_function_scale_print (FILE *); | |
154 | |
155 /* Get the original node field of ipa_node_params associated with node NODE. */ | |
156 static inline struct cgraph_node * | |
157 ipcp_get_orig_node (struct cgraph_node *node) | |
158 { | |
159 return IPA_NODE_REF (node)->ipcp_orig_node; | |
160 } | |
161 | |
162 /* Return true if NODE describes a cloned/versioned function. */ | |
163 static inline bool | |
164 ipcp_node_is_clone (struct cgraph_node *node) | |
165 { | |
166 return (ipcp_get_orig_node (node) != NULL); | |
167 } | |
168 | |
169 /* Create ipa_node_params and its data structures for NEW_NODE. Set ORIG_NODE | |
170 as the ipcp_orig_node field in ipa_node_params. */ | |
171 static void | |
172 ipcp_init_cloned_node (struct cgraph_node *orig_node, | |
173 struct cgraph_node *new_node) | |
174 { | |
175 ipa_check_create_node_params (); | |
176 ipa_initialize_node_params (new_node); | |
177 IPA_NODE_REF (new_node)->ipcp_orig_node = orig_node; | |
178 } | |
179 | |
180 /* Perform intraprocedrual analysis needed for ipcp. */ | |
181 static void | |
182 ipcp_analyze_node (struct cgraph_node *node) | |
183 { | |
184 /* Unreachable nodes should have been eliminated before ipcp. */ | |
185 gcc_assert (node->needed || node->reachable); | |
186 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
187 node->local.versionable = tree_versionable_function_p (node->decl); |
0 | 188 ipa_initialize_node_params (node); |
189 ipa_detect_param_modifications (node); | |
190 } | |
191 | |
192 /* Return scale for NODE. */ | |
193 static inline gcov_type | |
194 ipcp_get_node_scale (struct cgraph_node *node) | |
195 { | |
196 return IPA_NODE_REF (node)->count_scale; | |
197 } | |
198 | |
199 /* Set COUNT as scale for NODE. */ | |
200 static inline void | |
201 ipcp_set_node_scale (struct cgraph_node *node, gcov_type count) | |
202 { | |
203 IPA_NODE_REF (node)->count_scale = count; | |
204 } | |
205 | |
206 /* Return whether LAT is a constant lattice. */ | |
207 static inline bool | |
208 ipcp_lat_is_const (struct ipcp_lattice *lat) | |
209 { | |
210 if (lat->type == IPA_CONST_VALUE) | |
211 return true; | |
212 else | |
213 return false; | |
214 } | |
215 | |
216 /* Return whether LAT is a constant lattice that ipa-cp can actually insert | |
217 into the code (i.e. constants excluding member pointers and pointers). */ | |
218 static inline bool | |
219 ipcp_lat_is_insertable (struct ipcp_lattice *lat) | |
220 { | |
221 return lat->type == IPA_CONST_VALUE; | |
222 } | |
223 | |
224 /* Return true if LAT1 and LAT2 are equal. */ | |
225 static inline bool | |
226 ipcp_lats_are_equal (struct ipcp_lattice *lat1, struct ipcp_lattice *lat2) | |
227 { | |
228 gcc_assert (ipcp_lat_is_const (lat1) && ipcp_lat_is_const (lat2)); | |
229 if (lat1->type != lat2->type) | |
230 return false; | |
231 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
232 if (TREE_CODE (lat1->constant) == ADDR_EXPR |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
233 && TREE_CODE (lat2->constant) == ADDR_EXPR |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
234 && TREE_CODE (TREE_OPERAND (lat1->constant, 0)) == CONST_DECL |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
235 && TREE_CODE (TREE_OPERAND (lat2->constant, 0)) == CONST_DECL) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
236 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (lat1->constant, 0)), |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
237 DECL_INITIAL (TREE_OPERAND (lat2->constant, 0)), 0); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
238 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
239 return operand_equal_p (lat1->constant, lat2->constant, 0); |
0 | 240 } |
241 | |
242 /* Compute Meet arithmetics: | |
243 Meet (IPA_BOTTOM, x) = IPA_BOTTOM | |
244 Meet (IPA_TOP,x) = x | |
245 Meet (const_a,const_b) = IPA_BOTTOM, if const_a != const_b. | |
246 MEET (const_a,const_b) = const_a, if const_a == const_b.*/ | |
247 static void | |
248 ipa_lattice_meet (struct ipcp_lattice *res, struct ipcp_lattice *lat1, | |
249 struct ipcp_lattice *lat2) | |
250 { | |
251 if (lat1->type == IPA_BOTTOM || lat2->type == IPA_BOTTOM) | |
252 { | |
253 res->type = IPA_BOTTOM; | |
254 return; | |
255 } | |
256 if (lat1->type == IPA_TOP) | |
257 { | |
258 res->type = lat2->type; | |
259 res->constant = lat2->constant; | |
260 return; | |
261 } | |
262 if (lat2->type == IPA_TOP) | |
263 { | |
264 res->type = lat1->type; | |
265 res->constant = lat1->constant; | |
266 return; | |
267 } | |
268 if (!ipcp_lats_are_equal (lat1, lat2)) | |
269 { | |
270 res->type = IPA_BOTTOM; | |
271 return; | |
272 } | |
273 res->type = lat1->type; | |
274 res->constant = lat1->constant; | |
275 } | |
276 | |
277 /* Return the lattice corresponding to the Ith formal parameter of the function | |
278 described by INFO. */ | |
279 static inline struct ipcp_lattice * | |
280 ipcp_get_lattice (struct ipa_node_params *info, int i) | |
281 { | |
282 return &(info->params[i].ipcp_lattice); | |
283 } | |
284 | |
285 /* Given the jump function JFUNC, compute the lattice LAT that describes the | |
286 value coming down the callsite. INFO describes the caller node so that | |
287 pass-through jump functions can be evaluated. */ | |
288 static void | |
289 ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, | |
290 struct ipa_jump_func *jfunc) | |
291 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
292 if (jfunc->type == IPA_JF_CONST) |
0 | 293 { |
294 lat->type = IPA_CONST_VALUE; | |
295 lat->constant = jfunc->value.constant; | |
296 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
297 else if (jfunc->type == IPA_JF_PASS_THROUGH) |
0 | 298 { |
299 struct ipcp_lattice *caller_lat; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
300 tree cst; |
0 | 301 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
302 caller_lat = ipcp_get_lattice (info, jfunc->value.pass_through.formal_id); |
0 | 303 lat->type = caller_lat->type; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
304 if (caller_lat->type != IPA_CONST_VALUE) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
305 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
306 cst = caller_lat->constant; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
307 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
308 if (jfunc->value.pass_through.operation != NOP_EXPR) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
309 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
310 tree restype; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
311 if (TREE_CODE_CLASS (jfunc->value.pass_through.operation) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
312 == tcc_comparison) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
313 restype = boolean_type_node; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
314 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
315 restype = TREE_TYPE (cst); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
316 cst = fold_binary (jfunc->value.pass_through.operation, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
317 restype, cst, jfunc->value.pass_through.operand); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
318 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
319 if (!cst || !is_gimple_ip_invariant (cst)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
320 lat->type = IPA_BOTTOM; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
321 lat->constant = cst; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
322 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
323 else if (jfunc->type == IPA_JF_ANCESTOR) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
324 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
325 struct ipcp_lattice *caller_lat; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
326 tree t; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
327 bool ok; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
328 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
329 caller_lat = ipcp_get_lattice (info, jfunc->value.ancestor.formal_id); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
330 lat->type = caller_lat->type; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
331 if (caller_lat->type != IPA_CONST_VALUE) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
332 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
333 if (TREE_CODE (caller_lat->constant) != ADDR_EXPR) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
334 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
335 /* This can happen when the constant is a NULL pointer. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
336 lat->type = IPA_BOTTOM; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
337 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
338 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
339 t = TREE_OPERAND (caller_lat->constant, 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
340 ok = build_ref_for_offset (&t, TREE_TYPE (t), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
341 jfunc->value.ancestor.offset, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
342 jfunc->value.ancestor.type, false); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
343 if (!ok) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
344 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
345 lat->type = IPA_BOTTOM; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
346 lat->constant = NULL_TREE; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
347 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
348 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
349 lat->constant = build_fold_addr_expr (t); |
0 | 350 } |
351 else | |
352 lat->type = IPA_BOTTOM; | |
353 } | |
354 | |
355 /* True when OLD_LAT and NEW_LAT values are not the same. */ | |
356 | |
357 static bool | |
358 ipcp_lattice_changed (struct ipcp_lattice *old_lat, | |
359 struct ipcp_lattice *new_lat) | |
360 { | |
361 if (old_lat->type == new_lat->type) | |
362 { | |
363 if (!ipcp_lat_is_const (old_lat)) | |
364 return false; | |
365 if (ipcp_lats_are_equal (old_lat, new_lat)) | |
366 return false; | |
367 } | |
368 return true; | |
369 } | |
370 | |
371 /* Print all ipcp_lattices of all functions to F. */ | |
372 static void | |
373 ipcp_print_all_lattices (FILE * f) | |
374 { | |
375 struct cgraph_node *node; | |
376 int i, count; | |
377 | |
378 fprintf (f, "\nLattice:\n"); | |
379 for (node = cgraph_nodes; node; node = node->next) | |
380 { | |
381 struct ipa_node_params *info; | |
382 | |
383 if (!node->analyzed) | |
384 continue; | |
385 info = IPA_NODE_REF (node); | |
386 fprintf (f, " Node: %s:\n", cgraph_node_name (node)); | |
387 count = ipa_get_param_count (info); | |
388 for (i = 0; i < count; i++) | |
389 { | |
390 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
391 | |
392 fprintf (f, " param [%d]: ", i); | |
393 if (lat->type == IPA_CONST_VALUE) | |
394 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
395 tree cst = lat->constant; |
0 | 396 fprintf (f, "type is CONST "); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
397 print_generic_expr (f, cst, 0); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
398 if (TREE_CODE (cst) == ADDR_EXPR |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
399 && TREE_CODE (TREE_OPERAND (cst, 0)) == CONST_DECL) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
400 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
401 fprintf (f, " -> "); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
402 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (cst, 0)), |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
403 0); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
404 } |
0 | 405 fprintf (f, "\n"); |
406 } | |
407 else if (lat->type == IPA_TOP) | |
408 fprintf (f, "type is TOP\n"); | |
409 else | |
410 fprintf (f, "type is BOTTOM\n"); | |
411 } | |
412 } | |
413 } | |
414 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
415 /* Return true if ipcp algorithms would allow cloning NODE. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
416 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
417 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
418 ipcp_versionable_function_p (struct cgraph_node *node) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
419 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
420 struct cgraph_edge *edge; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
421 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
422 /* There are a number of generic reasons functions cannot be versioned. */ |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
423 if (!node->local.versionable) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
424 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
425 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
426 /* Removing arguments doesn't work if the function takes varargs |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
427 or use __builtin_apply_args. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
428 for (edge = node->callees; edge; edge = edge->next_callee) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
429 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
430 tree t = edge->callee->decl; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
431 if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
432 && (DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
433 || DECL_FUNCTION_CODE (t) == BUILT_IN_VA_START)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
434 return false; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
435 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
436 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
437 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
438 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
439 |
0 | 440 /* Return true if this NODE is viable candidate for cloning. */ |
441 static bool | |
442 ipcp_cloning_candidate_p (struct cgraph_node *node) | |
443 { | |
444 int n_calls = 0; | |
445 int n_hot_calls = 0; | |
446 gcov_type direct_call_sum = 0; | |
447 struct cgraph_edge *e; | |
448 | |
449 /* We never clone functions that are not visible from outside. | |
450 FIXME: in future we should clone such functions when they are called with | |
451 different constants, but current ipcp implementation is not good on this. | |
452 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
453 if (cgraph_only_called_directly_p (node) || !node->analyzed) |
0 | 454 return false; |
455 | |
456 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) | |
457 { | |
458 if (dump_file) | |
459 fprintf (dump_file, "Not considering %s for cloning; body is overwrittable.\n", | |
460 cgraph_node_name (node)); | |
461 return false; | |
462 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
463 if (!ipcp_versionable_function_p (node)) |
0 | 464 { |
465 if (dump_file) | |
466 fprintf (dump_file, "Not considering %s for cloning; body is not versionable.\n", | |
467 cgraph_node_name (node)); | |
468 return false; | |
469 } | |
470 for (e = node->callers; e; e = e->next_caller) | |
471 { | |
472 direct_call_sum += e->count; | |
473 n_calls ++; | |
474 if (cgraph_maybe_hot_edge_p (e)) | |
475 n_hot_calls ++; | |
476 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
477 |
0 | 478 if (!n_calls) |
479 { | |
480 if (dump_file) | |
481 fprintf (dump_file, "Not considering %s for cloning; no direct calls.\n", | |
482 cgraph_node_name (node)); | |
483 return false; | |
484 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
485 if (node->local.inline_summary.self_size < n_calls) |
0 | 486 { |
487 if (dump_file) | |
488 fprintf (dump_file, "Considering %s for cloning; code would shrink.\n", | |
489 cgraph_node_name (node)); | |
490 return true; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
491 } |
0 | 492 |
493 if (!flag_ipa_cp_clone) | |
494 { | |
495 if (dump_file) | |
496 fprintf (dump_file, "Not considering %s for cloning; -fipa-cp-clone disabled.\n", | |
497 cgraph_node_name (node)); | |
498 return false; | |
499 } | |
500 | |
501 if (!optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl))) | |
502 { | |
503 if (dump_file) | |
504 fprintf (dump_file, "Not considering %s for cloning; optimizing it for size.\n", | |
505 cgraph_node_name (node)); | |
506 return false; | |
507 } | |
508 | |
509 /* When profile is available and function is hot, propagate into it even if | |
510 calls seems cold; constant propagation can improve function's speed | |
511 significandly. */ | |
512 if (max_count) | |
513 { | |
514 if (direct_call_sum > node->count * 90 / 100) | |
515 { | |
516 if (dump_file) | |
517 fprintf (dump_file, "Considering %s for cloning; usually called directly.\n", | |
518 cgraph_node_name (node)); | |
519 return true; | |
520 } | |
521 } | |
522 if (!n_hot_calls) | |
523 { | |
524 if (dump_file) | |
525 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n", | |
526 cgraph_node_name (node)); | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
527 return false; |
0 | 528 } |
529 if (dump_file) | |
530 fprintf (dump_file, "Considering %s for cloning.\n", | |
531 cgraph_node_name (node)); | |
532 return true; | |
533 } | |
534 | |
535 /* Initialize ipcp_lattices array. The lattices corresponding to supported | |
536 types (integers, real types and Fortran constants defined as const_decls) | |
537 are initialized to IPA_TOP, the rest of them to IPA_BOTTOM. */ | |
538 static void | |
539 ipcp_initialize_node_lattices (struct cgraph_node *node) | |
540 { | |
541 int i; | |
542 struct ipa_node_params *info = IPA_NODE_REF (node); | |
543 enum ipa_lattice_type type; | |
544 | |
545 if (ipa_is_called_with_var_arguments (info)) | |
546 type = IPA_BOTTOM; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
547 else if (cgraph_only_called_directly_p (node)) |
0 | 548 type = IPA_TOP; |
549 /* When cloning is allowed, we can assume that externally visible functions | |
550 are not called. We will compensate this by cloning later. */ | |
551 else if (ipcp_cloning_candidate_p (node)) | |
552 type = IPA_TOP, n_cloning_candidates ++; | |
553 else | |
554 type = IPA_BOTTOM; | |
555 | |
556 for (i = 0; i < ipa_get_param_count (info) ; i++) | |
557 ipcp_get_lattice (info, i)->type = type; | |
558 } | |
559 | |
560 /* build INTEGER_CST tree with type TREE_TYPE and value according to LAT. | |
561 Return the tree. */ | |
562 static tree | |
563 build_const_val (struct ipcp_lattice *lat, tree tree_type) | |
564 { | |
565 tree val; | |
566 | |
567 gcc_assert (ipcp_lat_is_const (lat)); | |
568 val = lat->constant; | |
569 | |
570 if (!useless_type_conversion_p (tree_type, TREE_TYPE (val))) | |
571 { | |
572 if (fold_convertible_p (tree_type, val)) | |
573 return fold_build1 (NOP_EXPR, tree_type, val); | |
574 else | |
575 return fold_build1 (VIEW_CONVERT_EXPR, tree_type, val); | |
576 } | |
577 return val; | |
578 } | |
579 | |
580 /* Compute the proper scale for NODE. It is the ratio between the number of | |
581 direct calls (represented on the incoming cgraph_edges) and sum of all | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
582 invocations of NODE (represented as count in cgraph_node). |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
583 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
584 FIXME: This code is wrong. Since the callers can be also clones and |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
585 the clones are not scaled yet, the sums gets unrealistically high. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
586 To properly compute the counts, we would need to do propagation across |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
587 callgraph (as external call to A might imply call to non-clonned B |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
588 if A's clone calls clonned B). */ |
0 | 589 static void |
590 ipcp_compute_node_scale (struct cgraph_node *node) | |
591 { | |
592 gcov_type sum; | |
593 struct cgraph_edge *cs; | |
594 | |
595 sum = 0; | |
596 /* Compute sum of all counts of callers. */ | |
597 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
598 sum += cs->count; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
599 /* Work around the unrealistically high sum problem. We just don't want |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
600 the non-cloned body to have negative or very low frequency. Since |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
601 majority of execution time will be spent in clones anyway, this should |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
602 give good enough profile. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
603 if (sum > node->count * 9 / 10) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
604 sum = node->count * 9 / 10; |
0 | 605 if (node->count == 0) |
606 ipcp_set_node_scale (node, 0); | |
607 else | |
608 ipcp_set_node_scale (node, sum * REG_BR_PROB_BASE / node->count); | |
609 } | |
610 | |
611 /* Initialization and computation of IPCP data structures. This is the initial | |
612 intraprocedural analysis of functions, which gathers information to be | |
613 propagated later on. */ | |
614 static void | |
615 ipcp_init_stage (void) | |
616 { | |
617 struct cgraph_node *node; | |
618 | |
619 for (node = cgraph_nodes; node; node = node->next) | |
620 if (node->analyzed) | |
621 ipcp_analyze_node (node); | |
622 for (node = cgraph_nodes; node; node = node->next) | |
623 { | |
624 if (!node->analyzed) | |
625 continue; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
626 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
627 ipa_analyze_params_uses (node); |
0 | 628 /* building jump functions */ |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
629 ipa_compute_jump_functions (node); |
0 | 630 } |
631 } | |
632 | |
633 /* Return true if there are some formal parameters whose value is IPA_TOP (in | |
634 the whole compilation unit). Change their values to IPA_BOTTOM, since they | |
635 most probably get their values from outside of this compilation unit. */ | |
636 static bool | |
637 ipcp_change_tops_to_bottom (void) | |
638 { | |
639 int i, count; | |
640 struct cgraph_node *node; | |
641 bool prop_again; | |
642 | |
643 prop_again = false; | |
644 for (node = cgraph_nodes; node; node = node->next) | |
645 { | |
646 struct ipa_node_params *info = IPA_NODE_REF (node); | |
647 count = ipa_get_param_count (info); | |
648 for (i = 0; i < count; i++) | |
649 { | |
650 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
651 if (lat->type == IPA_TOP) | |
652 { | |
653 prop_again = true; | |
654 if (dump_file) | |
655 { | |
656 fprintf (dump_file, "Forcing param "); | |
657 print_generic_expr (dump_file, ipa_get_param (info, i), 0); | |
658 fprintf (dump_file, " of node %s to bottom.\n", | |
659 cgraph_node_name (node)); | |
660 } | |
661 lat->type = IPA_BOTTOM; | |
662 } | |
663 } | |
664 } | |
665 return prop_again; | |
666 } | |
667 | |
668 /* Interprocedural analysis. The algorithm propagates constants from the | |
669 caller's parameters to the callee's arguments. */ | |
670 static void | |
671 ipcp_propagate_stage (void) | |
672 { | |
673 int i; | |
674 struct ipcp_lattice inc_lat = { IPA_BOTTOM, NULL }; | |
675 struct ipcp_lattice new_lat = { IPA_BOTTOM, NULL }; | |
676 struct ipcp_lattice *dest_lat; | |
677 struct cgraph_edge *cs; | |
678 struct ipa_jump_func *jump_func; | |
679 struct ipa_func_list *wl; | |
680 int count; | |
681 | |
682 ipa_check_create_node_params (); | |
683 ipa_check_create_edge_args (); | |
684 | |
685 /* Initialize worklist to contain all functions. */ | |
686 wl = ipa_init_func_list (); | |
687 while (wl) | |
688 { | |
689 struct cgraph_node *node = ipa_pop_func_from_list (&wl); | |
690 struct ipa_node_params *info = IPA_NODE_REF (node); | |
691 | |
692 for (cs = node->callees; cs; cs = cs->next_callee) | |
693 { | |
694 struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee); | |
695 struct ipa_edge_args *args = IPA_EDGE_REF (cs); | |
696 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
697 if (ipa_is_called_with_var_arguments (callee_info) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
698 || !cs->callee->analyzed |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
699 || ipa_is_called_with_var_arguments (callee_info)) |
0 | 700 continue; |
701 | |
702 count = ipa_get_cs_argument_count (args); | |
703 for (i = 0; i < count; i++) | |
704 { | |
705 jump_func = ipa_get_ith_jump_func (args, i); | |
706 ipcp_lattice_from_jfunc (info, &inc_lat, jump_func); | |
707 dest_lat = ipcp_get_lattice (callee_info, i); | |
708 ipa_lattice_meet (&new_lat, &inc_lat, dest_lat); | |
709 if (ipcp_lattice_changed (&new_lat, dest_lat)) | |
710 { | |
711 dest_lat->type = new_lat.type; | |
712 dest_lat->constant = new_lat.constant; | |
713 ipa_push_func_to_list (&wl, cs->callee); | |
714 } | |
715 } | |
716 } | |
717 } | |
718 } | |
719 | |
720 /* Call the constant propagation algorithm and re-call it if necessary | |
721 (if there are undetermined values left). */ | |
722 static void | |
723 ipcp_iterate_stage (void) | |
724 { | |
725 struct cgraph_node *node; | |
726 n_cloning_candidates = 0; | |
727 | |
728 if (dump_file) | |
729 fprintf (dump_file, "\nIPA iterate stage:\n\n"); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
730 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
731 if (in_lto_p) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
732 ipa_update_after_lto_read (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
733 |
0 | 734 for (node = cgraph_nodes; node; node = node->next) |
735 { | |
736 ipcp_initialize_node_lattices (node); | |
737 ipcp_compute_node_scale (node); | |
738 } | |
739 if (dump_file && (dump_flags & TDF_DETAILS)) | |
740 { | |
741 ipcp_print_all_lattices (dump_file); | |
742 ipcp_function_scale_print (dump_file); | |
743 } | |
744 | |
745 ipcp_propagate_stage (); | |
746 if (ipcp_change_tops_to_bottom ()) | |
747 /* Some lattices have changed from IPA_TOP to IPA_BOTTOM. | |
748 This change should be propagated. */ | |
749 { | |
750 gcc_assert (n_cloning_candidates); | |
751 ipcp_propagate_stage (); | |
752 } | |
753 if (dump_file) | |
754 { | |
755 fprintf (dump_file, "\nIPA lattices after propagation:\n"); | |
756 ipcp_print_all_lattices (dump_file); | |
757 if (dump_flags & TDF_DETAILS) | |
758 ipcp_print_profile_data (dump_file); | |
759 } | |
760 } | |
761 | |
762 /* Check conditions to forbid constant insertion to function described by | |
763 NODE. */ | |
764 static inline bool | |
765 ipcp_node_modifiable_p (struct cgraph_node *node) | |
766 { | |
767 /* Once we will be able to do in-place replacement, we can be more | |
768 lax here. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
769 return ipcp_versionable_function_p (node); |
0 | 770 } |
771 | |
772 /* Print count scale data structures. */ | |
773 static void | |
774 ipcp_function_scale_print (FILE * f) | |
775 { | |
776 struct cgraph_node *node; | |
777 | |
778 for (node = cgraph_nodes; node; node = node->next) | |
779 { | |
780 if (!node->analyzed) | |
781 continue; | |
782 fprintf (f, "printing scale for %s: ", cgraph_node_name (node)); | |
783 fprintf (f, "value is " HOST_WIDE_INT_PRINT_DEC | |
784 " \n", (HOST_WIDE_INT) ipcp_get_node_scale (node)); | |
785 } | |
786 } | |
787 | |
788 /* Print counts of all cgraph nodes. */ | |
789 static void | |
790 ipcp_print_func_profile_counts (FILE * f) | |
791 { | |
792 struct cgraph_node *node; | |
793 | |
794 for (node = cgraph_nodes; node; node = node->next) | |
795 { | |
796 fprintf (f, "function %s: ", cgraph_node_name (node)); | |
797 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC | |
798 " \n", (HOST_WIDE_INT) node->count); | |
799 } | |
800 } | |
801 | |
802 /* Print counts of all cgraph edges. */ | |
803 static void | |
804 ipcp_print_call_profile_counts (FILE * f) | |
805 { | |
806 struct cgraph_node *node; | |
807 struct cgraph_edge *cs; | |
808 | |
809 for (node = cgraph_nodes; node; node = node->next) | |
810 { | |
811 for (cs = node->callees; cs; cs = cs->next_callee) | |
812 { | |
813 fprintf (f, "%s -> %s ", cgraph_node_name (cs->caller), | |
814 cgraph_node_name (cs->callee)); | |
815 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC " \n", | |
816 (HOST_WIDE_INT) cs->count); | |
817 } | |
818 } | |
819 } | |
820 | |
821 /* Print profile info for all functions. */ | |
822 static void | |
823 ipcp_print_profile_data (FILE * f) | |
824 { | |
825 fprintf (f, "\nNODE COUNTS :\n"); | |
826 ipcp_print_func_profile_counts (f); | |
827 fprintf (f, "\nCS COUNTS stage:\n"); | |
828 ipcp_print_call_profile_counts (f); | |
829 } | |
830 | |
831 /* Build and initialize ipa_replace_map struct according to LAT. This struct is | |
832 processed by versioning, which operates according to the flags set. | |
833 PARM_TREE is the formal parameter found to be constant. LAT represents the | |
834 constant. */ | |
835 static struct ipa_replace_map * | |
836 ipcp_create_replace_map (tree parm_tree, struct ipcp_lattice *lat) | |
837 { | |
838 struct ipa_replace_map *replace_map; | |
839 tree const_val; | |
840 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
841 replace_map = GGC_NEW (struct ipa_replace_map); |
0 | 842 const_val = build_const_val (lat, TREE_TYPE (parm_tree)); |
843 if (dump_file) | |
844 { | |
845 fprintf (dump_file, " replacing param "); | |
846 print_generic_expr (dump_file, parm_tree, 0); | |
847 fprintf (dump_file, " with const "); | |
848 print_generic_expr (dump_file, const_val, 0); | |
849 fprintf (dump_file, "\n"); | |
850 } | |
851 replace_map->old_tree = parm_tree; | |
852 replace_map->new_tree = const_val; | |
853 replace_map->replace_p = true; | |
854 replace_map->ref_p = false; | |
855 | |
856 return replace_map; | |
857 } | |
858 | |
859 /* Return true if this callsite should be redirected to the original callee | |
860 (instead of the cloned one). */ | |
861 static bool | |
862 ipcp_need_redirect_p (struct cgraph_edge *cs) | |
863 { | |
864 struct ipa_node_params *orig_callee_info; | |
865 int i, count; | |
866 struct ipa_jump_func *jump_func; | |
867 struct cgraph_node *node = cs->callee, *orig; | |
868 | |
869 if (!n_cloning_candidates) | |
870 return false; | |
871 | |
872 if ((orig = ipcp_get_orig_node (node)) != NULL) | |
873 node = orig; | |
874 if (ipcp_get_orig_node (cs->caller)) | |
875 return false; | |
876 | |
877 orig_callee_info = IPA_NODE_REF (node); | |
878 count = ipa_get_param_count (orig_callee_info); | |
879 for (i = 0; i < count; i++) | |
880 { | |
881 struct ipcp_lattice *lat = ipcp_get_lattice (orig_callee_info, i); | |
882 if (ipcp_lat_is_const (lat)) | |
883 { | |
884 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
885 if (jump_func->type != IPA_JF_CONST) |
0 | 886 return true; |
887 } | |
888 } | |
889 | |
890 return false; | |
891 } | |
892 | |
893 /* Fix the callsites and the call graph after function cloning was done. */ | |
894 static void | |
895 ipcp_update_callgraph (void) | |
896 { | |
897 struct cgraph_node *node; | |
898 | |
899 for (node = cgraph_nodes; node; node = node->next) | |
900 if (node->analyzed && ipcp_node_is_clone (node)) | |
901 { | |
902 bitmap args_to_skip = BITMAP_ALLOC (NULL); | |
903 struct cgraph_node *orig_node = ipcp_get_orig_node (node); | |
904 struct ipa_node_params *info = IPA_NODE_REF (orig_node); | |
905 int i, count = ipa_get_param_count (info); | |
906 struct cgraph_edge *cs, *next; | |
907 | |
908 for (i = 0; i < count; i++) | |
909 { | |
910 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
911 | |
912 /* We can proactively remove obviously unused arguments. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
913 if (!ipa_is_param_used (info, i)) |
0 | 914 { |
915 bitmap_set_bit (args_to_skip, i); | |
916 continue; | |
917 } | |
918 | |
919 if (lat->type == IPA_CONST_VALUE) | |
920 bitmap_set_bit (args_to_skip, i); | |
921 } | |
922 for (cs = node->callers; cs; cs = next) | |
923 { | |
924 next = cs->next_caller; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
925 if (!ipcp_node_is_clone (cs->caller) && ipcp_need_redirect_p (cs)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
926 cgraph_redirect_edge_callee (cs, orig_node); |
0 | 927 } |
928 } | |
929 } | |
930 | |
931 /* Update profiling info for versioned functions and the functions they were | |
932 versioned from. */ | |
933 static void | |
934 ipcp_update_profiling (void) | |
935 { | |
936 struct cgraph_node *node, *orig_node; | |
937 gcov_type scale, scale_complement; | |
938 struct cgraph_edge *cs; | |
939 | |
940 for (node = cgraph_nodes; node; node = node->next) | |
941 { | |
942 if (ipcp_node_is_clone (node)) | |
943 { | |
944 orig_node = ipcp_get_orig_node (node); | |
945 scale = ipcp_get_node_scale (orig_node); | |
946 node->count = orig_node->count * scale / REG_BR_PROB_BASE; | |
947 scale_complement = REG_BR_PROB_BASE - scale; | |
948 orig_node->count = | |
949 orig_node->count * scale_complement / REG_BR_PROB_BASE; | |
950 for (cs = node->callees; cs; cs = cs->next_callee) | |
951 cs->count = cs->count * scale / REG_BR_PROB_BASE; | |
952 for (cs = orig_node->callees; cs; cs = cs->next_callee) | |
953 cs->count = cs->count * scale_complement / REG_BR_PROB_BASE; | |
954 } | |
955 } | |
956 } | |
957 | |
958 /* If NODE was cloned, how much would program grow? */ | |
959 static long | |
960 ipcp_estimate_growth (struct cgraph_node *node) | |
961 { | |
962 struct cgraph_edge *cs; | |
963 int redirectable_node_callers = 0; | |
964 int removable_args = 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
965 bool need_original = !cgraph_only_called_directly_p (node); |
0 | 966 struct ipa_node_params *info; |
967 int i, count; | |
968 int growth; | |
969 | |
970 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
971 if (cs->caller == node || !ipcp_need_redirect_p (cs)) | |
972 redirectable_node_callers++; | |
973 else | |
974 need_original = true; | |
975 | |
976 /* If we will be able to fully replace orignal node, we never increase | |
977 program size. */ | |
978 if (!need_original) | |
979 return 0; | |
980 | |
981 info = IPA_NODE_REF (node); | |
982 count = ipa_get_param_count (info); | |
983 for (i = 0; i < count; i++) | |
984 { | |
985 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
986 | |
987 /* We can proactively remove obviously unused arguments. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
988 if (!ipa_is_param_used (info, i)) |
0 | 989 removable_args++; |
990 | |
991 if (lat->type == IPA_CONST_VALUE) | |
992 removable_args++; | |
993 } | |
994 | |
995 /* We make just very simple estimate of savings for removal of operand from | |
996 call site. Precise cost is dificult to get, as our size metric counts | |
997 constants and moves as free. Generally we are looking for cases that | |
998 small function is called very many times. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
999 growth = node->local.inline_summary.self_size |
0 | 1000 - removable_args * redirectable_node_callers; |
1001 if (growth < 0) | |
1002 return 0; | |
1003 return growth; | |
1004 } | |
1005 | |
1006 | |
1007 /* Estimate cost of cloning NODE. */ | |
1008 static long | |
1009 ipcp_estimate_cloning_cost (struct cgraph_node *node) | |
1010 { | |
1011 int freq_sum = 1; | |
1012 gcov_type count_sum = 1; | |
1013 struct cgraph_edge *e; | |
1014 int cost; | |
1015 | |
1016 cost = ipcp_estimate_growth (node) * 1000; | |
1017 if (!cost) | |
1018 { | |
1019 if (dump_file) | |
1020 fprintf (dump_file, "Versioning of %s will save code size\n", | |
1021 cgraph_node_name (node)); | |
1022 return 0; | |
1023 } | |
1024 | |
1025 for (e = node->callers; e; e = e->next_caller) | |
1026 if (!bitmap_bit_p (dead_nodes, e->caller->uid) | |
1027 && !ipcp_need_redirect_p (e)) | |
1028 { | |
1029 count_sum += e->count; | |
1030 freq_sum += e->frequency + 1; | |
1031 } | |
1032 | |
1033 if (max_count) | |
1034 cost /= count_sum * 1000 / max_count + 1; | |
1035 else | |
1036 cost /= freq_sum * 1000 / REG_BR_PROB_BASE + 1; | |
1037 if (dump_file) | |
1038 fprintf (dump_file, "Cost of versioning %s is %i, (size: %i, freq: %i)\n", | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1039 cgraph_node_name (node), cost, node->local.inline_summary.self_size, |
0 | 1040 freq_sum); |
1041 return cost + 1; | |
1042 } | |
1043 | |
1044 /* Return number of live constant parameters. */ | |
1045 static int | |
1046 ipcp_const_param_count (struct cgraph_node *node) | |
1047 { | |
1048 int const_param = 0; | |
1049 struct ipa_node_params *info = IPA_NODE_REF (node); | |
1050 int count = ipa_get_param_count (info); | |
1051 int i; | |
1052 | |
1053 for (i = 0; i < count; i++) | |
1054 { | |
1055 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
1056 if (ipcp_lat_is_insertable (lat) | |
1057 /* Do not count obviously unused arguments. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1058 && ipa_is_param_used (info, i)) |
0 | 1059 const_param++; |
1060 } | |
1061 return const_param; | |
1062 } | |
1063 | |
1064 /* Propagate the constant parameters found by ipcp_iterate_stage() | |
1065 to the function's code. */ | |
1066 static void | |
1067 ipcp_insert_stage (void) | |
1068 { | |
1069 struct cgraph_node *node, *node1 = NULL; | |
1070 int i; | |
1071 VEC (cgraph_edge_p, heap) * redirect_callers; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1072 VEC (ipa_replace_map_p,gc)* replace_trees; |
0 | 1073 int node_callers, count; |
1074 tree parm_tree; | |
1075 struct ipa_replace_map *replace_param; | |
1076 fibheap_t heap; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1077 long overall_size = 0, new_size = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1078 long max_new_size; |
0 | 1079 |
1080 ipa_check_create_node_params (); | |
1081 ipa_check_create_edge_args (); | |
1082 if (dump_file) | |
1083 fprintf (dump_file, "\nIPA insert stage:\n\n"); | |
1084 | |
1085 dead_nodes = BITMAP_ALLOC (NULL); | |
1086 | |
1087 for (node = cgraph_nodes; node; node = node->next) | |
1088 if (node->analyzed) | |
1089 { | |
1090 if (node->count > max_count) | |
1091 max_count = node->count; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1092 overall_size += node->local.inline_summary.self_size; |
0 | 1093 } |
1094 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1095 max_new_size = overall_size; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1096 if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1097 max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1098 max_new_size = max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1; |
0 | 1099 |
1100 /* First collect all functions we proved to have constant arguments to heap. */ | |
1101 heap = fibheap_new (); | |
1102 for (node = cgraph_nodes; node; node = node->next) | |
1103 { | |
1104 struct ipa_node_params *info; | |
1105 /* Propagation of the constant is forbidden in certain conditions. */ | |
1106 if (!node->analyzed || !ipcp_node_modifiable_p (node)) | |
1107 continue; | |
1108 info = IPA_NODE_REF (node); | |
1109 if (ipa_is_called_with_var_arguments (info)) | |
1110 continue; | |
1111 if (ipcp_const_param_count (node)) | |
1112 node->aux = fibheap_insert (heap, ipcp_estimate_cloning_cost (node), node); | |
1113 } | |
1114 | |
1115 /* Now clone in priority order until code size growth limits are met or | |
1116 heap is emptied. */ | |
1117 while (!fibheap_empty (heap)) | |
1118 { | |
1119 struct ipa_node_params *info; | |
1120 int growth = 0; | |
1121 bitmap args_to_skip; | |
1122 struct cgraph_edge *cs; | |
1123 | |
1124 node = (struct cgraph_node *)fibheap_extract_min (heap); | |
1125 node->aux = NULL; | |
1126 if (dump_file) | |
1127 fprintf (dump_file, "considering function %s\n", | |
1128 cgraph_node_name (node)); | |
1129 | |
1130 growth = ipcp_estimate_growth (node); | |
1131 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1132 if (new_size + growth > max_new_size) |
0 | 1133 break; |
1134 if (growth | |
1135 && optimize_function_for_size_p (DECL_STRUCT_FUNCTION (node->decl))) | |
1136 { | |
1137 if (dump_file) | |
1138 fprintf (dump_file, "Not versioning, cold code would grow"); | |
1139 continue; | |
1140 } | |
1141 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1142 new_size += growth; |
0 | 1143 |
1144 /* Look if original function becomes dead after clonning. */ | |
1145 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
1146 if (cs->caller == node || ipcp_need_redirect_p (cs)) | |
1147 break; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1148 if (!cs && cgraph_only_called_directly_p (node)) |
0 | 1149 bitmap_set_bit (dead_nodes, node->uid); |
1150 | |
1151 info = IPA_NODE_REF (node); | |
1152 count = ipa_get_param_count (info); | |
1153 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1154 replace_trees = VEC_alloc (ipa_replace_map_p, gc, 1); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1155 args_to_skip = BITMAP_GGC_ALLOC (); |
0 | 1156 for (i = 0; i < count; i++) |
1157 { | |
1158 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
1159 parm_tree = ipa_get_param (info, i); | |
1160 | |
1161 /* We can proactively remove obviously unused arguments. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1162 if (!ipa_is_param_used (info, i)) |
0 | 1163 { |
1164 bitmap_set_bit (args_to_skip, i); | |
1165 continue; | |
1166 } | |
1167 | |
1168 if (lat->type == IPA_CONST_VALUE) | |
1169 { | |
1170 replace_param = | |
1171 ipcp_create_replace_map (parm_tree, lat); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1172 VEC_safe_push (ipa_replace_map_p, gc, replace_trees, replace_param); |
0 | 1173 bitmap_set_bit (args_to_skip, i); |
1174 } | |
1175 } | |
1176 | |
1177 /* Compute how many callers node has. */ | |
1178 node_callers = 0; | |
1179 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
1180 node_callers++; | |
1181 redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers); | |
1182 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
1183 VEC_quick_push (cgraph_edge_p, redirect_callers, cs); | |
1184 | |
1185 /* Redirecting all the callers of the node to the | |
1186 new versioned node. */ | |
1187 node1 = | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1188 cgraph_create_virtual_clone (node, redirect_callers, replace_trees, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1189 args_to_skip); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1190 args_to_skip = NULL; |
0 | 1191 VEC_free (cgraph_edge_p, heap, redirect_callers); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1192 replace_trees = NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1193 |
0 | 1194 if (node1 == NULL) |
1195 continue; | |
1196 if (dump_file) | |
1197 fprintf (dump_file, "versioned function %s with growth %i, overall %i\n", | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1198 cgraph_node_name (node), (int)growth, (int)new_size); |
0 | 1199 ipcp_init_cloned_node (node, node1); |
1200 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1201 /* TODO: We can use indirect inlning info to produce new calls. */ |
0 | 1202 |
1203 if (dump_file) | |
1204 dump_function_to_file (node1->decl, dump_file, dump_flags); | |
1205 | |
1206 for (cs = node->callees; cs; cs = cs->next_callee) | |
1207 if (cs->callee->aux) | |
1208 { | |
1209 fibheap_delete_node (heap, (fibnode_t) cs->callee->aux); | |
1210 cs->callee->aux = fibheap_insert (heap, | |
1211 ipcp_estimate_cloning_cost (cs->callee), | |
1212 cs->callee); | |
1213 } | |
1214 } | |
1215 | |
1216 while (!fibheap_empty (heap)) | |
1217 { | |
1218 if (dump_file) | |
1219 fprintf (dump_file, "skipping function %s\n", | |
1220 cgraph_node_name (node)); | |
1221 node = (struct cgraph_node *) fibheap_extract_min (heap); | |
1222 node->aux = NULL; | |
1223 } | |
1224 fibheap_delete (heap); | |
1225 BITMAP_FREE (dead_nodes); | |
1226 ipcp_update_callgraph (); | |
1227 ipcp_update_profiling (); | |
1228 } | |
1229 | |
1230 /* The IPCP driver. */ | |
1231 static unsigned int | |
1232 ipcp_driver (void) | |
1233 { | |
1234 cgraph_remove_unreachable_nodes (true,dump_file); | |
1235 if (dump_file) | |
1236 { | |
1237 fprintf (dump_file, "\nIPA structures before propagation:\n"); | |
1238 if (dump_flags & TDF_DETAILS) | |
1239 ipa_print_all_params (dump_file); | |
1240 ipa_print_all_jump_functions (dump_file); | |
1241 } | |
1242 /* 2. Do the interprocedural propagation. */ | |
1243 ipcp_iterate_stage (); | |
1244 /* 3. Insert the constants found to the functions. */ | |
1245 ipcp_insert_stage (); | |
1246 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1247 { | |
1248 fprintf (dump_file, "\nProfiling info after insert stage:\n"); | |
1249 ipcp_print_profile_data (dump_file); | |
1250 } | |
1251 /* Free all IPCP structures. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1252 ipa_free_all_structures_after_ipa_cp (); |
0 | 1253 if (dump_file) |
1254 fprintf (dump_file, "\nIPA constant propagation end\n"); | |
1255 return 0; | |
1256 } | |
1257 | |
1258 /* Note function body size. */ | |
1259 static void | |
1260 ipcp_generate_summary (void) | |
1261 { | |
1262 if (dump_file) | |
1263 fprintf (dump_file, "\nIPA constant propagation start:\n"); | |
1264 ipa_check_create_node_params (); | |
1265 ipa_check_create_edge_args (); | |
1266 ipa_register_cgraph_hooks (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1267 /* 1. Call the init stage to initialize |
0 | 1268 the ipa_node_params and ipa_edge_args structures. */ |
1269 ipcp_init_stage (); | |
1270 } | |
1271 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1272 /* Write ipcp summary for nodes in SET. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1273 static void |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1274 ipcp_write_summary (cgraph_node_set set, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1275 varpool_node_set vset ATTRIBUTE_UNUSED) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1276 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1277 ipa_prop_write_jump_functions (set); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1278 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1279 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1280 /* Read ipcp summary. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1281 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1282 ipcp_read_summary (void) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1283 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1284 ipa_prop_read_jump_functions (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1285 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1286 |
0 | 1287 /* Gate for IPCP optimization. */ |
1288 static bool | |
1289 cgraph_gate_cp (void) | |
1290 { | |
1291 return flag_ipa_cp; | |
1292 } | |
1293 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1294 struct ipa_opt_pass_d pass_ipa_cp = |
0 | 1295 { |
1296 { | |
1297 IPA_PASS, | |
1298 "cp", /* name */ | |
1299 cgraph_gate_cp, /* gate */ | |
1300 ipcp_driver, /* execute */ | |
1301 NULL, /* sub */ | |
1302 NULL, /* next */ | |
1303 0, /* static_pass_number */ | |
1304 TV_IPA_CONSTANT_PROP, /* tv_id */ | |
1305 0, /* properties_required */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1306 0, /* properties_provided */ |
0 | 1307 0, /* properties_destroyed */ |
1308 0, /* todo_flags_start */ | |
1309 TODO_dump_cgraph | TODO_dump_func | | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1310 TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */ |
0 | 1311 }, |
1312 ipcp_generate_summary, /* generate_summary */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1313 ipcp_write_summary, /* write_summary */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1314 ipcp_read_summary, /* read_summary */ |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1315 NULL, /* write_optimization_summary */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1316 NULL, /* read_optimization_summary */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1317 NULL, /* stmt_fixup */ |
0 | 1318 0, /* TODOs */ |
1319 NULL, /* function_transform */ | |
1320 NULL, /* variable_transform */ | |
1321 }; |