Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-ssa-sink.c @ 118:fd00160c1b76
ifdef TARGET_64BIT
author | mir3636 |
---|---|
date | Tue, 27 Feb 2018 15:01:35 +0900 |
parents | 04ced10e8804 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* Code sinking for trees |
111 | 2 Copyright (C) 2001-2017 Free Software Foundation, Inc. |
0 | 3 Contributed by Daniel Berlin <dan@dberlin.org> |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
9 the Free Software Foundation; either version 3, or (at your option) | |
10 any later version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
111 | 24 #include "backend.h" |
0 | 25 #include "tree.h" |
26 #include "gimple.h" | |
111 | 27 #include "cfghooks.h" |
0 | 28 #include "tree-pass.h" |
111 | 29 #include "ssa.h" |
30 #include "gimple-pretty-print.h" | |
31 #include "fold-const.h" | |
32 #include "stor-layout.h" | |
33 #include "cfganal.h" | |
34 #include "gimple-iterator.h" | |
35 #include "tree-cfg.h" | |
0 | 36 #include "cfgloop.h" |
111 | 37 #include "params.h" |
0 | 38 |
39 /* TODO: | |
40 1. Sinking store only using scalar promotion (IE without moving the RHS): | |
41 | |
42 *q = p; | |
43 p = p + 1; | |
44 if (something) | |
45 *q = <not p>; | |
46 else | |
47 y = *q; | |
48 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
49 |
0 | 50 should become |
51 sinktemp = p; | |
52 p = p + 1; | |
53 if (something) | |
54 *q = <not p>; | |
55 else | |
56 { | |
57 *q = sinktemp; | |
58 y = *q | |
59 } | |
60 Store copy propagation will take care of the store elimination above. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
61 |
0 | 62 |
63 2. Sinking using Partial Dead Code Elimination. */ | |
64 | |
65 | |
66 static struct | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
67 { |
0 | 68 /* The number of statements sunk down the flowgraph by code sinking. */ |
69 int sunk; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
70 |
0 | 71 } sink_stats; |
72 | |
73 | |
74 /* Given a PHI, and one of its arguments (DEF), find the edge for | |
75 that argument and return it. If the argument occurs twice in the PHI node, | |
76 we return NULL. */ | |
77 | |
78 static basic_block | |
111 | 79 find_bb_for_arg (gphi *phi, tree def) |
0 | 80 { |
81 size_t i; | |
82 bool foundone = false; | |
83 basic_block result = NULL; | |
84 for (i = 0; i < gimple_phi_num_args (phi); i++) | |
85 if (PHI_ARG_DEF (phi, i) == def) | |
86 { | |
87 if (foundone) | |
88 return NULL; | |
89 foundone = true; | |
90 result = gimple_phi_arg_edge (phi, i)->src; | |
91 } | |
92 return result; | |
93 } | |
94 | |
95 /* When the first immediate use is in a statement, then return true if all | |
96 immediate uses in IMM are in the same statement. | |
97 We could also do the case where the first immediate use is in a phi node, | |
98 and all the other uses are in phis in the same basic block, but this | |
99 requires some expensive checking later (you have to make sure no def/vdef | |
100 in the statement occurs for multiple edges in the various phi nodes it's | |
101 used in, so that you only have one place you can sink it to. */ | |
102 | |
103 static bool | |
111 | 104 all_immediate_uses_same_place (def_operand_p def_p) |
0 | 105 { |
111 | 106 tree var = DEF_FROM_PTR (def_p); |
0 | 107 imm_use_iterator imm_iter; |
108 use_operand_p use_p; | |
109 | |
111 | 110 gimple *firstuse = NULL; |
111 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var) | |
0 | 112 { |
111 | 113 if (is_gimple_debug (USE_STMT (use_p))) |
114 continue; | |
115 if (firstuse == NULL) | |
116 firstuse = USE_STMT (use_p); | |
117 else | |
118 if (firstuse != USE_STMT (use_p)) | |
119 return false; | |
0 | 120 } |
121 | |
122 return true; | |
123 } | |
124 | |
125 /* Find the nearest common dominator of all of the immediate uses in IMM. */ | |
126 | |
127 static basic_block | |
111 | 128 nearest_common_dominator_of_uses (def_operand_p def_p, bool *debug_stmts) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
129 { |
111 | 130 tree var = DEF_FROM_PTR (def_p); |
131 auto_bitmap blocks; | |
0 | 132 basic_block commondom; |
133 unsigned int j; | |
134 bitmap_iterator bi; | |
135 imm_use_iterator imm_iter; | |
136 use_operand_p use_p; | |
137 | |
111 | 138 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var) |
0 | 139 { |
111 | 140 gimple *usestmt = USE_STMT (use_p); |
141 basic_block useblock; | |
0 | 142 |
111 | 143 if (gphi *phi = dyn_cast <gphi *> (usestmt)) |
144 { | |
145 int idx = PHI_ARG_INDEX_FROM_USE (use_p); | |
0 | 146 |
111 | 147 useblock = gimple_phi_arg_edge (phi, idx)->src; |
148 } | |
149 else if (is_gimple_debug (usestmt)) | |
150 { | |
151 *debug_stmts = true; | |
152 continue; | |
153 } | |
154 else | |
155 { | |
156 useblock = gimple_bb (usestmt); | |
157 } | |
0 | 158 |
111 | 159 /* Short circuit. Nothing dominates the entry block. */ |
160 if (useblock == ENTRY_BLOCK_PTR_FOR_FN (cfun)) | |
161 return NULL; | |
162 | |
163 bitmap_set_bit (blocks, useblock->index); | |
0 | 164 } |
111 | 165 commondom = BASIC_BLOCK_FOR_FN (cfun, bitmap_first_set_bit (blocks)); |
0 | 166 EXECUTE_IF_SET_IN_BITMAP (blocks, 0, j, bi) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
167 commondom = nearest_common_dominator (CDI_DOMINATORS, commondom, |
111 | 168 BASIC_BLOCK_FOR_FN (cfun, j)); |
0 | 169 return commondom; |
170 } | |
171 | |
111 | 172 /* Given EARLY_BB and LATE_BB, two blocks in a path through the dominator |
173 tree, return the best basic block between them (inclusive) to place | |
174 statements. | |
175 | |
176 We want the most control dependent block in the shallowest loop nest. | |
177 | |
178 If the resulting block is in a shallower loop nest, then use it. Else | |
179 only use the resulting block if it has significantly lower execution | |
180 frequency than EARLY_BB to avoid gratutious statement movement. We | |
181 consider statements with VOPS more desirable to move. | |
182 | |
183 This pass would obviously benefit from PDO as it utilizes block | |
184 frequencies. It would also benefit from recomputing frequencies | |
185 if profile data is not available since frequencies often get out | |
186 of sync with reality. */ | |
187 | |
188 static basic_block | |
189 select_best_block (basic_block early_bb, | |
190 basic_block late_bb, | |
191 gimple *stmt) | |
192 { | |
193 basic_block best_bb = late_bb; | |
194 basic_block temp_bb = late_bb; | |
195 int threshold; | |
196 | |
197 while (temp_bb != early_bb) | |
198 { | |
199 /* If we've moved into a lower loop nest, then that becomes | |
200 our best block. */ | |
201 if (bb_loop_depth (temp_bb) < bb_loop_depth (best_bb)) | |
202 best_bb = temp_bb; | |
203 | |
204 /* Walk up the dominator tree, hopefully we'll find a shallower | |
205 loop nest. */ | |
206 temp_bb = get_immediate_dominator (CDI_DOMINATORS, temp_bb); | |
207 } | |
208 | |
209 /* If we found a shallower loop nest, then we always consider that | |
210 a win. This will always give us the most control dependent block | |
211 within that loop nest. */ | |
212 if (bb_loop_depth (best_bb) < bb_loop_depth (early_bb)) | |
213 return best_bb; | |
214 | |
215 /* Get the sinking threshold. If the statement to be moved has memory | |
216 operands, then increase the threshold by 7% as those are even more | |
217 profitable to avoid, clamping at 100%. */ | |
218 threshold = PARAM_VALUE (PARAM_SINK_FREQUENCY_THRESHOLD); | |
219 if (gimple_vuse (stmt) || gimple_vdef (stmt)) | |
220 { | |
221 threshold += 7; | |
222 if (threshold > 100) | |
223 threshold = 100; | |
224 } | |
225 | |
226 /* If BEST_BB is at the same nesting level, then require it to have | |
227 significantly lower execution frequency to avoid gratutious movement. */ | |
228 if (bb_loop_depth (best_bb) == bb_loop_depth (early_bb) | |
229 && best_bb->frequency < (early_bb->frequency * threshold / 100.0)) | |
230 return best_bb; | |
231 | |
232 /* No better block found, so return EARLY_BB, which happens to be the | |
233 statement's original block. */ | |
234 return early_bb; | |
235 } | |
236 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
237 /* Given a statement (STMT) and the basic block it is currently in (FROMBB), |
0 | 238 determine the location to sink the statement to, if any. |
239 Returns true if there is such location; in that case, TOGSI points to the | |
240 statement before that STMT should be moved. */ | |
241 | |
242 static bool | |
111 | 243 statement_sink_location (gimple *stmt, basic_block frombb, |
244 gimple_stmt_iterator *togsi, bool *zero_uses_p) | |
0 | 245 { |
111 | 246 gimple *use; |
0 | 247 use_operand_p one_use = NULL_USE_OPERAND_P; |
248 basic_block sinkbb; | |
249 use_operand_p use_p; | |
250 def_operand_p def_p; | |
251 ssa_op_iter iter; | |
252 imm_use_iterator imm_iter; | |
253 | |
111 | 254 *zero_uses_p = false; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
255 |
111 | 256 /* We only can sink assignments and non-looping const/pure calls. */ |
257 int cf; | |
258 if (!is_gimple_assign (stmt) | |
259 && (!is_gimple_call (stmt) | |
260 || !((cf = gimple_call_flags (stmt)) & (ECF_CONST|ECF_PURE)) | |
261 || (cf & ECF_LOOPING_CONST_OR_PURE))) | |
0 | 262 return false; |
263 | |
111 | 264 /* We only can sink stmts with a single definition. */ |
265 def_p = single_ssa_def_operand (stmt, SSA_OP_ALL_DEFS); | |
266 if (def_p == NULL_DEF_OPERAND_P) | |
0 | 267 return false; |
268 | |
269 /* There are a few classes of things we can't or don't move, some because we | |
270 don't have code to handle it, some because it's not profitable and some | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
271 because it's not legal. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
272 |
0 | 273 We can't sink things that may be global stores, at least not without |
274 calculating a lot more information, because we may cause it to no longer | |
275 be seen by an external routine that needs it depending on where it gets | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
276 moved to. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
277 |
0 | 278 We can't sink statements that end basic blocks without splitting the |
279 incoming edge for the sink location to place it there. | |
280 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
281 We can't sink statements that have volatile operands. |
0 | 282 |
283 We don't want to sink dead code, so anything with 0 immediate uses is not | |
284 sunk. | |
285 | |
286 Don't sink BLKmode assignments if current function has any local explicit | |
287 register variables, as BLKmode assignments may involve memcpy or memset | |
288 calls or, on some targets, inline expansion thereof that sometimes need | |
289 to use specific hard registers. | |
290 | |
291 */ | |
292 if (stmt_ends_bb_p (stmt) | |
293 || gimple_has_side_effects (stmt) | |
294 || (cfun->has_local_explicit_reg_vars | |
111 | 295 && TYPE_MODE (TREE_TYPE (gimple_get_lhs (stmt))) == BLKmode)) |
0 | 296 return false; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
297 |
111 | 298 /* Return if there are no immediate uses of this stmt. */ |
299 if (has_zero_uses (DEF_FROM_PTR (def_p))) | |
0 | 300 { |
111 | 301 *zero_uses_p = true; |
302 return false; | |
0 | 303 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
304 |
111 | 305 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (DEF_FROM_PTR (def_p))) |
306 return false; | |
307 | |
0 | 308 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) |
309 { | |
310 tree use = USE_FROM_PTR (use_p); | |
311 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use)) | |
312 return false; | |
313 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
314 |
111 | 315 use = NULL; |
316 | |
317 /* If stmt is a store the one and only use needs to be the VOP | |
318 merging PHI node. */ | |
319 if (virtual_operand_p (DEF_FROM_PTR (def_p))) | |
320 { | |
321 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p)) | |
322 { | |
323 gimple *use_stmt = USE_STMT (use_p); | |
324 | |
325 /* A killing definition is not a use. */ | |
326 if ((gimple_has_lhs (use_stmt) | |
327 && operand_equal_p (gimple_get_lhs (stmt), | |
328 gimple_get_lhs (use_stmt), 0)) | |
329 || stmt_kills_ref_p (use_stmt, gimple_get_lhs (stmt))) | |
330 { | |
331 /* If use_stmt is or might be a nop assignment then USE_STMT | |
332 acts as a use as well as definition. */ | |
333 if (stmt != use_stmt | |
334 && ref_maybe_used_by_stmt_p (use_stmt, | |
335 gimple_get_lhs (stmt))) | |
336 return false; | |
337 continue; | |
338 } | |
339 | |
340 if (gimple_code (use_stmt) != GIMPLE_PHI) | |
341 return false; | |
342 | |
343 if (use | |
344 && use != use_stmt) | |
345 return false; | |
346 | |
347 use = use_stmt; | |
348 } | |
349 if (!use) | |
350 return false; | |
351 } | |
0 | 352 /* If all the immediate uses are not in the same place, find the nearest |
353 common dominator of all the immediate uses. For PHI nodes, we have to | |
354 find the nearest common dominator of all of the predecessor blocks, since | |
355 that is where insertion would have to take place. */ | |
111 | 356 else if (gimple_vuse (stmt) |
357 || !all_immediate_uses_same_place (def_p)) | |
0 | 358 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
359 bool debug_stmts = false; |
111 | 360 basic_block commondom = nearest_common_dominator_of_uses (def_p, |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
361 &debug_stmts); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
362 |
0 | 363 if (commondom == frombb) |
364 return false; | |
365 | |
111 | 366 /* If this is a load then do not sink past any stores. |
367 ??? This is overly simple but cheap. We basically look | |
368 for an existing load with the same VUSE in the path to one | |
369 of the sink candidate blocks and we adjust commondom to the | |
370 nearest to commondom. */ | |
371 if (gimple_vuse (stmt)) | |
372 { | |
373 /* Do not sink loads from hard registers. */ | |
374 if (gimple_assign_single_p (stmt) | |
375 && TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL | |
376 && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt))) | |
377 return false; | |
378 | |
379 imm_use_iterator imm_iter; | |
380 use_operand_p use_p; | |
381 basic_block found = NULL; | |
382 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vuse (stmt)) | |
383 { | |
384 gimple *use_stmt = USE_STMT (use_p); | |
385 basic_block bb = gimple_bb (use_stmt); | |
386 /* For PHI nodes the block we know sth about | |
387 is the incoming block with the use. */ | |
388 if (gimple_code (use_stmt) == GIMPLE_PHI) | |
389 bb = EDGE_PRED (bb, PHI_ARG_INDEX_FROM_USE (use_p))->src; | |
390 /* Any dominator of commondom would be ok with | |
391 adjusting commondom to that block. */ | |
392 bb = nearest_common_dominator (CDI_DOMINATORS, bb, commondom); | |
393 if (!found) | |
394 found = bb; | |
395 else if (dominated_by_p (CDI_DOMINATORS, bb, found)) | |
396 found = bb; | |
397 /* If we can't improve, stop. */ | |
398 if (found == commondom) | |
399 break; | |
400 } | |
401 commondom = found; | |
402 if (commondom == frombb) | |
403 return false; | |
404 } | |
405 | |
0 | 406 /* Our common dominator has to be dominated by frombb in order to be a |
407 trivially safe place to put this statement, since it has multiple | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
408 uses. */ |
0 | 409 if (!dominated_by_p (CDI_DOMINATORS, commondom, frombb)) |
410 return false; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
411 |
111 | 412 commondom = select_best_block (frombb, commondom, stmt); |
0 | 413 |
111 | 414 if (commondom == frombb) |
415 return false; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
416 |
0 | 417 *togsi = gsi_after_labels (commondom); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
418 |
0 | 419 return true; |
420 } | |
111 | 421 else |
0 | 422 { |
111 | 423 FOR_EACH_IMM_USE_FAST (one_use, imm_iter, DEF_FROM_PTR (def_p)) |
424 { | |
425 if (is_gimple_debug (USE_STMT (one_use))) | |
426 continue; | |
427 break; | |
428 } | |
429 use = USE_STMT (one_use); | |
0 | 430 |
111 | 431 if (gimple_code (use) != GIMPLE_PHI) |
432 { | |
433 sinkbb = gimple_bb (use); | |
434 sinkbb = select_best_block (frombb, gimple_bb (use), stmt); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
435 |
111 | 436 if (sinkbb == frombb) |
437 return false; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
438 |
111 | 439 *togsi = gsi_for_stmt (use); |
440 | |
441 return true; | |
442 } | |
0 | 443 } |
444 | |
111 | 445 sinkbb = find_bb_for_arg (as_a <gphi *> (use), DEF_FROM_PTR (def_p)); |
0 | 446 |
111 | 447 /* This can happen if there are multiple uses in a PHI. */ |
0 | 448 if (!sinkbb) |
449 return false; | |
111 | 450 |
451 sinkbb = select_best_block (frombb, sinkbb, stmt); | |
452 if (!sinkbb || sinkbb == frombb) | |
0 | 453 return false; |
454 | |
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
|
455 /* If the latch block is empty, don't make it non-empty by sinking |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
456 something into it. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
457 if (sinkbb == frombb->loop_father->latch |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
458 && empty_block_p (sinkbb)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
459 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
|
460 |
0 | 461 *togsi = gsi_after_labels (sinkbb); |
462 | |
463 return true; | |
464 } | |
465 | |
466 /* Perform code sinking on BB */ | |
467 | |
468 static void | |
469 sink_code_in_bb (basic_block bb) | |
470 { | |
471 basic_block son; | |
472 gimple_stmt_iterator gsi; | |
473 edge_iterator ei; | |
474 edge e; | |
475 bool last = true; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
476 |
0 | 477 /* If this block doesn't dominate anything, there can't be any place to sink |
478 the statements to. */ | |
479 if (first_dom_son (CDI_DOMINATORS, bb) == NULL) | |
480 goto earlyout; | |
481 | |
482 /* We can't move things across abnormal edges, so don't try. */ | |
483 FOR_EACH_EDGE (e, ei, bb->succs) | |
484 if (e->flags & EDGE_ABNORMAL) | |
485 goto earlyout; | |
486 | |
487 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);) | |
488 { | |
111 | 489 gimple *stmt = gsi_stmt (gsi); |
0 | 490 gimple_stmt_iterator togsi; |
111 | 491 bool zero_uses_p; |
0 | 492 |
111 | 493 if (!statement_sink_location (stmt, bb, &togsi, &zero_uses_p)) |
0 | 494 { |
111 | 495 gimple_stmt_iterator saved = gsi; |
0 | 496 if (!gsi_end_p (gsi)) |
497 gsi_prev (&gsi); | |
111 | 498 /* If we face a dead stmt remove it as it possibly blocks |
499 sinking of uses. */ | |
500 if (zero_uses_p | |
501 && ! gimple_vdef (stmt)) | |
502 { | |
503 gsi_remove (&saved, true); | |
504 release_defs (stmt); | |
505 } | |
506 else | |
507 last = false; | |
0 | 508 continue; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
509 } |
0 | 510 if (dump_file) |
511 { | |
512 fprintf (dump_file, "Sinking "); | |
513 print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS); | |
514 fprintf (dump_file, " from bb %d to bb %d\n", | |
515 bb->index, (gsi_bb (togsi))->index); | |
516 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
517 |
111 | 518 /* Update virtual operands of statements in the path we |
519 do not sink to. */ | |
520 if (gimple_vdef (stmt)) | |
521 { | |
522 imm_use_iterator iter; | |
523 use_operand_p use_p; | |
524 gimple *vuse_stmt; | |
525 | |
526 FOR_EACH_IMM_USE_STMT (vuse_stmt, iter, gimple_vdef (stmt)) | |
527 if (gimple_code (vuse_stmt) != GIMPLE_PHI) | |
528 FOR_EACH_IMM_USE_ON_STMT (use_p, iter) | |
529 SET_USE (use_p, gimple_vuse (stmt)); | |
530 } | |
531 | |
0 | 532 /* If this is the end of the basic block, we need to insert at the end |
533 of the basic block. */ | |
534 if (gsi_end_p (togsi)) | |
535 gsi_move_to_bb_end (&gsi, gsi_bb (togsi)); | |
536 else | |
537 gsi_move_before (&gsi, &togsi); | |
538 | |
539 sink_stats.sunk++; | |
540 | |
541 /* If we've just removed the last statement of the BB, the | |
542 gsi_end_p() test below would fail, but gsi_prev() would have | |
543 succeeded, and we want it to succeed. So we keep track of | |
544 whether we're at the last statement and pick up the new last | |
545 statement. */ | |
546 if (last) | |
547 { | |
548 gsi = gsi_last_bb (bb); | |
549 continue; | |
550 } | |
551 | |
552 last = false; | |
553 if (!gsi_end_p (gsi)) | |
554 gsi_prev (&gsi); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
555 |
0 | 556 } |
557 earlyout: | |
558 for (son = first_dom_son (CDI_POST_DOMINATORS, bb); | |
559 son; | |
560 son = next_dom_son (CDI_POST_DOMINATORS, son)) | |
561 { | |
562 sink_code_in_bb (son); | |
563 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
564 } |
0 | 565 |
566 /* Perform code sinking. | |
567 This moves code down the flowgraph when we know it would be | |
568 profitable to do so, or it wouldn't increase the number of | |
569 executions of the statement. | |
570 | |
571 IE given | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
572 |
0 | 573 a_1 = b + c; |
574 if (<something>) | |
575 { | |
576 } | |
577 else | |
578 { | |
579 foo (&b, &c); | |
580 a_5 = b + c; | |
581 } | |
582 a_6 = PHI (a_5, a_1); | |
583 USE a_6. | |
584 | |
585 we'll transform this into: | |
586 | |
587 if (<something>) | |
588 { | |
589 a_1 = b + c; | |
590 } | |
591 else | |
592 { | |
593 foo (&b, &c); | |
594 a_5 = b + c; | |
595 } | |
596 a_6 = PHI (a_5, a_1); | |
597 USE a_6. | |
598 | |
599 Note that this reduces the number of computations of a = b + c to 1 | |
600 when we take the else edge, instead of 2. | |
601 */ | |
111 | 602 namespace { |
603 | |
604 const pass_data pass_data_sink_code = | |
605 { | |
606 GIMPLE_PASS, /* type */ | |
607 "sink", /* name */ | |
608 OPTGROUP_NONE, /* optinfo_flags */ | |
609 TV_TREE_SINK, /* tv_id */ | |
610 /* PROP_no_crit_edges is ensured by running split_critical_edges in | |
611 pass_data_sink_code::execute (). */ | |
612 ( PROP_cfg | PROP_ssa ), /* properties_required */ | |
613 0, /* properties_provided */ | |
614 0, /* properties_destroyed */ | |
615 0, /* todo_flags_start */ | |
616 TODO_update_ssa, /* todo_flags_finish */ | |
617 }; | |
618 | |
619 class pass_sink_code : public gimple_opt_pass | |
620 { | |
621 public: | |
622 pass_sink_code (gcc::context *ctxt) | |
623 : gimple_opt_pass (pass_data_sink_code, ctxt) | |
624 {} | |
625 | |
626 /* opt_pass methods: */ | |
627 virtual bool gate (function *) { return flag_tree_sink != 0; } | |
628 virtual unsigned int execute (function *); | |
629 | |
630 }; // class pass_sink_code | |
631 | |
632 unsigned int | |
633 pass_sink_code::execute (function *fun) | |
0 | 634 { |
635 loop_optimizer_init (LOOPS_NORMAL); | |
111 | 636 split_critical_edges (); |
0 | 637 connect_infinite_loops_to_exit (); |
638 memset (&sink_stats, 0, sizeof (sink_stats)); | |
639 calculate_dominance_info (CDI_DOMINATORS); | |
640 calculate_dominance_info (CDI_POST_DOMINATORS); | |
111 | 641 sink_code_in_bb (EXIT_BLOCK_PTR_FOR_FN (fun)); |
642 statistics_counter_event (fun, "Sunk statements", sink_stats.sunk); | |
0 | 643 free_dominance_info (CDI_POST_DOMINATORS); |
644 remove_fake_exit_edges (); | |
645 loop_optimizer_finalize (); | |
646 | |
647 return 0; | |
648 } | |
649 | |
111 | 650 } // anon namespace |
0 | 651 |
111 | 652 gimple_opt_pass * |
653 make_pass_sink_code (gcc::context *ctxt) | |
0 | 654 { |
111 | 655 return new pass_sink_code (ctxt); |
656 } |