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