c++: ICE on anon struct with base [PR96636]
[official-gcc.git] / gcc / tree-ssa-threadbackward.c
blob2c0e9751101ca745dcbc6dd70710c3fdbfa57dba
1 /* SSA Jump Threading
2 Copyright (C) 2005-2021 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
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"
32 #include "tree-ssa-loop.h"
33 #include "cfganal.h"
34 #include "tree-pass.h"
35 #include "gimple-ssa.h"
36 #include "tree-phinodes.h"
37 #include "tree-inline.h"
38 #include "tree-vectorizer.h"
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"
46 // Path registry for the backwards threader. After all paths have been
47 // registered with register_path(), thread_through_all_blocks() is called
48 // to modify the CFG.
50 class back_threader_registry
52 public:
53 back_threader_registry (int max_allowable_paths);
54 ~back_threader_registry ();
55 bool register_path (const vec<basic_block> &, edge taken);
56 bool thread_through_all_blocks ();
58 private:
59 vec<vec<basic_block>> m_all_paths;
60 jump_thread_path_registry m_lowlevel_registry;
61 const int m_max_allowable_paths;
62 int m_threaded_paths;
65 // Class to abstract the profitability code for the backwards threader.
67 class back_threader_profitability
69 public:
70 back_threader_profitability (bool speed_p)
71 : m_speed_p (speed_p)
72 { }
73 bool profitable_path_p (const vec<basic_block> &, tree name, edge taken,
74 bool *irreducible_loop = NULL);
76 private:
77 const bool m_speed_p;
80 // Ranger based backwards threader.
82 class back_threader
84 // Temporary until we remove old code.
85 friend bool path_is_unreachable_p (const vec<jump_thread_edge *> &);
87 public:
88 back_threader (back_threader_profitability &, back_threader_registry &);
89 ~back_threader ();
90 void find_paths (basic_block bb, tree name);
92 private:
93 void maybe_register_path (edge taken_edge);
94 bool find_paths_to_names (basic_block bb, bitmap imports);
95 bool resolve_def (tree name, bitmap interesting, vec<tree> worklist);
96 bool resolve_phi (gphi *phi, bitmap imports);
97 edge find_taken_edge (const vec<basic_block> &path);
98 edge find_taken_edge_cond (const vec<basic_block> &path, gcond *);
99 edge find_taken_edge_switch (const vec<basic_block> &path, gswitch *);
101 back_threader_registry &m_registry;
102 back_threader_profitability &m_profit;
103 gimple_ranger m_ranger;
104 path_range_query m_solver;
106 // Current path being analyzed.
107 auto_vec<basic_block> m_path;
108 // Hash to mark visited BBs while analyzing a path.
109 hash_set<basic_block> m_visited_bbs;
110 // The set of SSA names, any of which could potentially change the
111 // value of the final conditional in a path.
112 bitmap m_imports;
113 // The last statement in the path.
114 gimple *m_last_stmt;
115 // This is a bit of a wart. It's used to pass the LHS SSA name to
116 // the profitability engine.
117 tree m_name;
118 // Marker to differentiate unreachable edges.
119 static const edge UNREACHABLE_EDGE;
122 // Used to differentiate unreachable edges, so we may stop the search
123 // in a the given direction.
124 const edge back_threader::UNREACHABLE_EDGE = (edge) -1;
126 back_threader::back_threader (back_threader_profitability &profit,
127 back_threader_registry &registry)
128 : m_registry (registry),
129 m_profit (profit),
130 m_solver (m_ranger)
132 m_last_stmt = NULL;
133 m_imports = BITMAP_ALLOC (NULL);
136 back_threader::~back_threader ()
138 m_path.release ();
139 BITMAP_FREE (m_imports);
142 // Register the current path for jump threading if it's profitable to
143 // do so. TAKEN_EDGE is the known edge out of the path.
145 void
146 back_threader::maybe_register_path (edge taken_edge)
148 bool irreducible = false;
149 bool profitable
150 = m_profit.profitable_path_p (m_path, m_name, taken_edge, &irreducible);
152 if (profitable)
154 m_registry.register_path (m_path, taken_edge);
156 if (irreducible)
157 vect_free_loop_info_assumptions (m_path[0]->loop_father);
161 // Return the known taken edge out of a path. If the path can be
162 // determined to be unreachable, return UNREACHABLE_EDGE. If no
163 // outgoing edge can be calculated, return NULL.
165 edge
166 back_threader::find_taken_edge (const vec<basic_block> &path)
168 gcc_checking_assert (path.length () > 1);
169 switch (gimple_code (m_last_stmt))
171 case GIMPLE_COND:
172 return find_taken_edge_cond (path, as_a<gcond *> (m_last_stmt));
174 case GIMPLE_SWITCH:
175 return find_taken_edge_switch (path, as_a<gswitch *> (m_last_stmt));
177 default:
178 return NULL;
182 // Same as find_taken_edge, but for paths ending in a switch.
184 edge
185 back_threader::find_taken_edge_switch (const vec<basic_block> &path,
186 gswitch *sw)
188 tree name = gimple_switch_index (sw);
189 int_range_max r;
191 m_solver.precompute_ranges (path, m_imports);
192 m_solver.range_of_expr (r, name, sw);
194 if (r.undefined_p ())
195 return UNREACHABLE_EDGE;
197 if (r.varying_p ())
198 return NULL;
200 tree val;
201 if (r.singleton_p (&val))
202 return ::find_taken_edge (gimple_bb (sw), val);
204 return NULL;
207 // Same as find_taken_edge, but for paths ending in a GIMPLE_COND.
209 edge
210 back_threader::find_taken_edge_cond (const vec<basic_block> &path,
211 gcond *cond)
213 m_solver.precompute_ranges (path, m_imports);
215 // Check if either operand is unreachable since this knowledge could
216 // help the caller cut down the search space.
217 int_range_max r;
218 m_solver.range_of_expr (r, gimple_cond_lhs (cond));
219 if (r.undefined_p ())
220 return UNREACHABLE_EDGE;
221 m_solver.range_of_expr (r, gimple_cond_rhs (cond));
222 if (r.undefined_p ())
223 return UNREACHABLE_EDGE;
225 m_solver.range_of_stmt (r, cond);
227 int_range<2> true_range (boolean_true_node, boolean_true_node);
228 int_range<2> false_range (boolean_false_node, boolean_false_node);
230 if (r == true_range || r == false_range)
232 edge e_true, e_false;
233 basic_block bb = gimple_bb (cond);
234 extract_true_false_edges_from_block (bb, &e_true, &e_false);
235 return r == true_range ? e_true : e_false;
237 return NULL;
240 // Populate a vector of trees from a bitmap.
242 static inline void
243 populate_worklist (vec<tree> worklist, bitmap bits)
245 bitmap_iterator bi;
246 unsigned i;
248 EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
250 tree name = ssa_name (i);
251 worklist.quick_push (name);
255 // If taking any of the incoming edges to a PHI causes the final
256 // conditional of the current path to be constant, register the
257 // path(s), and return TRUE.
259 bool
260 back_threader::resolve_phi (gphi *phi, bitmap interesting)
262 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (phi)))
263 return true;
265 bool done = false;
266 for (size_t i = 0; i < gimple_phi_num_args (phi); ++i)
268 edge e = gimple_phi_arg_edge (phi, i);
270 // This is like path_crosses_loops in profitable_path_p but more
271 // restrictive, since profitable_path_p allows threading the
272 // first block because it would be redirected anyhow.
274 // If we loosened the restriction and used profitable_path_p()
275 // here instead, we would peel off the first iterations of loops
276 // in places like tree-ssa/pr14341.c.
277 bool profitable_p = m_path[0]->loop_father == e->src->loop_father;
278 if (!profitable_p)
280 if (dump_file && (dump_flags & TDF_DETAILS))
281 fprintf (dump_file,
282 " FAIL: path through PHI in bb%d (incoming bb:%d) crosses loop\n",
283 e->dest->index, e->src->index);
284 continue;
287 tree arg = gimple_phi_arg_def (phi, i);
288 if (TREE_CODE (arg) == SSA_NAME)
290 unsigned v = SSA_NAME_VERSION (arg);
292 // Avoid loops as in: x_5 = PHI <x_5(2), ...>.
293 if (bitmap_bit_p (interesting, v))
294 continue;
296 bitmap_set_bit (interesting, v);
297 bitmap_set_bit (m_imports, v);
298 done |= find_paths_to_names (e->src, interesting);
299 bitmap_clear_bit (interesting, v);
301 else if (TREE_CODE (arg) == INTEGER_CST)
303 m_path.safe_push (e->src);
304 edge taken_edge = find_taken_edge (m_path);
305 if (taken_edge && taken_edge != UNREACHABLE_EDGE)
307 maybe_register_path (taken_edge);
308 done = true;
310 m_path.pop ();
313 return done;
316 // If the definition of NAME causes the final conditional of the
317 // current path to be constant, register the path, and return TRUE.
319 bool
320 back_threader::resolve_def (tree name, bitmap interesting, vec<tree> worklist)
322 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
324 // Handle PHIs.
325 if (is_a<gphi *> (def_stmt)
326 && resolve_phi (as_a<gphi *> (def_stmt), interesting))
327 return true;
329 // Defer copies of SSAs by adding the source to the worklist.
330 if (gimple_assign_single_p (def_stmt)
331 && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
333 tree rhs = gimple_assign_rhs1 (def_stmt);
334 bitmap_set_bit (m_imports, SSA_NAME_VERSION (rhs));
335 bitmap_set_bit (interesting, SSA_NAME_VERSION (rhs));
336 worklist.safe_push (rhs);
338 return false;
341 // Find jump threading paths to any of the SSA names in the
342 // INTERESTING bitmap, and register any such paths.
344 // Return TRUE if no further processing past this block is necessary.
345 // This is because we've either registered a path, or because there is
346 // nothing of interesting beyond this block.
348 // BB is the current path being processed.
350 bool
351 back_threader::find_paths_to_names (basic_block bb, bitmap interesting)
353 if (m_visited_bbs.add (bb))
354 return true;
356 m_path.safe_push (bb);
358 if (m_path.length () > 1
359 && !m_profit.profitable_path_p (m_path, m_name, NULL))
361 m_path.pop ();
362 m_visited_bbs.remove (bb);
363 return false;
366 auto_bitmap processed;
367 unsigned i;
368 bool done = false;
370 // We use a worklist instead of iterating through the bitmap,
371 // because we may add new items in-flight.
372 auto_vec<tree> worklist (bitmap_count_bits (interesting));
373 populate_worklist (worklist, interesting);
374 while (!worklist.is_empty ())
376 tree name = worklist.pop ();
377 unsigned i = SSA_NAME_VERSION (name);
378 basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (name));
380 // Process any names defined in this block.
381 if (def_bb == bb)
383 bitmap_set_bit (processed, i);
385 if (resolve_def (name, interesting, worklist))
387 done = true;
388 goto leave_bb;
391 // Examine blocks that define or export an interesting SSA,
392 // since they may compute a range which resolve this path.
393 if ((def_bb == bb
394 || bitmap_bit_p (m_ranger.gori ().exports (bb), i))
395 && m_path.length () > 1)
397 edge taken_edge = find_taken_edge (m_path);
398 if (taken_edge)
400 if (taken_edge != UNREACHABLE_EDGE)
401 maybe_register_path (taken_edge);
403 done = true;
404 goto leave_bb;
409 // If there are interesting names not yet processed, keep looking.
410 bitmap_and_compl_into (interesting, processed);
411 if (!bitmap_empty_p (interesting))
413 edge_iterator iter;
414 edge e;
415 FOR_EACH_EDGE (e, iter, bb->preds)
416 if ((e->flags & EDGE_ABNORMAL) == 0)
417 done |= find_paths_to_names (e->src, interesting);
420 leave_bb:
421 bitmap_iterator bi;
422 EXECUTE_IF_SET_IN_BITMAP (processed, 0, i, bi)
423 bitmap_set_bit (interesting, i);
425 m_path.pop ();
426 m_visited_bbs.remove (bb);
427 return done;
430 // Search backwards from BB looking for paths where the final
431 // conditional out of BB can be determined. NAME is the LHS of the
432 // final conditional. Register such paths for jump threading.
434 void
435 back_threader::find_paths (basic_block bb, tree name)
437 gimple *stmt = last_stmt (bb);
438 if (!stmt
439 || (gimple_code (stmt) != GIMPLE_COND
440 && gimple_code (stmt) != GIMPLE_SWITCH))
441 return;
443 if (EDGE_COUNT (bb->succs) > 1
444 || single_succ_to_potentially_threadable_block (bb))
446 m_last_stmt = stmt;
447 m_visited_bbs.empty ();
448 m_path.truncate (0);
449 m_name = name;
450 bitmap_clear (m_imports);
452 auto_bitmap interesting;
453 bitmap_copy (m_imports, m_ranger.gori ().imports (bb));
454 bitmap_copy (interesting, m_imports);
455 find_paths_to_names (bb, interesting);
459 // Dump a sequence of BBs through the CFG.
461 DEBUG_FUNCTION void
462 dump_path (FILE *dump_file, const vec<basic_block> &path)
464 for (size_t i = 0; i < path.length (); ++i)
466 fprintf (dump_file, "BB%d", path[i]->index);
467 if (i + 1 < path.length ())
468 fprintf (dump_file, " <- ");
470 fprintf (dump_file, "\n");
473 DEBUG_FUNCTION void
474 debug (const vec <basic_block> &path)
476 dump_path (stderr, path);
479 class thread_jumps
481 public:
482 thread_jumps (bool speed_p = true)
483 : m_profit (speed_p),
484 m_registry (param_max_fsm_thread_paths),
485 m_back_threader (m_profit, m_registry)
487 void find_jump_threads_backwards (basic_block bb);
488 void find_jump_threads_backwards_with_ranger (basic_block bb);
489 bool thread_through_all_blocks ();
491 private:
492 void maybe_register_path (const vec<basic_block> &m_path,
493 tree name,
494 edge taken_edge);
495 edge find_taken_edge (const vec<basic_block> &path, tree arg);
496 void handle_assignment (gimple *stmt, basic_block def_bb);
497 void handle_phi (gphi *phi, basic_block def_bb);
498 void fsm_find_control_statement_thread_paths (tree name);
499 bool check_subpath_and_update_thread_path (basic_block last_bb,
500 basic_block new_bb,
501 int *next_path_length);
503 /* Hash to keep track of seen bbs. */
504 hash_set<basic_block> m_visited_bbs;
505 /* Current path we're analyzing. */
506 auto_vec<basic_block> m_path;
507 /* Tracks if we have recursed through a loop PHI node. */
508 bool m_seen_loop_phi;
510 tree m_name;
511 back_threader_profitability m_profit;
512 back_threader_registry m_registry;
513 back_threader m_back_threader;
516 // Perform the actual jump threading for the all queued paths.
518 bool
519 thread_jumps::thread_through_all_blocks ()
521 return m_registry.thread_through_all_blocks ();
524 /* Simple helper to get the last statement from BB, which is assumed
525 to be a control statement. Return NULL if the last statement is
526 not a control statement. */
528 static gimple *
529 get_gimple_control_stmt (basic_block bb)
531 gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
533 if (gsi_end_p (gsi))
534 return NULL;
536 gimple *stmt = gsi_stmt (gsi);
537 enum gimple_code code = gimple_code (stmt);
538 if (code == GIMPLE_COND || code == GIMPLE_SWITCH || code == GIMPLE_GOTO)
539 return stmt;
540 return NULL;
543 /* Return true if the CFG contains at least one path from START_BB to
544 END_BB. When a path is found, record in PATH the blocks from
545 END_BB to START_BB. LOCAL_VISITED_BBS is used to make sure we
546 don't fall into an infinite loop. Bound the recursion to basic
547 blocks belonging to LOOP. */
549 static bool
550 fsm_find_thread_path (basic_block start_bb, basic_block end_bb,
551 vec<basic_block> &path,
552 hash_set<basic_block> &local_visited_bbs,
553 loop_p loop)
555 if (loop != start_bb->loop_father)
556 return false;
558 if (start_bb == end_bb)
560 path.safe_push (start_bb);
561 return true;
564 if (!local_visited_bbs.add (start_bb))
566 edge e;
567 edge_iterator ei;
568 FOR_EACH_EDGE (e, ei, start_bb->succs)
569 if (fsm_find_thread_path (e->dest, end_bb, path, local_visited_bbs,
570 loop))
572 path.safe_push (start_bb);
573 return true;
577 return false;
580 back_threader_registry::back_threader_registry (int max_allowable_paths)
581 : m_max_allowable_paths (max_allowable_paths)
583 m_all_paths.create (5);
584 m_threaded_paths = 0;
587 back_threader_registry::~back_threader_registry ()
589 m_all_paths.release ();
592 bool
593 back_threader_registry::thread_through_all_blocks ()
595 return m_lowlevel_registry.thread_through_all_blocks (true);
598 /* Examine jump threading path PATH and return TRUE if it is profitable to
599 thread it, otherwise return FALSE.
601 NAME is the SSA_NAME of the variable we found to have a constant
602 value on PATH. If unknown, SSA_NAME is NULL.
604 If the taken edge out of the path is known ahead of time it is passed in
605 TAKEN_EDGE, otherwise it is NULL.
607 CREATES_IRREDUCIBLE_LOOP, if non-null is set to TRUE if threading this path
608 would create an irreducible loop. */
610 bool
611 back_threader_profitability::profitable_path_p (const vec<basic_block> &m_path,
612 tree name,
613 edge taken_edge,
614 bool *creates_irreducible_loop)
616 gcc_checking_assert (!m_path.is_empty ());
618 /* We can an empty path here (excluding the DEF block) when the
619 statement that makes a conditional generate a compile-time
620 constant result is in the same block as the conditional.
622 That's not really a jump threading opportunity, but instead is
623 simple cprop & simplification. We could handle it here if we
624 wanted by wiring up all the incoming edges. If we run this
625 early in IPA, that might be worth doing. For now we just
626 reject that case. */
627 if (m_path.length () <= 1)
628 return false;
630 if (m_path.length () > (unsigned) param_max_fsm_thread_length)
632 if (dump_file && (dump_flags & TDF_DETAILS))
633 fprintf (dump_file, " FAIL: FSM jump-thread path not considered: "
634 "the number of basic blocks on the path "
635 "exceeds PARAM_MAX_FSM_THREAD_LENGTH.\n");
636 return false;
639 int n_insns = 0;
640 gimple_stmt_iterator gsi;
641 loop_p loop = m_path[0]->loop_father;
642 bool path_crosses_loops = false;
643 bool threaded_through_latch = false;
644 bool multiway_branch_in_path = false;
645 bool threaded_multiway_branch = false;
646 bool contains_hot_bb = false;
648 if (dump_file && (dump_flags & TDF_DETAILS))
649 fprintf (dump_file, "Checking profitability of path (backwards): ");
651 /* Count the number of instructions on the path: as these instructions
652 will have to be duplicated, we will not record the path if there
653 are too many instructions on the path. Also check that all the
654 blocks in the path belong to a single loop. */
655 for (unsigned j = 0; j < m_path.length (); j++)
657 basic_block bb = m_path[j];
659 if (dump_file && (dump_flags & TDF_DETAILS))
660 fprintf (dump_file, " bb:%i", bb->index);
661 /* Remember, blocks in the path are stored in opposite order
662 in the PATH array. The last entry in the array represents
663 the block with an outgoing edge that we will redirect to the
664 jump threading path. Thus we don't care about that block's
665 loop father, nor how many statements are in that block because
666 it will not be copied or whether or not it ends in a multiway
667 branch. */
668 if (j < m_path.length () - 1)
670 int orig_n_insns = n_insns;
671 if (bb->loop_father != loop)
673 path_crosses_loops = true;
674 break;
677 /* PHIs in the path will create degenerate PHIS in the
678 copied path which will then get propagated away, so
679 looking at just the duplicate path the PHIs would
680 seem unimportant.
682 But those PHIs, because they're assignments to objects
683 typically with lives that exist outside the thread path,
684 will tend to generate PHIs (or at least new PHI arguments)
685 at points where we leave the thread path and rejoin
686 the original blocks. So we do want to account for them.
688 We ignore virtual PHIs. We also ignore cases where BB
689 has a single incoming edge. That's the most common
690 degenerate PHI we'll see here. Finally we ignore PHIs
691 that are associated with the value we're tracking as
692 that object likely dies. */
693 if (EDGE_COUNT (bb->succs) > 1 && EDGE_COUNT (bb->preds) > 1)
695 for (gphi_iterator gsip = gsi_start_phis (bb);
696 !gsi_end_p (gsip);
697 gsi_next (&gsip))
699 gphi *phi = gsip.phi ();
700 tree dst = gimple_phi_result (phi);
702 /* Note that if both NAME and DST are anonymous
703 SSA_NAMEs, then we do not have enough information
704 to consider them associated. */
705 if (dst != name
706 && name
707 && TREE_CODE (name) == SSA_NAME
708 && (SSA_NAME_VAR (dst) != SSA_NAME_VAR (name)
709 || !SSA_NAME_VAR (dst))
710 && !virtual_operand_p (dst))
711 ++n_insns;
715 if (!contains_hot_bb && m_speed_p)
716 contains_hot_bb |= optimize_bb_for_speed_p (bb);
717 for (gsi = gsi_after_labels (bb);
718 !gsi_end_p (gsi);
719 gsi_next_nondebug (&gsi))
721 /* Do not allow OpenACC loop markers and __builtin_constant_p on
722 threading paths. The latter is disallowed, because an
723 expression might be constant on two threading paths, and
724 become non-constant (i.e.: phi) when they merge. */
725 gimple *stmt = gsi_stmt (gsi);
726 if (gimple_call_internal_p (stmt, IFN_UNIQUE)
727 || gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
728 return false;
729 /* Do not count empty statements and labels. */
730 if (gimple_code (stmt) != GIMPLE_NOP
731 && !(gimple_code (stmt) == GIMPLE_ASSIGN
732 && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
733 && !is_gimple_debug (stmt))
734 n_insns += estimate_num_insns (stmt, &eni_size_weights);
736 if (dump_file && (dump_flags & TDF_DETAILS))
737 fprintf (dump_file, " (%i insns)", n_insns-orig_n_insns);
739 /* We do not look at the block with the threaded branch
740 in this loop. So if any block with a last statement that
741 is a GIMPLE_SWITCH or GIMPLE_GOTO is seen, then we have a
742 multiway branch on our path.
744 The block in PATH[0] is special, it's the block were we're
745 going to be able to eliminate its branch. */
746 gimple *last = last_stmt (bb);
747 if (last && (gimple_code (last) == GIMPLE_SWITCH
748 || gimple_code (last) == GIMPLE_GOTO))
750 if (j == 0)
751 threaded_multiway_branch = true;
752 else
753 multiway_branch_in_path = true;
757 /* Note if we thread through the latch, we will want to include
758 the last entry in the array when determining if we thread
759 through the loop latch. */
760 if (loop->latch == bb)
761 threaded_through_latch = true;
764 gimple *stmt = get_gimple_control_stmt (m_path[0]);
765 gcc_assert (stmt);
767 /* We are going to remove the control statement at the end of the
768 last block in the threading path. So don't count it against our
769 statement count. */
771 int stmt_insns = estimate_num_insns (stmt, &eni_size_weights);
772 n_insns-= stmt_insns;
774 if (dump_file && (dump_flags & TDF_DETAILS))
775 fprintf (dump_file, "\n Control statement insns: %i\n"
776 " Overall: %i insns\n",
777 stmt_insns, n_insns);
779 if (creates_irreducible_loop)
781 /* If this path threaded through the loop latch back into the
782 same loop and the destination does not dominate the loop
783 latch, then this thread would create an irreducible loop. */
784 *creates_irreducible_loop = false;
785 if (taken_edge
786 && threaded_through_latch
787 && loop == taken_edge->dest->loop_father
788 && (determine_bb_domination_status (loop, taken_edge->dest)
789 == DOMST_NONDOMINATING))
790 *creates_irreducible_loop = true;
793 if (path_crosses_loops)
795 if (dump_file && (dump_flags & TDF_DETAILS))
796 fprintf (dump_file, " FAIL: FSM jump-thread path not considered: "
797 "the path crosses loops.\n");
798 return false;
801 /* Threading is profitable if the path duplicated is hot but also
802 in a case we separate cold path from hot path and permit optimization
803 of the hot path later. Be on the agressive side here. In some testcases,
804 as in PR 78407 this leads to noticeable improvements. */
805 if (m_speed_p
806 && ((taken_edge && optimize_edge_for_speed_p (taken_edge))
807 || contains_hot_bb))
809 if (n_insns >= param_max_fsm_thread_path_insns)
811 if (dump_file && (dump_flags & TDF_DETAILS))
812 fprintf (dump_file, " FAIL: FSM jump-thread path not considered: "
813 "the number of instructions on the path "
814 "exceeds PARAM_MAX_FSM_THREAD_PATH_INSNS.\n");
815 return false;
818 else if (!m_speed_p && n_insns > 1)
820 if (dump_file && (dump_flags & TDF_DETAILS))
821 fprintf (dump_file, " FAIL: FSM jump-thread path not considered: "
822 "duplication of %i insns is needed and optimizing for size.\n",
823 n_insns);
824 return false;
827 /* We avoid creating irreducible inner loops unless we thread through
828 a multiway branch, in which case we have deemed it worth losing
829 other loop optimizations later.
831 We also consider it worth creating an irreducible inner loop if
832 the number of copied statement is low relative to the length of
833 the path -- in that case there's little the traditional loop
834 optimizer would have done anyway, so an irreducible loop is not
835 so bad. */
836 if (!threaded_multiway_branch
837 && creates_irreducible_loop
838 && *creates_irreducible_loop
839 && (n_insns * (unsigned) param_fsm_scale_path_stmts
840 > (m_path.length () *
841 (unsigned) param_fsm_scale_path_blocks)))
844 if (dump_file && (dump_flags & TDF_DETAILS))
845 fprintf (dump_file,
846 " FAIL: FSM would create irreducible loop without threading "
847 "multiway branch.\n");
848 return false;
851 /* If this path does not thread through the loop latch, then we are
852 using the FSM threader to find old style jump threads. This
853 is good, except the FSM threader does not re-use an existing
854 threading path to reduce code duplication.
856 So for that case, drastically reduce the number of statements
857 we are allowed to copy. */
858 if (!(threaded_through_latch && threaded_multiway_branch)
859 && (n_insns * param_fsm_scale_path_stmts
860 >= param_max_jump_thread_duplication_stmts))
862 if (dump_file && (dump_flags & TDF_DETAILS))
863 fprintf (dump_file,
864 " FAIL: FSM did not thread around loop and would copy too "
865 "many statements.\n");
866 return false;
869 /* When there is a multi-way branch on the path, then threading can
870 explode the CFG due to duplicating the edges for that multi-way
871 branch. So like above, only allow a multi-way branch on the path
872 if we actually thread a multi-way branch. */
873 if (!threaded_multiway_branch && multiway_branch_in_path)
875 if (dump_file && (dump_flags & TDF_DETAILS))
876 fprintf (dump_file,
877 " FAIL: FSM Thread through multiway branch without threading "
878 "a multiway branch.\n");
879 return false;
881 return true;
884 /* Return the taken edge out of a path, assuming that the underlying assignment
885 or PHI SSA resolves to ARG. */
887 edge
888 thread_jumps::find_taken_edge (const vec<basic_block> &path, tree arg)
890 if (TREE_CODE_CLASS (TREE_CODE (arg)) != tcc_constant)
891 return NULL;
893 gcc_checking_assert (!path.is_empty ());
894 gimple *stmt = get_gimple_control_stmt (m_path[0]);
896 /* We have found a constant value for ARG. For GIMPLE_SWITCH
897 and GIMPLE_GOTO, we use it as-is. However, for a GIMPLE_COND
898 we need to substitute, fold and simplify so we can determine
899 the edge taken out of the last block. */
900 if (gimple_code (stmt) == GIMPLE_COND)
902 enum tree_code cond_code = gimple_cond_code (stmt);
904 /* We know the underyling format of the condition. */
905 arg = fold_binary (cond_code, boolean_type_node,
906 arg, gimple_cond_rhs (stmt));
909 /* If this path threaded through the loop latch back into the
910 same loop and the destination does not dominate the loop
911 latch, then this thread would create an irreducible loop.
913 We have to know the outgoing edge to figure this out. */
914 return ::find_taken_edge (m_path[0], arg);
917 /* The current path PATH is a vector of blocks forming a jump threading
918 path in reverse order. TAKEN_EDGE is the edge taken from path[0].
920 Convert the current path into the form used by register_jump_thread and
921 register it.
923 Return TRUE if successful or FALSE otherwise. */
925 bool
926 back_threader_registry::register_path (const vec<basic_block> &m_path,
927 edge taken_edge)
929 if (m_threaded_paths > m_max_allowable_paths)
931 if (dump_file && (dump_flags & TDF_DETAILS))
932 fprintf (dump_file, " FAIL: FSM jump-thread path not considered: "
933 "the number of previously recorded FSM paths to "
934 "thread exceeds PARAM_MAX_FSM_THREAD_PATHS.\n");
935 return false;
938 vec<jump_thread_edge *> *jump_thread_path
939 = m_lowlevel_registry.allocate_thread_path ();
941 /* Record the edges between the blocks in PATH. */
942 for (unsigned int j = 0; j + 1 < m_path.length (); j++)
944 basic_block bb1 = m_path[m_path.length () - j - 1];
945 basic_block bb2 = m_path[m_path.length () - j - 2];
947 edge e = find_edge (bb1, bb2);
948 gcc_assert (e);
949 jump_thread_edge *x
950 = m_lowlevel_registry.allocate_thread_edge (e, EDGE_FSM_THREAD);
951 jump_thread_path->safe_push (x);
954 /* Add the edge taken when the control variable has value ARG. */
955 jump_thread_edge *x
956 = m_lowlevel_registry.allocate_thread_edge (taken_edge,
957 EDGE_NO_COPY_SRC_BLOCK);
958 jump_thread_path->safe_push (x);
960 if (m_lowlevel_registry.register_jump_thread (jump_thread_path))
961 ++m_threaded_paths;
962 return true;
965 /* While following a chain of SSA_NAME definitions, we jumped from a
966 definition in LAST_BB to a definition in NEW_BB (walking
967 backwards).
969 Verify there is a single path between the blocks and none of the
970 blocks in the path is already in VISITED_BBS. If so, then update
971 VISISTED_BBS, add the new blocks to PATH and return TRUE.
972 Otherwise return FALSE.
974 Store the length of the subpath in NEXT_PATH_LENGTH. */
976 bool
977 thread_jumps::check_subpath_and_update_thread_path (basic_block last_bb,
978 basic_block new_bb,
979 int *next_path_length)
981 edge e;
982 int e_count = 0;
983 edge_iterator ei;
984 auto_vec<basic_block> next_path;
986 FOR_EACH_EDGE (e, ei, last_bb->preds)
988 hash_set<basic_block> local_visited_bbs;
990 if (fsm_find_thread_path (new_bb, e->src, next_path,
991 local_visited_bbs, e->src->loop_father))
992 ++e_count;
994 /* If there is more than one path, stop. */
995 if (e_count > 1)
996 return false;
999 /* Stop if we have not found a path: this could occur when the recursion
1000 is stopped by one of the bounds. */
1001 if (e_count == 0)
1002 return false;
1004 /* Make sure we haven't already visited any of the nodes in
1005 NEXT_PATH. Don't add them here to avoid pollution. */
1006 for (unsigned int i = 0; i + 1 < next_path.length (); i++)
1008 if (m_visited_bbs.contains (next_path[i]))
1009 return false;
1012 /* Now add the nodes to VISISTED_BBS. */
1013 for (unsigned int i = 0; i + 1 < next_path.length (); i++)
1014 m_visited_bbs.add (next_path[i]);
1016 /* Append all the nodes from NEXT_PATH to PATH. */
1017 m_path.safe_splice (next_path);
1018 *next_path_length = next_path.length ();
1020 return true;
1023 /* If this is a profitable jump thread path, register it.
1025 NAME is an SSA NAME with a possible constant value of ARG on PATH.
1027 DEF_BB is the basic block that ultimately defines the constant. */
1029 void
1030 thread_jumps::maybe_register_path (const vec<basic_block> &m_path,
1031 tree name,
1032 edge taken_edge)
1034 bool irreducible = false;
1035 bool profitable = m_profit.profitable_path_p (m_path, name, taken_edge,
1036 &irreducible);
1037 if (profitable)
1039 if (!m_registry.register_path (m_path, taken_edge))
1040 return;
1042 if (irreducible)
1043 vect_free_loop_info_assumptions (m_path[0]->loop_father);
1047 /* Given PHI which defines NAME in block DEF_BB, recurse through the
1048 PHI's arguments searching for paths where NAME will ultimately have
1049 a constant value.
1051 PATH contains the series of blocks to traverse that will result in
1052 NAME having a constant value. */
1054 void
1055 thread_jumps::handle_phi (gphi *phi, basic_block def_bb)
1057 /* Iterate over the arguments of PHI. */
1058 for (unsigned int i = 0; i < gimple_phi_num_args (phi); i++)
1060 tree arg = gimple_phi_arg_def (phi, i);
1061 basic_block bbi = gimple_phi_arg_edge (phi, i)->src;
1063 /* Skip edges pointing outside the current loop. */
1064 if (!arg || def_bb->loop_father != bbi->loop_father)
1065 continue;
1067 if (TREE_CODE (arg) == SSA_NAME)
1069 m_path.safe_push (bbi);
1070 /* Recursively follow SSA_NAMEs looking for a constant
1071 definition. */
1072 fsm_find_control_statement_thread_paths (arg);
1074 m_path.pop ();
1075 continue;
1078 m_path.safe_push (bbi);
1079 edge taken_edge = find_taken_edge (m_path, arg);
1080 if (taken_edge)
1081 maybe_register_path (m_path, m_name, taken_edge);
1082 m_path.pop ();
1086 /* Return TRUE if STMT is a gimple assignment we want to either directly
1087 handle or recurse through. Return FALSE otherwise.
1089 Note that adding more cases here requires adding cases to handle_assignment
1090 below. */
1092 static bool
1093 handle_assignment_p (gimple *stmt)
1095 if (is_gimple_assign (stmt))
1097 enum tree_code def_code = gimple_assign_rhs_code (stmt);
1099 /* If the RHS is an SSA_NAME, then we will recurse through it.
1100 Go ahead and filter out cases where the SSA_NAME is a default
1101 definition. There's little to be gained by trying to handle that. */
1102 if (def_code == SSA_NAME
1103 && !SSA_NAME_IS_DEFAULT_DEF (gimple_assign_rhs1 (stmt)))
1104 return true;
1106 /* If the RHS is a constant, then it's a terminal that we'll want
1107 to handle as well. */
1108 if (TREE_CODE_CLASS (def_code) == tcc_constant)
1109 return true;
1112 /* Anything not explicitly allowed is not handled. */
1113 return false;
1116 /* Given STMT which defines NAME in block DEF_BB, recurse through the
1117 PHI's arguments searching for paths where NAME will ultimately have
1118 a constant value.
1120 PATH contains the series of blocks to traverse that will result in
1121 NAME having a constant value. */
1123 void
1124 thread_jumps::handle_assignment (gimple *stmt, basic_block def_bb)
1126 tree arg = gimple_assign_rhs1 (stmt);
1128 if (TREE_CODE (arg) == SSA_NAME)
1129 fsm_find_control_statement_thread_paths (arg);
1130 else
1132 if (CHECKING_P)
1134 gcc_assert (!m_path.is_empty ());
1135 basic_block top = m_path[m_path.length () - 1];
1136 gcc_assert (top == def_bb);
1138 edge taken_edge = find_taken_edge (m_path, arg);
1139 if (taken_edge)
1140 maybe_register_path (m_path, m_name, taken_edge);
1144 /* We trace the value of the SSA_NAME NAME back through any phi nodes
1145 looking for places where it gets a constant value and save the
1146 path. */
1148 void
1149 thread_jumps::fsm_find_control_statement_thread_paths (tree name)
1151 /* If NAME appears in an abnormal PHI, then don't try to trace its
1152 value back through PHI nodes. */
1153 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
1154 return;
1156 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
1157 basic_block def_bb = gimple_bb (def_stmt);
1159 if (def_bb == NULL)
1160 return;
1162 /* We allow the SSA chain to contains PHIs and simple copies and constant
1163 initializations. */
1164 if (gimple_code (def_stmt) != GIMPLE_PHI
1165 && gimple_code (def_stmt) != GIMPLE_ASSIGN)
1166 return;
1168 if (gimple_code (def_stmt) == GIMPLE_PHI
1169 && (gimple_phi_num_args (def_stmt)
1170 >= (unsigned) param_fsm_maximum_phi_arguments))
1171 return;
1173 if (is_gimple_assign (def_stmt)
1174 && ! handle_assignment_p (def_stmt))
1175 return;
1177 /* Avoid infinite recursion. */
1178 if (m_visited_bbs.add (def_bb))
1179 return;
1181 int next_path_length = 0;
1182 basic_block last_bb_in_path = m_path.last ();
1184 if (loop_containing_stmt (def_stmt)->header == gimple_bb (def_stmt))
1186 /* Do not walk through more than one loop PHI node. */
1187 if (m_seen_loop_phi)
1188 return;
1189 m_seen_loop_phi = true;
1192 /* Following the chain of SSA_NAME definitions, we jumped from a definition in
1193 LAST_BB_IN_PATH to a definition in DEF_BB. When these basic blocks are
1194 different, append to PATH the blocks from LAST_BB_IN_PATH to DEF_BB. */
1195 if (def_bb != last_bb_in_path)
1197 /* When DEF_BB == LAST_BB_IN_PATH, then the first block in the path
1198 will already be in VISITED_BBS. When they are not equal, then we
1199 must ensure that first block is accounted for to ensure we do not
1200 create bogus jump threading paths. */
1201 m_visited_bbs.add (m_path[0]);
1202 if (!check_subpath_and_update_thread_path (last_bb_in_path, def_bb,
1203 &next_path_length))
1204 return;
1207 gcc_assert (m_path.last () == def_bb);
1209 if (gimple_code (def_stmt) == GIMPLE_PHI)
1210 handle_phi (as_a <gphi *> (def_stmt), def_bb);
1211 else if (gimple_code (def_stmt) == GIMPLE_ASSIGN)
1212 handle_assignment (def_stmt, def_bb);
1214 /* Remove all the nodes that we added from NEXT_PATH. */
1215 if (next_path_length)
1216 m_path.truncate (m_path.length () - next_path_length);
1219 /* Search backwards from BB looking for paths where NAME (an SSA_NAME)
1220 is a constant. Record such paths for jump threading.
1222 It is assumed that BB ends with a control statement and that by
1223 finding a path where NAME is a constant, we can thread the path.
1224 SPEED_P indicates that we could increase code size to improve the
1225 code path. */
1227 void
1228 thread_jumps::find_jump_threads_backwards (basic_block bb)
1230 if (param_threader_mode & THREADER_MODE_RANGER)
1232 find_jump_threads_backwards_with_ranger (bb);
1233 return;
1236 gimple *stmt = get_gimple_control_stmt (bb);
1237 if (!stmt)
1238 return;
1240 enum gimple_code code = gimple_code (stmt);
1241 tree name = NULL;
1242 if (code == GIMPLE_SWITCH)
1243 name = gimple_switch_index (as_a <gswitch *> (stmt));
1244 else if (code == GIMPLE_GOTO)
1245 name = gimple_goto_dest (stmt);
1246 else if (code == GIMPLE_COND)
1248 if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
1249 && TREE_CODE_CLASS (TREE_CODE (gimple_cond_rhs (stmt))) == tcc_constant
1250 && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
1251 || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
1252 name = gimple_cond_lhs (stmt);
1255 if (!name || TREE_CODE (name) != SSA_NAME)
1256 return;
1258 /* Initialize pass local data that's different for each BB. */
1259 m_path.truncate (0);
1260 m_path.safe_push (bb);
1261 m_visited_bbs.empty ();
1262 m_seen_loop_phi = false;
1263 m_name = name;
1265 fsm_find_control_statement_thread_paths (name);
1268 // Like find_jump_threads_backwards(), but using ranger.
1270 void
1271 thread_jumps::find_jump_threads_backwards_with_ranger (basic_block bb)
1273 gimple *stmt = get_gimple_control_stmt (bb);
1274 if (!stmt)
1275 return;
1277 enum gimple_code code = gimple_code (stmt);
1278 tree name = NULL;
1279 if (code == GIMPLE_SWITCH)
1280 name = gimple_switch_index (as_a <gswitch *> (stmt));
1281 else if (code == GIMPLE_GOTO)
1282 name = gimple_goto_dest (stmt);
1283 else if (code == GIMPLE_COND)
1284 name = gimple_cond_lhs (stmt);
1286 m_name = name;
1287 m_back_threader.find_paths (bb, name);
1290 namespace {
1292 const pass_data pass_data_thread_jumps =
1294 GIMPLE_PASS,
1295 "thread",
1296 OPTGROUP_NONE,
1297 TV_TREE_SSA_THREAD_JUMPS,
1298 ( PROP_cfg | PROP_ssa ),
1302 TODO_update_ssa,
1305 class pass_thread_jumps : public gimple_opt_pass
1307 public:
1308 pass_thread_jumps (gcc::context *ctxt)
1309 : gimple_opt_pass (pass_data_thread_jumps, ctxt)
1312 opt_pass * clone (void) { return new pass_thread_jumps (m_ctxt); }
1313 virtual bool gate (function *);
1314 virtual unsigned int execute (function *);
1317 bool
1318 pass_thread_jumps::gate (function *fun ATTRIBUTE_UNUSED)
1320 return flag_expensive_optimizations;
1323 // Try to thread blocks in FUN. Return TRUE if any jump thread paths were
1324 // registered.
1326 static bool
1327 try_thread_blocks (function *fun)
1329 /* Try to thread each block with more than one successor. */
1330 thread_jumps threader;
1331 basic_block bb;
1332 FOR_EACH_BB_FN (bb, fun)
1334 if (EDGE_COUNT (bb->succs) > 1)
1335 threader.find_jump_threads_backwards (bb);
1337 return threader.thread_through_all_blocks ();
1340 unsigned int
1341 pass_thread_jumps::execute (function *fun)
1343 loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES);
1345 // Iterative mode is a testing construct and is not meant for public
1346 // consumption. It is OFF by default.
1347 bool iterative = param_threader_iterative;
1349 bool changed = false;
1350 while (try_thread_blocks (fun))
1352 changed = true;
1354 if (!iterative)
1355 break;
1357 if ((param_threader_mode & THREADER_MODE_RANGER) == 0)
1358 break;
1359 cleanup_tree_cfg (TODO_update_ssa);
1362 loop_optimizer_finalize ();
1363 return changed ? TODO_cleanup_cfg : 0;
1368 gimple_opt_pass *
1369 make_pass_thread_jumps (gcc::context *ctxt)
1371 return new pass_thread_jumps (ctxt);
1374 namespace {
1376 const pass_data pass_data_early_thread_jumps =
1378 GIMPLE_PASS,
1379 "ethread",
1380 OPTGROUP_NONE,
1381 TV_TREE_SSA_THREAD_JUMPS,
1382 ( PROP_cfg | PROP_ssa ),
1386 ( TODO_cleanup_cfg | TODO_update_ssa ),
1389 class pass_early_thread_jumps : public gimple_opt_pass
1391 public:
1392 pass_early_thread_jumps (gcc::context *ctxt)
1393 : gimple_opt_pass (pass_data_early_thread_jumps, ctxt)
1396 opt_pass * clone (void) { return new pass_early_thread_jumps (m_ctxt); }
1397 virtual bool gate (function *);
1398 virtual unsigned int execute (function *);
1401 bool
1402 pass_early_thread_jumps::gate (function *fun ATTRIBUTE_UNUSED)
1404 return true;
1408 unsigned int
1409 pass_early_thread_jumps::execute (function *fun)
1411 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
1413 /* Try to thread each block with more than one successor. */
1414 thread_jumps threader (/*speed_p=*/false);
1415 basic_block bb;
1416 FOR_EACH_BB_FN (bb, fun)
1418 if (EDGE_COUNT (bb->succs) > 1)
1419 threader.find_jump_threads_backwards (bb);
1421 threader.thread_through_all_blocks ();
1423 loop_optimizer_finalize ();
1424 return 0;
1429 gimple_opt_pass *
1430 make_pass_early_thread_jumps (gcc::context *ctxt)
1432 return new pass_early_thread_jumps (ctxt);