]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-threadbackward.c
Avoid overly-greedy match in dejagnu regexp.
[thirdparty/gcc.git] / gcc / tree-ssa-threadbackward.c
CommitLineData
0732f75f 1/* SSA Jump Threading
99dee823 2 Copyright (C) 2005-2021 Free Software Foundation, Inc.
0732f75f
JL
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "backend.h"
24#include "predict.h"
25#include "tree.h"
26#include "gimple.h"
27#include "fold-const.h"
28#include "cfgloop.h"
29#include "gimple-iterator.h"
30#include "tree-cfg.h"
31#include "tree-ssa-threadupdate.h"
0732f75f
JL
32#include "tree-ssa-loop.h"
33#include "cfganal.h"
34#include "tree-pass.h"
8b2ef235
JL
35#include "gimple-ssa.h"
36#include "tree-phinodes.h"
27bddc4a 37#include "tree-inline.h"
0a4e5cf3 38#include "tree-vectorizer.h"
2e96b5f1
AH
39#include "value-range.h"
40#include "gimple-range.h"
41#include "tree-ssa-threadedge.h"
42#include "gimple-range-path.h"
43#include "ssa.h"
44#include "tree-cfgcleanup.h"
779275c0 45#include "tree-pretty-print.h"
01b50387 46#include "cfghooks.h"
0732f75f 47
69e55442
AH
48// Path registry for the backwards threader. After all paths have been
49// registered with register_path(), thread_through_all_blocks() is called
50// to modify the CFG.
51
7f6c2258 52class back_threader_registry : public back_jt_path_registry
69e55442
AH
53{
54public:
69e55442 55 bool register_path (const vec<basic_block> &, edge taken);
69e55442
AH
56};
57
58// Class to abstract the profitability code for the backwards threader.
59
60class back_threader_profitability
61{
62public:
63 back_threader_profitability (bool speed_p)
64 : m_speed_p (speed_p)
65 { }
66 bool profitable_path_p (const vec<basic_block> &, tree name, edge taken,
67 bool *irreducible_loop = NULL);
69e55442
AH
68private:
69 const bool m_speed_p;
70};
71
2e96b5f1
AH
72class back_threader
73{
2e96b5f1 74public:
401aaa59 75 back_threader (bool speed_p, bool resolve);
34cd97ff 76 void maybe_thread_block (basic_block bb);
01005550 77 bool thread_through_all_blocks (bool may_peel_loop_headers);
2e96b5f1 78private:
34cd97ff 79 void find_paths (basic_block bb, tree name);
cbeeadff 80 edge maybe_register_path ();
2e96b5f1 81 bool find_paths_to_names (basic_block bb, bitmap imports);
a3d3e8c3 82 bool resolve_def (tree name, bitmap interesting, vec<tree> &worklist);
8a04a5fb 83 void resolve_phi (gphi *phi, bitmap imports);
2e96b5f1
AH
84 edge find_taken_edge (const vec<basic_block> &path);
85 edge find_taken_edge_cond (const vec<basic_block> &path, gcond *);
86 edge find_taken_edge_switch (const vec<basic_block> &path, gswitch *);
779275c0
AH
87 virtual void debug ();
88 virtual void dump (FILE *out);
2e96b5f1 89
34cd97ff
AH
90 back_threader_registry m_registry;
91 back_threader_profitability m_profit;
2e96b5f1
AH
92 gimple_ranger m_ranger;
93 path_range_query m_solver;
94
95 // Current path being analyzed.
96 auto_vec<basic_block> m_path;
97 // Hash to mark visited BBs while analyzing a path.
98 hash_set<basic_block> m_visited_bbs;
99 // The set of SSA names, any of which could potentially change the
100 // value of the final conditional in a path.
d71e1be7 101 auto_bitmap m_imports;
2e96b5f1
AH
102 // The last statement in the path.
103 gimple *m_last_stmt;
104 // This is a bit of a wart. It's used to pass the LHS SSA name to
105 // the profitability engine.
106 tree m_name;
107 // Marker to differentiate unreachable edges.
108 static const edge UNREACHABLE_EDGE;
401aaa59
AH
109 // Set to TRUE if unknown SSA names along a path should be resolved
110 // with the ranger. Otherwise, unknown SSA names are assumed to be
5d4d64fa 111 // VARYING. Setting to true is more precise but slower.
401aaa59 112 bool m_resolve;
2e96b5f1
AH
113};
114
115// Used to differentiate unreachable edges, so we may stop the search
116// in a the given direction.
117const edge back_threader::UNREACHABLE_EDGE = (edge) -1;
118
401aaa59 119back_threader::back_threader (bool speed_p, bool resolve)
0bd68793 120 : m_profit (speed_p),
401aaa59 121 m_solver (m_ranger, resolve)
2e96b5f1
AH
122{
123 m_last_stmt = NULL;
401aaa59 124 m_resolve = resolve;
2e96b5f1
AH
125}
126
2e96b5f1 127// Register the current path for jump threading if it's profitable to
cbeeadff
AH
128// do so.
129//
130// Return the known taken edge out of the path, even if the path was
131// not registered, or NULL if the taken edge could not be determined.
2e96b5f1 132
cbeeadff
AH
133edge
134back_threader::maybe_register_path ()
2e96b5f1 135{
cbeeadff 136 edge taken_edge = find_taken_edge (m_path);
2e96b5f1 137
cbeeadff 138 if (taken_edge && taken_edge != UNREACHABLE_EDGE)
2e96b5f1 139 {
e53fbb17
AH
140 // Avoid circular paths.
141 if (m_visited_bbs.contains (taken_edge->dest))
142 return UNREACHABLE_EDGE;
143
cbeeadff
AH
144 bool irreducible = false;
145 bool profitable
146 = m_profit.profitable_path_p (m_path, m_name, taken_edge, &irreducible);
2e96b5f1 147
cbeeadff
AH
148 if (profitable)
149 {
150 m_registry.register_path (m_path, taken_edge);
151
152 if (irreducible)
153 vect_free_loop_info_assumptions (m_path[0]->loop_father);
154 }
2e96b5f1 155 }
cbeeadff 156 return taken_edge;
2e96b5f1
AH
157}
158
159// Return the known taken edge out of a path. If the path can be
160// determined to be unreachable, return UNREACHABLE_EDGE. If no
161// outgoing edge can be calculated, return NULL.
162
163edge
164back_threader::find_taken_edge (const vec<basic_block> &path)
165{
166 gcc_checking_assert (path.length () > 1);
167 switch (gimple_code (m_last_stmt))
168 {
169 case GIMPLE_COND:
170 return find_taken_edge_cond (path, as_a<gcond *> (m_last_stmt));
171
172 case GIMPLE_SWITCH:
173 return find_taken_edge_switch (path, as_a<gswitch *> (m_last_stmt));
174
175 default:
176 return NULL;
177 }
178}
179
180// Same as find_taken_edge, but for paths ending in a switch.
181
182edge
183back_threader::find_taken_edge_switch (const vec<basic_block> &path,
184 gswitch *sw)
185{
186 tree name = gimple_switch_index (sw);
187 int_range_max r;
188
83668368 189 m_solver.compute_ranges (path, m_imports);
2e96b5f1
AH
190 m_solver.range_of_expr (r, name, sw);
191
192 if (r.undefined_p ())
193 return UNREACHABLE_EDGE;
194
195 if (r.varying_p ())
196 return NULL;
197
113dab2b
AH
198 tree label = find_case_label_range (sw, &r);
199 if (!label)
200 return NULL;
2e96b5f1 201
113dab2b 202 return find_edge (gimple_bb (sw), label_to_block (cfun, CASE_LABEL (label)));
2e96b5f1
AH
203}
204
205// Same as find_taken_edge, but for paths ending in a GIMPLE_COND.
206
207edge
208back_threader::find_taken_edge_cond (const vec<basic_block> &path,
209 gcond *cond)
210{
2e96b5f1 211 int_range_max r;
2e96b5f1 212
83668368 213 m_solver.compute_ranges (path, m_imports);
2e96b5f1
AH
214 m_solver.range_of_stmt (r, cond);
215
90ef1535
AH
216 if (m_solver.unreachable_path_p ())
217 return UNREACHABLE_EDGE;
218
2e96b5f1
AH
219 int_range<2> true_range (boolean_true_node, boolean_true_node);
220 int_range<2> false_range (boolean_false_node, boolean_false_node);
221
222 if (r == true_range || r == false_range)
223 {
224 edge e_true, e_false;
225 basic_block bb = gimple_bb (cond);
226 extract_true_false_edges_from_block (bb, &e_true, &e_false);
227 return r == true_range ? e_true : e_false;
228 }
229 return NULL;
230}
231
232// Populate a vector of trees from a bitmap.
233
234static inline void
a3d3e8c3 235populate_worklist (vec<tree> &worklist, bitmap bits)
2e96b5f1
AH
236{
237 bitmap_iterator bi;
238 unsigned i;
239
240 EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
241 {
242 tree name = ssa_name (i);
243 worklist.quick_push (name);
244 }
245}
246
8a04a5fb 247// Find jump threading paths that go through a PHI.
2e96b5f1 248
8a04a5fb 249void
2e96b5f1
AH
250back_threader::resolve_phi (gphi *phi, bitmap interesting)
251{
252 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (phi)))
8a04a5fb 253 return;
2e96b5f1 254
2e96b5f1
AH
255 for (size_t i = 0; i < gimple_phi_num_args (phi); ++i)
256 {
257 edge e = gimple_phi_arg_edge (phi, i);
258
259 // This is like path_crosses_loops in profitable_path_p but more
260 // restrictive, since profitable_path_p allows threading the
261 // first block because it would be redirected anyhow.
262 //
263 // If we loosened the restriction and used profitable_path_p()
264 // here instead, we would peel off the first iterations of loops
265 // in places like tree-ssa/pr14341.c.
266 bool profitable_p = m_path[0]->loop_father == e->src->loop_father;
267 if (!profitable_p)
268 {
269 if (dump_file && (dump_flags & TDF_DETAILS))
270 fprintf (dump_file,
271 " FAIL: path through PHI in bb%d (incoming bb:%d) crosses loop\n",
272 e->dest->index, e->src->index);
273 continue;
274 }
275
276 tree arg = gimple_phi_arg_def (phi, i);
8a04a5fb 277 unsigned v = 0;
2e96b5f1 278
8a04a5fb
AH
279 if (TREE_CODE (arg) == SSA_NAME
280 && !bitmap_bit_p (interesting, SSA_NAME_VERSION (arg)))
281 {
282 // Record that ARG is interesting when searching down this path.
283 v = SSA_NAME_VERSION (arg);
284 gcc_checking_assert (v != 0);
2e96b5f1
AH
285 bitmap_set_bit (interesting, v);
286 bitmap_set_bit (m_imports, v);
2e96b5f1 287 }
8a04a5fb
AH
288
289 find_paths_to_names (e->src, interesting);
290
291 if (v)
292 bitmap_clear_bit (interesting, v);
2e96b5f1 293 }
2e96b5f1
AH
294}
295
296// If the definition of NAME causes the final conditional of the
297// current path to be constant, register the path, and return TRUE.
298
299bool
a3d3e8c3 300back_threader::resolve_def (tree name, bitmap interesting, vec<tree> &worklist)
2e96b5f1
AH
301{
302 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
303
304 // Handle PHIs.
8a04a5fb
AH
305 if (is_a<gphi *> (def_stmt))
306 {
307 resolve_phi (as_a<gphi *> (def_stmt), interesting);
308 return true;
309 }
2e96b5f1
AH
310
311 // Defer copies of SSAs by adding the source to the worklist.
312 if (gimple_assign_single_p (def_stmt)
313 && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
314 {
315 tree rhs = gimple_assign_rhs1 (def_stmt);
316 bitmap_set_bit (m_imports, SSA_NAME_VERSION (rhs));
317 bitmap_set_bit (interesting, SSA_NAME_VERSION (rhs));
318 worklist.safe_push (rhs);
319 }
320 return false;
321}
322
323// Find jump threading paths to any of the SSA names in the
324// INTERESTING bitmap, and register any such paths.
325//
326// Return TRUE if no further processing past this block is necessary.
327// This is because we've either registered a path, or because there is
328// nothing of interesting beyond this block.
329//
330// BB is the current path being processed.
331
332bool
333back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
334{
335 if (m_visited_bbs.add (bb))
336 return true;
337
338 m_path.safe_push (bb);
339
340 if (m_path.length () > 1
341 && !m_profit.profitable_path_p (m_path, m_name, NULL))
342 {
343 m_path.pop ();
344 m_visited_bbs.remove (bb);
345 return false;
346 }
347
f6d01233
AH
348 // Try to resolve the path without looking back.
349 if (m_path.length () > 1 && maybe_register_path ())
401aaa59
AH
350 {
351 m_path.pop ();
352 m_visited_bbs.remove (bb);
353 return true;
354 }
355
2e96b5f1
AH
356 auto_bitmap processed;
357 unsigned i;
358 bool done = false;
359
360 // We use a worklist instead of iterating through the bitmap,
361 // because we may add new items in-flight.
362 auto_vec<tree> worklist (bitmap_count_bits (interesting));
363 populate_worklist (worklist, interesting);
364 while (!worklist.is_empty ())
365 {
366 tree name = worklist.pop ();
367 unsigned i = SSA_NAME_VERSION (name);
368 basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (name));
369
370 // Process any names defined in this block.
371 if (def_bb == bb)
372 {
373 bitmap_set_bit (processed, i);
374
375 if (resolve_def (name, interesting, worklist))
376 {
377 done = true;
378 goto leave_bb;
379 }
380 }
381 // Examine blocks that define or export an interesting SSA,
382 // since they may compute a range which resolve this path.
383 if ((def_bb == bb
384 || bitmap_bit_p (m_ranger.gori ().exports (bb), i))
385 && m_path.length () > 1)
386 {
cbeeadff 387 if (maybe_register_path ())
2e96b5f1 388 {
2e96b5f1
AH
389 done = true;
390 goto leave_bb;
391 }
392 }
393 }
394
395 // If there are interesting names not yet processed, keep looking.
396 bitmap_and_compl_into (interesting, processed);
397 if (!bitmap_empty_p (interesting))
398 {
399 edge_iterator iter;
400 edge e;
401 FOR_EACH_EDGE (e, iter, bb->preds)
402 if ((e->flags & EDGE_ABNORMAL) == 0)
403 done |= find_paths_to_names (e->src, interesting);
404 }
405
406 leave_bb:
407 bitmap_iterator bi;
408 EXECUTE_IF_SET_IN_BITMAP (processed, 0, i, bi)
409 bitmap_set_bit (interesting, i);
410
411 m_path.pop ();
412 m_visited_bbs.remove (bb);
413 return done;
414}
415
416// Search backwards from BB looking for paths where the final
417// conditional out of BB can be determined. NAME is the LHS of the
418// final conditional. Register such paths for jump threading.
419
420void
421back_threader::find_paths (basic_block bb, tree name)
422{
423 gimple *stmt = last_stmt (bb);
424 if (!stmt
425 || (gimple_code (stmt) != GIMPLE_COND
426 && gimple_code (stmt) != GIMPLE_SWITCH))
427 return;
428
429 if (EDGE_COUNT (bb->succs) > 1
430 || single_succ_to_potentially_threadable_block (bb))
431 {
432 m_last_stmt = stmt;
433 m_visited_bbs.empty ();
434 m_path.truncate (0);
435 m_name = name;
436 bitmap_clear (m_imports);
437
438 auto_bitmap interesting;
439 bitmap_copy (m_imports, m_ranger.gori ().imports (bb));
440 bitmap_copy (interesting, m_imports);
441 find_paths_to_names (bb, interesting);
442 }
443}
444
34cd97ff
AH
445// Simple helper to get the last statement from BB, which is assumed
446// to be a control statement. Return NULL if the last statement is
447// not a control statement.
21f0717a 448
3d466672
JL
449static gimple *
450get_gimple_control_stmt (basic_block bb)
451{
21f0717a 452 gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
3d466672
JL
453
454 if (gsi_end_p (gsi))
455 return NULL;
456
457 gimple *stmt = gsi_stmt (gsi);
458 enum gimple_code code = gimple_code (stmt);
21f0717a
JL
459 if (code == GIMPLE_COND || code == GIMPLE_SWITCH || code == GIMPLE_GOTO)
460 return stmt;
461 return NULL;
3d466672
JL
462}
463
34cd97ff
AH
464// Search backwards from BB looking for paths where the final
465// conditional maybe threaded to a successor block. Record such paths
466// for jump threading.
0732f75f 467
34cd97ff
AH
468void
469back_threader::maybe_thread_block (basic_block bb)
0732f75f 470{
34cd97ff
AH
471 gimple *stmt = get_gimple_control_stmt (bb);
472 if (!stmt)
473 return;
0732f75f 474
34cd97ff
AH
475 enum gimple_code code = gimple_code (stmt);
476 tree name;
477 if (code == GIMPLE_SWITCH)
478 name = gimple_switch_index (as_a <gswitch *> (stmt));
479 else if (code == GIMPLE_COND)
480 name = gimple_cond_lhs (stmt);
481 else if (code == GIMPLE_GOTO)
482 name = gimple_goto_dest (stmt);
483 else
484 name = NULL;
485
486 find_paths (bb, name);
487}
488
489// Perform the actual jump threading for the all queued paths.
490
491bool
01005550 492back_threader::thread_through_all_blocks (bool may_peel_loop_headers)
34cd97ff 493{
01005550 494 return m_registry.thread_through_all_blocks (may_peel_loop_headers);
34cd97ff
AH
495}
496
497// Dump a sequence of BBs through the CFG.
0732f75f 498
34cd97ff
AH
499DEBUG_FUNCTION void
500dump_path (FILE *dump_file, const vec<basic_block> &path)
501{
502 for (size_t i = 0; i < path.length (); ++i)
0732f75f 503 {
34cd97ff
AH
504 fprintf (dump_file, "BB%d", path[i]->index);
505 if (i + 1 < path.length ())
506 fprintf (dump_file, " <- ");
0732f75f 507 }
34cd97ff
AH
508 fprintf (dump_file, "\n");
509}
0732f75f 510
34cd97ff
AH
511DEBUG_FUNCTION void
512debug (const vec <basic_block> &path)
513{
514 dump_path (stderr, path);
0732f75f
JL
515}
516
779275c0
AH
517void
518back_threader::dump (FILE *out)
519{
520 m_solver.dump (out);
521 fprintf (out, "\nCandidates for pre-computation:\n");
522 fprintf (out, "===================================\n");
523
524 bitmap_iterator bi;
525 unsigned i;
526
527 EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
528 {
529 tree name = ssa_name (i);
530 print_generic_expr (out, name, TDF_NONE);
531 fprintf (out, "\n");
532 }
533}
534
535void
536back_threader::debug ()
537{
538 dump (stderr);
539}
540
69e55442
AH
541/* Examine jump threading path PATH and return TRUE if it is profitable to
542 thread it, otherwise return FALSE.
bb5e62d6
JL
543
544 NAME is the SSA_NAME of the variable we found to have a constant
69e55442 545 value on PATH. If unknown, SSA_NAME is NULL.
bb5e62d6 546
69e55442
AH
547 If the taken edge out of the path is known ahead of time it is passed in
548 TAKEN_EDGE, otherwise it is NULL.
bb5e62d6 549
69e55442 550 CREATES_IRREDUCIBLE_LOOP, if non-null is set to TRUE if threading this path
01b50387
AH
551 would create an irreducible loop.
552
553 ?? It seems we should be able to loosen some of the restrictions in
554 this function after loop optimizations have run. */
69e55442
AH
555
556bool
557back_threader_profitability::profitable_path_p (const vec<basic_block> &m_path,
558 tree name,
559 edge taken_edge,
560 bool *creates_irreducible_loop)
bb5e62d6 561{
69e55442 562 gcc_checking_assert (!m_path.is_empty ());
ad071b2b 563
69e55442
AH
564 /* We can an empty path here (excluding the DEF block) when the
565 statement that makes a conditional generate a compile-time
566 constant result is in the same block as the conditional.
ad071b2b
JL
567
568 That's not really a jump threading opportunity, but instead is
569 simple cprop & simplification. We could handle it here if we
570 wanted by wiring up all the incoming edges. If we run this
571 early in IPA, that might be worth doing. For now we just
572 reject that case. */
69e55442
AH
573 if (m_path.length () <= 1)
574 return false;
ad071b2b 575
82cd78f2
AH
576 if (m_path.length () > (unsigned) param_max_fsm_thread_length)
577 {
578 if (dump_file && (dump_flags & TDF_DETAILS))
579 fprintf (dump_file, " FAIL: Jump-thread path not considered: "
580 "the number of basic blocks on the path "
581 "exceeds PARAM_MAX_FSM_THREAD_LENGTH.\n");
582 return false;
583 }
584
bb5e62d6
JL
585 int n_insns = 0;
586 gimple_stmt_iterator gsi;
cde30fe0 587 loop_p loop = m_path[0]->loop_father;
bb5e62d6
JL
588 bool path_crosses_loops = false;
589 bool threaded_through_latch = false;
590 bool multiway_branch_in_path = false;
591 bool threaded_multiway_branch = false;
0f0c2cc3
JH
592 bool contains_hot_bb = false;
593
594 if (dump_file && (dump_flags & TDF_DETAILS))
595 fprintf (dump_file, "Checking profitability of path (backwards): ");
bb5e62d6
JL
596
597 /* Count the number of instructions on the path: as these instructions
598 will have to be duplicated, we will not record the path if there
599 are too many instructions on the path. Also check that all the
600 blocks in the path belong to a single loop. */
cde30fe0 601 for (unsigned j = 0; j < m_path.length (); j++)
bb5e62d6 602 {
cde30fe0 603 basic_block bb = m_path[j];
bb5e62d6 604
0f0c2cc3
JH
605 if (dump_file && (dump_flags & TDF_DETAILS))
606 fprintf (dump_file, " bb:%i", bb->index);
bb5e62d6
JL
607 /* Remember, blocks in the path are stored in opposite order
608 in the PATH array. The last entry in the array represents
609 the block with an outgoing edge that we will redirect to the
610 jump threading path. Thus we don't care about that block's
611 loop father, nor how many statements are in that block because
612 it will not be copied or whether or not it ends in a multiway
613 branch. */
cde30fe0 614 if (j < m_path.length () - 1)
bb5e62d6 615 {
0f0c2cc3 616 int orig_n_insns = n_insns;
bb5e62d6
JL
617 if (bb->loop_father != loop)
618 {
619 path_crosses_loops = true;
779275c0
AH
620
621 // Dump rest of blocks.
622 if (dump_file && (dump_flags & TDF_DETAILS))
623 for (j++; j < m_path.length (); j++)
624 {
625 bb = m_path[j];
626 fprintf (dump_file, " bb:%i", bb->index);
627 }
bb5e62d6
JL
628 break;
629 }
630
631 /* PHIs in the path will create degenerate PHIS in the
632 copied path which will then get propagated away, so
633 looking at just the duplicate path the PHIs would
634 seem unimportant.
635
636 But those PHIs, because they're assignments to objects
637 typically with lives that exist outside the thread path,
638 will tend to generate PHIs (or at least new PHI arguments)
639 at points where we leave the thread path and rejoin
640 the original blocks. So we do want to account for them.
641
642 We ignore virtual PHIs. We also ignore cases where BB
643 has a single incoming edge. That's the most common
644 degenerate PHI we'll see here. Finally we ignore PHIs
645 that are associated with the value we're tracking as
646 that object likely dies. */
647 if (EDGE_COUNT (bb->succs) > 1 && EDGE_COUNT (bb->preds) > 1)
648 {
649 for (gphi_iterator gsip = gsi_start_phis (bb);
650 !gsi_end_p (gsip);
651 gsi_next (&gsip))
652 {
653 gphi *phi = gsip.phi ();
654 tree dst = gimple_phi_result (phi);
655
656 /* Note that if both NAME and DST are anonymous
657 SSA_NAMEs, then we do not have enough information
658 to consider them associated. */
fda5c810 659 if (dst != name
69e55442
AH
660 && name
661 && TREE_CODE (name) == SSA_NAME
fda5c810
RB
662 && (SSA_NAME_VAR (dst) != SSA_NAME_VAR (name)
663 || !SSA_NAME_VAR (dst))
bb5e62d6
JL
664 && !virtual_operand_p (dst))
665 ++n_insns;
666 }
667 }
668
cde30fe0 669 if (!contains_hot_bb && m_speed_p)
0f0c2cc3 670 contains_hot_bb |= optimize_bb_for_speed_p (bb);
bb5e62d6
JL
671 for (gsi = gsi_after_labels (bb);
672 !gsi_end_p (gsi);
673 gsi_next_nondebug (&gsi))
674 {
70a62009
IL
675 /* Do not allow OpenACC loop markers and __builtin_constant_p on
676 threading paths. The latter is disallowed, because an
677 expression might be constant on two threading paths, and
678 become non-constant (i.e.: phi) when they merge. */
bb5e62d6 679 gimple *stmt = gsi_stmt (gsi);
70a62009
IL
680 if (gimple_call_internal_p (stmt, IFN_UNIQUE)
681 || gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
69e55442 682 return false;
bb5e62d6
JL
683 /* Do not count empty statements and labels. */
684 if (gimple_code (stmt) != GIMPLE_NOP
685 && !(gimple_code (stmt) == GIMPLE_ASSIGN
686 && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
687 && !is_gimple_debug (stmt))
0f0c2cc3 688 n_insns += estimate_num_insns (stmt, &eni_size_weights);
bb5e62d6 689 }
0f0c2cc3
JH
690 if (dump_file && (dump_flags & TDF_DETAILS))
691 fprintf (dump_file, " (%i insns)", n_insns-orig_n_insns);
bb5e62d6
JL
692
693 /* We do not look at the block with the threaded branch
694 in this loop. So if any block with a last statement that
695 is a GIMPLE_SWITCH or GIMPLE_GOTO is seen, then we have a
696 multiway branch on our path.
697
698 The block in PATH[0] is special, it's the block were we're
699 going to be able to eliminate its branch. */
700 gimple *last = last_stmt (bb);
701 if (last && (gimple_code (last) == GIMPLE_SWITCH
702 || gimple_code (last) == GIMPLE_GOTO))
703 {
704 if (j == 0)
705 threaded_multiway_branch = true;
706 else
707 multiway_branch_in_path = true;
708 }
709 }
710
711 /* Note if we thread through the latch, we will want to include
712 the last entry in the array when determining if we thread
713 through the loop latch. */
714 if (loop->latch == bb)
01b50387
AH
715 {
716 threaded_through_latch = true;
717 if (dump_file && (dump_flags & TDF_DETAILS))
718 fprintf (dump_file, " (latch)");
719 }
bb5e62d6
JL
720 }
721
cde30fe0 722 gimple *stmt = get_gimple_control_stmt (m_path[0]);
27bddc4a
JH
723 gcc_assert (stmt);
724
bb5e62d6
JL
725 /* We are going to remove the control statement at the end of the
726 last block in the threading path. So don't count it against our
727 statement count. */
bb5e62d6 728
0f0c2cc3
JH
729 int stmt_insns = estimate_num_insns (stmt, &eni_size_weights);
730 n_insns-= stmt_insns;
731
732 if (dump_file && (dump_flags & TDF_DETAILS))
733 fprintf (dump_file, "\n Control statement insns: %i\n"
734 " Overall: %i insns\n",
735 stmt_insns, n_insns);
27bddc4a 736
69e55442 737 if (creates_irreducible_loop)
bb5e62d6 738 {
69e55442
AH
739 /* If this path threaded through the loop latch back into the
740 same loop and the destination does not dominate the loop
741 latch, then this thread would create an irreducible loop. */
742 *creates_irreducible_loop = false;
743 if (taken_edge
744 && threaded_through_latch
745 && loop == taken_edge->dest->loop_father
746 && (determine_bb_domination_status (loop, taken_edge->dest)
747 == DOMST_NONDOMINATING))
748 *creates_irreducible_loop = true;
bb5e62d6
JL
749 }
750
bb5e62d6
JL
751 if (path_crosses_loops)
752 {
753 if (dump_file && (dump_flags & TDF_DETAILS))
c7a669af 754 fprintf (dump_file, " FAIL: Jump-thread path not considered: "
bb5e62d6 755 "the path crosses loops.\n");
69e55442 756 return false;
bb5e62d6
JL
757 }
758
0f0c2cc3
JH
759 /* Threading is profitable if the path duplicated is hot but also
760 in a case we separate cold path from hot path and permit optimization
761 of the hot path later. Be on the agressive side here. In some testcases,
762 as in PR 78407 this leads to noticeable improvements. */
69e55442
AH
763 if (m_speed_p
764 && ((taken_edge && optimize_edge_for_speed_p (taken_edge))
765 || contains_hot_bb))
27bddc4a 766 {
028d4092 767 if (n_insns >= param_max_fsm_thread_path_insns)
27bddc4a
JH
768 {
769 if (dump_file && (dump_flags & TDF_DETAILS))
c7a669af 770 fprintf (dump_file, " FAIL: Jump-thread path not considered: "
27bddc4a
JH
771 "the number of instructions on the path "
772 "exceeds PARAM_MAX_FSM_THREAD_PATH_INSNS.\n");
69e55442 773 return false;
27bddc4a
JH
774 }
775 }
69e55442 776 else if (!m_speed_p && n_insns > 1)
bb5e62d6
JL
777 {
778 if (dump_file && (dump_flags & TDF_DETAILS))
c7a669af 779 fprintf (dump_file, " FAIL: Jump-thread path not considered: "
27bddc4a
JH
780 "duplication of %i insns is needed and optimizing for size.\n",
781 n_insns);
69e55442 782 return false;
bb5e62d6
JL
783 }
784
785 /* We avoid creating irreducible inner loops unless we thread through
786 a multiway branch, in which case we have deemed it worth losing
787 other loop optimizations later.
788
789 We also consider it worth creating an irreducible inner loop if
790 the number of copied statement is low relative to the length of
791 the path -- in that case there's little the traditional loop
792 optimizer would have done anyway, so an irreducible loop is not
793 so bad. */
69e55442
AH
794 if (!threaded_multiway_branch
795 && creates_irreducible_loop
796 && *creates_irreducible_loop
028d4092 797 && (n_insns * (unsigned) param_fsm_scale_path_stmts
cde30fe0 798 > (m_path.length () *
028d4092 799 (unsigned) param_fsm_scale_path_blocks)))
bb5e62d6
JL
800
801 {
802 if (dump_file && (dump_flags & TDF_DETAILS))
803 fprintf (dump_file,
c7a669af 804 " FAIL: Would create irreducible loop without threading "
bb5e62d6 805 "multiway branch.\n");
69e55442 806 return false;
bb5e62d6
JL
807 }
808
c7a669af
AH
809 /* The generic copier used by the backthreader does not re-use an
810 existing threading path to reduce code duplication. So for that
811 case, drastically reduce the number of statements we are allowed
812 to copy. */
bb5e62d6 813 if (!(threaded_through_latch && threaded_multiway_branch)
028d4092
ML
814 && (n_insns * param_fsm_scale_path_stmts
815 >= param_max_jump_thread_duplication_stmts))
bb5e62d6
JL
816 {
817 if (dump_file && (dump_flags & TDF_DETAILS))
818 fprintf (dump_file,
c7a669af 819 " FAIL: Did not thread around loop and would copy too "
bb5e62d6 820 "many statements.\n");
69e55442 821 return false;
bb5e62d6
JL
822 }
823
824 /* When there is a multi-way branch on the path, then threading can
825 explode the CFG due to duplicating the edges for that multi-way
826 branch. So like above, only allow a multi-way branch on the path
827 if we actually thread a multi-way branch. */
828 if (!threaded_multiway_branch && multiway_branch_in_path)
829 {
830 if (dump_file && (dump_flags & TDF_DETAILS))
831 fprintf (dump_file,
c7a669af 832 " FAIL: Thread through multiway branch without threading "
bb5e62d6 833 "a multiway branch.\n");
69e55442 834 return false;
bb5e62d6 835 }
01b50387
AH
836
837 /* Threading through an empty latch would cause code to be added to
838 the latch. This could alter the loop form sufficiently to cause
839 loop optimizations to fail. Disable these threads until after
840 loop optimizations have run. */
841 if ((threaded_through_latch
842 || (taken_edge && taken_edge->dest == loop->latch))
843 && !(cfun->curr_properties & PROP_loop_opts_done)
844 && empty_block_p (loop->latch))
845 {
846 if (dump_file && (dump_flags & TDF_DETAILS))
847 fprintf (dump_file,
c7a669af 848 " FAIL: Thread through latch before loop opts would create non-empty latch\n");
01b50387
AH
849 return false;
850
851 }
69e55442
AH
852 return true;
853}
854
cde30fe0
AH
855/* The current path PATH is a vector of blocks forming a jump threading
856 path in reverse order. TAKEN_EDGE is the edge taken from path[0].
081fdda6 857
cde30fe0 858 Convert the current path into the form used by register_jump_thread and
69e55442 859 register it.
081fdda6 860
69e55442
AH
861 Return TRUE if successful or FALSE otherwise. */
862
863bool
864back_threader_registry::register_path (const vec<basic_block> &m_path,
865 edge taken_edge)
081fdda6 866{
7f6c2258 867 vec<jump_thread_edge *> *jump_thread_path = allocate_thread_path ();
081fdda6 868
c7a669af
AH
869 // The generic copier ignores the edge type. We can build the
870 // thread edges with any type.
cde30fe0 871 for (unsigned int j = 0; j + 1 < m_path.length (); j++)
081fdda6 872 {
cde30fe0
AH
873 basic_block bb1 = m_path[m_path.length () - j - 1];
874 basic_block bb2 = m_path[m_path.length () - j - 2];
8af01c66 875
081fdda6
JL
876 edge e = find_edge (bb1, bb2);
877 gcc_assert (e);
7f6c2258 878 push_edge (jump_thread_path, e, EDGE_COPY_SRC_BLOCK);
081fdda6
JL
879 }
880
7f6c2258
AH
881 push_edge (jump_thread_path, taken_edge, EDGE_NO_COPY_SRC_BLOCK);
882 register_jump_thread (jump_thread_path);
69e55442 883 return true;
081fdda6
JL
884}
885
5d4d64fa
AH
886// Try to thread blocks in FUN. RESOLVE is TRUE when fully resolving
887// unknown SSAs. SPEED is TRUE when optimizing for speed.
888//
889// Return TRUE if any jump thread paths were registered.
8b2ef235 890
2e96b5f1 891static bool
5d4d64fa 892try_thread_blocks (function *fun, bool resolve, bool speed)
8b2ef235 893{
5d4d64fa 894 back_threader threader (speed, resolve);
8b2ef235
JL
895 basic_block bb;
896 FOR_EACH_BB_FN (bb, fun)
897 {
898 if (EDGE_COUNT (bb->succs) > 1)
34cd97ff 899 threader.maybe_thread_block (bb);
8b2ef235 900 }
01005550 901 return threader.thread_through_all_blocks (/*peel_loop_headers=*/true);
2e96b5f1
AH
902}
903
5d4d64fa
AH
904static unsigned int
905do_early_thread_jumps (function *fun, bool resolve)
2e96b5f1 906{
5d4d64fa 907 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
2e96b5f1 908
5d4d64fa 909 try_thread_blocks (fun, resolve, /*speed=*/false);
bb7ebad1
RB
910
911 loop_optimizer_finalize ();
5d4d64fa 912 return 0;
8b2ef235
JL
913}
914
5d4d64fa
AH
915static unsigned int
916do_thread_jumps (function *fun, bool resolve)
8b2ef235 917{
5d4d64fa
AH
918 loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES);
919
920 bool changed = try_thread_blocks (fun, resolve, /*speed=*/true);
921
922 loop_optimizer_finalize ();
923
924 return changed ? TODO_cleanup_cfg : 0;
8b2ef235 925}
b720e919
JH
926
927namespace {
928
929const pass_data pass_data_early_thread_jumps =
930{
931 GIMPLE_PASS,
932 "ethread",
933 OPTGROUP_NONE,
934 TV_TREE_SSA_THREAD_JUMPS,
935 ( PROP_cfg | PROP_ssa ),
936 0,
937 0,
938 0,
939 ( TODO_cleanup_cfg | TODO_update_ssa ),
940};
941
5d4d64fa
AH
942const pass_data pass_data_thread_jumps =
943{
944 GIMPLE_PASS,
945 "thread",
946 OPTGROUP_NONE,
947 TV_TREE_SSA_THREAD_JUMPS,
948 ( PROP_cfg | PROP_ssa ),
949 0,
950 0,
951 0,
952 TODO_update_ssa,
953};
954
955const pass_data pass_data_thread_jumps_full =
956{
957 GIMPLE_PASS,
958 "thread-full",
959 OPTGROUP_NONE,
960 TV_TREE_SSA_THREAD_JUMPS,
961 ( PROP_cfg | PROP_ssa ),
962 0,
963 0,
964 0,
965 TODO_update_ssa,
966};
967
968// Early jump threading pass optimizing for size.
b720e919
JH
969class pass_early_thread_jumps : public gimple_opt_pass
970{
971public:
972 pass_early_thread_jumps (gcc::context *ctxt)
973 : gimple_opt_pass (pass_data_early_thread_jumps, ctxt)
974 {}
975
5d4d64fa
AH
976 opt_pass * clone () override
977 {
978 return new pass_early_thread_jumps (m_ctxt);
979 }
980 bool gate (function *) override
981 {
982 return flag_thread_jumps;
983 }
984 unsigned int execute (function *fun) override
985 {
986 return do_early_thread_jumps (fun, /*resolve=*/false);
987 }
b720e919
JH
988};
989
5d4d64fa
AH
990// Jump threading pass without resolving of unknown SSAs.
991class pass_thread_jumps : public gimple_opt_pass
b720e919 992{
5d4d64fa
AH
993public:
994 pass_thread_jumps (gcc::context *ctxt)
995 : gimple_opt_pass (pass_data_thread_jumps, ctxt)
996 {}
997 opt_pass * clone (void) override
998 {
999 return new pass_thread_jumps (m_ctxt);
1000 }
1001 bool gate (function *) override
1002 {
1003 return flag_thread_jumps && flag_expensive_optimizations;
1004 }
1005 unsigned int execute (function *fun) override
1006 {
1007 return do_thread_jumps (fun, /*resolve=*/false);
1008 }
1009};
b720e919 1010
5d4d64fa
AH
1011// Jump threading pass that fully resolves unknown SSAs.
1012class pass_thread_jumps_full : public gimple_opt_pass
b720e919 1013{
5d4d64fa
AH
1014public:
1015 pass_thread_jumps_full (gcc::context *ctxt)
1016 : gimple_opt_pass (pass_data_thread_jumps_full, ctxt)
1017 {}
1018 opt_pass * clone (void) override
1019 {
dece6ae7 1020 return new pass_thread_jumps_full (m_ctxt);
5d4d64fa
AH
1021 }
1022 bool gate (function *) override
1023 {
1024 return flag_thread_jumps && flag_expensive_optimizations;
1025 }
1026 unsigned int execute (function *fun) override
1027 {
1028 return do_thread_jumps (fun, /*resolve=*/true);
1029 }
1030};
108fdd6d 1031
5d4d64fa 1032} // namespace {
108fdd6d 1033
5d4d64fa
AH
1034gimple_opt_pass *
1035make_pass_thread_jumps (gcc::context *ctxt)
1036{
1037 return new pass_thread_jumps (ctxt);
b720e919
JH
1038}
1039
5d4d64fa
AH
1040gimple_opt_pass *
1041make_pass_thread_jumps_full (gcc::context *ctxt)
1042{
1043 return new pass_thread_jumps_full (ctxt);
b720e919
JH
1044}
1045
1046gimple_opt_pass *
1047make_pass_early_thread_jumps (gcc::context *ctxt)
1048{
1049 return new pass_early_thread_jumps (ctxt);
1050}