c++: Implement C++26 P2573R2 - = delete("should have a reason"); [PR114458]
[official-gcc.git] / gcc / mode-switching.cc
blob9041838a791f4989e02ddc9141f91fcb3ba85c3f
1 /* CPU mode switching
2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "cfghooks.h"
27 #include "df.h"
28 #include "memmodel.h"
29 #include "tm_p.h"
30 #include "regs.h"
31 #include "emit-rtl.h"
32 #include "cfgrtl.h"
33 #include "cfganal.h"
34 #include "lcm.h"
35 #include "cfgcleanup.h"
36 #include "tree-pass.h"
37 #include "cfgbuild.h"
39 /* We want target macros for the mode switching code to be able to refer
40 to instruction attribute values. */
41 #include "insn-attr.h"
43 #ifdef OPTIMIZE_MODE_SWITCHING
45 /* The algorithm for setting the modes consists of scanning the insn list
46 and finding all the insns which require a specific mode. Each insn gets
47 a unique struct seginfo element. These structures are inserted into a list
48 for each basic block. For each entity, there is an array of bb_info over
49 the flow graph basic blocks (local var 'bb_info'), which contains a list
50 of all insns within that basic block, in the order they are encountered.
52 For each entity, any basic block WITHOUT any insns requiring a specific
53 mode are given a single entry without a mode (each basic block in the
54 flow graph must have at least one entry in the segment table).
56 The LCM algorithm is then run over the flow graph to determine where to
57 place the sets to the highest-priority mode with respect to the first
58 insn in any one block. Any adjustments required to the transparency
59 vectors are made, then the next iteration starts for the next-lower
60 priority mode, till for each entity all modes are exhausted.
62 More details can be found in the code of optimize_mode_switching. */
64 /* This structure contains the information for each insn which requires
65 either single or double mode to be set.
66 MODE is the mode this insn must be executed in.
67 INSN_PTR is the insn to be executed (may be the note that marks the
68 beginning of a basic block).
69 NEXT is the next insn in the same basic block. */
70 struct seginfo
72 int prev_mode;
73 int mode;
74 rtx_insn *insn_ptr;
75 struct seginfo *next;
76 HARD_REG_SET regs_live;
79 struct bb_info
81 struct seginfo *seginfo;
82 int computing;
83 int mode_out;
84 int mode_in;
85 int single_succ;
88 /* Clear ode I from entity J in bitmap B. */
89 #define clear_mode_bit(b, j, i) \
90 bitmap_clear_bit (b, (j * max_num_modes) + i)
92 /* Test mode I from entity J in bitmap B. */
93 #define mode_bit_p(b, j, i) \
94 bitmap_bit_p (b, (j * max_num_modes) + i)
96 /* Set mode I from entity J in bitmal B. */
97 #define set_mode_bit(b, j, i) \
98 bitmap_set_bit (b, (j * max_num_modes) + i)
100 /* Emit modes segments from EDGE_LIST associated with entity E.
101 INFO gives mode availability for each mode. */
103 static bool
104 commit_mode_sets (struct edge_list *edge_list, int e, struct bb_info *info)
106 bool need_commit = false;
108 for (int ed = NUM_EDGES (edge_list) - 1; ed >= 0; ed--)
110 edge eg = INDEX_EDGE (edge_list, ed);
112 if (eg->aux)
114 int mode = (int) (intptr_t) eg->aux - 1;
115 HARD_REG_SET live_at_edge;
116 basic_block src_bb = eg->src;
117 int cur_mode = info[src_bb->index].mode_out;
118 rtx_insn *mode_set;
120 REG_SET_TO_HARD_REG_SET (live_at_edge, df_get_live_out (src_bb));
122 rtl_profile_for_edge (eg);
123 start_sequence ();
125 targetm.mode_switching.emit (e, mode, cur_mode, live_at_edge);
127 mode_set = get_insns ();
128 end_sequence ();
129 default_rtl_profile ();
131 /* Do not bother to insert empty sequence. */
132 if (mode_set == NULL)
133 continue;
135 /* We should not get an abnormal edge here. */
136 gcc_assert (! (eg->flags & EDGE_ABNORMAL));
138 need_commit = true;
139 insert_insn_on_edge (mode_set, eg);
143 return need_commit;
146 /* Allocate a new BBINFO structure, initialized with the PREV_MODE, MODE,
147 INSN, and REGS_LIVE parameters.
148 INSN may not be a NOTE_INSN_BASIC_BLOCK, unless it is an empty
149 basic block; that allows us later to insert instructions in a FIFO-like
150 manner. */
152 static struct seginfo *
153 new_seginfo (int prev_mode, int mode, rtx_insn *insn,
154 const HARD_REG_SET &regs_live)
156 struct seginfo *ptr;
158 gcc_assert (!NOTE_INSN_BASIC_BLOCK_P (insn)
159 || insn == BB_END (NOTE_BASIC_BLOCK (insn)));
160 ptr = XNEW (struct seginfo);
161 ptr->prev_mode = prev_mode;
162 ptr->mode = mode;
163 ptr->insn_ptr = insn;
164 ptr->next = NULL;
165 ptr->regs_live = regs_live;
166 return ptr;
169 /* Add a seginfo element to the end of a list.
170 TAIL is a pointer to the list's null terminator.
171 INFO is the structure to be linked in. */
173 static void
174 add_seginfo (struct seginfo ***tail_ptr, struct seginfo *info)
176 **tail_ptr = info;
177 *tail_ptr = &info->next;
180 /* Record in LIVE that register REG died. */
182 static void
183 reg_dies (rtx reg, HARD_REG_SET *live)
185 int regno;
187 if (!REG_P (reg))
188 return;
190 regno = REGNO (reg);
191 if (regno < FIRST_PSEUDO_REGISTER)
192 remove_from_hard_reg_set (live, GET_MODE (reg), regno);
195 /* Record in LIVE that register REG became live.
196 This is called via note_stores. */
198 static void
199 reg_becomes_live (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *live)
201 int regno;
203 if (GET_CODE (reg) == SUBREG)
204 reg = SUBREG_REG (reg);
206 if (!REG_P (reg))
207 return;
209 regno = REGNO (reg);
210 if (regno < FIRST_PSEUDO_REGISTER)
211 add_to_hard_reg_set ((HARD_REG_SET *) live, GET_MODE (reg), regno);
214 /* Split the fallthrough edge to the exit block, so that we can note
215 that there NORMAL_MODE is required. Return the new block if it's
216 inserted before the exit block. Otherwise return null. */
218 static basic_block
219 create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
221 edge eg;
222 edge_iterator ei;
223 basic_block pre_exit;
225 /* The only non-call predecessor at this stage is a block with a
226 fallthrough edge; there can be at most one, but there could be
227 none at all, e.g. when exit is called. */
228 pre_exit = 0;
229 FOR_EACH_EDGE (eg, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
230 if (eg->flags & EDGE_FALLTHRU)
232 basic_block src_bb = eg->src;
233 rtx_insn *last_insn;
234 rtx ret_reg;
236 gcc_assert (!pre_exit);
237 /* If this function returns a value at the end, we have to
238 insert the final mode switch before the return value copy
239 to its hard register.
241 x86 targets use mode-switching infrastructure to
242 conditionally insert vzeroupper instruction at the exit
243 from the function where there is no need to switch the
244 mode before the return value copy. The vzeroupper insertion
245 pass runs after reload, so use !reload_completed as a stand-in
246 for x86 to skip the search for the return value copy insn.
248 N.b.: the code below assumes that the return copy insn
249 immediately precedes its corresponding use insn. This
250 assumption does not hold after reload, since sched1 pass
251 can schedule the return copy insn away from its
252 corresponding use insn. */
253 if (!reload_completed
254 && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == 1
255 && NONJUMP_INSN_P ((last_insn = BB_END (src_bb)))
256 && GET_CODE (PATTERN (last_insn)) == USE
257 && GET_CODE ((ret_reg = XEXP (PATTERN (last_insn), 0))) == REG)
259 auto_bitmap live;
260 df_simulate_initialize_backwards (src_bb, live);
262 int ret_start = REGNO (ret_reg);
263 int nregs = REG_NREGS (ret_reg);
264 int ret_end = ret_start + nregs;
265 bool short_block = false;
266 bool multi_reg_return = false;
267 bool forced_late_switch = false;
268 rtx_insn *before_return_copy;
270 df_simulate_one_insn_backwards (src_bb, last_insn, live);
274 rtx_insn *return_copy = PREV_INSN (last_insn);
275 rtx return_copy_pat, copy_reg;
276 int copy_start, copy_num;
277 int j;
279 df_simulate_one_insn_backwards (src_bb, return_copy, live);
281 if (NONDEBUG_INSN_P (return_copy))
283 /* When using SJLJ exceptions, the call to the
284 unregister function is inserted between the
285 clobber of the return value and the copy.
286 We do not want to split the block before this
287 or any other call; if we have not found the
288 copy yet, the copy must have been deleted. */
289 if (CALL_P (return_copy))
291 short_block = true;
292 break;
294 return_copy_pat = PATTERN (return_copy);
295 switch (GET_CODE (return_copy_pat))
297 case USE:
298 /* Skip USEs of multiple return registers.
299 __builtin_apply pattern is also handled here. */
300 if (GET_CODE (XEXP (return_copy_pat, 0)) == REG
301 && (targetm.calls.function_value_regno_p
302 (REGNO (XEXP (return_copy_pat, 0)))))
304 multi_reg_return = true;
305 last_insn = return_copy;
306 continue;
308 break;
310 case ASM_OPERANDS:
311 /* Skip barrier insns. */
312 if (!MEM_VOLATILE_P (return_copy_pat))
313 break;
315 /* Fall through. */
317 case ASM_INPUT:
318 case UNSPEC_VOLATILE:
319 last_insn = return_copy;
320 continue;
322 default:
323 break;
326 /* If the return register is not (in its entirety)
327 likely spilled, the return copy might be
328 partially or completely optimized away. */
329 return_copy_pat = single_set (return_copy);
330 if (!return_copy_pat)
332 return_copy_pat = PATTERN (return_copy);
333 if (GET_CODE (return_copy_pat) != CLOBBER)
334 break;
335 else if (!optimize)
337 /* This might be (clobber (reg [<result>]))
338 when not optimizing. Then check if
339 the previous insn is the clobber for
340 the return register. */
341 copy_reg = SET_DEST (return_copy_pat);
342 if (GET_CODE (copy_reg) == REG
343 && !HARD_REGISTER_NUM_P (REGNO (copy_reg)))
345 if (INSN_P (PREV_INSN (return_copy)))
347 return_copy = PREV_INSN (return_copy);
348 return_copy_pat = PATTERN (return_copy);
349 if (GET_CODE (return_copy_pat) != CLOBBER)
350 break;
355 copy_reg = SET_DEST (return_copy_pat);
356 if (GET_CODE (copy_reg) == REG)
357 copy_start = REGNO (copy_reg);
358 else if (GET_CODE (copy_reg) == SUBREG
359 && GET_CODE (SUBREG_REG (copy_reg)) == REG)
360 copy_start = REGNO (SUBREG_REG (copy_reg));
361 else
363 /* When control reaches end of non-void function,
364 there are no return copy insns at all. This
365 avoids an ice on that invalid function. */
366 if (ret_start + nregs == ret_end)
367 short_block = true;
368 break;
370 if (!targetm.calls.function_value_regno_p (copy_start))
371 copy_num = 0;
372 else
373 copy_num = hard_regno_nregs (copy_start,
374 GET_MODE (copy_reg));
376 /* If the return register is not likely spilled, - as is
377 the case for floating point on SH4 - then it might
378 be set by an arithmetic operation that needs a
379 different mode than the exit block. */
380 HARD_REG_SET hard_regs_live;
381 REG_SET_TO_HARD_REG_SET (hard_regs_live, live);
382 for (j = n_entities - 1; j >= 0; j--)
384 int e = entity_map[j];
385 int mode =
386 targetm.mode_switching.needed (e, return_copy,
387 hard_regs_live);
389 if (mode != num_modes[e]
390 && mode != targetm.mode_switching.exit (e))
391 break;
393 if (j >= 0)
395 /* __builtin_return emits a sequence of loads to all
396 return registers. One of them might require
397 another mode than MODE_EXIT, even if it is
398 unrelated to the return value, so we want to put
399 the final mode switch after it. */
400 if (multi_reg_return
401 && targetm.calls.function_value_regno_p
402 (copy_start))
403 forced_late_switch = true;
405 /* For the SH4, floating point loads depend on fpscr,
406 thus we might need to put the final mode switch
407 after the return value copy. That is still OK,
408 because a floating point return value does not
409 conflict with address reloads. */
410 if (copy_start >= ret_start
411 && copy_start + copy_num <= ret_end
412 && GET_CODE (return_copy_pat) == SET
413 && OBJECT_P (SET_SRC (return_copy_pat)))
414 forced_late_switch = true;
415 break;
417 if (copy_num == 0)
419 last_insn = return_copy;
420 continue;
423 if (copy_start >= ret_start
424 && copy_start + copy_num <= ret_end)
425 nregs -= copy_num;
426 else if (!multi_reg_return
427 || !targetm.calls.function_value_regno_p
428 (copy_start))
429 break;
430 last_insn = return_copy;
432 /* ??? Exception handling can lead to the return value
433 copy being already separated from the return value use,
434 as in unwind-dw2.c .
435 Similarly, conditionally returning without a value,
436 and conditionally using builtin_return can lead to an
437 isolated use. */
438 if (return_copy == BB_HEAD (src_bb))
440 short_block = true;
441 break;
443 last_insn = return_copy;
445 while (nregs);
447 /* If we didn't see a full return value copy, verify that there
448 is a plausible reason for this. If some, but not all of the
449 return register is likely spilled, we can expect that there
450 is a copy for the likely spilled part. */
451 gcc_assert (!nregs
452 || forced_late_switch
453 || short_block
454 || !(targetm.class_likely_spilled_p
455 (REGNO_REG_CLASS (ret_start)))
456 || nregs != REG_NREGS (ret_reg)
457 /* For multi-hard-register floating point
458 values, sometimes the likely-spilled part
459 is ordinarily copied first, then the other
460 part is set with an arithmetic operation.
461 This doesn't actually cause reload
462 failures, so let it pass. */
463 || (GET_MODE_CLASS (GET_MODE (ret_reg)) != MODE_INT
464 && nregs != 1));
466 if (!NOTE_INSN_BASIC_BLOCK_P (last_insn))
468 before_return_copy
469 = emit_note_before (NOTE_INSN_DELETED, last_insn);
470 /* Instructions preceding LAST_INSN in the same block might
471 require a different mode than MODE_EXIT, so if we might
472 have such instructions, keep them in a separate block
473 from pre_exit. */
474 src_bb = split_block (src_bb,
475 PREV_INSN (before_return_copy))->dest;
477 else
478 before_return_copy = last_insn;
479 pre_exit = split_block (src_bb, before_return_copy)->src;
481 else
483 pre_exit = split_edge (eg);
487 return pre_exit;
490 /* Return the confluence of modes MODE1 and MODE2 for entity ENTITY,
491 using NO_MODE to represent an unknown mode if nothing more precise
492 is available. */
495 mode_confluence (int entity, int mode1, int mode2, int no_mode)
497 if (mode1 == mode2)
498 return mode1;
500 if (mode1 != no_mode
501 && mode2 != no_mode
502 && targetm.mode_switching.confluence)
503 return targetm.mode_switching.confluence (entity, mode1, mode2);
505 return no_mode;
508 /* Information for the dataflow problems below. */
509 struct
511 /* Information about each basic block, indexed by block id. */
512 struct bb_info *bb_info;
514 /* A bitmap of blocks for which the current entity is transparent. */
515 sbitmap transp;
517 /* The entity that we're processing. */
518 int entity;
520 /* The number of modes defined for the entity, and thus the identifier
521 of the "don't know" mode. */
522 int no_mode;
523 } confluence_info;
525 /* Propagate information about any mode change on edge E to the
526 destination block's mode_in. Return true if something changed.
528 The mode_in and mode_out fields use no_mode + 1 to mean "not yet set". */
530 static bool
531 forward_confluence_n (edge e)
533 /* The entry and exit blocks have no useful mode information. */
534 if (e->src->index == ENTRY_BLOCK || e->dest->index == EXIT_BLOCK)
535 return false;
537 /* We don't control mode changes across abnormal edges. */
538 if (e->flags & EDGE_ABNORMAL)
539 return false;
541 /* E->aux is nonzero if we have computed the LCM problem and scheduled
542 E to change the mode to E->aux - 1. Otherwise model the change
543 from the source to the destination. */
544 struct bb_info *bb_info = confluence_info.bb_info;
545 int no_mode = confluence_info.no_mode;
546 int src_mode = bb_info[e->src->index].mode_out;
547 if (e->aux)
548 src_mode = (int) (intptr_t) e->aux - 1;
549 if (src_mode == no_mode + 1)
550 return false;
552 int dest_mode = bb_info[e->dest->index].mode_in;
553 if (dest_mode == no_mode + 1)
555 bb_info[e->dest->index].mode_in = src_mode;
556 return true;
559 int entity = confluence_info.entity;
560 int new_mode = mode_confluence (entity, src_mode, dest_mode, no_mode);
561 if (dest_mode == new_mode)
562 return false;
564 bb_info[e->dest->index].mode_in = new_mode;
565 return true;
568 /* Update block BB_INDEX's mode_out based on its mode_in. Return true if
569 something changed. */
571 static bool
572 forward_transfer (int bb_index)
574 /* The entry and exit blocks have no useful mode information. */
575 if (bb_index == ENTRY_BLOCK || bb_index == EXIT_BLOCK)
576 return false;
578 /* Only propagate through a block if the entity is transparent. */
579 struct bb_info *bb_info = confluence_info.bb_info;
580 if (bb_info[bb_index].computing != confluence_info.no_mode
581 || bb_info[bb_index].mode_out == bb_info[bb_index].mode_in)
582 return false;
584 bb_info[bb_index].mode_out = bb_info[bb_index].mode_in;
585 return true;
588 /* A backwards confluence function. Update the bb_info single_succ
589 field for E's source block, based on changes to E's destination block.
590 At the end of the dataflow problem, single_succ is the single mode
591 that all successors require (directly or indirectly), or no_mode
592 if there are conflicting requirements.
594 Initially, a value of no_mode + 1 means "don't know". */
596 static bool
597 single_succ_confluence_n (edge e)
599 /* The entry block has no associated mode information. */
600 if (e->src->index == ENTRY_BLOCK)
601 return false;
603 /* We don't control mode changes across abnormal edges. */
604 if (e->flags & EDGE_ABNORMAL)
605 return false;
607 /* Do nothing if we've already found a conflict. */
608 struct bb_info *bb_info = confluence_info.bb_info;
609 int no_mode = confluence_info.no_mode;
610 int src_mode = bb_info[e->src->index].single_succ;
611 if (src_mode == no_mode)
612 return false;
614 /* Work out what mode the destination block (or its successors) require. */
615 int dest_mode;
616 if (e->dest->index == EXIT_BLOCK)
617 dest_mode = no_mode;
618 else if (bitmap_bit_p (confluence_info.transp, e->dest->index))
619 dest_mode = bb_info[e->dest->index].single_succ;
620 else
621 dest_mode = bb_info[e->dest->index].seginfo->mode;
623 /* Do nothing if the destination block has no new information. */
624 if (dest_mode == no_mode + 1 || dest_mode == src_mode)
625 return false;
627 /* Detect conflicting modes. */
628 if (src_mode != no_mode + 1)
629 dest_mode = no_mode;
631 bb_info[e->src->index].single_succ = dest_mode;
632 return true;
635 /* A backward transfer function for computing the bb_info single_succ
636 fields, as described above single_succ_confluence. */
638 static bool
639 single_succ_transfer (int bb_index)
641 /* We don't have any field to transfer to. Assume that, after the
642 first iteration, we are only called if single_succ has changed.
643 We should then process incoming edges if the entity is transparent. */
644 return bitmap_bit_p (confluence_info.transp, bb_index);
647 /* Check whether the target wants to back-propagate a mode change across
648 edge E, and update the source block's computed mode if so. Return true
649 if something changed. */
651 static bool
652 backprop_confluence_n (edge e)
654 /* The entry and exit blocks have no useful mode information. */
655 if (e->src->index == ENTRY_BLOCK || e->dest->index == EXIT_BLOCK)
656 return false;
658 /* We don't control mode changes across abnormal edges. */
659 if (e->flags & EDGE_ABNORMAL)
660 return false;
662 /* We can only require a new mode in the source block if the entity
663 was originally transparent there. */
664 if (!bitmap_bit_p (confluence_info.transp, e->src->index))
665 return false;
667 /* Exit now if there is no required mode, or if all paths into the
668 source block leave the entity in the required mode. */
669 struct bb_info *bb_info = confluence_info.bb_info;
670 int no_mode = confluence_info.no_mode;
671 int src_mode = bb_info[e->src->index].mode_out;
672 int dest_mode = bb_info[e->dest->index].mode_in;
673 if (dest_mode == no_mode || src_mode == dest_mode)
674 return false;
676 /* See what the target thinks about this transition. */
677 int entity = confluence_info.entity;
678 int new_mode = targetm.mode_switching.backprop (entity, src_mode,
679 dest_mode);
680 if (new_mode == no_mode)
681 return false;
683 /* The target doesn't like the current transition, but would be happy
684 with a transition from NEW_MODE.
686 If we force the source block to use NEW_MODE, we might introduce a
687 double transition on at least one path through the function (one to
688 NEW_MODE and then one to DEST_MODE). Therefore, if all destination
689 blocks require the same mode, it is usually better to bring that
690 mode requirement forward.
692 If that isn't possible, merge the preference for this edge with
693 the preferences for other edges. no_mode + 1 indicates that there
694 was no previous preference. */
695 int old_mode = bb_info[e->src->index].computing;
696 if (bb_info[e->src->index].single_succ != no_mode)
697 new_mode = bb_info[e->src->index].single_succ;
698 else if (old_mode != no_mode + 1)
699 new_mode = mode_confluence (entity, old_mode, new_mode, no_mode);
701 if (old_mode == new_mode)
702 return false;
704 bb_info[e->src->index].computing = new_mode;
705 return true;
708 /* If the current entity was originally transparent in block BB_INDEX,
709 update the incoming mode to match the outgoing mode. Register a mode
710 change if the entity is no longer transparent.
712 Also, as an on-the-fly optimization, check whether the entity was
713 originally transparent in BB_INDEX and if all successor blocks require
714 the same mode. If so, anticipate the mode change in BB_INDEX if
715 doing it on the incoming edges would require no more mode changes than
716 doing it on the outgoing edges. The aim is to reduce the total number
717 of mode changes emitted for the function (and thus reduce code size and
718 cfg complexity) without increasing the number of mode changes on any
719 given path through the function. A typical case where it helps is:
727 where the entity is transparent in the T blocks and is required to have
728 mode M in the M blocks. If there are no redundancies leading up to this,
729 there will be two mutually-exclusive changes to mode M, one on each of
730 the T->M edges. The optimization instead converts it to:
732 T T M
733 / \ / \ / \
734 T M -> M M -> M M
735 \ / \ / \ /
736 M M M
738 which creates a single transition to M for both paths through the diamond.
740 Return true if something changed. */
742 static bool
743 backprop_transfer (int bb_index)
745 /* The entry and exit blocks have no useful mode information. */
746 if (bb_index == ENTRY_BLOCK || bb_index == EXIT_BLOCK)
747 return false;
749 /* We can only require a new mode if the entity was previously
750 transparent. */
751 if (!bitmap_bit_p (confluence_info.transp, bb_index))
752 return false;
754 struct bb_info *bb_info = confluence_info.bb_info;
755 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
756 int no_mode = confluence_info.no_mode;
757 int mode_in = bb_info[bb_index].mode_in;
758 int mode_out = bb_info[bb_index].computing;
759 if (mode_out == no_mode + 1)
761 /* The entity is still transparent for this block. See whether
762 all successor blocks need the same mode, either directly or
763 indirectly. */
764 mode_out = bb_info[bb_index].single_succ;
765 if (mode_out == no_mode)
766 return false;
768 /* Get a minimum bound on the number of transitions that would be
769 removed if BB itself required MODE_OUT. */
770 unsigned int moved = 0;
771 for (edge e : bb->succs)
772 if (e->dest->index != EXIT_BLOCK
773 && mode_out == bb_info[e->dest->index].seginfo->mode)
774 moved += 1;
776 /* See whether making the mode change on all incoming edges would
777 be no worse than making it on MOVED outgoing edges. */
778 if (moved < EDGE_COUNT (bb->preds))
779 return false;
781 bb_info[bb_index].mode_out = mode_out;
782 bb_info[bb_index].computing = mode_out;
784 else if (mode_out == mode_in)
785 return false;
787 bb_info[bb_index].mode_in = mode_out;
788 bb_info[bb_index].seginfo->mode = mode_out;
789 return true;
792 /* Find all insns that need a particular mode setting, and insert the
793 necessary mode switches. Return true if we did work. */
795 static int
796 optimize_mode_switching (void)
798 int e;
799 basic_block bb;
800 bool need_commit = false;
801 static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
802 #define N_ENTITIES ARRAY_SIZE (num_modes)
803 int entity_map[N_ENTITIES] = {};
804 struct bb_info *bb_info[N_ENTITIES] = {};
805 int i, j;
806 int n_entities = 0;
807 int max_num_modes = 0;
808 bool emitted ATTRIBUTE_UNUSED = false;
809 basic_block post_entry = 0;
810 basic_block pre_exit = 0;
811 struct edge_list *edge_list = 0;
813 /* These bitmaps are used for the LCM algorithm. */
814 sbitmap *kill, *del, *insert, *antic, *transp, *comp;
815 sbitmap *avin, *avout;
817 for (e = N_ENTITIES - 1; e >= 0; e--)
818 if (OPTIMIZE_MODE_SWITCHING (e))
820 int entry_exit_extra = 0;
822 /* Create the list of segments within each basic block.
823 If NORMAL_MODE is defined, allow for two extra
824 blocks split from the entry and exit block. */
825 if (targetm.mode_switching.entry && targetm.mode_switching.exit)
826 entry_exit_extra = 3;
828 bb_info[n_entities]
829 = XCNEWVEC (struct bb_info,
830 last_basic_block_for_fn (cfun) + entry_exit_extra);
831 entity_map[n_entities++] = e;
832 if (num_modes[e] > max_num_modes)
833 max_num_modes = num_modes[e];
836 if (! n_entities)
837 return 0;
839 /* Make sure if MODE_ENTRY is defined MODE_EXIT is defined. */
840 gcc_assert ((targetm.mode_switching.entry && targetm.mode_switching.exit)
841 || (!targetm.mode_switching.entry
842 && !targetm.mode_switching.exit));
844 if (targetm.mode_switching.entry && targetm.mode_switching.exit)
846 /* Split the edge from the entry block, so that we can note that
847 there NORMAL_MODE is supplied. */
848 post_entry = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
849 pre_exit = create_pre_exit (n_entities, entity_map, num_modes);
852 df_note_add_problem ();
853 df_analyze ();
855 /* Create the bitmap vectors. */
856 antic = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
857 n_entities * max_num_modes);
858 transp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
859 n_entities * max_num_modes);
860 comp = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
861 n_entities * max_num_modes);
862 avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
863 n_entities * max_num_modes);
864 avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
865 n_entities * max_num_modes);
866 kill = sbitmap_vector_alloc (last_basic_block_for_fn (cfun),
867 n_entities * max_num_modes);
869 bitmap_vector_ones (transp, last_basic_block_for_fn (cfun));
870 bitmap_vector_clear (antic, last_basic_block_for_fn (cfun));
871 bitmap_vector_clear (comp, last_basic_block_for_fn (cfun));
873 auto_sbitmap transp_all (last_basic_block_for_fn (cfun));
875 auto_bitmap blocks;
877 /* Forward-propagate mode information through blocks where the entity
878 is transparent, so that mode_in describes the mode on entry to each
879 block and mode_out describes the mode on exit from each block. */
880 auto forwprop_mode_info = [&](struct bb_info *info,
881 int entity, int no_mode)
883 /* Use no_mode + 1 to mean "not yet set". */
884 FOR_EACH_BB_FN (bb, cfun)
886 if (bb_has_abnormal_pred (bb))
887 info[bb->index].mode_in = info[bb->index].seginfo->mode;
888 else
889 info[bb->index].mode_in = no_mode + 1;
890 if (info[bb->index].computing != no_mode)
891 info[bb->index].mode_out = info[bb->index].computing;
892 else
893 info[bb->index].mode_out = no_mode + 1;
896 confluence_info.bb_info = info;
897 confluence_info.transp = nullptr;
898 confluence_info.entity = entity;
899 confluence_info.no_mode = no_mode;
901 bitmap_set_range (blocks, 0, last_basic_block_for_fn (cfun));
902 df_simple_dataflow (DF_FORWARD, NULL, NULL, forward_confluence_n,
903 forward_transfer, blocks,
904 df_get_postorder (DF_FORWARD),
905 df_get_n_blocks (DF_FORWARD));
909 if (targetm.mode_switching.backprop)
910 clear_aux_for_edges ();
912 for (j = n_entities - 1; j >= 0; j--)
914 int e = entity_map[j];
915 int no_mode = num_modes[e];
916 struct bb_info *info = bb_info[j];
917 rtx_insn *insn;
919 bitmap_ones (transp_all);
921 /* Determine what the first use (if any) need for a mode of entity E is.
922 This will be the mode that is anticipatable for this block.
923 Also compute the initial transparency settings. */
924 FOR_EACH_BB_FN (bb, cfun)
926 struct seginfo **tail_ptr = &info[bb->index].seginfo;
927 struct seginfo *ptr;
928 int last_mode = no_mode;
929 bool any_set_required = false;
930 HARD_REG_SET live_now;
932 info[bb->index].mode_out = info[bb->index].mode_in = no_mode;
934 REG_SET_TO_HARD_REG_SET (live_now, df_get_live_in (bb));
936 /* Pretend the mode is clobbered across abnormal edges. */
938 edge_iterator ei;
939 edge eg;
940 FOR_EACH_EDGE (eg, ei, bb->preds)
941 if (eg->flags & EDGE_COMPLEX)
942 break;
943 if (eg)
945 rtx_insn *ins_pos = BB_HEAD (bb);
946 if (LABEL_P (ins_pos))
947 ins_pos = NEXT_INSN (ins_pos);
948 gcc_assert (NOTE_INSN_BASIC_BLOCK_P (ins_pos));
949 if (ins_pos != BB_END (bb))
950 ins_pos = NEXT_INSN (ins_pos);
951 if (bb_has_eh_pred (bb)
952 && targetm.mode_switching.eh_handler)
953 last_mode = targetm.mode_switching.eh_handler (e);
954 ptr = new_seginfo (no_mode, last_mode, ins_pos, live_now);
955 add_seginfo (&tail_ptr, ptr);
956 bitmap_clear_bit (transp_all, bb->index);
960 FOR_BB_INSNS (bb, insn)
962 if (NONDEBUG_INSN_P (insn))
964 int mode = targetm.mode_switching.needed (e, insn, live_now);
965 rtx link;
967 if (mode != no_mode && mode != last_mode)
969 ptr = new_seginfo (last_mode, mode, insn, live_now);
970 add_seginfo (&tail_ptr, ptr);
971 bitmap_clear_bit (transp_all, bb->index);
972 any_set_required = true;
973 last_mode = mode;
976 /* Update LIVE_NOW. */
977 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
978 if (REG_NOTE_KIND (link) == REG_DEAD)
979 reg_dies (XEXP (link, 0), &live_now);
981 note_stores (insn, reg_becomes_live, &live_now);
982 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
983 if (REG_NOTE_KIND (link) == REG_UNUSED)
984 reg_dies (XEXP (link, 0), &live_now);
986 if (targetm.mode_switching.after)
987 last_mode = targetm.mode_switching.after (e, last_mode,
988 insn, live_now);
992 info[bb->index].computing = last_mode;
993 /* Check for blocks without ANY mode requirements.
994 N.B. because of MODE_AFTER, last_mode might still
995 be different from no_mode, in which case we need to
996 mark the block as nontransparent. */
997 if (!any_set_required)
999 ptr = new_seginfo (last_mode, no_mode, BB_END (bb), live_now);
1000 add_seginfo (&tail_ptr, ptr);
1001 if (last_mode != no_mode)
1002 bitmap_clear_bit (transp_all, bb->index);
1005 if (targetm.mode_switching.entry && targetm.mode_switching.exit)
1007 info[post_entry->index].mode_out =
1008 info[post_entry->index].mode_in = no_mode;
1010 int mode = targetm.mode_switching.entry (e);
1011 if (mode != no_mode)
1013 /* Insert a fake computing definition of MODE into entry
1014 blocks which compute no mode. This represents the mode on
1015 entry. */
1016 info[post_entry->index].computing = mode;
1017 bitmap_clear_bit (transp_all, post_entry->index);
1020 if (pre_exit)
1022 info[pre_exit->index].mode_out =
1023 info[pre_exit->index].mode_in = no_mode;
1025 int mode = targetm.mode_switching.exit (e);
1026 if (mode != no_mode)
1028 info[pre_exit->index].seginfo->mode = mode;
1029 bitmap_clear_bit (transp_all, pre_exit->index);
1034 /* If the target requests it, back-propagate selected mode requirements
1035 through transparent blocks. */
1036 if (targetm.mode_switching.backprop)
1038 /* First work out the mode on entry to and exit from each block. */
1039 forwprop_mode_info (info, e, no_mode);
1041 /* Compute the single_succ fields, as described above
1042 single_succ_confluence. */
1043 FOR_EACH_BB_FN (bb, cfun)
1044 info[bb->index].single_succ = no_mode + 1;
1046 confluence_info.transp = transp_all;
1047 bitmap_set_range (blocks, 0, last_basic_block_for_fn (cfun));
1048 df_simple_dataflow (DF_BACKWARD, NULL, NULL,
1049 single_succ_confluence_n,
1050 single_succ_transfer, blocks,
1051 df_get_postorder (DF_BACKWARD),
1052 df_get_n_blocks (DF_BACKWARD));
1054 FOR_EACH_BB_FN (bb, cfun)
1056 /* Repurpose mode_in as the first mode required by the block,
1057 or the output mode if none. */
1058 if (info[bb->index].seginfo->mode != no_mode)
1059 info[bb->index].mode_in = info[bb->index].seginfo->mode;
1061 /* In transparent blocks, use computing == no_mode + 1
1062 to indicate that no propagation has taken place. */
1063 if (info[bb->index].computing == no_mode)
1064 info[bb->index].computing = no_mode + 1;
1067 bitmap_set_range (blocks, 0, last_basic_block_for_fn (cfun));
1068 df_simple_dataflow (DF_BACKWARD, NULL, NULL, backprop_confluence_n,
1069 backprop_transfer, blocks,
1070 df_get_postorder (DF_BACKWARD),
1071 df_get_n_blocks (DF_BACKWARD));
1073 /* Any block that now computes a mode is no longer transparent. */
1074 FOR_EACH_BB_FN (bb, cfun)
1075 if (info[bb->index].computing == no_mode + 1)
1076 info[bb->index].computing = no_mode;
1077 else if (info[bb->index].computing != no_mode)
1078 bitmap_clear_bit (transp_all, bb->index);
1081 /* Set the anticipatable and computing arrays. */
1082 for (i = 0; i < no_mode; i++)
1084 int m = targetm.mode_switching.priority (entity_map[j], i);
1086 FOR_EACH_BB_FN (bb, cfun)
1088 if (!bitmap_bit_p (transp_all, bb->index))
1089 clear_mode_bit (transp[bb->index], j, m);
1091 if (info[bb->index].seginfo->mode == m)
1092 set_mode_bit (antic[bb->index], j, m);
1094 if (info[bb->index].computing == m)
1095 set_mode_bit (comp[bb->index], j, m);
1100 /* Calculate the optimal locations for the
1101 placement mode switches to modes with priority I. */
1103 FOR_EACH_BB_FN (bb, cfun)
1104 bitmap_not (kill[bb->index], transp[bb->index]);
1106 edge_list = pre_edge_lcm_avs (n_entities * max_num_modes, transp, comp, antic,
1107 kill, avin, avout, &insert, &del);
1109 auto_sbitmap jumping_blocks (last_basic_block_for_fn (cfun));
1110 bitmap_clear (jumping_blocks);
1111 for (j = n_entities - 1; j >= 0; j--)
1113 int no_mode = num_modes[entity_map[j]];
1114 struct bb_info *info = bb_info[j];
1116 /* Insert all mode sets that have been inserted by lcm. */
1118 for (int ed = NUM_EDGES (edge_list) - 1; ed >= 0; ed--)
1120 edge eg = INDEX_EDGE (edge_list, ed);
1122 eg->aux = (void *) (intptr_t) 0;
1124 for (i = 0; i < no_mode; i++)
1126 int m = targetm.mode_switching.priority (entity_map[j], i);
1127 if (mode_bit_p (insert[ed], j, m))
1129 eg->aux = (void *) (intptr_t) (m + 1);
1130 break;
1135 /* mode_in and mode_out can be calculated directly from avin and
1136 avout if all the modes are mutually exclusive. Use the target-
1137 provided confluence function otherwise. */
1138 if (targetm.mode_switching.confluence)
1139 forwprop_mode_info (info, entity_map[j], no_mode);
1141 FOR_EACH_BB_FN (bb, cfun)
1143 auto modes_confluence = [&](sbitmap *av)
1145 for (int i = 0; i < no_mode; ++i)
1146 if (mode_bit_p (av[bb->index], j, i))
1148 for (int i2 = i + 1; i2 < no_mode; ++i2)
1149 if (mode_bit_p (av[bb->index], j, i2))
1150 return no_mode;
1151 return i;
1153 return no_mode;
1156 /* intialize mode in/out availability for bb. */
1157 if (!targetm.mode_switching.confluence)
1159 info[bb->index].mode_out = modes_confluence (avout);
1160 info[bb->index].mode_in = modes_confluence (avin);
1163 for (i = 0; i < no_mode; i++)
1164 if (mode_bit_p (del[bb->index], j, i))
1165 info[bb->index].seginfo->mode = no_mode;
1167 /* See whether the target can perform the first transition.
1168 If not, push it onto the incoming edges. The earlier backprop
1169 pass should ensure that the resulting transitions are valid. */
1170 if (targetm.mode_switching.backprop)
1172 int from_mode = info[bb->index].mode_in;
1173 int to_mode = info[bb->index].seginfo->mode;
1174 if (targetm.mode_switching.backprop (entity_map[j], from_mode,
1175 to_mode) != no_mode)
1177 for (edge e : bb->preds)
1178 e->aux = (void *) (intptr_t) (to_mode + 1);
1179 info[bb->index].mode_in = to_mode;
1184 /* Now output the remaining mode sets in all the segments. */
1186 /* In case there was no mode inserted. the mode information on the edge
1187 might not be complete.
1188 Update mode info on edges and commit pending mode sets. */
1189 need_commit |= commit_mode_sets (edge_list, entity_map[j], bb_info[j]);
1191 /* Reset modes for next entity. */
1192 clear_aux_for_edges ();
1194 FOR_EACH_BB_FN (bb, cfun)
1196 struct seginfo *ptr, *next;
1197 struct seginfo *first = bb_info[j][bb->index].seginfo;
1199 for (ptr = first; ptr; ptr = next)
1201 next = ptr->next;
1202 if (ptr->mode != no_mode)
1204 rtx_insn *mode_set;
1206 rtl_profile_for_bb (bb);
1207 start_sequence ();
1209 int cur_mode = (ptr == first && ptr->prev_mode == no_mode
1210 ? bb_info[j][bb->index].mode_in
1211 : ptr->prev_mode);
1213 targetm.mode_switching.emit (entity_map[j], ptr->mode,
1214 cur_mode, ptr->regs_live);
1215 mode_set = get_insns ();
1216 end_sequence ();
1218 /* Insert MODE_SET only if it is nonempty. */
1219 if (mode_set != NULL_RTX)
1221 for (auto insn = mode_set; insn; insn = NEXT_INSN (insn))
1222 if (JUMP_P (insn))
1224 rebuild_jump_labels_chain (mode_set);
1225 bitmap_set_bit (jumping_blocks, bb->index);
1226 break;
1228 emitted = true;
1229 if (NOTE_INSN_BASIC_BLOCK_P (ptr->insn_ptr))
1230 /* We need to emit the insns in a FIFO-like manner,
1231 i.e. the first to be emitted at our insertion
1232 point ends up first in the instruction steam.
1233 Because we made sure that NOTE_INSN_BASIC_BLOCK is
1234 only used for initially empty basic blocks, we
1235 can achieve this by appending at the end of
1236 the block. */
1237 emit_insn_after
1238 (mode_set, BB_END (NOTE_BASIC_BLOCK (ptr->insn_ptr)));
1239 else
1240 emit_insn_before (mode_set, ptr->insn_ptr);
1243 default_rtl_profile ();
1246 free (ptr);
1250 free (bb_info[j]);
1253 free_edge_list (edge_list);
1255 /* Finished. Free up all the things we've allocated. */
1256 sbitmap_vector_free (del);
1257 sbitmap_vector_free (insert);
1258 sbitmap_vector_free (kill);
1259 sbitmap_vector_free (antic);
1260 sbitmap_vector_free (transp);
1261 sbitmap_vector_free (comp);
1262 sbitmap_vector_free (avin);
1263 sbitmap_vector_free (avout);
1265 gcc_assert (SBITMAP_SIZE ((sbitmap) jumping_blocks)
1266 == (unsigned int) last_basic_block_for_fn (cfun));
1267 if (!bitmap_empty_p (jumping_blocks))
1268 find_many_sub_basic_blocks (jumping_blocks);
1270 if (need_commit)
1271 commit_edge_insertions ();
1273 if (targetm.mode_switching.entry && targetm.mode_switching.exit)
1275 free_dominance_info (CDI_DOMINATORS);
1276 cleanup_cfg (CLEANUP_NO_INSN_DEL);
1278 else if (!need_commit && !emitted)
1279 return 0;
1281 return 1;
1284 #endif /* OPTIMIZE_MODE_SWITCHING */
1286 namespace {
1288 const pass_data pass_data_mode_switching =
1290 RTL_PASS, /* type */
1291 "mode_sw", /* name */
1292 OPTGROUP_NONE, /* optinfo_flags */
1293 TV_MODE_SWITCH, /* tv_id */
1294 0, /* properties_required */
1295 0, /* properties_provided */
1296 0, /* properties_destroyed */
1297 0, /* todo_flags_start */
1298 TODO_df_finish, /* todo_flags_finish */
1301 class pass_mode_switching : public rtl_opt_pass
1303 public:
1304 pass_mode_switching (gcc::context *ctxt)
1305 : rtl_opt_pass (pass_data_mode_switching, ctxt)
1308 /* opt_pass methods: */
1309 /* The epiphany backend creates a second instance of this pass, so we need
1310 a clone method. */
1311 opt_pass * clone () final override { return new pass_mode_switching (m_ctxt); }
1312 bool gate (function *) final override
1314 #ifdef OPTIMIZE_MODE_SWITCHING
1315 return true;
1316 #else
1317 return false;
1318 #endif
1321 unsigned int execute (function *) final override
1323 #ifdef OPTIMIZE_MODE_SWITCHING
1324 optimize_mode_switching ();
1325 #endif /* OPTIMIZE_MODE_SWITCHING */
1326 return 0;
1329 }; // class pass_mode_switching
1331 } // anon namespace
1333 rtl_opt_pass *
1334 make_pass_mode_switching (gcc::context *ctxt)
1336 return new pass_mode_switching (ctxt);