Mercurial > hg > CbC > CbC_gcc
annotate gcc/ipa-cp.c @ 108:7ad14f446135
add CbC-example/rectypeTest/
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 14 Jun 2012 20:30:24 +0900 |
parents | f6334be47118 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Interprocedural constant propagation |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 |
63
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 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
53 David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon, Comp86, pg |
0 | 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 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
73 -ipcp_generate_summary() is the first stage driver. |
0 | 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 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
120 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
121 This pass also performs devirtualization - turns virtual calls into direct |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
122 ones if it can prove that all invocations of the function call the same |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
123 callee. This is achieved by building a list of all base types (actually, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
124 their BINFOs) that individual parameters can have in an iterative matter |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
125 just like propagating scalar constants and then examining whether virtual |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
126 calls which take a parameter as their object fold to the same target for all |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
127 these types. If we cannot enumerate all types or there is a type which does |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
128 not have any BINFO associated with it, cannot_devirtualize of the associated |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
129 parameter descriptor is set which is an equivalent of BOTTOM lattice value |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
130 in standard IPA constant propagation. |
0 | 131 */ |
132 | |
133 #include "config.h" | |
134 #include "system.h" | |
135 #include "coretypes.h" | |
136 #include "tree.h" | |
137 #include "target.h" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
138 #include "gimple.h" |
0 | 139 #include "cgraph.h" |
140 #include "ipa-prop.h" | |
141 #include "tree-flow.h" | |
142 #include "tree-pass.h" | |
143 #include "flags.h" | |
144 #include "timevar.h" | |
145 #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
|
146 #include "tree-pretty-print.h" |
0 | 147 #include "tree-dump.h" |
148 #include "tree-inline.h" | |
149 #include "fibheap.h" | |
150 #include "params.h" | |
151 | |
152 /* Number of functions identified as candidates for cloning. When not cloning | |
153 we can simplify iterate stage not forcing it to go through the decision | |
154 on what is profitable and what not. */ | |
155 static int n_cloning_candidates; | |
156 | |
157 /* Maximal count found in program. */ | |
158 static gcov_type max_count; | |
159 | |
160 /* Cgraph nodes that has been completely replaced by cloning during iterate | |
161 * stage and will be removed after ipcp is finished. */ | |
162 static bitmap dead_nodes; | |
163 | |
164 static void ipcp_print_profile_data (FILE *); | |
165 static void ipcp_function_scale_print (FILE *); | |
166 | |
167 /* Get the original node field of ipa_node_params associated with node NODE. */ | |
168 static inline struct cgraph_node * | |
169 ipcp_get_orig_node (struct cgraph_node *node) | |
170 { | |
171 return IPA_NODE_REF (node)->ipcp_orig_node; | |
172 } | |
173 | |
174 /* Return true if NODE describes a cloned/versioned function. */ | |
175 static inline bool | |
176 ipcp_node_is_clone (struct cgraph_node *node) | |
177 { | |
178 return (ipcp_get_orig_node (node) != NULL); | |
179 } | |
180 | |
181 /* Create ipa_node_params and its data structures for NEW_NODE. Set ORIG_NODE | |
182 as the ipcp_orig_node field in ipa_node_params. */ | |
183 static void | |
184 ipcp_init_cloned_node (struct cgraph_node *orig_node, | |
185 struct cgraph_node *new_node) | |
186 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
187 gcc_checking_assert (ipa_node_params_vector |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
188 && (VEC_length (ipa_node_params_t, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
189 ipa_node_params_vector) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
190 > (unsigned) cgraph_max_uid)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
191 gcc_checking_assert (IPA_NODE_REF (new_node)->params); |
0 | 192 IPA_NODE_REF (new_node)->ipcp_orig_node = orig_node; |
193 } | |
194 | |
195 /* Return scale for NODE. */ | |
196 static inline gcov_type | |
197 ipcp_get_node_scale (struct cgraph_node *node) | |
198 { | |
199 return IPA_NODE_REF (node)->count_scale; | |
200 } | |
201 | |
202 /* Set COUNT as scale for NODE. */ | |
203 static inline void | |
204 ipcp_set_node_scale (struct cgraph_node *node, gcov_type count) | |
205 { | |
206 IPA_NODE_REF (node)->count_scale = count; | |
207 } | |
208 | |
209 /* Return whether LAT is a constant lattice. */ | |
210 static inline bool | |
211 ipcp_lat_is_const (struct ipcp_lattice *lat) | |
212 { | |
213 if (lat->type == IPA_CONST_VALUE) | |
214 return true; | |
215 else | |
216 return false; | |
217 } | |
218 | |
219 /* Return whether LAT is a constant lattice that ipa-cp can actually insert | |
220 into the code (i.e. constants excluding member pointers and pointers). */ | |
221 static inline bool | |
222 ipcp_lat_is_insertable (struct ipcp_lattice *lat) | |
223 { | |
224 return lat->type == IPA_CONST_VALUE; | |
225 } | |
226 | |
227 /* Return true if LAT1 and LAT2 are equal. */ | |
228 static inline bool | |
229 ipcp_lats_are_equal (struct ipcp_lattice *lat1, struct ipcp_lattice *lat2) | |
230 { | |
231 gcc_assert (ipcp_lat_is_const (lat1) && ipcp_lat_is_const (lat2)); | |
232 if (lat1->type != lat2->type) | |
233 return false; | |
234 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
235 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
|
236 && 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
|
237 && 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
|
238 && 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
|
239 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
|
240 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
|
241 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
242 return operand_equal_p (lat1->constant, lat2->constant, 0); |
0 | 243 } |
244 | |
245 /* Compute Meet arithmetics: | |
246 Meet (IPA_BOTTOM, x) = IPA_BOTTOM | |
247 Meet (IPA_TOP,x) = x | |
248 Meet (const_a,const_b) = IPA_BOTTOM, if const_a != const_b. | |
249 MEET (const_a,const_b) = const_a, if const_a == const_b.*/ | |
250 static void | |
251 ipa_lattice_meet (struct ipcp_lattice *res, struct ipcp_lattice *lat1, | |
252 struct ipcp_lattice *lat2) | |
253 { | |
254 if (lat1->type == IPA_BOTTOM || lat2->type == IPA_BOTTOM) | |
255 { | |
256 res->type = IPA_BOTTOM; | |
257 return; | |
258 } | |
259 if (lat1->type == IPA_TOP) | |
260 { | |
261 res->type = lat2->type; | |
262 res->constant = lat2->constant; | |
263 return; | |
264 } | |
265 if (lat2->type == IPA_TOP) | |
266 { | |
267 res->type = lat1->type; | |
268 res->constant = lat1->constant; | |
269 return; | |
270 } | |
271 if (!ipcp_lats_are_equal (lat1, lat2)) | |
272 { | |
273 res->type = IPA_BOTTOM; | |
274 return; | |
275 } | |
276 res->type = lat1->type; | |
277 res->constant = lat1->constant; | |
278 } | |
279 | |
280 /* Return the lattice corresponding to the Ith formal parameter of the function | |
281 described by INFO. */ | |
282 static inline struct ipcp_lattice * | |
283 ipcp_get_lattice (struct ipa_node_params *info, int i) | |
284 { | |
285 return &(info->params[i].ipcp_lattice); | |
286 } | |
287 | |
288 /* Given the jump function JFUNC, compute the lattice LAT that describes the | |
289 value coming down the callsite. INFO describes the caller node so that | |
290 pass-through jump functions can be evaluated. */ | |
291 static void | |
292 ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat, | |
293 struct ipa_jump_func *jfunc) | |
294 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
295 if (jfunc->type == IPA_JF_CONST) |
0 | 296 { |
297 lat->type = IPA_CONST_VALUE; | |
298 lat->constant = jfunc->value.constant; | |
299 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
300 else if (jfunc->type == IPA_JF_PASS_THROUGH) |
0 | 301 { |
302 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
|
303 tree cst; |
0 | 304 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
305 caller_lat = ipcp_get_lattice (info, jfunc->value.pass_through.formal_id); |
0 | 306 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
|
307 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
|
308 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
309 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
|
310 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
311 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
|
312 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
313 tree restype; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
314 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
|
315 == tcc_comparison) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
316 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
|
317 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
318 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
|
319 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
|
320 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
|
321 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
322 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
|
323 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
|
324 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
|
325 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
326 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
|
327 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
328 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
|
329 tree t; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
330 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
331 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
|
332 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
|
333 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
|
334 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
335 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
|
336 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
337 /* 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
|
338 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
|
339 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
340 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
341 t = TREE_OPERAND (caller_lat->constant, 0); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
342 t = build_ref_for_offset (EXPR_LOCATION (t), t, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
343 jfunc->value.ancestor.offset, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
344 jfunc->value.ancestor.type, NULL, false); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
345 lat->constant = build_fold_addr_expr (t); |
0 | 346 } |
347 else | |
348 lat->type = IPA_BOTTOM; | |
349 } | |
350 | |
351 /* True when OLD_LAT and NEW_LAT values are not the same. */ | |
352 | |
353 static bool | |
354 ipcp_lattice_changed (struct ipcp_lattice *old_lat, | |
355 struct ipcp_lattice *new_lat) | |
356 { | |
357 if (old_lat->type == new_lat->type) | |
358 { | |
359 if (!ipcp_lat_is_const (old_lat)) | |
360 return false; | |
361 if (ipcp_lats_are_equal (old_lat, new_lat)) | |
362 return false; | |
363 } | |
364 return true; | |
365 } | |
366 | |
367 /* Print all ipcp_lattices of all functions to F. */ | |
368 static void | |
369 ipcp_print_all_lattices (FILE * f) | |
370 { | |
371 struct cgraph_node *node; | |
372 int i, count; | |
373 | |
374 fprintf (f, "\nLattice:\n"); | |
375 for (node = cgraph_nodes; node; node = node->next) | |
376 { | |
377 struct ipa_node_params *info; | |
378 | |
379 if (!node->analyzed) | |
380 continue; | |
381 info = IPA_NODE_REF (node); | |
382 fprintf (f, " Node: %s:\n", cgraph_node_name (node)); | |
383 count = ipa_get_param_count (info); | |
384 for (i = 0; i < count; i++) | |
385 { | |
386 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
387 | |
388 fprintf (f, " param [%d]: ", i); | |
389 if (lat->type == IPA_CONST_VALUE) | |
390 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
391 tree cst = lat->constant; |
0 | 392 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
|
393 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
|
394 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
|
395 && 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
|
396 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
397 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
|
398 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
|
399 0); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
400 } |
0 | 401 } |
402 else if (lat->type == IPA_TOP) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
403 fprintf (f, "type is TOP"); |
0 | 404 else |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
405 fprintf (f, "type is BOTTOM"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
406 if (ipa_param_cannot_devirtualize_p (info, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
407 fprintf (f, " - cannot_devirtualize set\n"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
408 else if (ipa_param_types_vec_empty (info, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
409 fprintf (f, " - type list empty\n"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
410 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
411 fprintf (f, "\n"); |
0 | 412 } |
413 } | |
414 } | |
415 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
416 /* 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
|
417 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
418 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
419 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
|
420 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
421 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
|
422 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
423 /* There are a number of generic reasons functions cannot be versioned. We |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
424 also cannot remove parameters if there are type attributes such as fnspec |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
425 present. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
426 if (!node->local.versionable |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
427 || TYPE_ATTRIBUTES (TREE_TYPE (node->decl))) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
428 return false; |
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 /* 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
|
431 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
|
432 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
|
433 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
434 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
|
435 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
|
436 && (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
|
437 || 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
|
438 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
|
439 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
440 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
441 return true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
442 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
443 |
0 | 444 /* Return true if this NODE is viable candidate for cloning. */ |
445 static bool | |
446 ipcp_cloning_candidate_p (struct cgraph_node *node) | |
447 { | |
448 int n_calls = 0; | |
449 int n_hot_calls = 0; | |
450 gcov_type direct_call_sum = 0; | |
451 struct cgraph_edge *e; | |
452 | |
453 /* We never clone functions that are not visible from outside. | |
454 FIXME: in future we should clone such functions when they are called with | |
455 different constants, but current ipcp implementation is not good on this. | |
456 */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
457 if (cgraph_only_called_directly_p (node) || !node->analyzed) |
0 | 458 return false; |
459 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
460 /* When function address is taken, we are pretty sure it will be called in hidden way. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
461 if (node->address_taken) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
462 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
463 if (dump_file) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
464 fprintf (dump_file, "Not considering %s for cloning; address is taken.\n", |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
465 cgraph_node_name (node)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
466 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
467 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
468 |
0 | 469 if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) |
470 { | |
471 if (dump_file) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
472 fprintf (dump_file, "Not considering %s for cloning; body is overwritable.\n", |
0 | 473 cgraph_node_name (node)); |
474 return false; | |
475 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
476 if (!ipcp_versionable_function_p (node)) |
0 | 477 { |
478 if (dump_file) | |
479 fprintf (dump_file, "Not considering %s for cloning; body is not versionable.\n", | |
480 cgraph_node_name (node)); | |
481 return false; | |
482 } | |
483 for (e = node->callers; e; e = e->next_caller) | |
484 { | |
485 direct_call_sum += e->count; | |
486 n_calls ++; | |
487 if (cgraph_maybe_hot_edge_p (e)) | |
488 n_hot_calls ++; | |
489 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
490 |
0 | 491 if (!n_calls) |
492 { | |
493 if (dump_file) | |
494 fprintf (dump_file, "Not considering %s for cloning; no direct calls.\n", | |
495 cgraph_node_name (node)); | |
496 return false; | |
497 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
498 if (node->local.inline_summary.self_size < n_calls) |
0 | 499 { |
500 if (dump_file) | |
501 fprintf (dump_file, "Considering %s for cloning; code would shrink.\n", | |
502 cgraph_node_name (node)); | |
503 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
|
504 } |
0 | 505 |
506 if (!flag_ipa_cp_clone) | |
507 { | |
508 if (dump_file) | |
509 fprintf (dump_file, "Not considering %s for cloning; -fipa-cp-clone disabled.\n", | |
510 cgraph_node_name (node)); | |
511 return false; | |
512 } | |
513 | |
514 if (!optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl))) | |
515 { | |
516 if (dump_file) | |
517 fprintf (dump_file, "Not considering %s for cloning; optimizing it for size.\n", | |
518 cgraph_node_name (node)); | |
519 return false; | |
520 } | |
521 | |
522 /* When profile is available and function is hot, propagate into it even if | |
523 calls seems cold; constant propagation can improve function's speed | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
524 significantly. */ |
0 | 525 if (max_count) |
526 { | |
527 if (direct_call_sum > node->count * 90 / 100) | |
528 { | |
529 if (dump_file) | |
530 fprintf (dump_file, "Considering %s for cloning; usually called directly.\n", | |
531 cgraph_node_name (node)); | |
532 return true; | |
533 } | |
534 } | |
535 if (!n_hot_calls) | |
536 { | |
537 if (dump_file) | |
538 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n", | |
539 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
|
540 return false; |
0 | 541 } |
542 if (dump_file) | |
543 fprintf (dump_file, "Considering %s for cloning.\n", | |
544 cgraph_node_name (node)); | |
545 return true; | |
546 } | |
547 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
548 /* Mark parameter with index I of function described by INFO as unsuitable for |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
549 devirtualization. Return true if it has already been marked so. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
550 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
551 static bool |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
552 ipa_set_param_cannot_devirtualize (struct ipa_node_params *info, int i) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
553 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
554 bool ret = info->params[i].cannot_devirtualize; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
555 info->params[i].cannot_devirtualize = true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
556 if (info->params[i].types) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
557 VEC_free (tree, heap, info->params[i].types); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
558 return ret; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
559 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
560 |
0 | 561 /* Initialize ipcp_lattices array. The lattices corresponding to supported |
562 types (integers, real types and Fortran constants defined as const_decls) | |
563 are initialized to IPA_TOP, the rest of them to IPA_BOTTOM. */ | |
564 static void | |
565 ipcp_initialize_node_lattices (struct cgraph_node *node) | |
566 { | |
567 int i; | |
568 struct ipa_node_params *info = IPA_NODE_REF (node); | |
569 enum ipa_lattice_type type; | |
570 | |
571 if (ipa_is_called_with_var_arguments (info)) | |
572 type = IPA_BOTTOM; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
573 else if (node->local.local) |
0 | 574 type = IPA_TOP; |
575 /* When cloning is allowed, we can assume that externally visible functions | |
576 are not called. We will compensate this by cloning later. */ | |
577 else if (ipcp_cloning_candidate_p (node)) | |
578 type = IPA_TOP, n_cloning_candidates ++; | |
579 else | |
580 type = IPA_BOTTOM; | |
581 | |
582 for (i = 0; i < ipa_get_param_count (info) ; i++) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
583 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
584 ipcp_get_lattice (info, i)->type = type; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
585 if (type == IPA_BOTTOM) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
586 ipa_set_param_cannot_devirtualize (info, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
587 } |
0 | 588 } |
589 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
590 /* Build a constant tree with type TREE_TYPE and value according to LAT. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
591 Return the tree, or, if it is not possible to convert such value |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
592 to TREE_TYPE, NULL. */ |
0 | 593 static tree |
594 build_const_val (struct ipcp_lattice *lat, tree tree_type) | |
595 { | |
596 tree val; | |
597 | |
598 gcc_assert (ipcp_lat_is_const (lat)); | |
599 val = lat->constant; | |
600 | |
601 if (!useless_type_conversion_p (tree_type, TREE_TYPE (val))) | |
602 { | |
603 if (fold_convertible_p (tree_type, val)) | |
604 return fold_build1 (NOP_EXPR, tree_type, val); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
605 else if (TYPE_SIZE (tree_type) == TYPE_SIZE (TREE_TYPE (val))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
606 return fold_build1 (VIEW_CONVERT_EXPR, tree_type, val); |
0 | 607 else |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
608 return NULL; |
0 | 609 } |
610 return val; | |
611 } | |
612 | |
613 /* Compute the proper scale for NODE. It is the ratio between the number of | |
614 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
|
615 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
|
616 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
617 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
|
618 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
|
619 To properly compute the counts, we would need to do propagation across |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
620 callgraph (as external call to A might imply call to non-cloned B |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
621 if A's clone calls cloned B). */ |
0 | 622 static void |
623 ipcp_compute_node_scale (struct cgraph_node *node) | |
624 { | |
625 gcov_type sum; | |
626 struct cgraph_edge *cs; | |
627 | |
628 sum = 0; | |
629 /* Compute sum of all counts of callers. */ | |
630 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
631 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
|
632 /* 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
|
633 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
|
634 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
|
635 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
|
636 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
|
637 sum = node->count * 9 / 10; |
0 | 638 if (node->count == 0) |
639 ipcp_set_node_scale (node, 0); | |
640 else | |
641 ipcp_set_node_scale (node, sum * REG_BR_PROB_BASE / node->count); | |
642 } | |
643 | |
644 /* Return true if there are some formal parameters whose value is IPA_TOP (in | |
645 the whole compilation unit). Change their values to IPA_BOTTOM, since they | |
646 most probably get their values from outside of this compilation unit. */ | |
647 static bool | |
648 ipcp_change_tops_to_bottom (void) | |
649 { | |
650 int i, count; | |
651 struct cgraph_node *node; | |
652 bool prop_again; | |
653 | |
654 prop_again = false; | |
655 for (node = cgraph_nodes; node; node = node->next) | |
656 { | |
657 struct ipa_node_params *info = IPA_NODE_REF (node); | |
658 count = ipa_get_param_count (info); | |
659 for (i = 0; i < count; i++) | |
660 { | |
661 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
662 if (lat->type == IPA_TOP) | |
663 { | |
664 prop_again = true; | |
665 if (dump_file) | |
666 { | |
667 fprintf (dump_file, "Forcing param "); | |
668 print_generic_expr (dump_file, ipa_get_param (info, i), 0); | |
669 fprintf (dump_file, " of node %s to bottom.\n", | |
670 cgraph_node_name (node)); | |
671 } | |
672 lat->type = IPA_BOTTOM; | |
673 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
674 if (!ipa_param_cannot_devirtualize_p (info, i) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
675 && ipa_param_types_vec_empty (info, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
676 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
677 prop_again = true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
678 ipa_set_param_cannot_devirtualize (info, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
679 if (dump_file) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
680 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
681 fprintf (dump_file, "Marking param "); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
682 print_generic_expr (dump_file, ipa_get_param (info, i), 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
683 fprintf (dump_file, " of node %s as unusable for " |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
684 "devirtualization.\n", |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
685 cgraph_node_name (node)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
686 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
687 } |
0 | 688 } |
689 } | |
690 return prop_again; | |
691 } | |
692 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
693 /* Insert BINFO to the list of known types of parameter number I of the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
694 function described by CALLEE_INFO. Return true iff the type information |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
695 associated with the callee parameter changed in any way. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
696 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
697 static bool |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
698 ipcp_add_param_type (struct ipa_node_params *callee_info, int i, tree binfo) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
699 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
700 int j, count; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
701 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
702 if (ipa_param_cannot_devirtualize_p (callee_info, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
703 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
704 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
705 if (callee_info->params[i].types) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
706 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
707 count = VEC_length (tree, callee_info->params[i].types); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
708 for (j = 0; j < count; j++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
709 if (VEC_index (tree, callee_info->params[i].types, j) == binfo) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
710 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
711 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
712 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
713 if (VEC_length (tree, callee_info->params[i].types) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
714 == (unsigned) PARAM_VALUE (PARAM_DEVIRT_TYPE_LIST_SIZE)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
715 return !ipa_set_param_cannot_devirtualize (callee_info, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
716 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
717 VEC_safe_push (tree, heap, callee_info->params[i].types, binfo); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
718 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
719 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
720 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
721 /* Copy known types information for parameter number CALLEE_IDX of CALLEE_INFO |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
722 from a parameter of CALLER_INFO as described by JF. Return true iff the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
723 type information changed in any way. JF must be a pass-through or an |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
724 ancestor jump function. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
725 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
726 static bool |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
727 ipcp_copy_types (struct ipa_node_params *caller_info, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
728 struct ipa_node_params *callee_info, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
729 int callee_idx, struct ipa_jump_func *jf) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
730 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
731 int caller_idx, j, count; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
732 bool res; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
733 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
734 if (ipa_param_cannot_devirtualize_p (callee_info, callee_idx)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
735 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
736 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
737 if (jf->type == IPA_JF_PASS_THROUGH) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
738 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
739 if (jf->value.pass_through.operation != NOP_EXPR) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
740 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
741 ipa_set_param_cannot_devirtualize (callee_info, callee_idx); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
742 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
743 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
744 caller_idx = jf->value.pass_through.formal_id; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
745 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
746 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
747 caller_idx = jf->value.ancestor.formal_id; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
748 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
749 if (ipa_param_cannot_devirtualize_p (caller_info, caller_idx)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
750 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
751 ipa_set_param_cannot_devirtualize (callee_info, callee_idx); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
752 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
753 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
754 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
755 if (!caller_info->params[caller_idx].types) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
756 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
757 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
758 res = false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
759 count = VEC_length (tree, caller_info->params[caller_idx].types); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
760 for (j = 0; j < count; j++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
761 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
762 tree binfo = VEC_index (tree, caller_info->params[caller_idx].types, j); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
763 if (jf->type == IPA_JF_ANCESTOR) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
764 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
765 binfo = get_binfo_at_offset (binfo, jf->value.ancestor.offset, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
766 jf->value.ancestor.type); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
767 if (!binfo) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
768 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
769 ipa_set_param_cannot_devirtualize (callee_info, callee_idx); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
770 return true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
771 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
772 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
773 res |= ipcp_add_param_type (callee_info, callee_idx, binfo); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
774 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
775 return res; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
776 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
777 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
778 /* Propagate type information for parameter of CALLEE_INFO number I as |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
779 described by JF. CALLER_INFO describes the caller. Return true iff the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
780 type information changed in any way. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
781 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
782 static bool |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
783 ipcp_propagate_types (struct ipa_node_params *caller_info, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
784 struct ipa_node_params *callee_info, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
785 struct ipa_jump_func *jf, int i) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
786 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
787 switch (jf->type) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
788 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
789 case IPA_JF_UNKNOWN: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
790 case IPA_JF_CONST_MEMBER_PTR: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
791 case IPA_JF_CONST: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
792 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
793 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
794 case IPA_JF_KNOWN_TYPE: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
795 return ipcp_add_param_type (callee_info, i, jf->value.base_binfo); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
796 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
797 case IPA_JF_PASS_THROUGH: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
798 case IPA_JF_ANCESTOR: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
799 return ipcp_copy_types (caller_info, callee_info, i, jf); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
800 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
801 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
802 /* If we reach this we cannot use this parameter for devirtualization. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
803 return !ipa_set_param_cannot_devirtualize (callee_info, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
804 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
805 |
0 | 806 /* Interprocedural analysis. The algorithm propagates constants from the |
807 caller's parameters to the callee's arguments. */ | |
808 static void | |
809 ipcp_propagate_stage (void) | |
810 { | |
811 int i; | |
812 struct ipcp_lattice inc_lat = { IPA_BOTTOM, NULL }; | |
813 struct ipcp_lattice new_lat = { IPA_BOTTOM, NULL }; | |
814 struct ipcp_lattice *dest_lat; | |
815 struct cgraph_edge *cs; | |
816 struct ipa_jump_func *jump_func; | |
817 struct ipa_func_list *wl; | |
818 int count; | |
819 | |
820 ipa_check_create_node_params (); | |
821 ipa_check_create_edge_args (); | |
822 | |
823 /* Initialize worklist to contain all functions. */ | |
824 wl = ipa_init_func_list (); | |
825 while (wl) | |
826 { | |
827 struct cgraph_node *node = ipa_pop_func_from_list (&wl); | |
828 struct ipa_node_params *info = IPA_NODE_REF (node); | |
829 | |
830 for (cs = node->callees; cs; cs = cs->next_callee) | |
831 { | |
832 struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee); | |
833 struct ipa_edge_args *args = IPA_EDGE_REF (cs); | |
834 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
835 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
|
836 || !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
|
837 || ipa_is_called_with_var_arguments (callee_info)) |
0 | 838 continue; |
839 | |
840 count = ipa_get_cs_argument_count (args); | |
841 for (i = 0; i < count; i++) | |
842 { | |
843 jump_func = ipa_get_ith_jump_func (args, i); | |
844 ipcp_lattice_from_jfunc (info, &inc_lat, jump_func); | |
845 dest_lat = ipcp_get_lattice (callee_info, i); | |
846 ipa_lattice_meet (&new_lat, &inc_lat, dest_lat); | |
847 if (ipcp_lattice_changed (&new_lat, dest_lat)) | |
848 { | |
849 dest_lat->type = new_lat.type; | |
850 dest_lat->constant = new_lat.constant; | |
851 ipa_push_func_to_list (&wl, cs->callee); | |
852 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
853 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
854 if (ipcp_propagate_types (info, callee_info, jump_func, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
855 ipa_push_func_to_list (&wl, cs->callee); |
0 | 856 } |
857 } | |
858 } | |
859 } | |
860 | |
861 /* Call the constant propagation algorithm and re-call it if necessary | |
862 (if there are undetermined values left). */ | |
863 static void | |
864 ipcp_iterate_stage (void) | |
865 { | |
866 struct cgraph_node *node; | |
867 n_cloning_candidates = 0; | |
868 | |
869 if (dump_file) | |
870 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
|
871 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
872 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
|
873 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
|
874 |
0 | 875 for (node = cgraph_nodes; node; node = node->next) |
876 { | |
877 ipcp_initialize_node_lattices (node); | |
878 ipcp_compute_node_scale (node); | |
879 } | |
880 if (dump_file && (dump_flags & TDF_DETAILS)) | |
881 { | |
882 ipcp_print_all_lattices (dump_file); | |
883 ipcp_function_scale_print (dump_file); | |
884 } | |
885 | |
886 ipcp_propagate_stage (); | |
887 if (ipcp_change_tops_to_bottom ()) | |
888 /* Some lattices have changed from IPA_TOP to IPA_BOTTOM. | |
889 This change should be propagated. */ | |
890 { | |
891 gcc_assert (n_cloning_candidates); | |
892 ipcp_propagate_stage (); | |
893 } | |
894 if (dump_file) | |
895 { | |
896 fprintf (dump_file, "\nIPA lattices after propagation:\n"); | |
897 ipcp_print_all_lattices (dump_file); | |
898 if (dump_flags & TDF_DETAILS) | |
899 ipcp_print_profile_data (dump_file); | |
900 } | |
901 } | |
902 | |
903 /* Check conditions to forbid constant insertion to function described by | |
904 NODE. */ | |
905 static inline bool | |
906 ipcp_node_modifiable_p (struct cgraph_node *node) | |
907 { | |
908 /* Once we will be able to do in-place replacement, we can be more | |
909 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
|
910 return ipcp_versionable_function_p (node); |
0 | 911 } |
912 | |
913 /* Print count scale data structures. */ | |
914 static void | |
915 ipcp_function_scale_print (FILE * f) | |
916 { | |
917 struct cgraph_node *node; | |
918 | |
919 for (node = cgraph_nodes; node; node = node->next) | |
920 { | |
921 if (!node->analyzed) | |
922 continue; | |
923 fprintf (f, "printing scale for %s: ", cgraph_node_name (node)); | |
924 fprintf (f, "value is " HOST_WIDE_INT_PRINT_DEC | |
925 " \n", (HOST_WIDE_INT) ipcp_get_node_scale (node)); | |
926 } | |
927 } | |
928 | |
929 /* Print counts of all cgraph nodes. */ | |
930 static void | |
931 ipcp_print_func_profile_counts (FILE * f) | |
932 { | |
933 struct cgraph_node *node; | |
934 | |
935 for (node = cgraph_nodes; node; node = node->next) | |
936 { | |
937 fprintf (f, "function %s: ", cgraph_node_name (node)); | |
938 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC | |
939 " \n", (HOST_WIDE_INT) node->count); | |
940 } | |
941 } | |
942 | |
943 /* Print counts of all cgraph edges. */ | |
944 static void | |
945 ipcp_print_call_profile_counts (FILE * f) | |
946 { | |
947 struct cgraph_node *node; | |
948 struct cgraph_edge *cs; | |
949 | |
950 for (node = cgraph_nodes; node; node = node->next) | |
951 { | |
952 for (cs = node->callees; cs; cs = cs->next_callee) | |
953 { | |
954 fprintf (f, "%s -> %s ", cgraph_node_name (cs->caller), | |
955 cgraph_node_name (cs->callee)); | |
956 fprintf (f, "count is " HOST_WIDE_INT_PRINT_DEC " \n", | |
957 (HOST_WIDE_INT) cs->count); | |
958 } | |
959 } | |
960 } | |
961 | |
962 /* Print profile info for all functions. */ | |
963 static void | |
964 ipcp_print_profile_data (FILE * f) | |
965 { | |
966 fprintf (f, "\nNODE COUNTS :\n"); | |
967 ipcp_print_func_profile_counts (f); | |
968 fprintf (f, "\nCS COUNTS stage:\n"); | |
969 ipcp_print_call_profile_counts (f); | |
970 } | |
971 | |
972 /* Build and initialize ipa_replace_map struct according to LAT. This struct is | |
973 processed by versioning, which operates according to the flags set. | |
974 PARM_TREE is the formal parameter found to be constant. LAT represents the | |
975 constant. */ | |
976 static struct ipa_replace_map * | |
977 ipcp_create_replace_map (tree parm_tree, struct ipcp_lattice *lat) | |
978 { | |
979 struct ipa_replace_map *replace_map; | |
980 tree const_val; | |
981 | |
982 const_val = build_const_val (lat, TREE_TYPE (parm_tree)); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
983 if (const_val == NULL_TREE) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
984 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
985 if (dump_file) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
986 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
987 fprintf (dump_file, " const "); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
988 print_generic_expr (dump_file, lat->constant, 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
989 fprintf (dump_file, " can't be converted to param "); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
990 print_generic_expr (dump_file, parm_tree, 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
991 fprintf (dump_file, "\n"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
992 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
993 return NULL; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
994 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
995 replace_map = ggc_alloc_ipa_replace_map (); |
0 | 996 if (dump_file) |
997 { | |
998 fprintf (dump_file, " replacing param "); | |
999 print_generic_expr (dump_file, parm_tree, 0); | |
1000 fprintf (dump_file, " with const "); | |
1001 print_generic_expr (dump_file, const_val, 0); | |
1002 fprintf (dump_file, "\n"); | |
1003 } | |
1004 replace_map->old_tree = parm_tree; | |
1005 replace_map->new_tree = const_val; | |
1006 replace_map->replace_p = true; | |
1007 replace_map->ref_p = false; | |
1008 | |
1009 return replace_map; | |
1010 } | |
1011 | |
1012 /* Return true if this callsite should be redirected to the original callee | |
1013 (instead of the cloned one). */ | |
1014 static bool | |
1015 ipcp_need_redirect_p (struct cgraph_edge *cs) | |
1016 { | |
1017 struct ipa_node_params *orig_callee_info; | |
1018 int i, count; | |
1019 struct cgraph_node *node = cs->callee, *orig; | |
1020 | |
1021 if (!n_cloning_candidates) | |
1022 return false; | |
1023 | |
1024 if ((orig = ipcp_get_orig_node (node)) != NULL) | |
1025 node = orig; | |
1026 if (ipcp_get_orig_node (cs->caller)) | |
1027 return false; | |
1028 | |
1029 orig_callee_info = IPA_NODE_REF (node); | |
1030 count = ipa_get_param_count (orig_callee_info); | |
1031 for (i = 0; i < count; i++) | |
1032 { | |
1033 struct ipcp_lattice *lat = ipcp_get_lattice (orig_callee_info, i); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1034 struct ipa_jump_func *jump_func; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1035 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1036 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1037 if ((ipcp_lat_is_const (lat) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1038 && jump_func->type != IPA_JF_CONST) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1039 || (!ipa_param_cannot_devirtualize_p (orig_callee_info, i) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1040 && !ipa_param_types_vec_empty (orig_callee_info, i) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1041 && jump_func->type != IPA_JF_CONST |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1042 && jump_func->type != IPA_JF_KNOWN_TYPE)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1043 return true; |
0 | 1044 } |
1045 | |
1046 return false; | |
1047 } | |
1048 | |
1049 /* Fix the callsites and the call graph after function cloning was done. */ | |
1050 static void | |
1051 ipcp_update_callgraph (void) | |
1052 { | |
1053 struct cgraph_node *node; | |
1054 | |
1055 for (node = cgraph_nodes; node; node = node->next) | |
1056 if (node->analyzed && ipcp_node_is_clone (node)) | |
1057 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1058 bitmap args_to_skip = NULL; |
0 | 1059 struct cgraph_node *orig_node = ipcp_get_orig_node (node); |
1060 struct ipa_node_params *info = IPA_NODE_REF (orig_node); | |
1061 int i, count = ipa_get_param_count (info); | |
1062 struct cgraph_edge *cs, *next; | |
1063 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1064 if (node->local.can_change_signature) |
0 | 1065 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1066 args_to_skip = BITMAP_ALLOC (NULL); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1067 for (i = 0; i < count; i++) |
0 | 1068 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1069 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1070 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1071 /* We can proactively remove obviously unused arguments. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1072 if (!ipa_is_param_used (info, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1073 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1074 bitmap_set_bit (args_to_skip, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1075 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1076 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1077 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1078 if (lat->type == IPA_CONST_VALUE) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1079 bitmap_set_bit (args_to_skip, i); |
0 | 1080 } |
1081 } | |
1082 for (cs = node->callers; cs; cs = next) | |
1083 { | |
1084 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
|
1085 if (!ipcp_node_is_clone (cs->caller) && ipcp_need_redirect_p (cs)) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1086 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1087 if (dump_file) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1088 fprintf (dump_file, "Redirecting edge %s/%i -> %s/%i " |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1089 "back to %s/%i.", |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1090 cgraph_node_name (cs->caller), cs->caller->uid, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1091 cgraph_node_name (cs->callee), cs->callee->uid, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1092 cgraph_node_name (orig_node), orig_node->uid); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1093 cgraph_redirect_edge_callee (cs, orig_node); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1094 } |
0 | 1095 } |
1096 } | |
1097 } | |
1098 | |
1099 /* Update profiling info for versioned functions and the functions they were | |
1100 versioned from. */ | |
1101 static void | |
1102 ipcp_update_profiling (void) | |
1103 { | |
1104 struct cgraph_node *node, *orig_node; | |
1105 gcov_type scale, scale_complement; | |
1106 struct cgraph_edge *cs; | |
1107 | |
1108 for (node = cgraph_nodes; node; node = node->next) | |
1109 { | |
1110 if (ipcp_node_is_clone (node)) | |
1111 { | |
1112 orig_node = ipcp_get_orig_node (node); | |
1113 scale = ipcp_get_node_scale (orig_node); | |
1114 node->count = orig_node->count * scale / REG_BR_PROB_BASE; | |
1115 scale_complement = REG_BR_PROB_BASE - scale; | |
1116 orig_node->count = | |
1117 orig_node->count * scale_complement / REG_BR_PROB_BASE; | |
1118 for (cs = node->callees; cs; cs = cs->next_callee) | |
1119 cs->count = cs->count * scale / REG_BR_PROB_BASE; | |
1120 for (cs = orig_node->callees; cs; cs = cs->next_callee) | |
1121 cs->count = cs->count * scale_complement / REG_BR_PROB_BASE; | |
1122 } | |
1123 } | |
1124 } | |
1125 | |
1126 /* If NODE was cloned, how much would program grow? */ | |
1127 static long | |
1128 ipcp_estimate_growth (struct cgraph_node *node) | |
1129 { | |
1130 struct cgraph_edge *cs; | |
1131 int redirectable_node_callers = 0; | |
1132 int removable_args = 0; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1133 bool need_original |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1134 = !cgraph_will_be_removed_from_program_if_no_direct_calls (node); |
0 | 1135 struct ipa_node_params *info; |
1136 int i, count; | |
1137 int growth; | |
1138 | |
1139 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
1140 if (cs->caller == node || !ipcp_need_redirect_p (cs)) | |
1141 redirectable_node_callers++; | |
1142 else | |
1143 need_original = true; | |
1144 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1145 /* If we will be able to fully replace original node, we never increase |
0 | 1146 program size. */ |
1147 if (!need_original) | |
1148 return 0; | |
1149 | |
1150 info = IPA_NODE_REF (node); | |
1151 count = ipa_get_param_count (info); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1152 if (node->local.can_change_signature) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1153 for (i = 0; i < count; i++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1154 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1155 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
0 | 1156 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1157 /* We can proactively remove obviously unused arguments. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1158 if (!ipa_is_param_used (info, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1159 removable_args++; |
0 | 1160 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1161 if (lat->type == IPA_CONST_VALUE) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1162 removable_args++; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1163 } |
0 | 1164 |
1165 /* We make just very simple estimate of savings for removal of operand from | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1166 call site. Precise cost is difficult to get, as our size metric counts |
0 | 1167 constants and moves as free. Generally we are looking for cases that |
1168 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
|
1169 growth = node->local.inline_summary.self_size |
0 | 1170 - removable_args * redirectable_node_callers; |
1171 if (growth < 0) | |
1172 return 0; | |
1173 return growth; | |
1174 } | |
1175 | |
1176 | |
1177 /* Estimate cost of cloning NODE. */ | |
1178 static long | |
1179 ipcp_estimate_cloning_cost (struct cgraph_node *node) | |
1180 { | |
1181 int freq_sum = 1; | |
1182 gcov_type count_sum = 1; | |
1183 struct cgraph_edge *e; | |
1184 int cost; | |
1185 | |
1186 cost = ipcp_estimate_growth (node) * 1000; | |
1187 if (!cost) | |
1188 { | |
1189 if (dump_file) | |
1190 fprintf (dump_file, "Versioning of %s will save code size\n", | |
1191 cgraph_node_name (node)); | |
1192 return 0; | |
1193 } | |
1194 | |
1195 for (e = node->callers; e; e = e->next_caller) | |
1196 if (!bitmap_bit_p (dead_nodes, e->caller->uid) | |
1197 && !ipcp_need_redirect_p (e)) | |
1198 { | |
1199 count_sum += e->count; | |
1200 freq_sum += e->frequency + 1; | |
1201 } | |
1202 | |
1203 if (max_count) | |
1204 cost /= count_sum * 1000 / max_count + 1; | |
1205 else | |
1206 cost /= freq_sum * 1000 / REG_BR_PROB_BASE + 1; | |
1207 if (dump_file) | |
1208 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
|
1209 cgraph_node_name (node), cost, node->local.inline_summary.self_size, |
0 | 1210 freq_sum); |
1211 return cost + 1; | |
1212 } | |
1213 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1214 /* Walk indirect calls of NODE and if any polymorphic can be turned into a |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1215 direct one now, do so. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1216 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1217 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1218 ipcp_process_devirtualization_opportunities (struct cgraph_node *node) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1219 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1220 struct ipa_node_params *info = IPA_NODE_REF (node); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1221 struct cgraph_edge *ie, *next_ie; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1222 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1223 for (ie = node->indirect_calls; ie; ie = next_ie) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1224 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1225 int param_index, types_count, j; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1226 HOST_WIDE_INT token; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1227 tree target, delta; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1228 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1229 next_ie = ie->next_callee; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1230 if (!ie->indirect_info->polymorphic) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1231 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1232 param_index = ie->indirect_info->param_index; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1233 if (param_index == -1 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1234 || ipa_param_cannot_devirtualize_p (info, param_index) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1235 || ipa_param_types_vec_empty (info, param_index)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1236 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1237 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1238 token = ie->indirect_info->otr_token; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1239 target = NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1240 types_count = VEC_length (tree, info->params[param_index].types); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1241 for (j = 0; j < types_count; j++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1242 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1243 tree binfo = VEC_index (tree, info->params[param_index].types, j); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1244 tree d; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1245 tree t = gimple_get_virt_mehtod_for_binfo (token, binfo, &d, true); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1246 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1247 if (!t) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1248 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1249 target = NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1250 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1251 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1252 else if (!target) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1253 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1254 target = t; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1255 delta = d; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1256 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1257 else if (target != t || !tree_int_cst_equal (delta, d)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1258 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1259 target = NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1260 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1261 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1262 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1263 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1264 if (target) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1265 ipa_make_edge_direct_to_target (ie, target, delta); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1266 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1267 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1268 |
0 | 1269 /* Return number of live constant parameters. */ |
1270 static int | |
1271 ipcp_const_param_count (struct cgraph_node *node) | |
1272 { | |
1273 int const_param = 0; | |
1274 struct ipa_node_params *info = IPA_NODE_REF (node); | |
1275 int count = ipa_get_param_count (info); | |
1276 int i; | |
1277 | |
1278 for (i = 0; i < count; i++) | |
1279 { | |
1280 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1281 if ((ipcp_lat_is_insertable (lat) |
0 | 1282 /* Do not count obviously unused arguments. */ |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1283 && ipa_is_param_used (info, i)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1284 || (!ipa_param_cannot_devirtualize_p (info, i) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1285 && !ipa_param_types_vec_empty (info, i))) |
0 | 1286 const_param++; |
1287 } | |
1288 return const_param; | |
1289 } | |
1290 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1291 /* Given that a formal parameter of NODE given by INDEX is known to be constant |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1292 CST, try to find any indirect edges that can be made direct and make them |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1293 so. Note that INDEX is the number the parameter at the time of analyzing |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1294 parameter uses and parameter removals should not be considered for it. (In |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1295 fact, the parameter itself has just been removed.) */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1296 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1297 static void |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1298 ipcp_discover_new_direct_edges (struct cgraph_node *node, int index, tree cst) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1299 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1300 struct cgraph_edge *ie, *next_ie; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1301 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1302 for (ie = node->indirect_calls; ie; ie = next_ie) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1303 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1304 struct cgraph_indirect_call_info *ici = ie->indirect_info; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1305 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1306 next_ie = ie->next_callee; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1307 if (ici->param_index != index |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1308 || ici->polymorphic) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1309 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1310 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1311 ipa_make_edge_direct_to_target (ie, cst, NULL_TREE); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1312 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1313 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1314 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1315 |
0 | 1316 /* Propagate the constant parameters found by ipcp_iterate_stage() |
1317 to the function's code. */ | |
1318 static void | |
1319 ipcp_insert_stage (void) | |
1320 { | |
1321 struct cgraph_node *node, *node1 = NULL; | |
1322 int i; | |
1323 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
|
1324 VEC (ipa_replace_map_p,gc)* replace_trees; |
0 | 1325 int node_callers, count; |
1326 tree parm_tree; | |
1327 struct ipa_replace_map *replace_param; | |
1328 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
|
1329 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
|
1330 long max_new_size; |
0 | 1331 |
1332 ipa_check_create_node_params (); | |
1333 ipa_check_create_edge_args (); | |
1334 if (dump_file) | |
1335 fprintf (dump_file, "\nIPA insert stage:\n\n"); | |
1336 | |
1337 dead_nodes = BITMAP_ALLOC (NULL); | |
1338 | |
1339 for (node = cgraph_nodes; node; node = node->next) | |
1340 if (node->analyzed) | |
1341 { | |
1342 if (node->count > max_count) | |
1343 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
|
1344 overall_size += node->local.inline_summary.self_size; |
0 | 1345 } |
1346 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1347 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
|
1348 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
|
1349 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
|
1350 max_new_size = max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1; |
0 | 1351 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1352 /* First collect all functions we proved to have constant arguments to |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1353 heap. */ |
0 | 1354 heap = fibheap_new (); |
1355 for (node = cgraph_nodes; node; node = node->next) | |
1356 { | |
1357 struct ipa_node_params *info; | |
1358 /* Propagation of the constant is forbidden in certain conditions. */ | |
1359 if (!node->analyzed || !ipcp_node_modifiable_p (node)) | |
1360 continue; | |
1361 info = IPA_NODE_REF (node); | |
1362 if (ipa_is_called_with_var_arguments (info)) | |
1363 continue; | |
1364 if (ipcp_const_param_count (node)) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1365 node->aux = fibheap_insert (heap, ipcp_estimate_cloning_cost (node), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1366 node); |
0 | 1367 } |
1368 | |
1369 /* Now clone in priority order until code size growth limits are met or | |
1370 heap is emptied. */ | |
1371 while (!fibheap_empty (heap)) | |
1372 { | |
1373 struct ipa_node_params *info; | |
1374 int growth = 0; | |
1375 bitmap args_to_skip; | |
1376 struct cgraph_edge *cs; | |
1377 | |
1378 node = (struct cgraph_node *)fibheap_extract_min (heap); | |
1379 node->aux = NULL; | |
1380 if (dump_file) | |
1381 fprintf (dump_file, "considering function %s\n", | |
1382 cgraph_node_name (node)); | |
1383 | |
1384 growth = ipcp_estimate_growth (node); | |
1385 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1386 if (new_size + growth > max_new_size) |
0 | 1387 break; |
1388 if (growth | |
1389 && optimize_function_for_size_p (DECL_STRUCT_FUNCTION (node->decl))) | |
1390 { | |
1391 if (dump_file) | |
1392 fprintf (dump_file, "Not versioning, cold code would grow"); | |
1393 continue; | |
1394 } | |
1395 | |
1396 info = IPA_NODE_REF (node); | |
1397 count = ipa_get_param_count (info); | |
1398 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1399 replace_trees = VEC_alloc (ipa_replace_map_p, gc, 1); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1400 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1401 if (node->local.can_change_signature) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1402 args_to_skip = BITMAP_GGC_ALLOC (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1403 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1404 args_to_skip = NULL; |
0 | 1405 for (i = 0; i < count; i++) |
1406 { | |
1407 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); | |
1408 parm_tree = ipa_get_param (info, i); | |
1409 | |
1410 /* We can proactively remove obviously unused arguments. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1411 if (!ipa_is_param_used (info, i)) |
0 | 1412 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1413 if (args_to_skip) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1414 bitmap_set_bit (args_to_skip, i); |
0 | 1415 continue; |
1416 } | |
1417 | |
1418 if (lat->type == IPA_CONST_VALUE) | |
1419 { | |
1420 replace_param = | |
1421 ipcp_create_replace_map (parm_tree, lat); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1422 if (replace_param == NULL) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1423 break; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1424 VEC_safe_push (ipa_replace_map_p, gc, replace_trees, replace_param); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1425 if (args_to_skip) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1426 bitmap_set_bit (args_to_skip, i); |
0 | 1427 } |
1428 } | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1429 if (i < count) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1430 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1431 if (dump_file) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1432 fprintf (dump_file, "Not versioning, some parameters couldn't be replaced"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1433 continue; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1434 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1435 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1436 new_size += growth; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1437 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1438 /* Look if original function becomes dead after cloning. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1439 for (cs = node->callers; cs != NULL; cs = cs->next_caller) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1440 if (cs->caller == node || ipcp_need_redirect_p (cs)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1441 break; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1442 if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1443 bitmap_set_bit (dead_nodes, node->uid); |
0 | 1444 |
1445 /* Compute how many callers node has. */ | |
1446 node_callers = 0; | |
1447 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
1448 node_callers++; | |
1449 redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers); | |
1450 for (cs = node->callers; cs != NULL; cs = cs->next_caller) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1451 if (!cs->indirect_inlining_edge) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1452 VEC_quick_push (cgraph_edge_p, redirect_callers, cs); |
0 | 1453 |
1454 /* Redirecting all the callers of the node to the | |
1455 new versioned node. */ | |
1456 node1 = | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1457 cgraph_create_virtual_clone (node, redirect_callers, replace_trees, |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1458 args_to_skip, "constprop"); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1459 args_to_skip = NULL; |
0 | 1460 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
|
1461 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
|
1462 |
0 | 1463 if (node1 == NULL) |
1464 continue; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1465 ipcp_process_devirtualization_opportunities (node1); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1466 |
0 | 1467 if (dump_file) |
1468 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
|
1469 cgraph_node_name (node), (int)growth, (int)new_size); |
0 | 1470 ipcp_init_cloned_node (node, node1); |
1471 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1472 info = IPA_NODE_REF (node); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1473 for (i = 0; i < count; i++) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1474 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1475 struct ipcp_lattice *lat = ipcp_get_lattice (info, i); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1476 if (lat->type == IPA_CONST_VALUE) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1477 ipcp_discover_new_direct_edges (node1, i, lat->constant); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1478 } |
0 | 1479 |
1480 if (dump_file) | |
1481 dump_function_to_file (node1->decl, dump_file, dump_flags); | |
1482 | |
1483 for (cs = node->callees; cs; cs = cs->next_callee) | |
1484 if (cs->callee->aux) | |
1485 { | |
1486 fibheap_delete_node (heap, (fibnode_t) cs->callee->aux); | |
1487 cs->callee->aux = fibheap_insert (heap, | |
1488 ipcp_estimate_cloning_cost (cs->callee), | |
1489 cs->callee); | |
1490 } | |
1491 } | |
1492 | |
1493 while (!fibheap_empty (heap)) | |
1494 { | |
1495 if (dump_file) | |
1496 fprintf (dump_file, "skipping function %s\n", | |
1497 cgraph_node_name (node)); | |
1498 node = (struct cgraph_node *) fibheap_extract_min (heap); | |
1499 node->aux = NULL; | |
1500 } | |
1501 fibheap_delete (heap); | |
1502 BITMAP_FREE (dead_nodes); | |
1503 ipcp_update_callgraph (); | |
1504 ipcp_update_profiling (); | |
1505 } | |
1506 | |
1507 /* The IPCP driver. */ | |
1508 static unsigned int | |
1509 ipcp_driver (void) | |
1510 { | |
1511 cgraph_remove_unreachable_nodes (true,dump_file); | |
1512 if (dump_file) | |
1513 { | |
1514 fprintf (dump_file, "\nIPA structures before propagation:\n"); | |
1515 if (dump_flags & TDF_DETAILS) | |
1516 ipa_print_all_params (dump_file); | |
1517 ipa_print_all_jump_functions (dump_file); | |
1518 } | |
1519 /* 2. Do the interprocedural propagation. */ | |
1520 ipcp_iterate_stage (); | |
1521 /* 3. Insert the constants found to the functions. */ | |
1522 ipcp_insert_stage (); | |
1523 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1524 { | |
1525 fprintf (dump_file, "\nProfiling info after insert stage:\n"); | |
1526 ipcp_print_profile_data (dump_file); | |
1527 } | |
1528 /* 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
|
1529 ipa_free_all_structures_after_ipa_cp (); |
0 | 1530 if (dump_file) |
1531 fprintf (dump_file, "\nIPA constant propagation end\n"); | |
1532 return 0; | |
1533 } | |
1534 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1535 /* Initialization and computation of IPCP data structures. This is the initial |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1536 intraprocedural analysis of functions, which gathers information to be |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1537 propagated later on. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1538 |
0 | 1539 static void |
1540 ipcp_generate_summary (void) | |
1541 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1542 struct cgraph_node *node; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1543 |
0 | 1544 if (dump_file) |
1545 fprintf (dump_file, "\nIPA constant propagation start:\n"); | |
1546 ipa_check_create_node_params (); | |
1547 ipa_check_create_edge_args (); | |
1548 ipa_register_cgraph_hooks (); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1549 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1550 for (node = cgraph_nodes; node; node = node->next) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1551 if (node->analyzed) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1552 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1553 /* Unreachable nodes should have been eliminated before ipcp. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1554 gcc_assert (node->needed || node->reachable); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1555 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1556 node->local.versionable = tree_versionable_function_p (node->decl); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1557 ipa_analyze_node (node); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1558 } |
0 | 1559 } |
1560 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1561 /* 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
|
1562 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
|
1563 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
|
1564 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
|
1565 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1566 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
|
1567 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1568 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1569 /* 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
|
1570 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1571 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
|
1572 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1573 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
|
1574 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1575 |
0 | 1576 /* Gate for IPCP optimization. */ |
1577 static bool | |
1578 cgraph_gate_cp (void) | |
1579 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1580 /* FIXME: We should remove the optimize check after we ensure we never run |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1581 IPA passes when not optimizing. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1582 return flag_ipa_cp && optimize; |
0 | 1583 } |
1584 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
47
diff
changeset
|
1585 struct ipa_opt_pass_d pass_ipa_cp = |
0 | 1586 { |
1587 { | |
1588 IPA_PASS, | |
1589 "cp", /* name */ | |
1590 cgraph_gate_cp, /* gate */ | |
1591 ipcp_driver, /* execute */ | |
1592 NULL, /* sub */ | |
1593 NULL, /* next */ | |
1594 0, /* static_pass_number */ | |
1595 TV_IPA_CONSTANT_PROP, /* tv_id */ | |
1596 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
|
1597 0, /* properties_provided */ |
0 | 1598 0, /* properties_destroyed */ |
1599 0, /* todo_flags_start */ | |
1600 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
|
1601 TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */ |
0 | 1602 }, |
1603 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
|
1604 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
|
1605 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
|
1606 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
|
1607 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
|
1608 NULL, /* stmt_fixup */ |
0 | 1609 0, /* TODOs */ |
1610 NULL, /* function_transform */ | |
1611 NULL, /* variable_transform */ | |
1612 }; |