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)
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/>. */
22 #include "coretypes.h"
27 #include "fold-const.h"
29 #include "gimple-iterator.h"
31 #include "tree-ssa-threadupdate.h"
32 #include "tree-ssa-loop.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"
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
50 class back_threader_registry
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 ();
59 vec
<vec
<basic_block
>> m_all_paths
;
60 jump_thread_path_registry m_lowlevel_registry
;
61 const int m_max_allowable_paths
;
65 // Class to abstract the profitability code for the backwards threader.
67 class back_threader_profitability
70 back_threader_profitability (bool speed_p
)
73 bool profitable_path_p (const vec
<basic_block
> &, tree name
, edge taken
,
74 bool *irreducible_loop
= NULL
);
80 // Ranger based backwards threader.
84 // Temporary until we remove old code.
85 friend bool path_is_unreachable_p (const vec
<jump_thread_edge
*> &);
88 back_threader (back_threader_profitability
&, back_threader_registry
&);
90 void find_paths (basic_block bb
, tree name
);
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.
113 // The last statement in the path.
115 // This is a bit of a wart. It's used to pass the LHS SSA name to
116 // the profitability engine.
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
®istry
)
128 : m_registry (registry
),
133 m_imports
= BITMAP_ALLOC (NULL
);
136 back_threader::~back_threader ()
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.
146 back_threader::maybe_register_path (edge taken_edge
)
148 bool irreducible
= false;
150 = m_profit
.profitable_path_p (m_path
, m_name
, taken_edge
, &irreducible
);
154 m_registry
.register_path (m_path
, taken_edge
);
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.
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
))
172 return find_taken_edge_cond (path
, as_a
<gcond
*> (m_last_stmt
));
175 return find_taken_edge_switch (path
, as_a
<gswitch
*> (m_last_stmt
));
182 // Same as find_taken_edge, but for paths ending in a switch.
185 back_threader::find_taken_edge_switch (const vec
<basic_block
> &path
,
188 tree name
= gimple_switch_index (sw
);
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
;
201 if (r
.singleton_p (&val
))
202 return ::find_taken_edge (gimple_bb (sw
), val
);
207 // Same as find_taken_edge, but for paths ending in a GIMPLE_COND.
210 back_threader::find_taken_edge_cond (const vec
<basic_block
> &path
,
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.
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
;
240 // Populate a vector of trees from a bitmap.
243 populate_worklist (vec
<tree
> worklist
, bitmap bits
)
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.
260 back_threader::resolve_phi (gphi
*phi
, bitmap interesting
)
262 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (phi
)))
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
;
280 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
282 " FAIL: path through PHI in bb%d (incoming bb:%d) crosses loop\n",
283 e
->dest
->index
, e
->src
->index
);
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
))
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
);
316 // If the definition of NAME causes the final conditional of the
317 // current path to be constant, register the path, and return TRUE.
320 back_threader::resolve_def (tree name
, bitmap interesting
, vec
<tree
> worklist
)
322 gimple
*def_stmt
= SSA_NAME_DEF_STMT (name
);
325 if (is_a
<gphi
*> (def_stmt
)
326 && resolve_phi (as_a
<gphi
*> (def_stmt
), interesting
))
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
);
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.
351 back_threader::find_paths_to_names (basic_block bb
, bitmap interesting
)
353 if (m_visited_bbs
.add (bb
))
356 m_path
.safe_push (bb
);
358 if (m_path
.length () > 1
359 && !m_profit
.profitable_path_p (m_path
, m_name
, NULL
))
362 m_visited_bbs
.remove (bb
);
366 auto_bitmap processed
;
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.
383 bitmap_set_bit (processed
, i
);
385 if (resolve_def (name
, interesting
, worklist
))
391 // Examine blocks that define or export an interesting SSA,
392 // since they may compute a range which resolve this path.
394 || bitmap_bit_p (m_ranger
.gori ().exports (bb
), i
))
395 && m_path
.length () > 1)
397 edge taken_edge
= find_taken_edge (m_path
);
400 if (taken_edge
!= UNREACHABLE_EDGE
)
401 maybe_register_path (taken_edge
);
409 // If there are interesting names not yet processed, keep looking.
410 bitmap_and_compl_into (interesting
, processed
);
411 if (!bitmap_empty_p (interesting
))
415 FOR_EACH_EDGE (e
, iter
, bb
->preds
)
416 if ((e
->flags
& EDGE_ABNORMAL
) == 0)
417 done
|= find_paths_to_names (e
->src
, interesting
);
422 EXECUTE_IF_SET_IN_BITMAP (processed
, 0, i
, bi
)
423 bitmap_set_bit (interesting
, i
);
426 m_visited_bbs
.remove (bb
);
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.
435 back_threader::find_paths (basic_block bb
, tree name
)
437 gimple
*stmt
= last_stmt (bb
);
439 || (gimple_code (stmt
) != GIMPLE_COND
440 && gimple_code (stmt
) != GIMPLE_SWITCH
))
443 if (EDGE_COUNT (bb
->succs
) > 1
444 || single_succ_to_potentially_threadable_block (bb
))
447 m_visited_bbs
.empty ();
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.
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");
474 debug (const vec
<basic_block
> &path
)
476 dump_path (stderr
, path
);
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 ();
492 void maybe_register_path (const vec
<basic_block
> &m_path
,
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
,
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
;
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.
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. */
529 get_gimple_control_stmt (basic_block bb
)
531 gimple_stmt_iterator gsi
= gsi_last_nondebug_bb (bb
);
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
)
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. */
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
,
555 if (loop
!= start_bb
->loop_father
)
558 if (start_bb
== end_bb
)
560 path
.safe_push (start_bb
);
564 if (!local_visited_bbs
.add (start_bb
))
568 FOR_EACH_EDGE (e
, ei
, start_bb
->succs
)
569 if (fsm_find_thread_path (e
->dest
, end_bb
, path
, local_visited_bbs
,
572 path
.safe_push (start_bb
);
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 ();
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. */
611 back_threader_profitability::profitable_path_p (const vec
<basic_block
> &m_path
,
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
627 if (m_path
.length () <= 1)
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");
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
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;
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
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
);
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. */
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
))
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
);
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
))
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
))
751 threaded_multiway_branch
= true;
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]);
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
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;
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");
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. */
806 && ((taken_edge
&& optimize_edge_for_speed_p (taken_edge
))
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");
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",
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
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
))
846 " FAIL: FSM would create irreducible loop without threading "
847 "multiway branch.\n");
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
))
864 " FAIL: FSM did not thread around loop and would copy too "
865 "many statements.\n");
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
))
877 " FAIL: FSM Thread through multiway branch without threading "
878 "a multiway branch.\n");
884 /* Return the taken edge out of a path, assuming that the underlying assignment
885 or PHI SSA resolves to ARG. */
888 thread_jumps::find_taken_edge (const vec
<basic_block
> &path
, tree arg
)
890 if (TREE_CODE_CLASS (TREE_CODE (arg
)) != tcc_constant
)
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
923 Return TRUE if successful or FALSE otherwise. */
926 back_threader_registry::register_path (const vec
<basic_block
> &m_path
,
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");
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
);
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. */
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
))
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
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. */
977 thread_jumps::check_subpath_and_update_thread_path (basic_block last_bb
,
979 int *next_path_length
)
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
))
994 /* If there is more than one path, stop. */
999 /* Stop if we have not found a path: this could occur when the recursion
1000 is stopped by one of the bounds. */
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
]))
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 ();
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. */
1030 thread_jumps::maybe_register_path (const vec
<basic_block
> &m_path
,
1034 bool irreducible
= false;
1035 bool profitable
= m_profit
.profitable_path_p (m_path
, name
, taken_edge
,
1039 if (!m_registry
.register_path (m_path
, taken_edge
))
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
1051 PATH contains the series of blocks to traverse that will result in
1052 NAME having a constant value. */
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
)
1067 if (TREE_CODE (arg
) == SSA_NAME
)
1069 m_path
.safe_push (bbi
);
1070 /* Recursively follow SSA_NAMEs looking for a constant
1072 fsm_find_control_statement_thread_paths (arg
);
1078 m_path
.safe_push (bbi
);
1079 edge taken_edge
= find_taken_edge (m_path
, arg
);
1081 maybe_register_path (m_path
, m_name
, taken_edge
);
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
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
)))
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
)
1112 /* Anything not explicitly allowed is not handled. */
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
1120 PATH contains the series of blocks to traverse that will result in
1121 NAME having a constant value. */
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
);
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
);
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
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
))
1156 gimple
*def_stmt
= SSA_NAME_DEF_STMT (name
);
1157 basic_block def_bb
= gimple_bb (def_stmt
);
1162 /* We allow the SSA chain to contains PHIs and simple copies and constant
1164 if (gimple_code (def_stmt
) != GIMPLE_PHI
1165 && gimple_code (def_stmt
) != GIMPLE_ASSIGN
)
1168 if (gimple_code (def_stmt
) == GIMPLE_PHI
1169 && (gimple_phi_num_args (def_stmt
)
1170 >= (unsigned) param_fsm_maximum_phi_arguments
))
1173 if (is_gimple_assign (def_stmt
)
1174 && ! handle_assignment_p (def_stmt
))
1177 /* Avoid infinite recursion. */
1178 if (m_visited_bbs
.add (def_bb
))
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
)
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
,
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
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
);
1236 gimple
*stmt
= get_gimple_control_stmt (bb
);
1240 enum gimple_code code
= gimple_code (stmt
);
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
)
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;
1265 fsm_find_control_statement_thread_paths (name
);
1268 // Like find_jump_threads_backwards(), but using ranger.
1271 thread_jumps::find_jump_threads_backwards_with_ranger (basic_block bb
)
1273 gimple
*stmt
= get_gimple_control_stmt (bb
);
1277 enum gimple_code code
= gimple_code (stmt
);
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
);
1287 m_back_threader
.find_paths (bb
, name
);
1292 const pass_data pass_data_thread_jumps
=
1297 TV_TREE_SSA_THREAD_JUMPS
,
1298 ( PROP_cfg
| PROP_ssa
),
1305 class pass_thread_jumps
: public gimple_opt_pass
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
*);
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
1327 try_thread_blocks (function
*fun
)
1329 /* Try to thread each block with more than one successor. */
1330 thread_jumps threader
;
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 ();
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
))
1357 if ((param_threader_mode
& THREADER_MODE_RANGER
) == 0)
1359 cleanup_tree_cfg (TODO_update_ssa
);
1362 loop_optimizer_finalize ();
1363 return changed
? TODO_cleanup_cfg
: 0;
1369 make_pass_thread_jumps (gcc::context
*ctxt
)
1371 return new pass_thread_jumps (ctxt
);
1376 const pass_data pass_data_early_thread_jumps
=
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
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
*);
1402 pass_early_thread_jumps::gate (function
*fun ATTRIBUTE_UNUSED
)
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);
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 ();
1430 make_pass_early_thread_jumps (gcc::context
*ctxt
)
1432 return new pass_early_thread_jumps (ctxt
);