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
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
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"
35 #include "cfgcleanup.h"
36 #include "tree-pass.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. */
76 HARD_REG_SET regs_live
;
81 struct seginfo
*seginfo
;
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. */
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
);
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
;
120 REG_SET_TO_HARD_REG_SET (live_at_edge
, df_get_live_out (src_bb
));
122 rtl_profile_for_edge (eg
);
125 targetm
.mode_switching
.emit (e
, mode
, cur_mode
, live_at_edge
);
127 mode_set
= get_insns ();
129 default_rtl_profile ();
131 /* Do not bother to insert empty sequence. */
132 if (mode_set
== NULL
)
135 /* We should not get an abnormal edge here. */
136 gcc_assert (! (eg
->flags
& EDGE_ABNORMAL
));
139 insert_insn_on_edge (mode_set
, eg
);
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
152 static struct seginfo
*
153 new_seginfo (int prev_mode
, int mode
, rtx_insn
*insn
,
154 const HARD_REG_SET
®s_live
)
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
;
163 ptr
->insn_ptr
= insn
;
165 ptr
->regs_live
= regs_live
;
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. */
174 add_seginfo (struct seginfo
***tail_ptr
, struct seginfo
*info
)
177 *tail_ptr
= &info
->next
;
180 /* Record in LIVE that register REG died. */
183 reg_dies (rtx reg
, HARD_REG_SET
*live
)
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. */
199 reg_becomes_live (rtx reg
, const_rtx setter ATTRIBUTE_UNUSED
, void *live
)
203 if (GET_CODE (reg
) == SUBREG
)
204 reg
= SUBREG_REG (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. */
219 create_pre_exit (int n_entities
, int *entity_map
, const int *num_modes
)
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. */
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
;
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
)
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
;
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
))
294 return_copy_pat
= PATTERN (return_copy
);
295 switch (GET_CODE (return_copy_pat
))
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
;
311 /* Skip barrier insns. */
312 if (!MEM_VOLATILE_P (return_copy_pat
))
318 case UNSPEC_VOLATILE
:
319 last_insn
= return_copy
;
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
)
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
)
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
));
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
)
370 if (!targetm
.calls
.function_value_regno_p (copy_start
))
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
];
386 targetm
.mode_switching
.needed (e
, return_copy
,
389 if (mode
!= num_modes
[e
]
390 && mode
!= targetm
.mode_switching
.exit (e
))
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. */
401 && targetm
.calls
.function_value_regno_p
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;
419 last_insn
= return_copy
;
423 if (copy_start
>= ret_start
424 && copy_start
+ copy_num
<= ret_end
)
426 else if (!multi_reg_return
427 || !targetm
.calls
.function_value_regno_p
430 last_insn
= return_copy
;
432 /* ??? Exception handling can lead to the return value
433 copy being already separated from the return value use,
435 Similarly, conditionally returning without a value,
436 and conditionally using builtin_return can lead to an
438 if (return_copy
== BB_HEAD (src_bb
))
443 last_insn
= return_copy
;
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. */
452 || forced_late_switch
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
466 if (!NOTE_INSN_BASIC_BLOCK_P (last_insn
))
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
474 src_bb
= split_block (src_bb
,
475 PREV_INSN (before_return_copy
))->dest
;
478 before_return_copy
= last_insn
;
479 pre_exit
= split_block (src_bb
, before_return_copy
)->src
;
483 pre_exit
= split_edge (eg
);
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
495 mode_confluence (int entity
, int mode1
, int mode2
, int no_mode
)
502 && targetm
.mode_switching
.confluence
)
503 return targetm
.mode_switching
.confluence (entity
, mode1
, mode2
);
508 /* Information for the dataflow problems below. */
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. */
517 /* The entity that we're processing. */
520 /* The number of modes defined for the entity, and thus the identifier
521 of the "don't know" mode. */
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". */
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
)
537 /* We don't control mode changes across abnormal edges. */
538 if (e
->flags
& EDGE_ABNORMAL
)
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
;
548 src_mode
= (int) (intptr_t) e
->aux
- 1;
549 if (src_mode
== no_mode
+ 1)
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
;
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
)
564 bb_info
[e
->dest
->index
].mode_in
= new_mode
;
568 /* Update block BB_INDEX's mode_out based on its mode_in. Return true if
569 something changed. */
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
)
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
)
584 bb_info
[bb_index
].mode_out
= bb_info
[bb_index
].mode_in
;
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". */
597 single_succ_confluence_n (edge e
)
599 /* The entry block has no associated mode information. */
600 if (e
->src
->index
== ENTRY_BLOCK
)
603 /* We don't control mode changes across abnormal edges. */
604 if (e
->flags
& EDGE_ABNORMAL
)
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
)
614 /* Work out what mode the destination block (or its successors) require. */
616 if (e
->dest
->index
== EXIT_BLOCK
)
618 else if (bitmap_bit_p (confluence_info
.transp
, e
->dest
->index
))
619 dest_mode
= bb_info
[e
->dest
->index
].single_succ
;
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
)
627 /* Detect conflicting modes. */
628 if (src_mode
!= no_mode
+ 1)
631 bb_info
[e
->src
->index
].single_succ
= dest_mode
;
635 /* A backward transfer function for computing the bb_info single_succ
636 fields, as described above single_succ_confluence. */
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. */
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
)
658 /* We don't control mode changes across abnormal edges. */
659 if (e
->flags
& EDGE_ABNORMAL
)
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
))
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
)
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
,
680 if (new_mode
== no_mode
)
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
)
704 bb_info
[e
->src
->index
].computing
= new_mode
;
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:
738 which creates a single transition to M for both paths through the diamond.
740 Return true if something changed. */
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
)
749 /* We can only require a new mode if the entity was previously
751 if (!bitmap_bit_p (confluence_info
.transp
, bb_index
))
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
764 mode_out
= bb_info
[bb_index
].single_succ
;
765 if (mode_out
== no_mode
)
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
)
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
))
781 bb_info
[bb_index
].mode_out
= mode_out
;
782 bb_info
[bb_index
].computing
= mode_out
;
784 else if (mode_out
== mode_in
)
787 bb_info
[bb_index
].mode_in
= mode_out
;
788 bb_info
[bb_index
].seginfo
->mode
= mode_out
;
792 /* Find all insns that need a particular mode setting, and insert the
793 necessary mode switches. Return true if we did work. */
796 optimize_mode_switching (void)
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
] = {};
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;
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
];
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 ();
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
));
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
;
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
;
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
];
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
;
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. */
940 FOR_EACH_EDGE (eg
, ei
, bb
->preds
)
941 if (eg
->flags
& EDGE_COMPLEX
)
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
);
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;
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
,
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
1016 info
[post_entry
->index
].computing
= mode
;
1017 bitmap_clear_bit (transp_all
, post_entry
->index
);
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);
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
))
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
)
1202 if (ptr
->mode
!= no_mode
)
1206 rtl_profile_for_bb (bb
);
1209 int cur_mode
= (ptr
== first
&& ptr
->prev_mode
== no_mode
1210 ? bb_info
[j
][bb
->index
].mode_in
1213 targetm
.mode_switching
.emit (entity_map
[j
], ptr
->mode
,
1214 cur_mode
, ptr
->regs_live
);
1215 mode_set
= get_insns ();
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
))
1224 rebuild_jump_labels_chain (mode_set
);
1225 bitmap_set_bit (jumping_blocks
, bb
->index
);
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
1238 (mode_set
, BB_END (NOTE_BASIC_BLOCK (ptr
->insn_ptr
)));
1240 emit_insn_before (mode_set
, ptr
->insn_ptr
);
1243 default_rtl_profile ();
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
);
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
)
1284 #endif /* OPTIMIZE_MODE_SWITCHING */
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
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
1311 opt_pass
* clone () final override
{ return new pass_mode_switching (m_ctxt
); }
1312 bool gate (function
*) final override
1314 #ifdef OPTIMIZE_MODE_SWITCHING
1321 unsigned int execute (function
*) final override
1323 #ifdef OPTIMIZE_MODE_SWITCHING
1324 optimize_mode_switching ();
1325 #endif /* OPTIMIZE_MODE_SWITCHING */
1329 }; // class pass_mode_switching
1334 make_pass_mode_switching (gcc::context
*ctxt
)
1336 return new pass_mode_switching (ctxt
);