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