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"
45 #include "tree-pretty-print.h"
48 // Path registry for the backwards threader. After all paths have been
49 // registered with register_path(), thread_through_all_blocks() is called
52 class back_threader_registry
55 back_threader_registry (int max_allowable_paths
);
56 bool register_path (const vec
<basic_block
> &, edge taken
);
57 bool thread_through_all_blocks (bool may_peel_loop_headers
);
59 back_jt_path_registry m_lowlevel_registry
;
60 const int m_max_allowable_paths
;
64 // Class to abstract the profitability code for the backwards threader.
66 class back_threader_profitability
69 back_threader_profitability (bool speed_p
)
72 bool profitable_path_p (const vec
<basic_block
> &, tree name
, edge taken
,
73 bool *irreducible_loop
= NULL
);
81 back_threader (bool speed_p
);
83 void maybe_thread_block (basic_block bb
);
84 bool thread_through_all_blocks (bool may_peel_loop_headers
);
86 void find_paths (basic_block bb
, tree name
);
87 edge
maybe_register_path ();
88 bool find_paths_to_names (basic_block bb
, bitmap imports
);
89 bool resolve_def (tree name
, bitmap interesting
, vec
<tree
> &worklist
);
90 bool resolve_phi (gphi
*phi
, bitmap imports
);
91 edge
find_taken_edge (const vec
<basic_block
> &path
);
92 edge
find_taken_edge_cond (const vec
<basic_block
> &path
, gcond
*);
93 edge
find_taken_edge_switch (const vec
<basic_block
> &path
, gswitch
*);
94 virtual void debug ();
95 virtual void dump (FILE *out
);
97 back_threader_registry m_registry
;
98 back_threader_profitability m_profit
;
99 gimple_ranger m_ranger
;
100 path_range_query m_solver
;
102 // Current path being analyzed.
103 auto_vec
<basic_block
> m_path
;
104 // Hash to mark visited BBs while analyzing a path.
105 hash_set
<basic_block
> m_visited_bbs
;
106 // The set of SSA names, any of which could potentially change the
107 // value of the final conditional in a path.
109 // The last statement in the path.
111 // This is a bit of a wart. It's used to pass the LHS SSA name to
112 // the profitability engine.
114 // Marker to differentiate unreachable edges.
115 static const edge UNREACHABLE_EDGE
;
118 // Used to differentiate unreachable edges, so we may stop the search
119 // in a the given direction.
120 const edge
back_threader::UNREACHABLE_EDGE
= (edge
) -1;
122 back_threader::back_threader (bool speed_p
)
123 : m_registry (param_max_fsm_thread_paths
),
125 m_solver (m_ranger
, /*resolve=*/false)
128 m_imports
= BITMAP_ALLOC (NULL
);
131 back_threader::~back_threader ()
134 BITMAP_FREE (m_imports
);
137 // Register the current path for jump threading if it's profitable to
140 // Return the known taken edge out of the path, even if the path was
141 // not registered, or NULL if the taken edge could not be determined.
144 back_threader::maybe_register_path ()
146 edge taken_edge
= find_taken_edge (m_path
);
148 if (taken_edge
&& taken_edge
!= UNREACHABLE_EDGE
)
150 bool irreducible
= false;
152 = m_profit
.profitable_path_p (m_path
, m_name
, taken_edge
, &irreducible
);
156 m_registry
.register_path (m_path
, taken_edge
);
159 vect_free_loop_info_assumptions (m_path
[0]->loop_father
);
165 // Return the known taken edge out of a path. If the path can be
166 // determined to be unreachable, return UNREACHABLE_EDGE. If no
167 // outgoing edge can be calculated, return NULL.
170 back_threader::find_taken_edge (const vec
<basic_block
> &path
)
172 gcc_checking_assert (path
.length () > 1);
173 switch (gimple_code (m_last_stmt
))
176 return find_taken_edge_cond (path
, as_a
<gcond
*> (m_last_stmt
));
179 return find_taken_edge_switch (path
, as_a
<gswitch
*> (m_last_stmt
));
186 // Same as find_taken_edge, but for paths ending in a switch.
189 back_threader::find_taken_edge_switch (const vec
<basic_block
> &path
,
192 tree name
= gimple_switch_index (sw
);
195 m_solver
.compute_ranges (path
, m_imports
);
196 m_solver
.range_of_expr (r
, name
, sw
);
198 if (r
.undefined_p ())
199 return UNREACHABLE_EDGE
;
205 if (r
.singleton_p (&val
))
206 return ::find_taken_edge (gimple_bb (sw
), val
);
211 // Same as find_taken_edge, but for paths ending in a GIMPLE_COND.
214 back_threader::find_taken_edge_cond (const vec
<basic_block
> &path
,
219 m_solver
.compute_ranges (path
, m_imports
);
220 m_solver
.range_of_stmt (r
, cond
);
222 if (m_solver
.unreachable_path_p ())
223 return UNREACHABLE_EDGE
;
225 int_range
<2> true_range (boolean_true_node
, boolean_true_node
);
226 int_range
<2> false_range (boolean_false_node
, boolean_false_node
);
228 if (r
== true_range
|| r
== false_range
)
230 edge e_true
, e_false
;
231 basic_block bb
= gimple_bb (cond
);
232 extract_true_false_edges_from_block (bb
, &e_true
, &e_false
);
233 return r
== true_range
? e_true
: e_false
;
238 // Populate a vector of trees from a bitmap.
241 populate_worklist (vec
<tree
> &worklist
, bitmap bits
)
246 EXECUTE_IF_SET_IN_BITMAP (bits
, 0, i
, bi
)
248 tree name
= ssa_name (i
);
249 worklist
.quick_push (name
);
253 // If taking any of the incoming edges to a PHI causes the final
254 // conditional of the current path to be constant, register the
255 // path(s), and return TRUE.
258 back_threader::resolve_phi (gphi
*phi
, bitmap interesting
)
260 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (phi
)))
264 for (size_t i
= 0; i
< gimple_phi_num_args (phi
); ++i
)
266 edge e
= gimple_phi_arg_edge (phi
, i
);
268 // This is like path_crosses_loops in profitable_path_p but more
269 // restrictive, since profitable_path_p allows threading the
270 // first block because it would be redirected anyhow.
272 // If we loosened the restriction and used profitable_path_p()
273 // here instead, we would peel off the first iterations of loops
274 // in places like tree-ssa/pr14341.c.
275 bool profitable_p
= m_path
[0]->loop_father
== e
->src
->loop_father
;
278 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
280 " FAIL: path through PHI in bb%d (incoming bb:%d) crosses loop\n",
281 e
->dest
->index
, e
->src
->index
);
285 tree arg
= gimple_phi_arg_def (phi
, i
);
286 if (TREE_CODE (arg
) == SSA_NAME
)
288 unsigned v
= SSA_NAME_VERSION (arg
);
290 // Avoid loops as in: x_5 = PHI <x_5(2), ...>.
291 if (bitmap_bit_p (interesting
, v
))
294 bitmap_set_bit (interesting
, v
);
295 bitmap_set_bit (m_imports
, v
);
296 done
|= find_paths_to_names (e
->src
, interesting
);
297 bitmap_clear_bit (interesting
, v
);
299 else if (TREE_CODE (arg
) == INTEGER_CST
)
301 m_path
.safe_push (e
->src
);
302 edge taken_edge
= maybe_register_path ();
303 if (taken_edge
&& taken_edge
!= UNREACHABLE_EDGE
)
311 // If the definition of NAME causes the final conditional of the
312 // current path to be constant, register the path, and return TRUE.
315 back_threader::resolve_def (tree name
, bitmap interesting
, vec
<tree
> &worklist
)
317 gimple
*def_stmt
= SSA_NAME_DEF_STMT (name
);
320 if (is_a
<gphi
*> (def_stmt
)
321 && resolve_phi (as_a
<gphi
*> (def_stmt
), interesting
))
324 // Defer copies of SSAs by adding the source to the worklist.
325 if (gimple_assign_single_p (def_stmt
)
326 && TREE_CODE (gimple_assign_rhs1 (def_stmt
)) == SSA_NAME
)
328 tree rhs
= gimple_assign_rhs1 (def_stmt
);
329 bitmap_set_bit (m_imports
, SSA_NAME_VERSION (rhs
));
330 bitmap_set_bit (interesting
, SSA_NAME_VERSION (rhs
));
331 worklist
.safe_push (rhs
);
336 // Find jump threading paths to any of the SSA names in the
337 // INTERESTING bitmap, and register any such paths.
339 // Return TRUE if no further processing past this block is necessary.
340 // This is because we've either registered a path, or because there is
341 // nothing of interesting beyond this block.
343 // BB is the current path being processed.
346 back_threader::find_paths_to_names (basic_block bb
, bitmap interesting
)
348 if (m_visited_bbs
.add (bb
))
351 m_path
.safe_push (bb
);
353 if (m_path
.length () > 1
354 && !m_profit
.profitable_path_p (m_path
, m_name
, NULL
))
357 m_visited_bbs
.remove (bb
);
361 auto_bitmap processed
;
365 // We use a worklist instead of iterating through the bitmap,
366 // because we may add new items in-flight.
367 auto_vec
<tree
> worklist (bitmap_count_bits (interesting
));
368 populate_worklist (worklist
, interesting
);
369 while (!worklist
.is_empty ())
371 tree name
= worklist
.pop ();
372 unsigned i
= SSA_NAME_VERSION (name
);
373 basic_block def_bb
= gimple_bb (SSA_NAME_DEF_STMT (name
));
375 // Process any names defined in this block.
378 bitmap_set_bit (processed
, i
);
380 if (resolve_def (name
, interesting
, worklist
))
386 // Examine blocks that define or export an interesting SSA,
387 // since they may compute a range which resolve this path.
389 || bitmap_bit_p (m_ranger
.gori ().exports (bb
), i
))
390 && m_path
.length () > 1)
392 if (maybe_register_path ())
400 // If there are interesting names not yet processed, keep looking.
401 bitmap_and_compl_into (interesting
, processed
);
402 if (!bitmap_empty_p (interesting
))
406 FOR_EACH_EDGE (e
, iter
, bb
->preds
)
407 if ((e
->flags
& EDGE_ABNORMAL
) == 0)
408 done
|= find_paths_to_names (e
->src
, interesting
);
413 EXECUTE_IF_SET_IN_BITMAP (processed
, 0, i
, bi
)
414 bitmap_set_bit (interesting
, i
);
417 m_visited_bbs
.remove (bb
);
421 // Search backwards from BB looking for paths where the final
422 // conditional out of BB can be determined. NAME is the LHS of the
423 // final conditional. Register such paths for jump threading.
426 back_threader::find_paths (basic_block bb
, tree name
)
428 gimple
*stmt
= last_stmt (bb
);
430 || (gimple_code (stmt
) != GIMPLE_COND
431 && gimple_code (stmt
) != GIMPLE_SWITCH
))
434 if (EDGE_COUNT (bb
->succs
) > 1
435 || single_succ_to_potentially_threadable_block (bb
))
438 m_visited_bbs
.empty ();
441 bitmap_clear (m_imports
);
443 auto_bitmap interesting
;
444 bitmap_copy (m_imports
, m_ranger
.gori ().imports (bb
));
445 bitmap_copy (interesting
, m_imports
);
446 find_paths_to_names (bb
, interesting
);
450 // Simple helper to get the last statement from BB, which is assumed
451 // to be a control statement. Return NULL if the last statement is
452 // not a control statement.
455 get_gimple_control_stmt (basic_block bb
)
457 gimple_stmt_iterator gsi
= gsi_last_nondebug_bb (bb
);
462 gimple
*stmt
= gsi_stmt (gsi
);
463 enum gimple_code code
= gimple_code (stmt
);
464 if (code
== GIMPLE_COND
|| code
== GIMPLE_SWITCH
|| code
== GIMPLE_GOTO
)
469 // Search backwards from BB looking for paths where the final
470 // conditional maybe threaded to a successor block. Record such paths
471 // for jump threading.
474 back_threader::maybe_thread_block (basic_block bb
)
476 gimple
*stmt
= get_gimple_control_stmt (bb
);
480 enum gimple_code code
= gimple_code (stmt
);
482 if (code
== GIMPLE_SWITCH
)
483 name
= gimple_switch_index (as_a
<gswitch
*> (stmt
));
484 else if (code
== GIMPLE_COND
)
485 name
= gimple_cond_lhs (stmt
);
486 else if (code
== GIMPLE_GOTO
)
487 name
= gimple_goto_dest (stmt
);
491 find_paths (bb
, name
);
494 // Perform the actual jump threading for the all queued paths.
497 back_threader::thread_through_all_blocks (bool may_peel_loop_headers
)
499 return m_registry
.thread_through_all_blocks (may_peel_loop_headers
);
502 // Dump a sequence of BBs through the CFG.
505 dump_path (FILE *dump_file
, const vec
<basic_block
> &path
)
507 for (size_t i
= 0; i
< path
.length (); ++i
)
509 fprintf (dump_file
, "BB%d", path
[i
]->index
);
510 if (i
+ 1 < path
.length ())
511 fprintf (dump_file
, " <- ");
513 fprintf (dump_file
, "\n");
517 debug (const vec
<basic_block
> &path
)
519 dump_path (stderr
, path
);
523 back_threader::dump (FILE *out
)
526 fprintf (out
, "\nCandidates for pre-computation:\n");
527 fprintf (out
, "===================================\n");
532 EXECUTE_IF_SET_IN_BITMAP (m_imports
, 0, i
, bi
)
534 tree name
= ssa_name (i
);
535 print_generic_expr (out
, name
, TDF_NONE
);
541 back_threader::debug ()
546 back_threader_registry::back_threader_registry (int max_allowable_paths
)
547 : m_max_allowable_paths (max_allowable_paths
)
549 m_threaded_paths
= 0;
553 back_threader_registry::thread_through_all_blocks (bool may_peel_loop_headers
)
555 return m_lowlevel_registry
.thread_through_all_blocks (may_peel_loop_headers
);
558 /* Examine jump threading path PATH and return TRUE if it is profitable to
559 thread it, otherwise return FALSE.
561 NAME is the SSA_NAME of the variable we found to have a constant
562 value on PATH. If unknown, SSA_NAME is NULL.
564 If the taken edge out of the path is known ahead of time it is passed in
565 TAKEN_EDGE, otherwise it is NULL.
567 CREATES_IRREDUCIBLE_LOOP, if non-null is set to TRUE if threading this path
568 would create an irreducible loop.
570 ?? It seems we should be able to loosen some of the restrictions in
571 this function after loop optimizations have run. */
574 back_threader_profitability::profitable_path_p (const vec
<basic_block
> &m_path
,
577 bool *creates_irreducible_loop
)
579 gcc_checking_assert (!m_path
.is_empty ());
581 /* We can an empty path here (excluding the DEF block) when the
582 statement that makes a conditional generate a compile-time
583 constant result is in the same block as the conditional.
585 That's not really a jump threading opportunity, but instead is
586 simple cprop & simplification. We could handle it here if we
587 wanted by wiring up all the incoming edges. If we run this
588 early in IPA, that might be worth doing. For now we just
590 if (m_path
.length () <= 1)
593 if (m_path
.length () > (unsigned) param_max_fsm_thread_length
)
595 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
596 fprintf (dump_file
, " FAIL: Jump-thread path not considered: "
597 "the number of basic blocks on the path "
598 "exceeds PARAM_MAX_FSM_THREAD_LENGTH.\n");
603 gimple_stmt_iterator gsi
;
604 loop_p loop
= m_path
[0]->loop_father
;
605 bool path_crosses_loops
= false;
606 bool threaded_through_latch
= false;
607 bool multiway_branch_in_path
= false;
608 bool threaded_multiway_branch
= false;
609 bool contains_hot_bb
= false;
611 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
612 fprintf (dump_file
, "Checking profitability of path (backwards): ");
614 /* Count the number of instructions on the path: as these instructions
615 will have to be duplicated, we will not record the path if there
616 are too many instructions on the path. Also check that all the
617 blocks in the path belong to a single loop. */
618 for (unsigned j
= 0; j
< m_path
.length (); j
++)
620 basic_block bb
= m_path
[j
];
622 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
623 fprintf (dump_file
, " bb:%i", bb
->index
);
624 /* Remember, blocks in the path are stored in opposite order
625 in the PATH array. The last entry in the array represents
626 the block with an outgoing edge that we will redirect to the
627 jump threading path. Thus we don't care about that block's
628 loop father, nor how many statements are in that block because
629 it will not be copied or whether or not it ends in a multiway
631 if (j
< m_path
.length () - 1)
633 int orig_n_insns
= n_insns
;
634 if (bb
->loop_father
!= loop
)
636 path_crosses_loops
= true;
638 // Dump rest of blocks.
639 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
640 for (j
++; j
< m_path
.length (); j
++)
643 fprintf (dump_file
, " bb:%i", bb
->index
);
648 /* PHIs in the path will create degenerate PHIS in the
649 copied path which will then get propagated away, so
650 looking at just the duplicate path the PHIs would
653 But those PHIs, because they're assignments to objects
654 typically with lives that exist outside the thread path,
655 will tend to generate PHIs (or at least new PHI arguments)
656 at points where we leave the thread path and rejoin
657 the original blocks. So we do want to account for them.
659 We ignore virtual PHIs. We also ignore cases where BB
660 has a single incoming edge. That's the most common
661 degenerate PHI we'll see here. Finally we ignore PHIs
662 that are associated with the value we're tracking as
663 that object likely dies. */
664 if (EDGE_COUNT (bb
->succs
) > 1 && EDGE_COUNT (bb
->preds
) > 1)
666 for (gphi_iterator gsip
= gsi_start_phis (bb
);
670 gphi
*phi
= gsip
.phi ();
671 tree dst
= gimple_phi_result (phi
);
673 /* Note that if both NAME and DST are anonymous
674 SSA_NAMEs, then we do not have enough information
675 to consider them associated. */
678 && TREE_CODE (name
) == SSA_NAME
679 && (SSA_NAME_VAR (dst
) != SSA_NAME_VAR (name
)
680 || !SSA_NAME_VAR (dst
))
681 && !virtual_operand_p (dst
))
686 if (!contains_hot_bb
&& m_speed_p
)
687 contains_hot_bb
|= optimize_bb_for_speed_p (bb
);
688 for (gsi
= gsi_after_labels (bb
);
690 gsi_next_nondebug (&gsi
))
692 /* Do not allow OpenACC loop markers and __builtin_constant_p on
693 threading paths. The latter is disallowed, because an
694 expression might be constant on two threading paths, and
695 become non-constant (i.e.: phi) when they merge. */
696 gimple
*stmt
= gsi_stmt (gsi
);
697 if (gimple_call_internal_p (stmt
, IFN_UNIQUE
)
698 || gimple_call_builtin_p (stmt
, BUILT_IN_CONSTANT_P
))
700 /* Do not count empty statements and labels. */
701 if (gimple_code (stmt
) != GIMPLE_NOP
702 && !(gimple_code (stmt
) == GIMPLE_ASSIGN
703 && gimple_assign_rhs_code (stmt
) == ASSERT_EXPR
)
704 && !is_gimple_debug (stmt
))
705 n_insns
+= estimate_num_insns (stmt
, &eni_size_weights
);
707 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
708 fprintf (dump_file
, " (%i insns)", n_insns
-orig_n_insns
);
710 /* We do not look at the block with the threaded branch
711 in this loop. So if any block with a last statement that
712 is a GIMPLE_SWITCH or GIMPLE_GOTO is seen, then we have a
713 multiway branch on our path.
715 The block in PATH[0] is special, it's the block were we're
716 going to be able to eliminate its branch. */
717 gimple
*last
= last_stmt (bb
);
718 if (last
&& (gimple_code (last
) == GIMPLE_SWITCH
719 || gimple_code (last
) == GIMPLE_GOTO
))
722 threaded_multiway_branch
= true;
724 multiway_branch_in_path
= true;
728 /* Note if we thread through the latch, we will want to include
729 the last entry in the array when determining if we thread
730 through the loop latch. */
731 if (loop
->latch
== bb
)
733 threaded_through_latch
= true;
734 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
735 fprintf (dump_file
, " (latch)");
739 gimple
*stmt
= get_gimple_control_stmt (m_path
[0]);
742 /* We are going to remove the control statement at the end of the
743 last block in the threading path. So don't count it against our
746 int stmt_insns
= estimate_num_insns (stmt
, &eni_size_weights
);
747 n_insns
-= stmt_insns
;
749 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
750 fprintf (dump_file
, "\n Control statement insns: %i\n"
751 " Overall: %i insns\n",
752 stmt_insns
, n_insns
);
754 if (creates_irreducible_loop
)
756 /* If this path threaded through the loop latch back into the
757 same loop and the destination does not dominate the loop
758 latch, then this thread would create an irreducible loop. */
759 *creates_irreducible_loop
= false;
761 && threaded_through_latch
762 && loop
== taken_edge
->dest
->loop_father
763 && (determine_bb_domination_status (loop
, taken_edge
->dest
)
764 == DOMST_NONDOMINATING
))
765 *creates_irreducible_loop
= true;
768 if (path_crosses_loops
)
770 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
771 fprintf (dump_file
, " FAIL: Jump-thread path not considered: "
772 "the path crosses loops.\n");
776 /* Threading is profitable if the path duplicated is hot but also
777 in a case we separate cold path from hot path and permit optimization
778 of the hot path later. Be on the agressive side here. In some testcases,
779 as in PR 78407 this leads to noticeable improvements. */
781 && ((taken_edge
&& optimize_edge_for_speed_p (taken_edge
))
784 if (n_insns
>= param_max_fsm_thread_path_insns
)
786 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
787 fprintf (dump_file
, " FAIL: Jump-thread path not considered: "
788 "the number of instructions on the path "
789 "exceeds PARAM_MAX_FSM_THREAD_PATH_INSNS.\n");
793 else if (!m_speed_p
&& n_insns
> 1)
795 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
796 fprintf (dump_file
, " FAIL: Jump-thread path not considered: "
797 "duplication of %i insns is needed and optimizing for size.\n",
802 /* We avoid creating irreducible inner loops unless we thread through
803 a multiway branch, in which case we have deemed it worth losing
804 other loop optimizations later.
806 We also consider it worth creating an irreducible inner loop if
807 the number of copied statement is low relative to the length of
808 the path -- in that case there's little the traditional loop
809 optimizer would have done anyway, so an irreducible loop is not
811 if (!threaded_multiway_branch
812 && creates_irreducible_loop
813 && *creates_irreducible_loop
814 && (n_insns
* (unsigned) param_fsm_scale_path_stmts
815 > (m_path
.length () *
816 (unsigned) param_fsm_scale_path_blocks
)))
819 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
821 " FAIL: Would create irreducible loop without threading "
822 "multiway branch.\n");
826 /* The generic copier used by the backthreader does not re-use an
827 existing threading path to reduce code duplication. So for that
828 case, drastically reduce the number of statements we are allowed
830 if (!(threaded_through_latch
&& threaded_multiway_branch
)
831 && (n_insns
* param_fsm_scale_path_stmts
832 >= param_max_jump_thread_duplication_stmts
))
834 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
836 " FAIL: Did not thread around loop and would copy too "
837 "many statements.\n");
841 /* When there is a multi-way branch on the path, then threading can
842 explode the CFG due to duplicating the edges for that multi-way
843 branch. So like above, only allow a multi-way branch on the path
844 if we actually thread a multi-way branch. */
845 if (!threaded_multiway_branch
&& multiway_branch_in_path
)
847 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
849 " FAIL: Thread through multiway branch without threading "
850 "a multiway branch.\n");
854 /* Threading through an empty latch would cause code to be added to
855 the latch. This could alter the loop form sufficiently to cause
856 loop optimizations to fail. Disable these threads until after
857 loop optimizations have run. */
858 if ((threaded_through_latch
859 || (taken_edge
&& taken_edge
->dest
== loop
->latch
))
860 && !(cfun
->curr_properties
& PROP_loop_opts_done
)
861 && empty_block_p (loop
->latch
))
863 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
865 " FAIL: Thread through latch before loop opts would create non-empty latch\n");
872 /* The current path PATH is a vector of blocks forming a jump threading
873 path in reverse order. TAKEN_EDGE is the edge taken from path[0].
875 Convert the current path into the form used by register_jump_thread and
878 Return TRUE if successful or FALSE otherwise. */
881 back_threader_registry::register_path (const vec
<basic_block
> &m_path
,
884 if (m_threaded_paths
> m_max_allowable_paths
)
886 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
887 fprintf (dump_file
, " FAIL: Jump-thread path not considered: "
888 "the number of previously recorded paths to "
889 "thread exceeds PARAM_MAX_FSM_THREAD_PATHS.\n");
893 vec
<jump_thread_edge
*> *jump_thread_path
894 = m_lowlevel_registry
.allocate_thread_path ();
896 // The generic copier ignores the edge type. We can build the
897 // thread edges with any type.
898 for (unsigned int j
= 0; j
+ 1 < m_path
.length (); j
++)
900 basic_block bb1
= m_path
[m_path
.length () - j
- 1];
901 basic_block bb2
= m_path
[m_path
.length () - j
- 2];
903 edge e
= find_edge (bb1
, bb2
);
905 m_lowlevel_registry
.push_edge (jump_thread_path
, e
, EDGE_COPY_SRC_BLOCK
);
908 m_lowlevel_registry
.push_edge (jump_thread_path
,
909 taken_edge
, EDGE_NO_COPY_SRC_BLOCK
);
911 if (m_lowlevel_registry
.register_jump_thread (jump_thread_path
))
918 const pass_data pass_data_thread_jumps
=
923 TV_TREE_SSA_THREAD_JUMPS
,
924 ( PROP_cfg
| PROP_ssa
),
931 class pass_thread_jumps
: public gimple_opt_pass
934 pass_thread_jumps (gcc::context
*ctxt
)
935 : gimple_opt_pass (pass_data_thread_jumps
, ctxt
)
938 opt_pass
* clone (void) { return new pass_thread_jumps (m_ctxt
); }
939 virtual bool gate (function
*);
940 virtual unsigned int execute (function
*);
944 pass_thread_jumps::gate (function
*fun ATTRIBUTE_UNUSED
)
946 return flag_thread_jumps
&& flag_expensive_optimizations
;
949 // Try to thread blocks in FUN. Return TRUE if any jump thread paths were
953 try_thread_blocks (function
*fun
)
955 /* Try to thread each block with more than one successor. */
956 back_threader
threader (/*speed_p=*/true);
958 FOR_EACH_BB_FN (bb
, fun
)
960 if (EDGE_COUNT (bb
->succs
) > 1)
961 threader
.maybe_thread_block (bb
);
963 return threader
.thread_through_all_blocks (/*peel_loop_headers=*/true);
967 pass_thread_jumps::execute (function
*fun
)
969 loop_optimizer_init (LOOPS_HAVE_PREHEADERS
| LOOPS_HAVE_SIMPLE_LATCHES
);
971 bool changed
= try_thread_blocks (fun
);
973 loop_optimizer_finalize ();
975 return changed
? TODO_cleanup_cfg
: 0;
981 make_pass_thread_jumps (gcc::context
*ctxt
)
983 return new pass_thread_jumps (ctxt
);
988 const pass_data pass_data_early_thread_jumps
=
993 TV_TREE_SSA_THREAD_JUMPS
,
994 ( PROP_cfg
| PROP_ssa
),
998 ( TODO_cleanup_cfg
| TODO_update_ssa
),
1001 class pass_early_thread_jumps
: public gimple_opt_pass
1004 pass_early_thread_jumps (gcc::context
*ctxt
)
1005 : gimple_opt_pass (pass_data_early_thread_jumps
, ctxt
)
1008 opt_pass
* clone (void) { return new pass_early_thread_jumps (m_ctxt
); }
1009 virtual bool gate (function
*);
1010 virtual unsigned int execute (function
*);
1014 pass_early_thread_jumps::gate (function
*fun ATTRIBUTE_UNUSED
)
1016 return flag_thread_jumps
;
1020 pass_early_thread_jumps::execute (function
*fun
)
1022 loop_optimizer_init (AVOID_CFG_MODIFICATIONS
);
1024 /* Try to thread each block with more than one successor. */
1025 back_threader
threader (/*speed_p=*/false);
1027 FOR_EACH_BB_FN (bb
, fun
)
1029 if (EDGE_COUNT (bb
->succs
) > 1)
1030 threader
.maybe_thread_block (bb
);
1032 threader
.thread_through_all_blocks (/*peel_loop_headers=*/true);
1034 loop_optimizer_finalize ();
1041 make_pass_early_thread_jumps (gcc::context
*ctxt
)
1043 return new pass_early_thread_jumps (ctxt
);