]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gimple-ssa-split-paths.c
Allow automatics in equivalences
[thirdparty/gcc.git] / gcc / gimple-ssa-split-paths.c
CommitLineData
b0e3fe96 1/* Support routines for Splitting Paths to loop backedges
fbd26352 2 Copyright (C) 2015-2019 Free Software Foundation, Inc.
b0e3fe96 3 Contributed by Ajit Kumar Agarwal <ajitkum@xilinx.com>.
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
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
18along 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"
24#include "backend.h"
25#include "tree.h"
26#include "gimple.h"
27#include "tree-pass.h"
3f0ff0d8 28#include "tree-cfg.h"
b0e3fe96 29#include "cfganal.h"
30#include "cfgloop.h"
31#include "gimple-iterator.h"
32#include "tracer.h"
d7390210 33#include "predict.h"
3f0ff0d8 34#include "params.h"
1e74686c 35#include "gimple-ssa.h"
36#include "tree-phinodes.h"
37#include "ssa-iterators.h"
b0e3fe96 38
39/* Given LATCH, the latch block in a loop, see if the shape of the
40 path reaching LATCH is suitable for being split by duplication.
41 If so, return the block that will be duplicated into its predecessor
42 paths. Else return NULL. */
43
44static basic_block
45find_block_to_duplicate_for_splitting_paths (basic_block latch)
46{
47 /* We should have simple latches at this point. So the latch should
48 have a single successor. This implies the predecessor of the latch
49 likely has the loop exit. And it's that predecessor we're most
50 interested in. To keep things simple, we're going to require that
51 the latch have a single predecessor too. */
52 if (single_succ_p (latch) && single_pred_p (latch))
53 {
54 basic_block bb = get_immediate_dominator (CDI_DOMINATORS, latch);
55 gcc_assert (single_pred_edge (latch)->src == bb);
56
57 /* If BB has been marked as not to be duplicated, then honor that
58 request. */
59 if (ignore_bb_p (bb))
60 return NULL;
61
62 gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb));
63 /* The immediate dominator of the latch must end in a conditional. */
64 if (!last || gimple_code (last) != GIMPLE_COND)
65 return NULL;
66
67 /* We're hoping that BB is a join point for an IF-THEN-ELSE diamond
68 region. Verify that it is.
69
70 First, verify that BB has two predecessors (each arm of the
71 IF-THEN-ELSE) and two successors (the latch and exit). */
72 if (EDGE_COUNT (bb->preds) == 2 && EDGE_COUNT (bb->succs) == 2)
73 {
74 /* Now verify that BB's immediate dominator ends in a
75 conditional as well. */
76 basic_block bb_idom = get_immediate_dominator (CDI_DOMINATORS, bb);
77 gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb_idom));
78 if (!last || gimple_code (last) != GIMPLE_COND)
79 return NULL;
80
81 /* And that BB's immediate dominator's successors are the
2ac4967f 82 predecessors of BB or BB itself. */
83 if (!(EDGE_PRED (bb, 0)->src == bb_idom
84 || find_edge (bb_idom, EDGE_PRED (bb, 0)->src))
85 || !(EDGE_PRED (bb, 1)->src == bb_idom
86 || find_edge (bb_idom, EDGE_PRED (bb, 1)->src)))
b0e3fe96 87 return NULL;
88
2ac4967f 89 /* And that the predecessors of BB each have a single successor
90 or are BB's immediate domiator itself. */
91 if (!(EDGE_PRED (bb, 0)->src == bb_idom
92 || single_succ_p (EDGE_PRED (bb, 0)->src))
93 || !(EDGE_PRED (bb, 1)->src == bb_idom
94 || single_succ_p (EDGE_PRED (bb, 1)->src)))
3f0ff0d8 95 return NULL;
96
b0e3fe96 97 /* So at this point we have a simple diamond for an IF-THEN-ELSE
98 construct starting at BB_IDOM, with a join point at BB. BB
99 pass control outside the loop or to the loop latch.
100
101 We're going to want to create two duplicates of BB, one for
102 each successor of BB_IDOM. */
103 return bb;
104 }
105 }
106 return NULL;
107}
108
3f0ff0d8 109/* Return the number of non-debug statements in a block. */
110static unsigned int
111count_stmts_in_block (basic_block bb)
112{
113 gimple_stmt_iterator gsi;
114 unsigned int num_stmts = 0;
115
116 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
117 {
118 gimple *stmt = gsi_stmt (gsi);
119 if (!is_gimple_debug (stmt))
120 num_stmts++;
121 }
122 return num_stmts;
123}
124
125/* Return TRUE if CODE represents a tree code that is not likely to
126 be easily if-convertable because it likely expands into multiple
127 insns, FALSE otherwise. */
128static bool
129poor_ifcvt_candidate_code (enum tree_code code)
130{
131 return (code == MIN_EXPR
132 || code == MAX_EXPR
133 || code == ABS_EXPR
134 || code == COND_EXPR
135 || code == CALL_EXPR);
136}
137
b0e3fe96 138/* Return TRUE if BB is a reasonable block to duplicate by examining
139 its size, false otherwise. BB will always be a loop latch block.
140
3f0ff0d8 141 Things to consider:
142
143 We do not want to spoil if-conversion if at all possible.
144
145 Most of the benefit seems to be from eliminating the unconditional
146 jump rather than CSE/DCE opportunities. So favor duplicating
147 small latches. A latch with just a conditional branch is ideal.
148
149 CSE/DCE opportunties crop up when statements from the predecessors
150 feed statements in the latch and allow statements in the latch to
151 simplify. */
b0e3fe96 152
153static bool
154is_feasible_trace (basic_block bb)
155{
3f0ff0d8 156 basic_block pred1 = EDGE_PRED (bb, 0)->src;
157 basic_block pred2 = EDGE_PRED (bb, 1)->src;
158 int num_stmts_in_join = count_stmts_in_block (bb);
2ac4967f 159 int num_stmts_in_pred1
160 = EDGE_COUNT (pred1->succs) == 1 ? count_stmts_in_block (pred1) : 0;
161 int num_stmts_in_pred2
162 = EDGE_COUNT (pred2->succs) == 1 ? count_stmts_in_block (pred2) : 0;
3f0ff0d8 163
164 /* This is meant to catch cases that are likely opportunities for
165 if-conversion. Essentially we look for the case where
166 BB's predecessors are both single statement blocks where
167 the output of that statement feed the same PHI in BB. */
168 if (num_stmts_in_pred1 == 1 && num_stmts_in_pred2 == 1)
b0e3fe96 169 {
3f0ff0d8 170 gimple *stmt1 = last_and_only_stmt (pred1);
171 gimple *stmt2 = last_and_only_stmt (pred2);
172
173 if (stmt1 && stmt2
174 && gimple_code (stmt1) == GIMPLE_ASSIGN
175 && gimple_code (stmt2) == GIMPLE_ASSIGN)
176 {
177 enum tree_code code1 = gimple_assign_rhs_code (stmt1);
178 enum tree_code code2 = gimple_assign_rhs_code (stmt2);
179
180 if (!poor_ifcvt_candidate_code (code1)
181 && !poor_ifcvt_candidate_code (code2))
182 {
183 tree lhs1 = gimple_assign_lhs (stmt1);
184 tree lhs2 = gimple_assign_lhs (stmt2);
185 gimple_stmt_iterator gsi;
186 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
187 {
188 gimple *phi = gsi_stmt (gsi);
189 if ((gimple_phi_arg_def (phi, 0) == lhs1
190 && gimple_phi_arg_def (phi, 1) == lhs2)
191 || (gimple_phi_arg_def (phi, 1) == lhs1
192 && gimple_phi_arg_def (phi, 0) == lhs2))
193 {
194 if (dump_file && (dump_flags & TDF_DETAILS))
195 fprintf (dump_file,
196 "Block %d appears to be a join point for "
197 "if-convertable diamond.\n",
198 bb->index);
199 return false;
200 }
201 }
202 }
203 }
b0e3fe96 204 }
205
0e625e0b 206 /* Canonicalize the form. */
207 if (num_stmts_in_pred1 == 0 && num_stmts_in_pred2 == 1)
208 {
209 std::swap (pred1, pred2);
210 std::swap (num_stmts_in_pred1, num_stmts_in_pred2);
211 }
212
0e625e0b 213 /* Another variant. This one is half-diamond. */
214 if (num_stmts_in_pred1 == 1 && num_stmts_in_pred2 == 0
215 && dominated_by_p (CDI_DOMINATORS, pred1, pred2))
216 {
217 gimple *stmt1 = last_and_only_stmt (pred1);
218
219 /* The only statement in PRED1 must be an assignment that is
220 not a good candidate for if-conversion. This may need some
221 generalization. */
222 if (stmt1 && gimple_code (stmt1) == GIMPLE_ASSIGN)
223 {
224 enum tree_code code1 = gimple_assign_rhs_code (stmt1);
225
226 if (!poor_ifcvt_candidate_code (code1))
227 {
228 tree lhs1 = gimple_assign_lhs (stmt1);
229 tree rhs1 = gimple_assign_rhs1 (stmt1);
230
231 gimple_stmt_iterator gsi;
232 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
233 {
234 gimple *phi = gsi_stmt (gsi);
235 if ((gimple_phi_arg_def (phi, 0) == lhs1
236 && gimple_phi_arg_def (phi, 1) == rhs1)
237 || (gimple_phi_arg_def (phi, 1) == lhs1
238 && gimple_phi_arg_def (phi, 0) == rhs1))
239 {
240 if (dump_file && (dump_flags & TDF_DETAILS))
241 fprintf (dump_file,
242 "Block %d appears to be a join point for "
243 "if-convertable half-diamond.\n",
244 bb->index);
245 return false;
246 }
247 }
248 }
249 }
250 }
251
1e74686c 252 /* If the joiner has no PHIs with useful uses there is zero chance
253 of CSE/DCE/jump-threading possibilities exposed by duplicating it. */
254 bool found_useful_phi = false;
255 for (gphi_iterator si = gsi_start_phis (bb); ! gsi_end_p (si);
256 gsi_next (&si))
257 {
258 gphi *phi = si.phi ();
259 use_operand_p use_p;
260 imm_use_iterator iter;
261 FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
262 {
263 gimple *stmt = USE_STMT (use_p);
264 if (is_gimple_debug (stmt))
265 continue;
266 /* If there's a use in the joiner this might be a CSE/DCE
cd0e3f58 267 opportunity, but not if the use is in a conditional
268 which makes this a likely if-conversion candidate. */
269 if (gimple_bb (stmt) == bb
270 && (!is_gimple_assign (stmt)
271 || (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
272 != tcc_comparison)))
1e74686c 273 {
274 found_useful_phi = true;
275 break;
276 }
277 /* If the use is on a loop header PHI and on one path the
278 value is unchanged this might expose a jump threading
279 opportunity. */
280 if (gimple_code (stmt) == GIMPLE_PHI
281 && gimple_bb (stmt) == bb->loop_father->header
282 /* But for memory the PHI alone isn't good enough. */
283 && ! virtual_operand_p (gimple_phi_result (stmt)))
284 {
ea75e670 285 bool found_unchanged_path = false;
1e74686c 286 for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
287 if (gimple_phi_arg_def (phi, i) == gimple_phi_result (stmt))
288 {
ea75e670 289 found_unchanged_path = true;
1e74686c 290 break;
291 }
ea75e670 292 /* If we found an unchanged path this can only be a threading
293 opportunity if we have uses of the loop header PHI result
294 in a stmt dominating the merge block. Otherwise the
295 splitting may prevent if-conversion. */
296 if (found_unchanged_path)
297 {
298 use_operand_p use2_p;
299 imm_use_iterator iter2;
300 FOR_EACH_IMM_USE_FAST (use2_p, iter2, gimple_phi_result (stmt))
301 {
d592b7eb 302 gimple *use_stmt = USE_STMT (use2_p);
303 if (is_gimple_debug (use_stmt))
46f66a87 304 continue;
d592b7eb 305 basic_block use_bb = gimple_bb (use_stmt);
ea75e670 306 if (use_bb != bb
307 && dominated_by_p (CDI_DOMINATORS, bb, use_bb))
308 {
d592b7eb 309 if (gcond *cond = dyn_cast <gcond *> (use_stmt))
310 if (gimple_cond_code (cond) == EQ_EXPR
311 || gimple_cond_code (cond) == NE_EXPR)
312 found_useful_phi = true;
ea75e670 313 break;
314 }
315 }
316 }
1e74686c 317 if (found_useful_phi)
318 break;
319 }
320 }
321 if (found_useful_phi)
322 break;
323 }
ea75e670 324 /* There is one exception namely a controlling condition we can propagate
325 an equivalence from to the joiner. */
326 bool found_cprop_opportunity = false;
327 basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
328 gcond *cond = as_a <gcond *> (last_stmt (dom));
329 if (gimple_cond_code (cond) == EQ_EXPR
330 || gimple_cond_code (cond) == NE_EXPR)
331 for (unsigned i = 0; i < 2; ++i)
332 {
333 tree op = gimple_op (cond, i);
334 if (TREE_CODE (op) == SSA_NAME)
335 {
336 use_operand_p use_p;
337 imm_use_iterator iter;
338 FOR_EACH_IMM_USE_FAST (use_p, iter, op)
46f66a87 339 {
340 if (is_gimple_debug (USE_STMT (use_p)))
341 continue;
342 if (gimple_bb (USE_STMT (use_p)) == bb)
343 {
344 found_cprop_opportunity = true;
345 break;
346 }
347 }
ea75e670 348 }
349 if (found_cprop_opportunity)
350 break;
351 }
352
353 if (! found_useful_phi && ! found_cprop_opportunity)
1e74686c 354 {
355 if (dump_file && (dump_flags & TDF_DETAILS))
356 fprintf (dump_file,
357 "Block %d is a join that does not expose CSE/DCE/jump-thread "
358 "opportunities when duplicated.\n",
359 bb->index);
360 return false;
361 }
362
3f0ff0d8 363 /* We may want something here which looks at dataflow and tries
364 to guess if duplication of BB is likely to result in simplification
365 of instructions in BB in either the original or the duplicate. */
366
367 /* Upper Hard limit on the number statements to copy. */
368 if (num_stmts_in_join
369 >= PARAM_VALUE (PARAM_MAX_JUMP_THREAD_DUPLICATION_STMTS))
370 return false;
b0e3fe96 371
3f0ff0d8 372 return true;
b0e3fe96 373}
374
375/* If the immediate dominator of the latch of the loop is
376 block with conditional branch, then the loop latch is
377 duplicated to its predecessors path preserving the SSA
378 semantics.
379
380 CFG before transformation.
381
382 2
383 |
384 |
385 +---->3
386 | / \
387 | / \
388 | 4 5
389 | \ /
390 | \ /
391 | 6
392 | / \
393 | / \
394 | 8 7
395 | | |
396 ---+ E
397
398
399
400 Block 8 is the latch. We're going to make copies of block 6 (9 & 10)
401 and wire things up so they look like this:
402
403 2
404 |
405 |
406 +---->3
407 | / \
408 | / \
409 | 4 5
410 | | |
411 | | |
412 | 9 10
413 | |\ /|
414 | | \ / |
415 | | 7 |
416 | | | |
417 | | E |
418 | | |
419 | \ /
420 | \ /
421 +-----8
422
423
424 Blocks 9 and 10 will get merged into blocks 4 & 5 respectively which
425 enables CSE, DCE and other optimizations to occur on a larger block
426 of code. */
427
428static bool
429split_paths ()
430{
431 bool changed = false;
432 loop_p loop;
433
434 loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
435 initialize_original_copy_tables ();
436 calculate_dominance_info (CDI_DOMINATORS);
437
438 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
439 {
d7390210 440 /* Only split paths if we are optimizing this loop for speed. */
441 if (!optimize_loop_for_speed_p (loop))
442 continue;
443
b0e3fe96 444 /* See if there is a block that we can duplicate to split the
445 path to the loop latch. */
d7390210 446 basic_block bb
447 = find_block_to_duplicate_for_splitting_paths (loop->latch);
b0e3fe96 448
449 /* BB is the merge point for an IF-THEN-ELSE we want to transform.
450
fc7a3a00 451 Essentially we want to create a duplicate of bb and redirect the
452 first predecessor of BB to the duplicate (leaving the second
453 predecessor as is. This will split the path leading to the latch
454 re-using BB to avoid useless copying. */
b0e3fe96 455 if (bb && is_feasible_trace (bb))
456 {
457 if (dump_file && (dump_flags & TDF_DETAILS))
458 fprintf (dump_file,
459 "Duplicating join block %d into predecessor paths\n",
460 bb->index);
461 basic_block pred0 = EDGE_PRED (bb, 0)->src;
2ac4967f 462 if (EDGE_COUNT (pred0->succs) != 1)
463 pred0 = EDGE_PRED (bb, 1)->src;
b0e3fe96 464 transform_duplicate (pred0, bb);
b0e3fe96 465 changed = true;
01c5d15d 466
467 /* If BB has an outgoing edge marked as IRREDUCIBLE, then
468 duplicating BB may result in an irreducible region turning
469 into a natural loop.
470
471 Long term we might want to hook this into the block
472 duplication code, but as we've seen with similar changes
473 for edge removal, that can be somewhat risky. */
474 if (EDGE_SUCC (bb, 0)->flags & EDGE_IRREDUCIBLE_LOOP
475 || EDGE_SUCC (bb, 1)->flags & EDGE_IRREDUCIBLE_LOOP)
476 {
477 if (dump_file && (dump_flags & TDF_DETAILS))
478 fprintf (dump_file,
479 "Join block %d has EDGE_IRREDUCIBLE_LOOP set. "
480 "Scheduling loop fixups.\n",
481 bb->index);
482 loops_state_set (LOOPS_NEED_FIXUP);
483 }
b0e3fe96 484 }
485 }
486
487 loop_optimizer_finalize ();
488 free_original_copy_tables ();
489 return changed;
490}
491
492/* Main entry point for splitting paths. Returns TODO_cleanup_cfg if any
493 paths where split, otherwise return zero. */
494
495static unsigned int
496execute_split_paths ()
497{
498 /* If we don't have at least 2 real blocks and backedges in the
499 CFG, then there's no point in trying to perform path splitting. */
500 if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1
501 || !mark_dfs_back_edges ())
502 return 0;
503
504 bool changed = split_paths();
505 if (changed)
506 free_dominance_info (CDI_DOMINATORS);
507
508 return changed ? TODO_cleanup_cfg : 0;
509}
510
511static bool
512gate_split_paths ()
513{
514 return flag_split_paths;
515}
516
517namespace {
518
519const pass_data pass_data_split_paths =
520{
521 GIMPLE_PASS, /* type */
522 "split-paths", /* name */
523 OPTGROUP_NONE, /* optinfo_flags */
524 TV_SPLIT_PATHS, /* tv_id */
525 PROP_ssa, /* properties_required */
526 0, /* properties_provided */
527 0, /* properties_destroyed */
528 0, /* todo_flags_start */
529 TODO_update_ssa, /* todo_flags_finish */
530};
531
532class pass_split_paths : public gimple_opt_pass
533{
534 public:
535 pass_split_paths (gcc::context *ctxt)
536 : gimple_opt_pass (pass_data_split_paths, ctxt)
537 {}
538 /* opt_pass methods: */
539 opt_pass * clone () { return new pass_split_paths (m_ctxt); }
540 virtual bool gate (function *) { return gate_split_paths (); }
541 virtual unsigned int execute (function *) { return execute_split_paths (); }
542
543}; // class pass_split_paths
544
545} // anon namespace
546
547gimple_opt_pass *
548make_pass_split_paths (gcc::context *ctxt)
549{
550 return new pass_split_paths (ctxt);
551}