1 /* If-conversion support.
2 Copyright (C) 2000-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
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
39 #include "cfgcleanup.h"
43 #include "tree-pass.h"
45 #include "shrink-wrap.h"
49 #ifndef MAX_CONDITIONAL_EXECUTE
50 #define MAX_CONDITIONAL_EXECUTE \
51 (BRANCH_COST (optimize_function_for_speed_p (cfun), false) \
55 #define IFCVT_MULTIPLE_DUMPS 1
57 #define NULL_BLOCK ((basic_block) NULL)
59 /* True if after combine pass. */
60 static bool ifcvt_after_combine
;
62 /* True if the target has the cbranchcc4 optab. */
63 static bool have_cbranchcc4
;
65 /* # of IF-THEN or IF-THEN-ELSE blocks we looked at */
66 static int num_possible_if_blocks
;
68 /* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
70 static int num_updated_if_blocks
;
72 /* # of changes made. */
73 static int num_true_changes
;
75 /* Whether conditional execution changes were made. */
76 static bool cond_exec_changed_p
;
78 /* Forward references. */
79 static int count_bb_insns (const_basic_block
);
80 static bool cheap_bb_rtx_cost_p (const_basic_block
, profile_probability
, int);
81 static rtx_insn
*first_active_insn (basic_block
);
82 static rtx_insn
*last_active_insn (basic_block
, bool);
83 static rtx_insn
*find_active_insn_before (basic_block
, rtx_insn
*);
84 static rtx_insn
*find_active_insn_after (basic_block
, rtx_insn
*);
85 static basic_block
block_fallthru (basic_block
);
86 static rtx
cond_exec_get_condition (rtx_insn
*, bool);
87 static rtx
noce_get_condition (rtx_insn
*, rtx_insn
**, bool);
88 static bool noce_operand_ok (const_rtx
);
89 static void merge_if_block (ce_if_block
*);
90 static bool find_cond_trap (basic_block
, edge
, edge
);
91 static basic_block
find_if_header (basic_block
, int);
92 static int block_jumps_and_fallthru (basic_block
, basic_block
);
93 static bool noce_find_if_block (basic_block
, edge
, edge
, int);
94 static bool cond_exec_find_if_block (ce_if_block
*);
95 static bool find_if_case_1 (basic_block
, edge
, edge
);
96 static bool find_if_case_2 (basic_block
, edge
, edge
);
97 static bool dead_or_predicable (basic_block
, basic_block
, basic_block
,
99 static void noce_emit_move_insn (rtx
, rtx
);
100 static rtx_insn
*block_has_only_trap (basic_block
);
101 static void init_noce_multiple_sets_info (basic_block
,
102 auto_delete_vec
<noce_multiple_sets_info
> &);
103 static bool noce_convert_multiple_sets_1 (struct noce_if_info
*,
104 auto_delete_vec
<noce_multiple_sets_info
> &, int *);
106 /* Count the number of non-jump active insns in BB. */
109 count_bb_insns (const_basic_block bb
)
112 rtx_insn
*insn
= BB_HEAD (bb
);
116 if (active_insn_p (insn
) && !JUMP_P (insn
))
119 if (insn
== BB_END (bb
))
121 insn
= NEXT_INSN (insn
);
127 /* Determine whether the total insn_cost on non-jump insns in
128 basic block BB is less than MAX_COST. This function returns
129 false if the cost of any instruction could not be estimated.
131 The cost of the non-jump insns in BB is scaled by REG_BR_PROB_BASE
132 as those insns are being speculated. MAX_COST is scaled with SCALE
133 plus a small fudge factor. */
136 cheap_bb_rtx_cost_p (const_basic_block bb
,
137 profile_probability prob
, int max_cost
)
140 rtx_insn
*insn
= BB_HEAD (bb
);
141 bool speed
= optimize_bb_for_speed_p (bb
);
142 int scale
= prob
.initialized_p () ? prob
.to_reg_br_prob_base ()
145 /* Set scale to REG_BR_PROB_BASE to void the identical scaling
146 applied to insn_cost when optimizing for size. Only do
147 this after combine because if-conversion might interfere with
148 passes before combine.
150 Use optimize_function_for_speed_p instead of the pre-defined
151 variable speed to make sure it is set to same value for all
152 basic blocks in one if-conversion transformation. */
153 if (!optimize_function_for_speed_p (cfun
) && ifcvt_after_combine
)
154 scale
= REG_BR_PROB_BASE
;
155 /* Our branch probability/scaling factors are just estimates and don't
156 account for cases where we can get speculation for free and other
157 secondary benefits. So we fudge the scale factor to make speculating
158 appear a little more profitable when optimizing for performance. */
160 scale
+= REG_BR_PROB_BASE
/ 8;
167 if (NONJUMP_INSN_P (insn
))
169 int cost
= insn_cost (insn
, speed
) * REG_BR_PROB_BASE
;
173 /* If this instruction is the load or set of a "stack" register,
174 such as a floating point register on x87, then the cost of
175 speculatively executing this insn may need to include
176 the additional cost of popping its result off of the
177 register stack. Unfortunately, correctly recognizing and
178 accounting for this additional overhead is tricky, so for
179 now we simply prohibit such speculative execution. */
182 rtx set
= single_set (insn
);
183 if (set
&& STACK_REG_P (SET_DEST (set
)))
189 if (count
>= max_cost
)
192 else if (CALL_P (insn
))
195 if (insn
== BB_END (bb
))
197 insn
= NEXT_INSN (insn
);
203 /* Return the first non-jump active insn in the basic block. */
206 first_active_insn (basic_block bb
)
208 rtx_insn
*insn
= BB_HEAD (bb
);
212 if (insn
== BB_END (bb
))
214 insn
= NEXT_INSN (insn
);
217 while (NOTE_P (insn
) || DEBUG_INSN_P (insn
))
219 if (insn
== BB_END (bb
))
221 insn
= NEXT_INSN (insn
);
230 /* Return the last non-jump active (non-jump) insn in the basic block. */
233 last_active_insn (basic_block bb
, bool skip_use_p
)
235 rtx_insn
*insn
= BB_END (bb
);
236 rtx_insn
*head
= BB_HEAD (bb
);
240 || DEBUG_INSN_P (insn
)
242 && NONJUMP_INSN_P (insn
)
243 && GET_CODE (PATTERN (insn
)) == USE
))
247 insn
= PREV_INSN (insn
);
256 /* Return the active insn before INSN inside basic block CURR_BB. */
259 find_active_insn_before (basic_block curr_bb
, rtx_insn
*insn
)
261 if (!insn
|| insn
== BB_HEAD (curr_bb
))
264 while ((insn
= PREV_INSN (insn
)) != NULL_RTX
)
266 if (NONJUMP_INSN_P (insn
) || JUMP_P (insn
) || CALL_P (insn
))
269 /* No other active insn all the way to the start of the basic block. */
270 if (insn
== BB_HEAD (curr_bb
))
277 /* Return the active insn after INSN inside basic block CURR_BB. */
280 find_active_insn_after (basic_block curr_bb
, rtx_insn
*insn
)
282 if (!insn
|| insn
== BB_END (curr_bb
))
285 while ((insn
= NEXT_INSN (insn
)) != NULL_RTX
)
287 if (NONJUMP_INSN_P (insn
) || JUMP_P (insn
) || CALL_P (insn
))
290 /* No other active insn all the way to the end of the basic block. */
291 if (insn
== BB_END (curr_bb
))
298 /* Return the basic block reached by falling though the basic block BB. */
301 block_fallthru (basic_block bb
)
303 edge e
= find_fallthru_edge (bb
->succs
);
305 return (e
) ? e
->dest
: NULL_BLOCK
;
308 /* Return true if RTXs A and B can be safely interchanged. */
311 rtx_interchangeable_p (const_rtx a
, const_rtx b
)
313 if (!rtx_equal_p (a
, b
))
316 if (GET_CODE (a
) != MEM
)
319 /* A dead type-unsafe memory reference is legal, but a live type-unsafe memory
320 reference is not. Interchanging a dead type-unsafe memory reference with
321 a live type-safe one creates a live type-unsafe memory reference, in other
322 words, it makes the program illegal.
323 We check here conservatively whether the two memory references have equal
324 memory attributes. */
326 return mem_attrs_eq_p (get_mem_attrs (a
), get_mem_attrs (b
));
330 /* Go through a bunch of insns, converting them to conditional
331 execution format if possible. Return TRUE if all of the non-note
332 insns were processed. */
335 cond_exec_process_insns (ce_if_block
*ce_info ATTRIBUTE_UNUSED
,
336 /* if block information */rtx_insn
*start
,
337 /* first insn to look at */rtx end
,
338 /* last insn to look at */rtx test
,
339 /* conditional execution test */profile_probability
341 /* probability of branch taken. */bool mod_ok
)
343 bool must_be_last
= false;
351 for (insn
= start
; ; insn
= NEXT_INSN (insn
))
353 /* dwarf2out can't cope with conditional prologues. */
354 if (NOTE_P (insn
) && NOTE_KIND (insn
) == NOTE_INSN_PROLOGUE_END
)
357 if (NOTE_P (insn
) || DEBUG_INSN_P (insn
))
360 gcc_assert (NONJUMP_INSN_P (insn
) || CALL_P (insn
));
362 /* dwarf2out can't cope with conditional unwind info. */
363 if (RTX_FRAME_RELATED_P (insn
))
366 /* Remove USE insns that get in the way. */
367 if (reload_completed
&& GET_CODE (PATTERN (insn
)) == USE
)
369 /* ??? Ug. Actually unlinking the thing is problematic,
370 given what we'd have to coordinate with our callers. */
371 SET_INSN_DELETED (insn
);
375 /* Last insn wasn't last? */
379 if (modified_in_p (test
, insn
))
386 /* Now build the conditional form of the instruction. */
387 pattern
= PATTERN (insn
);
388 xtest
= copy_rtx (test
);
390 /* If this is already a COND_EXEC, rewrite the test to be an AND of the
392 if (GET_CODE (pattern
) == COND_EXEC
)
394 if (GET_MODE (xtest
) != GET_MODE (COND_EXEC_TEST (pattern
)))
397 xtest
= gen_rtx_AND (GET_MODE (xtest
), xtest
,
398 COND_EXEC_TEST (pattern
));
399 pattern
= COND_EXEC_CODE (pattern
);
402 pattern
= gen_rtx_COND_EXEC (VOIDmode
, xtest
, pattern
);
404 /* If the machine needs to modify the insn being conditionally executed,
405 say for example to force a constant integer operand into a temp
406 register, do so here. */
407 #ifdef IFCVT_MODIFY_INSN
408 IFCVT_MODIFY_INSN (ce_info
, pattern
, insn
);
413 validate_change (insn
, &PATTERN (insn
), pattern
, 1);
415 if (CALL_P (insn
) && prob_val
.initialized_p ())
416 validate_change (insn
, ®_NOTES (insn
),
417 gen_rtx_INT_LIST ((machine_mode
) REG_BR_PROB
,
418 prob_val
.to_reg_br_prob_note (),
419 REG_NOTES (insn
)), 1);
429 /* Return the condition for a jump. Do not do any special processing. */
432 cond_exec_get_condition (rtx_insn
*jump
, bool get_reversed
= false)
436 if (any_condjump_p (jump
))
437 test_if
= SET_SRC (pc_set (jump
));
440 cond
= XEXP (test_if
, 0);
442 /* If this branches to JUMP_LABEL when the condition is false,
443 reverse the condition. */
445 || (GET_CODE (XEXP (test_if
, 2)) == LABEL_REF
446 && label_ref_label (XEXP (test_if
, 2))
447 == JUMP_LABEL (jump
)))
449 enum rtx_code rev
= reversed_comparison_code (cond
, jump
);
453 cond
= gen_rtx_fmt_ee (rev
, GET_MODE (cond
), XEXP (cond
, 0),
460 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
461 to conditional execution. Return TRUE if we were successful at
462 converting the block. */
465 cond_exec_process_if_block (ce_if_block
* ce_info
,
466 /* if block information */bool do_multiple_p
)
468 basic_block test_bb
= ce_info
->test_bb
; /* last test block */
469 basic_block then_bb
= ce_info
->then_bb
; /* THEN */
470 basic_block else_bb
= ce_info
->else_bb
; /* ELSE or NULL */
471 rtx test_expr
; /* expression in IF_THEN_ELSE that is tested */
472 rtx_insn
*then_start
; /* first insn in THEN block */
473 rtx_insn
*then_end
; /* last insn + 1 in THEN block */
474 rtx_insn
*else_start
= NULL
; /* first insn in ELSE block or NULL */
475 rtx_insn
*else_end
= NULL
; /* last insn + 1 in ELSE block */
476 int max
; /* max # of insns to convert. */
477 bool then_mod_ok
; /* whether conditional mods are ok in THEN */
478 rtx true_expr
; /* test for else block insns */
479 rtx false_expr
; /* test for then block insns */
480 profile_probability true_prob_val
;/* probability of else block */
481 profile_probability false_prob_val
;/* probability of then block */
482 rtx_insn
*then_last_head
= NULL
; /* Last match at the head of THEN */
483 rtx_insn
*else_last_head
= NULL
; /* Last match at the head of ELSE */
484 rtx_insn
*then_first_tail
= NULL
; /* First match at the tail of THEN */
485 rtx_insn
*else_first_tail
= NULL
; /* First match at the tail of ELSE */
486 int then_n_insns
, else_n_insns
, n_insns
;
487 enum rtx_code false_code
;
490 /* If test is comprised of && or || elements, and we've failed at handling
491 all of them together, just use the last test if it is the special case of
492 && elements without an ELSE block. */
493 if (!do_multiple_p
&& ce_info
->num_multiple_test_blocks
)
495 if (else_bb
|| ! ce_info
->and_and_p
)
498 ce_info
->test_bb
= test_bb
= ce_info
->last_test_bb
;
499 ce_info
->num_multiple_test_blocks
= 0;
500 ce_info
->num_and_and_blocks
= 0;
501 ce_info
->num_or_or_blocks
= 0;
504 /* Find the conditional jump to the ELSE or JOIN part, and isolate
506 test_expr
= cond_exec_get_condition (BB_END (test_bb
));
510 /* If the conditional jump is more than just a conditional jump,
511 then we cannot do conditional execution conversion on this block. */
512 if (! onlyjump_p (BB_END (test_bb
)))
515 /* Collect the bounds of where we're to search, skipping any labels, jumps
516 and notes at the beginning and end of the block. Then count the total
517 number of insns and see if it is small enough to convert. */
518 then_start
= first_active_insn (then_bb
);
519 then_end
= last_active_insn (then_bb
, true);
520 then_n_insns
= ce_info
->num_then_insns
= count_bb_insns (then_bb
);
521 n_insns
= then_n_insns
;
522 max
= MAX_CONDITIONAL_EXECUTE
;
529 else_start
= first_active_insn (else_bb
);
530 else_end
= last_active_insn (else_bb
, true);
531 else_n_insns
= ce_info
->num_else_insns
= count_bb_insns (else_bb
);
532 n_insns
+= else_n_insns
;
534 /* Look for matching sequences at the head and tail of the two blocks,
535 and limit the range of insns to be converted if possible. */
536 n_matching
= flow_find_cross_jump (then_bb
, else_bb
,
537 &then_first_tail
, &else_first_tail
,
539 if (then_first_tail
== BB_HEAD (then_bb
))
540 then_start
= then_end
= NULL
;
541 if (else_first_tail
== BB_HEAD (else_bb
))
542 else_start
= else_end
= NULL
;
547 then_end
= find_active_insn_before (then_bb
, then_first_tail
);
549 else_end
= find_active_insn_before (else_bb
, else_first_tail
);
550 n_insns
-= 2 * n_matching
;
555 && then_n_insns
> n_matching
556 && else_n_insns
> n_matching
)
558 int longest_match
= MIN (then_n_insns
- n_matching
,
559 else_n_insns
- n_matching
);
561 = flow_find_head_matching_sequence (then_bb
, else_bb
,
570 /* We won't pass the insns in the head sequence to
571 cond_exec_process_insns, so we need to test them here
572 to make sure that they don't clobber the condition. */
573 for (insn
= BB_HEAD (then_bb
);
574 insn
!= NEXT_INSN (then_last_head
);
575 insn
= NEXT_INSN (insn
))
576 if (!LABEL_P (insn
) && !NOTE_P (insn
)
577 && !DEBUG_INSN_P (insn
)
578 && modified_in_p (test_expr
, insn
))
582 if (then_last_head
== then_end
)
583 then_start
= then_end
= NULL
;
584 if (else_last_head
== else_end
)
585 else_start
= else_end
= NULL
;
590 then_start
= find_active_insn_after (then_bb
, then_last_head
);
592 else_start
= find_active_insn_after (else_bb
, else_last_head
);
593 n_insns
-= 2 * n_matching
;
601 /* Map test_expr/test_jump into the appropriate MD tests to use on
602 the conditionally executed code. */
604 true_expr
= test_expr
;
606 false_code
= reversed_comparison_code (true_expr
, BB_END (test_bb
));
607 if (false_code
!= UNKNOWN
)
608 false_expr
= gen_rtx_fmt_ee (false_code
, GET_MODE (true_expr
),
609 XEXP (true_expr
, 0), XEXP (true_expr
, 1));
611 false_expr
= NULL_RTX
;
613 #ifdef IFCVT_MODIFY_TESTS
614 /* If the machine description needs to modify the tests, such as setting a
615 conditional execution register from a comparison, it can do so here. */
616 IFCVT_MODIFY_TESTS (ce_info
, true_expr
, false_expr
);
618 /* See if the conversion failed. */
619 if (!true_expr
|| !false_expr
)
623 note
= find_reg_note (BB_END (test_bb
), REG_BR_PROB
, NULL_RTX
);
626 true_prob_val
= profile_probability::from_reg_br_prob_note (XINT (note
, 0));
627 false_prob_val
= true_prob_val
.invert ();
631 true_prob_val
= profile_probability::uninitialized ();
632 false_prob_val
= profile_probability::uninitialized ();
635 /* If we have && or || tests, do them here. These tests are in the adjacent
636 blocks after the first block containing the test. */
637 if (ce_info
->num_multiple_test_blocks
> 0)
639 basic_block bb
= test_bb
;
640 basic_block last_test_bb
= ce_info
->last_test_bb
;
647 rtx_insn
*start
, *end
;
649 enum rtx_code f_code
;
651 bb
= block_fallthru (bb
);
652 start
= first_active_insn (bb
);
653 end
= last_active_insn (bb
, true);
655 && ! cond_exec_process_insns (ce_info
, start
, end
, false_expr
,
656 false_prob_val
, false))
659 /* If the conditional jump is more than just a conditional jump, then
660 we cannot do conditional execution conversion on this block. */
661 if (! onlyjump_p (BB_END (bb
)))
664 /* Find the conditional jump and isolate the test. */
665 t
= cond_exec_get_condition (BB_END (bb
));
669 f_code
= reversed_comparison_code (t
, BB_END (bb
));
670 if (f_code
== UNKNOWN
)
673 f
= gen_rtx_fmt_ee (f_code
, GET_MODE (t
), XEXP (t
, 0), XEXP (t
, 1));
674 if (ce_info
->and_and_p
)
676 t
= gen_rtx_AND (GET_MODE (t
), true_expr
, t
);
677 f
= gen_rtx_IOR (GET_MODE (t
), false_expr
, f
);
681 t
= gen_rtx_IOR (GET_MODE (t
), true_expr
, t
);
682 f
= gen_rtx_AND (GET_MODE (t
), false_expr
, f
);
685 /* If the machine description needs to modify the tests, such as
686 setting a conditional execution register from a comparison, it can
688 #ifdef IFCVT_MODIFY_MULTIPLE_TESTS
689 IFCVT_MODIFY_MULTIPLE_TESTS (ce_info
, bb
, t
, f
);
691 /* See if the conversion failed. */
699 while (bb
!= last_test_bb
);
702 /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
703 on then THEN block. */
704 then_mod_ok
= (else_bb
== NULL_BLOCK
);
706 /* Go through the THEN and ELSE blocks converting the insns if possible
707 to conditional execution. */
711 || ! cond_exec_process_insns (ce_info
, then_start
, then_end
,
712 false_expr
, false_prob_val
,
716 if (else_bb
&& else_end
717 && ! cond_exec_process_insns (ce_info
, else_start
, else_end
,
718 true_expr
, true_prob_val
, true))
721 /* If we cannot apply the changes, fail. Do not go through the normal fail
722 processing, since apply_change_group will call cancel_changes. */
723 if (! apply_change_group ())
725 #ifdef IFCVT_MODIFY_CANCEL
726 /* Cancel any machine dependent changes. */
727 IFCVT_MODIFY_CANCEL (ce_info
);
732 #ifdef IFCVT_MODIFY_FINAL
733 /* Do any machine dependent final modifications. */
734 IFCVT_MODIFY_FINAL (ce_info
);
737 /* Conversion succeeded. */
739 fprintf (dump_file
, "%d insn%s converted to conditional execution.\n",
740 n_insns
, (n_insns
== 1) ? " was" : "s were");
742 /* Merge the blocks! If we had matching sequences, make sure to delete one
743 copy at the appropriate location first: delete the copy in the THEN branch
744 for a tail sequence so that the remaining one is executed last for both
745 branches, and delete the copy in the ELSE branch for a head sequence so
746 that the remaining one is executed first for both branches. */
749 rtx_insn
*from
= then_first_tail
;
751 from
= find_active_insn_after (then_bb
, from
);
752 delete_insn_chain (from
, get_last_bb_insn (then_bb
), false);
755 delete_insn_chain (first_active_insn (else_bb
), else_last_head
, false);
757 merge_if_block (ce_info
);
758 cond_exec_changed_p
= true;
762 #ifdef IFCVT_MODIFY_CANCEL
763 /* Cancel any machine dependent changes. */
764 IFCVT_MODIFY_CANCEL (ce_info
);
771 static rtx
noce_emit_store_flag (struct noce_if_info
*, rtx
, bool, int);
772 static bool noce_try_move (struct noce_if_info
*);
773 static bool noce_try_ifelse_collapse (struct noce_if_info
*);
774 static bool noce_try_store_flag (struct noce_if_info
*);
775 static bool noce_try_addcc (struct noce_if_info
*);
776 static bool noce_try_store_flag_constants (struct noce_if_info
*);
777 static bool noce_try_store_flag_mask (struct noce_if_info
*);
778 static rtx
noce_emit_cmove (struct noce_if_info
*, rtx
, enum rtx_code
, rtx
,
779 rtx
, rtx
, rtx
, rtx
= NULL
, rtx
= NULL
);
780 static bool noce_try_cmove (struct noce_if_info
*);
781 static bool noce_try_cmove_arith (struct noce_if_info
*);
782 static rtx
noce_get_alt_condition (struct noce_if_info
*, rtx
, rtx_insn
**);
783 static bool noce_try_minmax (struct noce_if_info
*);
784 static bool noce_try_abs (struct noce_if_info
*);
785 static bool noce_try_sign_mask (struct noce_if_info
*);
786 static int noce_try_cond_zero_arith (struct noce_if_info
*);
788 /* Return the comparison code for reversed condition for IF_INFO,
789 or UNKNOWN if reversing the condition is not possible. */
791 static inline enum rtx_code
792 noce_reversed_cond_code (struct noce_if_info
*if_info
)
794 if (if_info
->rev_cond
)
795 return GET_CODE (if_info
->rev_cond
);
796 return reversed_comparison_code (if_info
->cond
, if_info
->jump
);
799 /* Return true if SEQ is a good candidate as a replacement for the
800 if-convertible sequence described in IF_INFO.
801 This is the default implementation that targets can override
802 through a target hook. */
805 default_noce_conversion_profitable_p (rtx_insn
*seq
,
806 struct noce_if_info
*if_info
)
808 bool speed_p
= if_info
->speed_p
;
810 /* Cost up the new sequence. */
811 unsigned int cost
= seq_cost (seq
, speed_p
);
813 if (cost
<= if_info
->original_cost
)
816 /* When compiling for size, we can make a reasonably accurately guess
817 at the size growth. When compiling for speed, use the maximum. */
818 return speed_p
&& cost
<= if_info
->max_seq_cost
;
821 /* Helper function for noce_try_store_flag*. */
824 noce_emit_store_flag (struct noce_if_info
*if_info
, rtx x
, bool reversep
,
827 rtx cond
= if_info
->cond
;
831 cond_complex
= (! general_operand (XEXP (cond
, 0), VOIDmode
)
832 || ! general_operand (XEXP (cond
, 1), VOIDmode
));
834 /* If earliest == jump, or when the condition is complex, try to
835 build the store_flag insn directly. */
839 rtx set
= pc_set (if_info
->jump
);
840 cond
= XEXP (SET_SRC (set
), 0);
841 if (GET_CODE (XEXP (SET_SRC (set
), 2)) == LABEL_REF
842 && label_ref_label (XEXP (SET_SRC (set
), 2)) == JUMP_LABEL (if_info
->jump
))
843 reversep
= !reversep
;
844 if (if_info
->then_else_reversed
)
845 reversep
= !reversep
;
849 && general_operand (XEXP (if_info
->rev_cond
, 0), VOIDmode
)
850 && general_operand (XEXP (if_info
->rev_cond
, 1), VOIDmode
))
852 cond
= if_info
->rev_cond
;
857 code
= reversed_comparison_code (cond
, if_info
->jump
);
859 code
= GET_CODE (cond
);
861 if ((if_info
->cond_earliest
== if_info
->jump
|| cond_complex
)
862 && (normalize
== 0 || STORE_FLAG_VALUE
== normalize
))
864 rtx src
= gen_rtx_fmt_ee (code
, GET_MODE (x
), XEXP (cond
, 0),
866 rtx set
= gen_rtx_SET (x
, src
);
869 rtx_insn
*insn
= emit_insn (set
);
871 if (recog_memoized (insn
) >= 0)
873 rtx_insn
*seq
= get_insns ();
877 if_info
->cond_earliest
= if_info
->jump
;
885 /* Don't even try if the comparison operands or the mode of X are weird. */
886 if (cond_complex
|| !SCALAR_INT_MODE_P (GET_MODE (x
)))
889 return emit_store_flag (x
, code
, XEXP (cond
, 0),
890 XEXP (cond
, 1), VOIDmode
,
891 (code
== LTU
|| code
== LEU
892 || code
== GEU
|| code
== GTU
), normalize
);
895 /* Return true if X can be safely forced into a register by copy_to_mode_reg
899 noce_can_force_operand (rtx x
)
901 if (general_operand (x
, VOIDmode
))
905 if (!noce_can_force_operand (SUBREG_REG (x
)))
909 if (ARITHMETIC_P (x
))
911 if (!noce_can_force_operand (XEXP (x
, 0))
912 || !noce_can_force_operand (XEXP (x
, 1)))
914 switch (GET_CODE (x
))
923 return code_to_optab (GET_CODE (x
));
928 if (!noce_can_force_operand (XEXP (x
, 0)))
930 switch (GET_CODE (x
))
943 return code_to_optab (GET_CODE (x
));
949 /* Emit instruction to move an rtx, possibly into STRICT_LOW_PART.
950 X is the destination/target and Y is the value to copy. */
953 noce_emit_move_insn (rtx x
, rtx y
)
955 machine_mode outmode
;
959 if (GET_CODE (x
) != STRICT_LOW_PART
)
961 rtx_insn
*seq
, *insn
;
966 /* Check that the SET_SRC is reasonable before calling emit_move_insn,
967 otherwise construct a suitable SET pattern ourselves. */
968 insn
= (OBJECT_P (y
) || CONSTANT_P (y
) || GET_CODE (y
) == SUBREG
)
969 ? emit_move_insn (x
, y
)
970 : emit_insn (gen_rtx_SET (x
, y
));
974 if (recog_memoized (insn
) <= 0)
976 if (GET_CODE (x
) == ZERO_EXTRACT
)
978 rtx op
= XEXP (x
, 0);
979 unsigned HOST_WIDE_INT size
= INTVAL (XEXP (x
, 1));
980 unsigned HOST_WIDE_INT start
= INTVAL (XEXP (x
, 2));
982 /* store_bit_field expects START to be relative to
983 BYTES_BIG_ENDIAN and adjusts this value for machines with
984 BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN. In order to be able to
985 invoke store_bit_field again it is necessary to have the START
986 value from the first call. */
987 if (BITS_BIG_ENDIAN
!= BYTES_BIG_ENDIAN
)
990 start
= BITS_PER_UNIT
- start
- size
;
993 gcc_assert (REG_P (op
));
994 start
= BITS_PER_WORD
- start
- size
;
998 gcc_assert (start
< (MEM_P (op
) ? BITS_PER_UNIT
: BITS_PER_WORD
));
999 store_bit_field (op
, size
, start
, 0, 0, GET_MODE (x
), y
, false,
1004 switch (GET_RTX_CLASS (GET_CODE (y
)))
1007 ot
= code_to_optab (GET_CODE (y
));
1008 if (ot
&& noce_can_force_operand (XEXP (y
, 0)))
1011 target
= expand_unop (GET_MODE (y
), ot
, XEXP (y
, 0), x
, 0);
1012 if (target
!= NULL_RTX
)
1015 emit_move_insn (x
, target
);
1023 case RTX_COMM_ARITH
:
1024 ot
= code_to_optab (GET_CODE (y
));
1026 && noce_can_force_operand (XEXP (y
, 0))
1027 && noce_can_force_operand (XEXP (y
, 1)))
1030 target
= expand_binop (GET_MODE (y
), ot
,
1031 XEXP (y
, 0), XEXP (y
, 1),
1032 x
, 0, OPTAB_DIRECT
);
1033 if (target
!= NULL_RTX
)
1036 emit_move_insn (x
, target
);
1052 outer
= XEXP (x
, 0);
1053 inner
= XEXP (outer
, 0);
1054 outmode
= GET_MODE (outer
);
1055 bitpos
= SUBREG_BYTE (outer
) * BITS_PER_UNIT
;
1056 store_bit_field (inner
, GET_MODE_BITSIZE (outmode
), bitpos
,
1057 0, 0, outmode
, y
, false, false);
1060 /* Return the CC reg if it is used in COND. */
1063 cc_in_cond (rtx cond
)
1065 if (have_cbranchcc4
&& cond
1066 && GET_MODE_CLASS (GET_MODE (XEXP (cond
, 0))) == MODE_CC
)
1067 return XEXP (cond
, 0);
1072 /* Return sequence of instructions generated by if conversion. This
1073 function calls end_sequence() to end the current stream, ensures
1074 that the instructions are unshared, recognizable non-jump insns.
1075 On failure, this function returns a NULL_RTX. */
1078 end_ifcvt_sequence (struct noce_if_info
*if_info
)
1081 rtx_insn
*seq
= get_insns ();
1082 rtx cc
= cc_in_cond (if_info
->cond
);
1084 set_used_flags (if_info
->x
);
1085 set_used_flags (if_info
->cond
);
1086 set_used_flags (if_info
->a
);
1087 set_used_flags (if_info
->b
);
1089 for (insn
= seq
; insn
; insn
= NEXT_INSN (insn
))
1090 set_used_flags (insn
);
1092 unshare_all_rtl_in_chain (seq
);
1095 /* Make sure that all of the instructions emitted are recognizable,
1096 and that we haven't introduced a new jump instruction.
1097 As an exercise for the reader, build a general mechanism that
1098 allows proper placement of required clobbers. */
1099 for (insn
= seq
; insn
; insn
= NEXT_INSN (insn
))
1101 || recog_memoized (insn
) == -1
1102 /* Make sure new generated code does not clobber CC. */
1103 || (cc
&& set_of (cc
, insn
)))
1109 /* Return true iff the then and else basic block (if it exists)
1110 consist of a single simple set instruction. */
1113 noce_simple_bbs (struct noce_if_info
*if_info
)
1115 if (!if_info
->then_simple
)
1118 if (if_info
->else_bb
)
1119 return if_info
->else_simple
;
1124 /* Convert "if (a != b) x = a; else x = b" into "x = a" and
1125 "if (a == b) x = a; else x = b" into "x = b". */
1128 noce_try_move (struct noce_if_info
*if_info
)
1130 rtx cond
= if_info
->cond
;
1131 enum rtx_code code
= GET_CODE (cond
);
1135 if (code
!= NE
&& code
!= EQ
)
1138 if (!noce_simple_bbs (if_info
))
1141 /* This optimization isn't valid if either A or B could be a NaN
1142 or a signed zero. */
1143 if (HONOR_NANS (if_info
->x
)
1144 || HONOR_SIGNED_ZEROS (if_info
->x
))
1147 /* Check whether the operands of the comparison are A and in
1149 if ((rtx_equal_p (if_info
->a
, XEXP (cond
, 0))
1150 && rtx_equal_p (if_info
->b
, XEXP (cond
, 1)))
1151 || (rtx_equal_p (if_info
->a
, XEXP (cond
, 1))
1152 && rtx_equal_p (if_info
->b
, XEXP (cond
, 0))))
1154 if (!rtx_interchangeable_p (if_info
->a
, if_info
->b
))
1157 y
= (code
== EQ
) ? if_info
->a
: if_info
->b
;
1159 /* Avoid generating the move if the source is the destination. */
1160 if (! rtx_equal_p (if_info
->x
, y
))
1163 noce_emit_move_insn (if_info
->x
, y
);
1164 seq
= end_ifcvt_sequence (if_info
);
1168 emit_insn_before_setloc (seq
, if_info
->jump
,
1169 INSN_LOCATION (if_info
->insn_a
));
1171 if_info
->transform_name
= "noce_try_move";
1177 /* Try forming an IF_THEN_ELSE (cond, b, a) and collapsing that
1178 through simplify_rtx. Sometimes that can eliminate the IF_THEN_ELSE.
1179 If that is the case, emit the result into x. */
1182 noce_try_ifelse_collapse (struct noce_if_info
* if_info
)
1184 if (!noce_simple_bbs (if_info
))
1187 machine_mode mode
= GET_MODE (if_info
->x
);
1188 rtx if_then_else
= simplify_gen_ternary (IF_THEN_ELSE
, mode
, mode
,
1189 if_info
->cond
, if_info
->b
,
1192 if (GET_CODE (if_then_else
) == IF_THEN_ELSE
)
1197 noce_emit_move_insn (if_info
->x
, if_then_else
);
1198 seq
= end_ifcvt_sequence (if_info
);
1202 emit_insn_before_setloc (seq
, if_info
->jump
,
1203 INSN_LOCATION (if_info
->insn_a
));
1205 if_info
->transform_name
= "noce_try_ifelse_collapse";
1210 /* Convert "if (test) x = 1; else x = 0".
1212 Only try 0 and STORE_FLAG_VALUE here. Other combinations will be
1213 tried in noce_try_store_flag_constants after noce_try_cmove has had
1214 a go at the conversion. */
1217 noce_try_store_flag (struct noce_if_info
*if_info
)
1223 if (!noce_simple_bbs (if_info
))
1226 if (CONST_INT_P (if_info
->b
)
1227 && INTVAL (if_info
->b
) == STORE_FLAG_VALUE
1228 && if_info
->a
== const0_rtx
)
1230 else if (if_info
->b
== const0_rtx
1231 && CONST_INT_P (if_info
->a
)
1232 && INTVAL (if_info
->a
) == STORE_FLAG_VALUE
1233 && noce_reversed_cond_code (if_info
) != UNKNOWN
)
1240 target
= noce_emit_store_flag (if_info
, if_info
->x
, reversep
, 0);
1243 if (target
!= if_info
->x
)
1244 noce_emit_move_insn (if_info
->x
, target
);
1246 seq
= end_ifcvt_sequence (if_info
);
1250 emit_insn_before_setloc (seq
, if_info
->jump
,
1251 INSN_LOCATION (if_info
->insn_a
));
1252 if_info
->transform_name
= "noce_try_store_flag";
1263 /* Convert "if (test) x = -A; else x = A" into
1264 x = A; if (test) x = -x if the machine can do the
1265 conditional negate form of this cheaply.
1266 Try this before noce_try_cmove that will just load the
1267 immediates into two registers and do a conditional select
1268 between them. If the target has a conditional negate or
1269 conditional invert operation we can save a potentially
1270 expensive constant synthesis. */
1273 noce_try_inverse_constants (struct noce_if_info
*if_info
)
1275 if (!noce_simple_bbs (if_info
))
1278 if (!CONST_INT_P (if_info
->a
)
1279 || !CONST_INT_P (if_info
->b
)
1280 || !REG_P (if_info
->x
))
1283 machine_mode mode
= GET_MODE (if_info
->x
);
1285 HOST_WIDE_INT val_a
= INTVAL (if_info
->a
);
1286 HOST_WIDE_INT val_b
= INTVAL (if_info
->b
);
1288 rtx cond
= if_info
->cond
;
1296 if (val_b
!= HOST_WIDE_INT_MIN
&& val_a
== -val_b
)
1298 else if (val_a
== ~val_b
)
1306 rtx tmp
= gen_reg_rtx (mode
);
1307 noce_emit_move_insn (tmp
, if_info
->a
);
1309 target
= emit_conditional_neg_or_complement (x
, code
, mode
, cond
, tmp
, tmp
);
1313 rtx_insn
*seq
= get_insns ();
1321 if (target
!= if_info
->x
)
1322 noce_emit_move_insn (if_info
->x
, target
);
1324 seq
= end_ifcvt_sequence (if_info
);
1329 emit_insn_before_setloc (seq
, if_info
->jump
,
1330 INSN_LOCATION (if_info
->insn_a
));
1331 if_info
->transform_name
= "noce_try_inverse_constants";
1340 /* Convert "if (test) x = a; else x = b", for A and B constant.
1341 Also allow A = y + c1, B = y + c2, with a common y between A
1345 noce_try_store_flag_constants (struct noce_if_info
*if_info
)
1350 HOST_WIDE_INT itrue
, ifalse
, diff
, tmp
;
1353 machine_mode mode
= GET_MODE (if_info
->x
);
1354 rtx common
= NULL_RTX
;
1359 /* Handle cases like x := test ? y + 3 : y + 4. */
1360 if (GET_CODE (a
) == PLUS
1361 && GET_CODE (b
) == PLUS
1362 && CONST_INT_P (XEXP (a
, 1))
1363 && CONST_INT_P (XEXP (b
, 1))
1364 && rtx_equal_p (XEXP (a
, 0), XEXP (b
, 0))
1365 /* Allow expressions that are not using the result or plain
1366 registers where we handle overlap below. */
1367 && (REG_P (XEXP (a
, 0))
1368 || (noce_operand_ok (XEXP (a
, 0))
1369 && ! reg_overlap_mentioned_p (if_info
->x
, XEXP (a
, 0)))))
1371 common
= XEXP (a
, 0);
1376 if (!noce_simple_bbs (if_info
))
1382 ifalse
= INTVAL (a
);
1384 bool subtract_flag_p
= false;
1386 diff
= (unsigned HOST_WIDE_INT
) itrue
- ifalse
;
1387 /* Make sure we can represent the difference between the two values. */
1389 != ((ifalse
< 0) != (itrue
< 0) ? ifalse
< 0 : ifalse
< itrue
))
1392 diff
= trunc_int_for_mode (diff
, mode
);
1394 can_reverse
= noce_reversed_cond_code (if_info
) != UNKNOWN
;
1396 if (diff
== STORE_FLAG_VALUE
|| diff
== -STORE_FLAG_VALUE
)
1399 /* We could collapse these cases but it is easier to follow the
1400 diff/STORE_FLAG_VALUE combinations when they are listed
1404 => 4 + (test != 0). */
1405 if (diff
< 0 && STORE_FLAG_VALUE
< 0)
1408 => can_reverse | 4 + (test == 0)
1409 !can_reverse | 3 - (test != 0). */
1410 else if (diff
> 0 && STORE_FLAG_VALUE
< 0)
1412 reversep
= can_reverse
;
1413 subtract_flag_p
= !can_reverse
;
1414 /* If we need to subtract the flag and we have PLUS-immediate
1415 A and B then it is unlikely to be beneficial to play tricks
1417 if (subtract_flag_p
&& common
)
1421 => can_reverse | 3 + (test == 0)
1422 !can_reverse | 4 - (test != 0). */
1423 else if (diff
< 0 && STORE_FLAG_VALUE
> 0)
1425 reversep
= can_reverse
;
1426 subtract_flag_p
= !can_reverse
;
1427 /* If we need to subtract the flag and we have PLUS-immediate
1428 A and B then it is unlikely to be beneficial to play tricks
1430 if (subtract_flag_p
&& common
)
1434 => 4 + (test != 0). */
1435 else if (diff
> 0 && STORE_FLAG_VALUE
> 0)
1440 /* Is this (cond) ? 2^n : 0? */
1441 else if (ifalse
== 0 && pow2p_hwi (itrue
)
1442 && STORE_FLAG_VALUE
== 1)
1444 /* Is this (cond) ? 0 : 2^n? */
1445 else if (itrue
== 0 && pow2p_hwi (ifalse
) && can_reverse
1446 && STORE_FLAG_VALUE
== 1)
1451 /* Is this (cond) ? -1 : x? */
1452 else if (itrue
== -1
1453 && STORE_FLAG_VALUE
== -1)
1455 /* Is this (cond) ? x : -1? */
1456 else if (ifalse
== -1 && can_reverse
1457 && STORE_FLAG_VALUE
== -1)
1467 std::swap (itrue
, ifalse
);
1468 diff
= trunc_int_for_mode (-(unsigned HOST_WIDE_INT
) diff
, mode
);
1473 /* If we have x := test ? x + 3 : x + 4 then move the original
1474 x out of the way while we store flags. */
1475 if (common
&& rtx_equal_p (common
, if_info
->x
))
1477 common
= gen_reg_rtx (mode
);
1478 noce_emit_move_insn (common
, if_info
->x
);
1481 target
= noce_emit_store_flag (if_info
, if_info
->x
, reversep
, normalize
);
1488 /* if (test) x = 3; else x = 4;
1489 => x = 3 + (test == 0); */
1490 if (diff
== STORE_FLAG_VALUE
|| diff
== -STORE_FLAG_VALUE
)
1492 /* Add the common part now. This may allow combine to merge this
1493 with the store flag operation earlier into some sort of conditional
1494 increment/decrement if the target allows it. */
1496 target
= expand_simple_binop (mode
, PLUS
,
1498 target
, 0, OPTAB_WIDEN
);
1500 /* Always use ifalse here. It should have been swapped with itrue
1501 when appropriate when reversep is true. */
1502 target
= expand_simple_binop (mode
, subtract_flag_p
? MINUS
: PLUS
,
1503 gen_int_mode (ifalse
, mode
), target
,
1504 if_info
->x
, 0, OPTAB_WIDEN
);
1506 /* Other cases are not beneficial when the original A and B are PLUS
1513 /* if (test) x = 8; else x = 0;
1514 => x = (test != 0) << 3; */
1515 else if (ifalse
== 0 && (tmp
= exact_log2 (itrue
)) >= 0)
1517 target
= expand_simple_binop (mode
, ASHIFT
,
1518 target
, GEN_INT (tmp
), if_info
->x
, 0,
1522 /* if (test) x = -1; else x = b;
1523 => x = -(test != 0) | b; */
1524 else if (itrue
== -1)
1526 target
= expand_simple_binop (mode
, IOR
,
1527 target
, gen_int_mode (ifalse
, mode
),
1528 if_info
->x
, 0, OPTAB_WIDEN
);
1542 if (target
!= if_info
->x
)
1543 noce_emit_move_insn (if_info
->x
, target
);
1545 seq
= end_ifcvt_sequence (if_info
);
1546 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
1549 emit_insn_before_setloc (seq
, if_info
->jump
,
1550 INSN_LOCATION (if_info
->insn_a
));
1551 if_info
->transform_name
= "noce_try_store_flag_constants";
1559 /* Convert "if (test) foo++" into "foo += (test != 0)", and
1560 similarly for "foo--". */
1563 noce_try_addcc (struct noce_if_info
*if_info
)
1570 if (!noce_simple_bbs (if_info
))
1573 if (GET_CODE (if_info
->a
) == PLUS
1574 && rtx_equal_p (XEXP (if_info
->a
, 0), if_info
->b
)
1575 && noce_reversed_cond_code (if_info
) != UNKNOWN
)
1577 rtx cond
= if_info
->rev_cond
;
1580 if (cond
== NULL_RTX
)
1582 cond
= if_info
->cond
;
1583 code
= reversed_comparison_code (cond
, if_info
->jump
);
1586 code
= GET_CODE (cond
);
1588 /* First try to use addcc pattern. */
1589 if (general_operand (XEXP (cond
, 0), VOIDmode
)
1590 && general_operand (XEXP (cond
, 1), VOIDmode
))
1593 target
= emit_conditional_add (if_info
->x
, code
,
1598 XEXP (if_info
->a
, 1),
1599 GET_MODE (if_info
->x
),
1600 (code
== LTU
|| code
== GEU
1601 || code
== LEU
|| code
== GTU
));
1604 if (target
!= if_info
->x
)
1605 noce_emit_move_insn (if_info
->x
, target
);
1607 seq
= end_ifcvt_sequence (if_info
);
1608 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
1611 emit_insn_before_setloc (seq
, if_info
->jump
,
1612 INSN_LOCATION (if_info
->insn_a
));
1613 if_info
->transform_name
= "noce_try_addcc";
1620 /* If that fails, construct conditional increment or decrement using
1621 setcc. We're changing a branch and an increment to a comparison and
1623 if (XEXP (if_info
->a
, 1) == const1_rtx
1624 || XEXP (if_info
->a
, 1) == constm1_rtx
)
1627 if (STORE_FLAG_VALUE
== INTVAL (XEXP (if_info
->a
, 1)))
1628 subtract
= false, normalize
= 0;
1629 else if (-STORE_FLAG_VALUE
== INTVAL (XEXP (if_info
->a
, 1)))
1630 subtract
= true, normalize
= 0;
1632 subtract
= false, normalize
= INTVAL (XEXP (if_info
->a
, 1));
1635 target
= noce_emit_store_flag (if_info
,
1636 gen_reg_rtx (GET_MODE (if_info
->x
)),
1640 target
= expand_simple_binop (GET_MODE (if_info
->x
),
1641 subtract
? MINUS
: PLUS
,
1642 if_info
->b
, target
, if_info
->x
,
1646 if (target
!= if_info
->x
)
1647 noce_emit_move_insn (if_info
->x
, target
);
1649 seq
= end_ifcvt_sequence (if_info
);
1650 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
1653 emit_insn_before_setloc (seq
, if_info
->jump
,
1654 INSN_LOCATION (if_info
->insn_a
));
1655 if_info
->transform_name
= "noce_try_addcc";
1665 /* Convert "if (test) x = 0;" to "x &= -(test == 0);" */
1668 noce_try_store_flag_mask (struct noce_if_info
*if_info
)
1674 if (!noce_simple_bbs (if_info
))
1679 if ((if_info
->a
== const0_rtx
1680 && (REG_P (if_info
->b
) || rtx_equal_p (if_info
->b
, if_info
->x
)))
1681 || ((reversep
= (noce_reversed_cond_code (if_info
) != UNKNOWN
))
1682 && if_info
->b
== const0_rtx
1683 && (REG_P (if_info
->a
) || rtx_equal_p (if_info
->a
, if_info
->x
))))
1686 target
= noce_emit_store_flag (if_info
,
1687 gen_reg_rtx (GET_MODE (if_info
->x
)),
1690 target
= expand_simple_binop (GET_MODE (if_info
->x
), AND
,
1691 reversep
? if_info
->a
: if_info
->b
,
1692 target
, if_info
->x
, 0,
1697 if (target
!= if_info
->x
)
1698 noce_emit_move_insn (if_info
->x
, target
);
1700 seq
= end_ifcvt_sequence (if_info
);
1701 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
1704 emit_insn_before_setloc (seq
, if_info
->jump
,
1705 INSN_LOCATION (if_info
->insn_a
));
1706 if_info
->transform_name
= "noce_try_store_flag_mask";
1717 /* Helper function for noce_try_cmove and noce_try_cmove_arith. */
1720 noce_emit_cmove (struct noce_if_info
*if_info
, rtx x
, enum rtx_code code
,
1721 rtx cmp_a
, rtx cmp_b
, rtx vfalse
, rtx vtrue
, rtx cc_cmp
,
1724 rtx target ATTRIBUTE_UNUSED
;
1725 bool unsignedp ATTRIBUTE_UNUSED
;
1727 /* If earliest == jump, try to build the cmove insn directly.
1728 This is helpful when combine has created some complex condition
1729 (like for alpha's cmovlbs) that we can't hope to regenerate
1730 through the normal interface. */
1732 if (if_info
->cond_earliest
== if_info
->jump
)
1734 rtx cond
= gen_rtx_fmt_ee (code
, GET_MODE (if_info
->cond
), cmp_a
, cmp_b
);
1735 rtx if_then_else
= gen_rtx_IF_THEN_ELSE (GET_MODE (x
),
1736 cond
, vtrue
, vfalse
);
1737 rtx set
= gen_rtx_SET (x
, if_then_else
);
1740 rtx_insn
*insn
= emit_insn (set
);
1742 if (recog_memoized (insn
) >= 0)
1744 rtx_insn
*seq
= get_insns ();
1754 unsignedp
= (code
== LTU
|| code
== GEU
1755 || code
== LEU
|| code
== GTU
);
1757 if (cc_cmp
!= NULL_RTX
&& rev_cc_cmp
!= NULL_RTX
)
1758 target
= emit_conditional_move (x
, cc_cmp
, rev_cc_cmp
,
1759 vtrue
, vfalse
, GET_MODE (x
));
1762 /* Don't even try if the comparison operands are weird
1763 except that the target supports cbranchcc4. */
1764 if (! general_operand (cmp_a
, GET_MODE (cmp_a
))
1765 || ! general_operand (cmp_b
, GET_MODE (cmp_b
)))
1767 if (!have_cbranchcc4
1768 || GET_MODE_CLASS (GET_MODE (cmp_a
)) != MODE_CC
1769 || cmp_b
!= const0_rtx
)
1773 target
= emit_conditional_move (x
, { code
, cmp_a
, cmp_b
, VOIDmode
},
1774 vtrue
, vfalse
, GET_MODE (x
),
1781 /* We might be faced with a situation like:
1784 vtrue = (subreg:M (reg:N VTRUE) BYTE)
1785 vfalse = (subreg:M (reg:N VFALSE) BYTE)
1787 We can't do a conditional move in mode M, but it's possible that we
1788 could do a conditional move in mode N instead and take a subreg of
1791 If we can't create new pseudos, though, don't bother. */
1792 if (reload_completed
)
1795 if (GET_CODE (vtrue
) == SUBREG
&& GET_CODE (vfalse
) == SUBREG
)
1797 rtx reg_vtrue
= SUBREG_REG (vtrue
);
1798 rtx reg_vfalse
= SUBREG_REG (vfalse
);
1799 poly_uint64 byte_vtrue
= SUBREG_BYTE (vtrue
);
1800 poly_uint64 byte_vfalse
= SUBREG_BYTE (vfalse
);
1801 rtx promoted_target
;
1803 if (GET_MODE (reg_vtrue
) != GET_MODE (reg_vfalse
)
1804 || maybe_ne (byte_vtrue
, byte_vfalse
)
1805 || (SUBREG_PROMOTED_VAR_P (vtrue
)
1806 != SUBREG_PROMOTED_VAR_P (vfalse
))
1807 || (SUBREG_PROMOTED_GET (vtrue
)
1808 != SUBREG_PROMOTED_GET (vfalse
)))
1811 promoted_target
= gen_reg_rtx (GET_MODE (reg_vtrue
));
1813 target
= emit_conditional_move (promoted_target
,
1814 { code
, cmp_a
, cmp_b
, VOIDmode
},
1815 reg_vtrue
, reg_vfalse
,
1816 GET_MODE (reg_vtrue
), unsignedp
);
1817 /* Nope, couldn't do it in that mode either. */
1821 target
= gen_rtx_SUBREG (GET_MODE (vtrue
), promoted_target
, byte_vtrue
);
1822 SUBREG_PROMOTED_VAR_P (target
) = SUBREG_PROMOTED_VAR_P (vtrue
);
1823 SUBREG_PROMOTED_SET (target
, SUBREG_PROMOTED_GET (vtrue
));
1824 emit_move_insn (x
, target
);
1831 /* Emit a conditional zero, returning TARGET or NULL_RTX upon failure.
1832 IF_INFO describes the if-conversion scenario under consideration.
1833 CZERO_CODE selects the condition (EQ/NE).
1834 NON_ZERO_OP is the nonzero operand of the conditional move
1835 TARGET is the desired output register. */
1838 noce_emit_czero (struct noce_if_info
*if_info
, enum rtx_code czero_code
,
1839 rtx non_zero_op
, rtx target
)
1841 machine_mode mode
= GET_MODE (target
);
1842 rtx cond_op0
= XEXP (if_info
->cond
, 0);
1844 = gen_rtx_fmt_ee (czero_code
, GET_MODE (cond_op0
), cond_op0
, const0_rtx
);
1846 = gen_rtx_IF_THEN_ELSE (mode
, czero_cond
, const0_rtx
, non_zero_op
);
1847 rtx set
= gen_rtx_SET (target
, if_then_else
);
1849 rtx_insn
*insn
= make_insn_raw (set
);
1851 if (recog_memoized (insn
) >= 0)
1860 /* Try only simple constants and registers here. More complex cases
1861 are handled in noce_try_cmove_arith after noce_try_store_flag_arith
1862 has had a go at it. */
1865 noce_try_cmove (struct noce_if_info
*if_info
)
1871 if (!noce_simple_bbs (if_info
))
1874 if ((CONSTANT_P (if_info
->a
) || register_operand (if_info
->a
, VOIDmode
))
1875 && (CONSTANT_P (if_info
->b
) || register_operand (if_info
->b
, VOIDmode
)))
1879 code
= GET_CODE (if_info
->cond
);
1880 target
= noce_emit_cmove (if_info
, if_info
->x
, code
,
1881 XEXP (if_info
->cond
, 0),
1882 XEXP (if_info
->cond
, 1),
1883 if_info
->a
, if_info
->b
);
1887 if (target
!= if_info
->x
)
1888 noce_emit_move_insn (if_info
->x
, target
);
1890 seq
= end_ifcvt_sequence (if_info
);
1891 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
1894 emit_insn_before_setloc (seq
, if_info
->jump
,
1895 INSN_LOCATION (if_info
->insn_a
));
1896 if_info
->transform_name
= "noce_try_cmove";
1900 /* If both a and b are constants try a last-ditch transformation:
1901 if (test) x = a; else x = b;
1902 => x = (-(test != 0) & (b - a)) + a;
1903 Try this only if the target-specific expansion above has failed.
1904 The target-specific expander may want to generate sequences that
1905 we don't know about, so give them a chance before trying this
1907 else if (!targetm
.have_conditional_execution ()
1908 && CONST_INT_P (if_info
->a
) && CONST_INT_P (if_info
->b
))
1910 machine_mode mode
= GET_MODE (if_info
->x
);
1911 HOST_WIDE_INT ifalse
= INTVAL (if_info
->a
);
1912 HOST_WIDE_INT itrue
= INTVAL (if_info
->b
);
1913 rtx target
= noce_emit_store_flag (if_info
, if_info
->x
, false, -1);
1920 HOST_WIDE_INT diff
= (unsigned HOST_WIDE_INT
) itrue
- ifalse
;
1921 /* Make sure we can represent the difference
1922 between the two values. */
1924 != ((ifalse
< 0) != (itrue
< 0) ? ifalse
< 0 : ifalse
< itrue
))
1930 diff
= trunc_int_for_mode (diff
, mode
);
1931 target
= expand_simple_binop (mode
, AND
,
1932 target
, gen_int_mode (diff
, mode
),
1933 if_info
->x
, 0, OPTAB_WIDEN
);
1935 target
= expand_simple_binop (mode
, PLUS
,
1936 target
, gen_int_mode (ifalse
, mode
),
1937 if_info
->x
, 0, OPTAB_WIDEN
);
1940 if (target
!= if_info
->x
)
1941 noce_emit_move_insn (if_info
->x
, target
);
1943 seq
= end_ifcvt_sequence (if_info
);
1944 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
1947 emit_insn_before_setloc (seq
, if_info
->jump
,
1948 INSN_LOCATION (if_info
->insn_a
));
1949 if_info
->transform_name
= "noce_try_cmove";
1965 /* Return true if X contains a conditional code mode rtx. */
1968 contains_ccmode_rtx_p (rtx x
)
1970 subrtx_iterator::array_type array
;
1971 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
1972 if (GET_MODE_CLASS (GET_MODE (*iter
)) == MODE_CC
)
1978 /* Helper for bb_valid_for_noce_process_p. Validate that
1979 the rtx insn INSN is a single set that does not set
1980 the conditional register CC and is in general valid for
1984 insn_valid_noce_process_p (rtx_insn
*insn
, rtx cc
)
1987 || !NONJUMP_INSN_P (insn
)
1988 || (cc
&& set_of (cc
, insn
)))
1991 rtx sset
= single_set (insn
);
1993 /* Currently support only simple single sets in test_bb. */
1995 || !noce_operand_ok (SET_DEST (sset
))
1996 || contains_ccmode_rtx_p (SET_DEST (sset
))
1997 || !noce_operand_ok (SET_SRC (sset
)))
2004 /* Return true iff the registers that the insns in BB_A set do not get
2005 used in BB_B. If TO_RENAME is non-NULL then it is a location that will be
2006 renamed later by the caller and so conflicts on it should be ignored
2007 in this function. */
2010 bbs_ok_for_cmove_arith (basic_block bb_a
, basic_block bb_b
, rtx to_rename
)
2013 bitmap bba_sets
= BITMAP_ALLOC (®_obstack
);
2018 FOR_BB_INSNS (bb_a
, a_insn
)
2020 if (!active_insn_p (a_insn
))
2023 rtx sset_a
= single_set (a_insn
);
2027 BITMAP_FREE (bba_sets
);
2030 /* Record all registers that BB_A sets. */
2031 FOR_EACH_INSN_DEF (def
, a_insn
)
2032 if (!(to_rename
&& DF_REF_REG (def
) == to_rename
))
2033 bitmap_set_bit (bba_sets
, DF_REF_REGNO (def
));
2038 FOR_BB_INSNS (bb_b
, b_insn
)
2040 if (!active_insn_p (b_insn
))
2043 rtx sset_b
= single_set (b_insn
);
2047 BITMAP_FREE (bba_sets
);
2051 /* Make sure this is a REG and not some instance
2052 of ZERO_EXTRACT or non-paradoxical SUBREG or other dangerous stuff.
2053 If we have a memory destination then we have a pair of simple
2054 basic blocks performing an operation of the form [addr] = c ? a : b.
2055 bb_valid_for_noce_process_p will have ensured that these are
2056 the only stores present. In that case [addr] should be the location
2057 to be renamed. Assert that the callers set this up properly. */
2058 if (MEM_P (SET_DEST (sset_b
)))
2059 gcc_assert (rtx_equal_p (SET_DEST (sset_b
), to_rename
));
2060 else if (!REG_P (SET_DEST (sset_b
))
2061 && !paradoxical_subreg_p (SET_DEST (sset_b
)))
2063 BITMAP_FREE (bba_sets
);
2067 /* If the insn uses a reg set in BB_A return false. */
2068 FOR_EACH_INSN_USE (use
, b_insn
)
2070 if (bitmap_bit_p (bba_sets
, DF_REF_REGNO (use
)))
2072 BITMAP_FREE (bba_sets
);
2079 BITMAP_FREE (bba_sets
);
2083 /* Emit copies of all the active instructions in BB except the last.
2084 This is a helper for noce_try_cmove_arith. */
2087 noce_emit_all_but_last (basic_block bb
)
2089 rtx_insn
*last
= last_active_insn (bb
, false);
2091 FOR_BB_INSNS (bb
, insn
)
2093 if (insn
!= last
&& active_insn_p (insn
))
2095 rtx_insn
*to_emit
= as_a
<rtx_insn
*> (copy_rtx (insn
));
2097 emit_insn (PATTERN (to_emit
));
2102 /* Helper for noce_try_cmove_arith. Emit the pattern TO_EMIT and return
2103 the resulting insn or NULL if it's not a valid insn. */
2106 noce_emit_insn (rtx to_emit
)
2108 gcc_assert (to_emit
);
2109 rtx_insn
*insn
= emit_insn (to_emit
);
2111 if (recog_memoized (insn
) < 0)
2117 /* Helper for noce_try_cmove_arith. Emit a copy of the insns up to
2118 and including the penultimate one in BB if it is not simple
2119 (as indicated by SIMPLE). Then emit LAST_INSN as the last
2120 insn in the block. The reason for that is that LAST_INSN may
2121 have been modified by the preparation in noce_try_cmove_arith. */
2124 noce_emit_bb (rtx last_insn
, basic_block bb
, bool simple
)
2127 noce_emit_all_but_last (bb
);
2129 if (last_insn
&& !noce_emit_insn (last_insn
))
2135 /* Try more complex cases involving conditional_move. */
2138 noce_try_cmove_arith (struct noce_if_info
*if_info
)
2144 rtx_insn
*insn_a
, *insn_b
;
2145 bool a_simple
= if_info
->then_simple
;
2146 bool b_simple
= if_info
->else_simple
;
2147 basic_block then_bb
= if_info
->then_bb
;
2148 basic_block else_bb
= if_info
->else_bb
;
2150 bool is_mem
= false;
2152 rtx cond
= if_info
->cond
;
2153 rtx_insn
*ifcvt_seq
;
2155 /* A conditional move from two memory sources is equivalent to a
2156 conditional on their addresses followed by a load. Don't do this
2157 early because it'll screw alias analysis. Note that we've
2158 already checked for no side effects. */
2159 if (cse_not_expected
2160 && MEM_P (a
) && MEM_P (b
)
2161 && MEM_ADDR_SPACE (a
) == MEM_ADDR_SPACE (b
))
2163 machine_mode address_mode
= get_address_mode (a
);
2167 x
= gen_reg_rtx (address_mode
);
2171 /* ??? We could handle this if we knew that a load from A or B could
2172 not trap or fault. This is also true if we've already loaded
2173 from the address along the path from ENTRY. */
2174 else if (may_trap_or_fault_p (a
) || may_trap_or_fault_p (b
))
2177 /* if (test) x = a + b; else x = c - d;
2184 code
= GET_CODE (cond
);
2185 insn_a
= if_info
->insn_a
;
2186 insn_b
= if_info
->insn_b
;
2188 machine_mode x_mode
= GET_MODE (x
);
2190 if (!can_conditionally_move_p (x_mode
))
2193 /* Possibly rearrange operands to make things come out more natural. */
2194 if (noce_reversed_cond_code (if_info
) != UNKNOWN
)
2196 bool reversep
= false;
2197 if (rtx_equal_p (b
, x
))
2199 else if (general_operand (b
, GET_MODE (b
)))
2204 if (if_info
->rev_cond
)
2206 cond
= if_info
->rev_cond
;
2207 code
= GET_CODE (cond
);
2210 code
= reversed_comparison_code (cond
, if_info
->jump
);
2212 std::swap (insn_a
, insn_b
);
2213 std::swap (a_simple
, b_simple
);
2214 std::swap (then_bb
, else_bb
);
2218 if (then_bb
&& else_bb
2219 && (!bbs_ok_for_cmove_arith (then_bb
, else_bb
, if_info
->orig_x
)
2220 || !bbs_ok_for_cmove_arith (else_bb
, then_bb
, if_info
->orig_x
)))
2225 /* If one of the blocks is empty then the corresponding B or A value
2226 came from the test block. The non-empty complex block that we will
2227 emit might clobber the register used by B or A, so move it to a pseudo
2230 rtx tmp_a
= NULL_RTX
;
2231 rtx tmp_b
= NULL_RTX
;
2233 if (b_simple
|| !else_bb
)
2234 tmp_b
= gen_reg_rtx (x_mode
);
2236 if (a_simple
|| !then_bb
)
2237 tmp_a
= gen_reg_rtx (x_mode
);
2242 rtx emit_a
= NULL_RTX
;
2243 rtx emit_b
= NULL_RTX
;
2244 rtx_insn
*tmp_insn
= NULL
;
2245 bool modified_in_a
= false;
2246 bool modified_in_b
= false;
2247 /* If either operand is complex, load it into a register first.
2248 The best way to do this is to copy the original insn. In this
2249 way we preserve any clobbers etc that the insn may have had.
2250 This is of course not possible in the IS_MEM case. */
2252 if (! general_operand (a
, GET_MODE (a
)) || tmp_a
)
2257 rtx reg
= gen_reg_rtx (GET_MODE (a
));
2258 emit_a
= gen_rtx_SET (reg
, a
);
2264 a
= tmp_a
? tmp_a
: gen_reg_rtx (GET_MODE (a
));
2266 rtx_insn
*copy_of_a
= as_a
<rtx_insn
*> (copy_rtx (insn_a
));
2267 rtx set
= single_set (copy_of_a
);
2270 emit_a
= PATTERN (copy_of_a
);
2274 rtx tmp_reg
= tmp_a
? tmp_a
: gen_reg_rtx (GET_MODE (a
));
2275 emit_a
= gen_rtx_SET (tmp_reg
, a
);
2281 if (! general_operand (b
, GET_MODE (b
)) || tmp_b
)
2285 rtx reg
= gen_reg_rtx (GET_MODE (b
));
2286 emit_b
= gen_rtx_SET (reg
, b
);
2292 b
= tmp_b
? tmp_b
: gen_reg_rtx (GET_MODE (b
));
2293 rtx_insn
*copy_of_b
= as_a
<rtx_insn
*> (copy_rtx (insn_b
));
2294 rtx set
= single_set (copy_of_b
);
2297 emit_b
= PATTERN (copy_of_b
);
2301 rtx tmp_reg
= tmp_b
? tmp_b
: gen_reg_rtx (GET_MODE (b
));
2302 emit_b
= gen_rtx_SET (tmp_reg
, b
);
2308 modified_in_a
= emit_a
!= NULL_RTX
&& modified_in_p (orig_b
, emit_a
);
2309 if (tmp_b
&& then_bb
)
2311 FOR_BB_INSNS (then_bb
, tmp_insn
)
2312 /* Don't check inside insn_a. We will have changed it to emit_a
2313 with a destination that doesn't conflict. */
2314 if (!(insn_a
&& tmp_insn
== insn_a
)
2315 && modified_in_p (orig_b
, tmp_insn
))
2317 modified_in_a
= true;
2323 modified_in_b
= emit_b
!= NULL_RTX
&& modified_in_p (orig_a
, emit_b
);
2324 if (tmp_a
&& else_bb
)
2326 FOR_BB_INSNS (else_bb
, tmp_insn
)
2327 /* Don't check inside insn_b. We will have changed it to emit_b
2328 with a destination that doesn't conflict. */
2329 if (!(insn_b
&& tmp_insn
== insn_b
)
2330 && modified_in_p (orig_a
, tmp_insn
))
2332 modified_in_b
= true;
2337 /* If insn to set up A clobbers any registers B depends on, try to
2338 swap insn that sets up A with the one that sets up B. If even
2339 that doesn't help, punt. */
2340 if (modified_in_a
&& !modified_in_b
)
2342 if (!noce_emit_bb (emit_b
, else_bb
, b_simple
))
2343 goto end_seq_and_fail
;
2345 if (!noce_emit_bb (emit_a
, then_bb
, a_simple
))
2346 goto end_seq_and_fail
;
2348 else if (!modified_in_a
)
2350 if (!noce_emit_bb (emit_a
, then_bb
, a_simple
))
2351 goto end_seq_and_fail
;
2353 if (!noce_emit_bb (emit_b
, else_bb
, b_simple
))
2354 goto end_seq_and_fail
;
2357 goto end_seq_and_fail
;
2359 target
= noce_emit_cmove (if_info
, x
, code
, XEXP (cond
, 0), XEXP (cond
, 1),
2363 goto end_seq_and_fail
;
2365 /* If we're handling a memory for above, emit the load now. */
2368 rtx mem
= gen_rtx_MEM (GET_MODE (if_info
->x
), target
);
2370 /* Copy over flags as appropriate. */
2371 if (MEM_VOLATILE_P (if_info
->a
) || MEM_VOLATILE_P (if_info
->b
))
2372 MEM_VOLATILE_P (mem
) = 1;
2373 if (MEM_ALIAS_SET (if_info
->a
) == MEM_ALIAS_SET (if_info
->b
))
2374 set_mem_alias_set (mem
, MEM_ALIAS_SET (if_info
->a
));
2376 MIN (MEM_ALIGN (if_info
->a
), MEM_ALIGN (if_info
->b
)));
2378 gcc_assert (MEM_ADDR_SPACE (if_info
->a
) == MEM_ADDR_SPACE (if_info
->b
));
2379 set_mem_addr_space (mem
, MEM_ADDR_SPACE (if_info
->a
));
2381 noce_emit_move_insn (if_info
->x
, mem
);
2383 else if (target
!= x
)
2384 noce_emit_move_insn (x
, target
);
2386 ifcvt_seq
= end_ifcvt_sequence (if_info
);
2387 if (!ifcvt_seq
|| !targetm
.noce_conversion_profitable_p (ifcvt_seq
, if_info
))
2390 emit_insn_before_setloc (ifcvt_seq
, if_info
->jump
,
2391 INSN_LOCATION (if_info
->insn_a
));
2392 if_info
->transform_name
= "noce_try_cmove_arith";
2400 /* For most cases, the simplified condition we found is the best
2401 choice, but this is not the case for the min/max/abs transforms.
2402 For these we wish to know that it is A or B in the condition. */
2405 noce_get_alt_condition (struct noce_if_info
*if_info
, rtx target
,
2406 rtx_insn
**earliest
)
2412 /* If target is already mentioned in the known condition, return it. */
2413 if (reg_mentioned_p (target
, if_info
->cond
))
2415 *earliest
= if_info
->cond_earliest
;
2416 return if_info
->cond
;
2419 set
= pc_set (if_info
->jump
);
2420 cond
= XEXP (SET_SRC (set
), 0);
2422 = GET_CODE (XEXP (SET_SRC (set
), 2)) == LABEL_REF
2423 && label_ref_label (XEXP (SET_SRC (set
), 2)) == JUMP_LABEL (if_info
->jump
);
2424 if (if_info
->then_else_reversed
)
2427 /* If we're looking for a constant, try to make the conditional
2428 have that constant in it. There are two reasons why it may
2429 not have the constant we want:
2431 1. GCC may have needed to put the constant in a register, because
2432 the target can't compare directly against that constant. For
2433 this case, we look for a SET immediately before the comparison
2434 that puts a constant in that register.
2436 2. GCC may have canonicalized the conditional, for example
2437 replacing "if x < 4" with "if x <= 3". We can undo that (or
2438 make equivalent types of changes) to get the constants we need
2439 if they're off by one in the right direction. */
2441 if (CONST_INT_P (target
))
2443 enum rtx_code code
= GET_CODE (if_info
->cond
);
2444 rtx op_a
= XEXP (if_info
->cond
, 0);
2445 rtx op_b
= XEXP (if_info
->cond
, 1);
2446 rtx_insn
*prev_insn
;
2448 /* First, look to see if we put a constant in a register. */
2449 prev_insn
= prev_nonnote_nondebug_insn (if_info
->cond_earliest
);
2451 && BLOCK_FOR_INSN (prev_insn
)
2452 == BLOCK_FOR_INSN (if_info
->cond_earliest
)
2453 && INSN_P (prev_insn
)
2454 && GET_CODE (PATTERN (prev_insn
)) == SET
)
2456 rtx src
= find_reg_equal_equiv_note (prev_insn
);
2458 src
= SET_SRC (PATTERN (prev_insn
));
2459 if (CONST_INT_P (src
))
2461 if (rtx_equal_p (op_a
, SET_DEST (PATTERN (prev_insn
))))
2463 else if (rtx_equal_p (op_b
, SET_DEST (PATTERN (prev_insn
))))
2466 if (CONST_INT_P (op_a
))
2468 std::swap (op_a
, op_b
);
2469 code
= swap_condition (code
);
2474 /* Now, look to see if we can get the right constant by
2475 adjusting the conditional. */
2476 if (CONST_INT_P (op_b
))
2478 HOST_WIDE_INT desired_val
= INTVAL (target
);
2479 HOST_WIDE_INT actual_val
= INTVAL (op_b
);
2484 if (desired_val
!= HOST_WIDE_INT_MAX
2485 && actual_val
== desired_val
+ 1)
2488 op_b
= GEN_INT (desired_val
);
2492 if (desired_val
!= HOST_WIDE_INT_MIN
2493 && actual_val
== desired_val
- 1)
2496 op_b
= GEN_INT (desired_val
);
2500 if (desired_val
!= HOST_WIDE_INT_MIN
2501 && actual_val
== desired_val
- 1)
2504 op_b
= GEN_INT (desired_val
);
2508 if (desired_val
!= HOST_WIDE_INT_MAX
2509 && actual_val
== desired_val
+ 1)
2512 op_b
= GEN_INT (desired_val
);
2520 /* If we made any changes, generate a new conditional that is
2521 equivalent to what we started with, but has the right
2523 if (code
!= GET_CODE (if_info
->cond
)
2524 || op_a
!= XEXP (if_info
->cond
, 0)
2525 || op_b
!= XEXP (if_info
->cond
, 1))
2527 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
), op_a
, op_b
);
2528 *earliest
= if_info
->cond_earliest
;
2533 cond
= canonicalize_condition (if_info
->jump
, cond
, reverse
,
2534 earliest
, target
, have_cbranchcc4
, true);
2535 if (! cond
|| ! reg_mentioned_p (target
, cond
))
2538 /* We almost certainly searched back to a different place.
2539 Need to re-verify correct lifetimes. */
2541 /* X may not be mentioned in the range (cond_earliest, jump]. */
2542 for (insn
= if_info
->jump
; insn
!= *earliest
; insn
= PREV_INSN (insn
))
2543 if (INSN_P (insn
) && reg_overlap_mentioned_p (if_info
->x
, PATTERN (insn
)))
2546 /* A and B may not be modified in the range [cond_earliest, jump). */
2547 for (insn
= *earliest
; insn
!= if_info
->jump
; insn
= NEXT_INSN (insn
))
2549 && (modified_in_p (if_info
->a
, insn
)
2550 || modified_in_p (if_info
->b
, insn
)))
2556 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc. */
2559 noce_try_minmax (struct noce_if_info
*if_info
)
2562 rtx_insn
*earliest
, *seq
;
2563 enum rtx_code code
, op
;
2566 if (!noce_simple_bbs (if_info
))
2569 /* ??? Reject modes with NaNs or signed zeros since we don't know how
2570 they will be resolved with an SMIN/SMAX. It wouldn't be too hard
2571 to get the target to tell us... */
2572 if (HONOR_SIGNED_ZEROS (if_info
->x
)
2573 || HONOR_NANS (if_info
->x
))
2576 cond
= noce_get_alt_condition (if_info
, if_info
->a
, &earliest
);
2580 /* Verify the condition is of the form we expect, and canonicalize
2581 the comparison code. */
2582 code
= GET_CODE (cond
);
2583 if (rtx_equal_p (XEXP (cond
, 0), if_info
->a
))
2585 if (! rtx_equal_p (XEXP (cond
, 1), if_info
->b
))
2588 else if (rtx_equal_p (XEXP (cond
, 1), if_info
->a
))
2590 if (! rtx_equal_p (XEXP (cond
, 0), if_info
->b
))
2592 code
= swap_condition (code
);
2597 /* Determine what sort of operation this is. Note that the code is for
2598 a taken branch, so the code->operation mapping appears backwards. */
2631 target
= expand_simple_binop (GET_MODE (if_info
->x
), op
,
2632 if_info
->a
, if_info
->b
,
2633 if_info
->x
, unsignedp
, OPTAB_WIDEN
);
2639 if (target
!= if_info
->x
)
2640 noce_emit_move_insn (if_info
->x
, target
);
2642 seq
= end_ifcvt_sequence (if_info
);
2646 emit_insn_before_setloc (seq
, if_info
->jump
, INSN_LOCATION (if_info
->insn_a
));
2647 if_info
->cond
= cond
;
2648 if_info
->cond_earliest
= earliest
;
2649 if_info
->rev_cond
= NULL_RTX
;
2650 if_info
->transform_name
= "noce_try_minmax";
2655 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);",
2656 "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);",
2660 noce_try_abs (struct noce_if_info
*if_info
)
2662 rtx cond
, target
, a
, b
, c
;
2663 rtx_insn
*earliest
, *seq
;
2665 bool one_cmpl
= false;
2667 if (!noce_simple_bbs (if_info
))
2670 /* Reject modes with signed zeros. */
2671 if (HONOR_SIGNED_ZEROS (if_info
->x
))
2674 /* Recognize A and B as constituting an ABS or NABS. The canonical
2675 form is a branch around the negation, taken when the object is the
2676 first operand of a comparison against 0 that evaluates to true. */
2679 if (GET_CODE (a
) == NEG
&& rtx_equal_p (XEXP (a
, 0), b
))
2681 else if (GET_CODE (b
) == NEG
&& rtx_equal_p (XEXP (b
, 0), a
))
2686 else if (GET_CODE (a
) == NOT
&& rtx_equal_p (XEXP (a
, 0), b
))
2691 else if (GET_CODE (b
) == NOT
&& rtx_equal_p (XEXP (b
, 0), a
))
2700 cond
= noce_get_alt_condition (if_info
, b
, &earliest
);
2704 /* Verify the condition is of the form we expect. */
2705 if (rtx_equal_p (XEXP (cond
, 0), b
))
2707 else if (rtx_equal_p (XEXP (cond
, 1), b
))
2715 /* Verify that C is zero. Search one step backward for a
2716 REG_EQUAL note or a simple source if necessary. */
2720 rtx_insn
*insn
= prev_nonnote_nondebug_insn (earliest
);
2722 && BLOCK_FOR_INSN (insn
) == BLOCK_FOR_INSN (earliest
)
2723 && (set
= single_set (insn
))
2724 && rtx_equal_p (SET_DEST (set
), c
))
2726 rtx note
= find_reg_equal_equiv_note (insn
);
2736 && GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
2737 && CONSTANT_POOL_ADDRESS_P (XEXP (c
, 0)))
2738 c
= get_pool_constant (XEXP (c
, 0));
2740 /* Work around funny ideas get_condition has wrt canonicalization.
2741 Note that these rtx constants are known to be CONST_INT, and
2742 therefore imply integer comparisons.
2743 The one_cmpl case is more complicated, as we want to handle
2744 only x < 0 ? ~x : x or x >= 0 ? x : ~x to one_cmpl_abs (x)
2745 and x < 0 ? x : ~x or x >= 0 ? ~x : x to ~one_cmpl_abs (x),
2746 but not other cases (x > -1 is equivalent of x >= 0). */
2747 if (c
== constm1_rtx
&& GET_CODE (cond
) == GT
)
2749 else if (c
== const1_rtx
&& GET_CODE (cond
) == LT
)
2754 else if (c
== CONST0_RTX (GET_MODE (b
)))
2757 && GET_CODE (cond
) != GE
2758 && GET_CODE (cond
) != LT
)
2764 /* Determine what sort of operation this is. */
2765 switch (GET_CODE (cond
))
2784 target
= expand_one_cmpl_abs_nojump (GET_MODE (if_info
->x
), b
,
2787 target
= expand_abs_nojump (GET_MODE (if_info
->x
), b
, if_info
->x
, 1);
2789 /* ??? It's a quandary whether cmove would be better here, especially
2790 for integers. Perhaps combine will clean things up. */
2791 if (target
&& negate
)
2794 target
= expand_simple_unop (GET_MODE (target
), NOT
, target
,
2797 target
= expand_simple_unop (GET_MODE (target
), NEG
, target
,
2807 if (target
!= if_info
->x
)
2808 noce_emit_move_insn (if_info
->x
, target
);
2810 seq
= end_ifcvt_sequence (if_info
);
2814 emit_insn_before_setloc (seq
, if_info
->jump
, INSN_LOCATION (if_info
->insn_a
));
2815 if_info
->cond
= cond
;
2816 if_info
->cond_earliest
= earliest
;
2817 if_info
->rev_cond
= NULL_RTX
;
2818 if_info
->transform_name
= "noce_try_abs";
2823 /* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;". */
2826 noce_try_sign_mask (struct noce_if_info
*if_info
)
2832 bool t_unconditional
;
2834 if (!noce_simple_bbs (if_info
))
2837 cond
= if_info
->cond
;
2838 code
= GET_CODE (cond
);
2843 if (if_info
->a
== const0_rtx
)
2845 if ((code
== LT
&& c
== const0_rtx
)
2846 || (code
== LE
&& c
== constm1_rtx
))
2849 else if (if_info
->b
== const0_rtx
)
2851 if ((code
== GE
&& c
== const0_rtx
)
2852 || (code
== GT
&& c
== constm1_rtx
))
2856 if (! t
|| side_effects_p (t
))
2859 /* We currently don't handle different modes. */
2860 mode
= GET_MODE (t
);
2861 if (GET_MODE (m
) != mode
)
2864 /* This is only profitable if T is unconditionally executed/evaluated in the
2865 original insn sequence or T is cheap and can't trap or fault. The former
2866 happens if B is the non-zero (T) value and if INSN_B was taken from
2867 TEST_BB, or there was no INSN_B which can happen for e.g. conditional
2868 stores to memory. For the cost computation use the block TEST_BB where
2869 the evaluation will end up after the transformation. */
2872 && (if_info
->insn_b
== NULL_RTX
2873 || BLOCK_FOR_INSN (if_info
->insn_b
) == if_info
->test_bb
));
2874 if (!(t_unconditional
2875 || ((set_src_cost (t
, mode
, if_info
->speed_p
)
2876 < COSTS_N_INSNS (2))
2877 && !may_trap_or_fault_p (t
))))
2880 if (!noce_can_force_operand (t
))
2884 /* Use emit_store_flag to generate "m < 0 ? -1 : 0" instead of expanding
2885 "(signed) m >> 31" directly. This benefits targets with specialized
2886 insns to obtain the signmask, but still uses ashr_optab otherwise. */
2887 m
= emit_store_flag (gen_reg_rtx (mode
), LT
, m
, const0_rtx
, mode
, 0, -1);
2888 t
= m
? expand_binop (mode
, and_optab
, m
, t
, NULL_RTX
, 0, OPTAB_DIRECT
)
2897 noce_emit_move_insn (if_info
->x
, t
);
2899 seq
= end_ifcvt_sequence (if_info
);
2903 emit_insn_before_setloc (seq
, if_info
->jump
, INSN_LOCATION (if_info
->insn_a
));
2904 if_info
->transform_name
= "noce_try_sign_mask";
2909 /* Check if OP is supported by conditional zero based if conversion,
2910 returning TRUE if satisfied otherwise FALSE.
2912 OP is the operation to check. */
2915 noce_cond_zero_binary_op_supported (rtx op
)
2917 enum rtx_code opcode
= GET_CODE (op
);
2919 if (opcode
== PLUS
|| opcode
== MINUS
|| opcode
== IOR
|| opcode
== XOR
2920 || opcode
== ASHIFT
|| opcode
== ASHIFTRT
|| opcode
== LSHIFTRT
2921 || opcode
== ROTATE
|| opcode
== ROTATERT
|| opcode
== AND
)
2927 /* Helper function to return REG itself,
2928 otherwise NULL_RTX for other RTX_CODE. */
2931 get_base_reg (rtx exp
)
2939 /* Check if IF-BB and THEN-BB satisfy the condition for conditional zero
2940 based if conversion, returning TRUE if satisfied otherwise FALSE.
2942 IF_INFO describes the if-conversion scenario under consideration.
2943 COMMON_PTR points to the common REG of canonicalized IF_INFO->A and
2945 CZERO_CODE_PTR points to the comparison code to use in czero RTX.
2946 A_PTR points to the A expression of canonicalized IF_INFO->A.
2947 TO_REPLACE points to the RTX to be replaced by czero RTX destnation. */
2950 noce_bbs_ok_for_cond_zero_arith (struct noce_if_info
*if_info
, rtx
*common_ptr
,
2952 enum rtx_code
*czero_code_ptr
, rtx
*a_ptr
,
2955 rtx common
= NULL_RTX
;
2956 rtx cond
= if_info
->cond
;
2957 rtx a
= copy_rtx (if_info
->a
);
2958 rtx b
= copy_rtx (if_info
->b
);
2959 rtx bin_op1
= NULL_RTX
;
2960 enum rtx_code czero_code
= UNKNOWN
;
2961 bool reverse
= false;
2962 rtx op0
, op1
, bin_exp
;
2964 if (!noce_simple_bbs (if_info
))
2967 /* COND must be EQ or NE comparision of a reg and 0. */
2968 if (GET_CODE (cond
) != NE
&& GET_CODE (cond
) != EQ
)
2970 if (!REG_P (XEXP (cond
, 0)) || !rtx_equal_p (XEXP (cond
, 1), const0_rtx
))
2973 /* Canonicalize x = y : (y op z) to x = (y op z) : y. */
2974 if (REG_P (a
) && noce_cond_zero_binary_op_supported (b
))
2980 /* Check if x = (y op z) : y is supported by czero based ifcvt. */
2981 if (!(noce_cond_zero_binary_op_supported (a
) && REG_P (b
)))
2986 /* Canonicalize x = (z op y) : y to x = (y op z) : y */
2987 op1
= get_base_reg (XEXP (bin_exp
, 1));
2988 if (op1
&& rtx_equal_p (op1
, b
) && COMMUTATIVE_ARITH_P (bin_exp
))
2989 std::swap (XEXP (bin_exp
, 0), XEXP (bin_exp
, 1));
2991 op0
= get_base_reg (XEXP (bin_exp
, 0));
2992 if (op0
&& rtx_equal_p (op0
, b
))
2995 bin_op1
= XEXP (bin_exp
, 1);
2996 czero_code
= (reverse
^ (GET_CODE (bin_exp
) == AND
))
2997 ? noce_reversed_cond_code (if_info
)
3003 if (czero_code
== UNKNOWN
)
3006 if (REG_P (bin_op1
))
3007 *to_replace
= &XEXP (bin_exp
, 1);
3011 *common_ptr
= common
;
3012 *bin_exp_ptr
= bin_exp
;
3013 *czero_code_ptr
= czero_code
;
3019 /* Try to covert if-then-else with conditional zero,
3020 returning TURE on success or FALSE on failure.
3021 IF_INFO describes the if-conversion scenario under consideration. */
3024 noce_try_cond_zero_arith (struct noce_if_info
*if_info
)
3026 rtx target
, rtmp
, a
;
3028 machine_mode mode
= GET_MODE (if_info
->x
);
3029 rtx common
= NULL_RTX
;
3030 enum rtx_code czero_code
= UNKNOWN
;
3031 rtx bin_exp
= NULL_RTX
;
3032 enum rtx_code bin_code
= UNKNOWN
;
3033 rtx non_zero_op
= NULL_RTX
;
3034 rtx
*to_replace
= NULL
;
3036 if (!noce_bbs_ok_for_cond_zero_arith (if_info
, &common
, &bin_exp
, &czero_code
,
3042 bin_code
= GET_CODE (bin_exp
);
3044 if (bin_code
== AND
)
3046 rtmp
= gen_reg_rtx (mode
);
3047 noce_emit_move_insn (rtmp
, a
);
3049 target
= noce_emit_czero (if_info
, czero_code
, common
, if_info
->x
);
3056 target
= expand_simple_binop (mode
, IOR
, rtmp
, target
, if_info
->x
, 0,
3064 if (target
!= if_info
->x
)
3065 noce_emit_move_insn (if_info
->x
, target
);
3069 non_zero_op
= *to_replace
;
3070 /* If x is used in both input and out like x = c ? x + z : x,
3071 use a new reg to avoid modifying x */
3072 if (common
&& rtx_equal_p (common
, if_info
->x
))
3073 target
= gen_reg_rtx (mode
);
3075 target
= if_info
->x
;
3077 target
= noce_emit_czero (if_info
, czero_code
, non_zero_op
, target
);
3078 if (!target
|| !to_replace
)
3084 *to_replace
= target
;
3085 noce_emit_move_insn (if_info
->x
, a
);
3088 seq
= end_ifcvt_sequence (if_info
);
3089 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
3092 emit_insn_before_setloc (seq
, if_info
->jump
, INSN_LOCATION (if_info
->insn_a
));
3093 if_info
->transform_name
= "noce_try_cond_zero_arith";
3097 /* Optimize away "if (x & C) x |= C" and similar bit manipulation
3101 noce_try_bitop (struct noce_if_info
*if_info
)
3103 rtx cond
, x
, a
, result
;
3105 scalar_int_mode mode
;
3110 cond
= if_info
->cond
;
3111 code
= GET_CODE (cond
);
3113 /* Check for an integer operation. */
3114 if (!is_a
<scalar_int_mode
> (GET_MODE (x
), &mode
))
3117 if (!noce_simple_bbs (if_info
))
3120 /* Check for no else condition. */
3121 if (! rtx_equal_p (x
, if_info
->b
))
3124 /* Check for a suitable condition. */
3125 if (code
!= NE
&& code
!= EQ
)
3127 if (XEXP (cond
, 1) != const0_rtx
)
3129 cond
= XEXP (cond
, 0);
3131 /* ??? We could also handle AND here. */
3132 if (GET_CODE (cond
) == ZERO_EXTRACT
)
3134 if (XEXP (cond
, 1) != const1_rtx
3135 || !CONST_INT_P (XEXP (cond
, 2))
3136 || ! rtx_equal_p (x
, XEXP (cond
, 0)))
3138 bitnum
= INTVAL (XEXP (cond
, 2));
3139 if (BITS_BIG_ENDIAN
)
3140 bitnum
= GET_MODE_BITSIZE (mode
) - 1 - bitnum
;
3141 if (bitnum
< 0 || bitnum
>= HOST_BITS_PER_WIDE_INT
)
3148 if (GET_CODE (a
) == IOR
|| GET_CODE (a
) == XOR
)
3150 /* Check for "if (X & C) x = x op C". */
3151 if (! rtx_equal_p (x
, XEXP (a
, 0))
3152 || !CONST_INT_P (XEXP (a
, 1))
3153 || (INTVAL (XEXP (a
, 1)) & GET_MODE_MASK (mode
))
3154 != HOST_WIDE_INT_1U
<< bitnum
)
3157 /* if ((x & C) == 0) x |= C; is transformed to x |= C. */
3158 /* if ((x & C) != 0) x |= C; is transformed to nothing. */
3159 if (GET_CODE (a
) == IOR
)
3160 result
= (code
== NE
) ? a
: NULL_RTX
;
3161 else if (code
== NE
)
3163 /* if ((x & C) == 0) x ^= C; is transformed to x |= C. */
3164 result
= gen_int_mode (HOST_WIDE_INT_1
<< bitnum
, mode
);
3165 result
= simplify_gen_binary (IOR
, mode
, x
, result
);
3169 /* if ((x & C) != 0) x ^= C; is transformed to x &= ~C. */
3170 result
= gen_int_mode (~(HOST_WIDE_INT_1
<< bitnum
), mode
);
3171 result
= simplify_gen_binary (AND
, mode
, x
, result
);
3174 else if (GET_CODE (a
) == AND
)
3176 /* Check for "if (X & C) x &= ~C". */
3177 if (! rtx_equal_p (x
, XEXP (a
, 0))
3178 || !CONST_INT_P (XEXP (a
, 1))
3179 || (INTVAL (XEXP (a
, 1)) & GET_MODE_MASK (mode
))
3180 != (~(HOST_WIDE_INT_1
<< bitnum
) & GET_MODE_MASK (mode
)))
3183 /* if ((x & C) == 0) x &= ~C; is transformed to nothing. */
3184 /* if ((x & C) != 0) x &= ~C; is transformed to x &= ~C. */
3185 result
= (code
== EQ
) ? a
: NULL_RTX
;
3193 noce_emit_move_insn (x
, result
);
3194 seq
= end_ifcvt_sequence (if_info
);
3198 emit_insn_before_setloc (seq
, if_info
->jump
,
3199 INSN_LOCATION (if_info
->insn_a
));
3201 if_info
->transform_name
= "noce_try_bitop";
3206 /* Similar to get_condition, only the resulting condition must be
3207 valid at JUMP, instead of at EARLIEST.
3209 If THEN_ELSE_REVERSED is true, the fallthrough does not go to the
3210 THEN block of the caller, and we have to reverse the condition. */
3213 noce_get_condition (rtx_insn
*jump
, rtx_insn
**earliest
,
3214 bool then_else_reversed
)
3219 if (! any_condjump_p (jump
))
3222 set
= pc_set (jump
);
3224 /* If this branches to JUMP_LABEL when the condition is false,
3225 reverse the condition. */
3226 reverse
= (GET_CODE (XEXP (SET_SRC (set
), 2)) == LABEL_REF
3227 && label_ref_label (XEXP (SET_SRC (set
), 2)) == JUMP_LABEL (jump
));
3229 /* We may have to reverse because the caller's if block is not canonical,
3230 i.e. the THEN block isn't the fallthrough block for the TEST block
3231 (see find_if_header). */
3232 if (then_else_reversed
)
3235 /* If the condition variable is a register and is MODE_INT, accept it. */
3237 cond
= XEXP (SET_SRC (set
), 0);
3238 tmp
= XEXP (cond
, 0);
3239 if (REG_P (tmp
) && GET_MODE_CLASS (GET_MODE (tmp
)) == MODE_INT
3240 && (GET_MODE (tmp
) != BImode
3241 || !targetm
.small_register_classes_for_mode_p (BImode
)))
3246 cond
= gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond
)),
3247 GET_MODE (cond
), tmp
, XEXP (cond
, 1));
3251 /* Otherwise, fall back on canonicalize_condition to do the dirty
3252 work of manipulating MODE_CC values and COMPARE rtx codes. */
3253 tmp
= canonicalize_condition (jump
, cond
, reverse
, earliest
,
3254 NULL_RTX
, have_cbranchcc4
, true);
3256 /* We don't handle side-effects in the condition, like handling
3257 REG_INC notes and making sure no duplicate conditions are emitted. */
3258 if (tmp
!= NULL_RTX
&& side_effects_p (tmp
))
3264 /* Return true if OP is ok for if-then-else processing. */
3267 noce_operand_ok (const_rtx op
)
3269 if (side_effects_p (op
))
3272 /* We special-case memories, so handle any of them with
3273 no address side effects. */
3275 return ! side_effects_p (XEXP (op
, 0));
3277 return ! may_trap_p (op
);
3280 /* Return true iff basic block TEST_BB is valid for noce if-conversion.
3281 The condition used in this if-conversion is in COND.
3282 In practice, check that TEST_BB ends with a single set
3283 x := a and all previous computations
3284 in TEST_BB don't produce any values that are live after TEST_BB.
3285 In other words, all the insns in TEST_BB are there only
3286 to compute a value for x. Add the rtx cost of the insns
3287 in TEST_BB to COST. Record whether TEST_BB is a single simple
3288 set instruction in SIMPLE_P. */
3291 bb_valid_for_noce_process_p (basic_block test_bb
, rtx cond
,
3292 unsigned int *cost
, bool *simple_p
)
3297 rtx_insn
*last_insn
= last_active_insn (test_bb
, false);
3298 rtx last_set
= NULL_RTX
;
3300 rtx cc
= cc_in_cond (cond
);
3302 if (!insn_valid_noce_process_p (last_insn
, cc
))
3305 /* Punt on blocks ending with asm goto or jumps with other side-effects,
3306 last_active_insn ignores JUMP_INSNs. */
3307 if (JUMP_P (BB_END (test_bb
)) && !onlyjump_p (BB_END (test_bb
)))
3310 last_set
= single_set (last_insn
);
3312 rtx x
= SET_DEST (last_set
);
3313 rtx_insn
*first_insn
= first_active_insn (test_bb
);
3314 rtx first_set
= single_set (first_insn
);
3319 /* We have a single simple set, that's okay. */
3320 bool speed_p
= optimize_bb_for_speed_p (test_bb
);
3322 if (first_insn
== last_insn
)
3324 *simple_p
= noce_operand_ok (SET_DEST (first_set
));
3325 *cost
+= pattern_cost (first_set
, speed_p
);
3329 rtx_insn
*prev_last_insn
= PREV_INSN (last_insn
);
3330 gcc_assert (prev_last_insn
);
3332 /* For now, disallow setting x multiple times in test_bb. */
3333 if (REG_P (x
) && reg_set_between_p (x
, first_insn
, prev_last_insn
))
3336 bitmap test_bb_temps
= BITMAP_ALLOC (®_obstack
);
3338 /* The regs that are live out of test_bb. */
3339 bitmap test_bb_live_out
= df_get_live_out (test_bb
);
3341 int potential_cost
= pattern_cost (last_set
, speed_p
);
3343 FOR_BB_INSNS (test_bb
, insn
)
3345 if (insn
!= last_insn
)
3347 if (!active_insn_p (insn
))
3350 if (!insn_valid_noce_process_p (insn
, cc
))
3351 goto free_bitmap_and_fail
;
3353 rtx sset
= single_set (insn
);
3355 rtx dest
= SET_DEST (sset
);
3356 if (SUBREG_P (dest
))
3357 dest
= SUBREG_REG (dest
);
3359 if (contains_mem_rtx_p (SET_SRC (sset
))
3361 || reg_overlap_mentioned_p (dest
, cond
))
3362 goto free_bitmap_and_fail
;
3364 potential_cost
+= pattern_cost (sset
, speed_p
);
3365 bitmap_set_bit (test_bb_temps
, REGNO (dest
));
3369 /* If any of the intermediate results in test_bb are live after test_bb
3371 if (bitmap_intersect_p (test_bb_live_out
, test_bb_temps
))
3372 goto free_bitmap_and_fail
;
3374 BITMAP_FREE (test_bb_temps
);
3375 *cost
+= potential_cost
;
3379 free_bitmap_and_fail
:
3380 BITMAP_FREE (test_bb_temps
);
3384 /* Helper function to emit a cmov sequence encapsulated in
3385 start_sequence () and end_sequence (). If NEED_CMOV is true
3386 we call noce_emit_cmove to create a cmove sequence. Otherwise emit
3387 a simple move. If successful, store the first instruction of the
3388 sequence in TEMP_DEST and the sequence costs in SEQ_COST. */
3391 try_emit_cmove_seq (struct noce_if_info
*if_info
, rtx temp
,
3392 rtx cond
, rtx new_val
, rtx old_val
, bool need_cmov
,
3393 unsigned *cost
, rtx
*temp_dest
,
3394 rtx cc_cmp
= NULL
, rtx rev_cc_cmp
= NULL
)
3396 rtx_insn
*seq
= NULL
;
3399 rtx x
= XEXP (cond
, 0);
3400 rtx y
= XEXP (cond
, 1);
3401 rtx_code cond_code
= GET_CODE (cond
);
3406 *temp_dest
= noce_emit_cmove (if_info
, temp
, cond_code
,
3407 x
, y
, new_val
, old_val
, cc_cmp
, rev_cc_cmp
);
3411 if (if_info
->then_else_reversed
)
3412 noce_emit_move_insn (temp
, old_val
);
3414 noce_emit_move_insn (temp
, new_val
);
3417 if (*temp_dest
!= NULL_RTX
)
3420 *cost
= seq_cost (seq
, if_info
->speed_p
);
3428 /* We have something like:
3431 { i = EXPR_A; j = EXPR_B; k = EXPR_C; }
3435 tmp_i = (x > y) ? EXPR_A : i;
3436 tmp_j = (x > y) ? EXPR_B : j;
3437 tmp_k = (x > y) ? EXPR_C : k;
3442 Subsequent passes are expected to clean up the extra moves.
3444 Look for special cases such as writes to one register which are
3445 read back in another SET, as might occur in a swap idiom or
3454 Which we want to rewrite to:
3456 tmp_i = (x > y) ? a : i;
3457 tmp_j = (x > y) ? tmp_i : j;
3461 We can catch these when looking at (SET x y) by keeping a list of the
3462 registers we would have targeted before if-conversion and looking back
3463 through it for an overlap with Y. If we find one, we rewire the
3464 conditional set to use the temporary we introduced earlier.
3466 IF_INFO contains the useful information about the block structure and
3467 jump instructions. */
3470 noce_convert_multiple_sets (struct noce_if_info
*if_info
)
3472 basic_block test_bb
= if_info
->test_bb
;
3473 basic_block then_bb
= if_info
->then_bb
;
3474 basic_block join_bb
= if_info
->join_bb
;
3475 rtx_insn
*jump
= if_info
->jump
;
3476 rtx_insn
*cond_earliest
;
3481 /* Decompose the condition attached to the jump. */
3482 rtx cond
= noce_get_condition (jump
, &cond_earliest
, false);
3483 rtx x
= XEXP (cond
, 0);
3484 rtx y
= XEXP (cond
, 1);
3486 auto_delete_vec
<noce_multiple_sets_info
> insn_info
;
3487 init_noce_multiple_sets_info (then_bb
, insn_info
);
3489 int last_needs_comparison
= -1;
3491 bool ok
= noce_convert_multiple_sets_1
3492 (if_info
, insn_info
, &last_needs_comparison
);
3496 /* If there are insns that overwrite part of the initial
3497 comparison, we can still omit creating temporaries for
3499 As the second try will always create a less expensive,
3500 valid sequence, we do not need to compare and can discard
3502 if (last_needs_comparison
!= -1)
3506 ok
= noce_convert_multiple_sets_1
3507 (if_info
, insn_info
, &last_needs_comparison
);
3508 /* Actually we should not fail anymore if we reached here,
3509 but better still check. */
3514 /* We must have seen some sort of insn to insert, otherwise we were
3515 given an empty BB to convert, and we can't handle that. */
3516 gcc_assert (!insn_info
.is_empty ());
3518 /* Now fixup the assignments.
3519 PR116405: Iterate in reverse order and keep track of the targets so that
3520 a move does not overwrite a subsequent value when multiple instructions
3521 have the same target. */
3523 noce_multiple_sets_info
*info
;
3524 bitmap set_targets
= BITMAP_ALLOC (®_obstack
);
3525 FOR_EACH_VEC_ELT_REVERSE (insn_info
, i
, info
)
3527 gcc_checking_assert (REG_P (info
->target
));
3529 if (info
->target
!= info
->temporary
3530 && !bitmap_bit_p (set_targets
, REGNO (info
->target
)))
3531 noce_emit_move_insn (info
->target
, info
->temporary
);
3533 bitmap_set_bit (set_targets
, REGNO (info
->target
));
3535 BITMAP_FREE (set_targets
);
3537 /* Actually emit the sequence if it isn't too expensive. */
3538 rtx_insn
*seq
= get_insns ();
3540 if (!targetm
.noce_conversion_profitable_p (seq
, if_info
))
3546 for (insn
= seq
; insn
; insn
= NEXT_INSN (insn
))
3547 set_used_flags (insn
);
3549 /* Mark all our temporaries and targets as used. */
3550 for (unsigned i
= 0; i
< insn_info
.length (); i
++)
3552 set_used_flags (insn_info
[i
]->temporary
);
3553 set_used_flags (insn_info
[i
]->target
);
3556 set_used_flags (cond
);
3560 unshare_all_rtl_in_chain (seq
);
3566 for (insn
= seq
; insn
; insn
= NEXT_INSN (insn
))
3567 if (JUMP_P (insn
) || CALL_P (insn
)
3568 || recog_memoized (insn
) == -1)
3571 emit_insn_before_setloc (seq
, if_info
->jump
,
3572 INSN_LOCATION (insn_info
.last ()->unmodified_insn
));
3574 /* Clean up THEN_BB and the edges in and out of it. */
3575 remove_edge (find_edge (test_bb
, join_bb
));
3576 remove_edge (find_edge (then_bb
, join_bb
));
3577 redirect_edge_and_branch_force (single_succ_edge (test_bb
), join_bb
);
3578 delete_basic_block (then_bb
);
3581 /* Maybe merge blocks now the jump is simple enough. */
3582 if (can_merge_blocks_p (test_bb
, join_bb
))
3584 merge_blocks (test_bb
, join_bb
);
3588 num_updated_if_blocks
++;
3589 if_info
->transform_name
= "noce_convert_multiple_sets";
3593 /* This goes through all relevant insns of IF_INFO->then_bb and tries to create
3594 conditional moves. Information for the insns is kept in INSN_INFO. */
3597 noce_convert_multiple_sets_1 (struct noce_if_info
*if_info
,
3598 auto_delete_vec
<noce_multiple_sets_info
> &insn_info
,
3599 int *last_needs_comparison
)
3601 basic_block then_bb
= if_info
->then_bb
;
3602 rtx_insn
*jump
= if_info
->jump
;
3603 rtx_insn
*cond_earliest
;
3605 /* Decompose the condition attached to the jump. */
3606 rtx cond
= noce_get_condition (jump
, &cond_earliest
, false);
3608 rtx cc_cmp
= cond_exec_get_condition (jump
);
3610 cc_cmp
= copy_rtx (cc_cmp
);
3611 rtx rev_cc_cmp
= cond_exec_get_condition (jump
, /* get_reversed */ true);
3613 rev_cc_cmp
= copy_rtx (rev_cc_cmp
);
3617 bool second_try
= *last_needs_comparison
!= -1;
3619 FOR_BB_INSNS (then_bb
, insn
)
3621 /* Skip over non-insns. */
3622 if (!active_insn_p (insn
))
3625 noce_multiple_sets_info
*info
= insn_info
[count
];
3627 rtx set
= single_set (insn
);
3628 gcc_checking_assert (set
);
3630 rtx target
= SET_DEST (set
);
3633 rtx new_val
= SET_SRC (set
);
3636 FOR_EACH_VEC_ELT (info
->rewired_src
, i
, ii
)
3637 new_val
= simplify_replace_rtx (new_val
, insn_info
[ii
]->target
,
3638 insn_info
[ii
]->temporary
);
3640 rtx old_val
= target
;
3642 /* As we are transforming
3652 we potentially check x > y before every set.
3653 Even though the check might be removed by subsequent passes, this means
3654 that we cannot transform
3663 since this would invalidate x and the following to-be-removed checks.
3664 Therefore we introduce a temporary every time we are about to
3665 overwrite a variable used in the check. Costing of a sequence with
3666 these is going to be inaccurate so only use temporaries when
3669 If performing a second try, we know how many insns require a
3670 temporary. For the last of these, we can omit creating one. */
3671 if (reg_overlap_mentioned_p (target
, cond
)
3672 && (!second_try
|| count
< *last_needs_comparison
))
3673 temp
= gen_reg_rtx (GET_MODE (target
));
3677 /* We have identified swap-style idioms before. A normal
3678 set will need to be a cmov while the first instruction of a swap-style
3679 idiom can be a regular move. This helps with costing. */
3680 bool need_cmov
= info
->need_cmov
;
3682 /* If we had a non-canonical conditional jump (i.e. one where
3683 the fallthrough is to the "else" case) we need to reverse
3684 the conditional select. */
3685 if (if_info
->then_else_reversed
)
3686 std::swap (old_val
, new_val
);
3688 /* Try emitting a conditional move passing the backend the
3689 canonicalized comparison. The backend is then able to
3690 recognize expressions like
3695 as min/max and emit an insn, accordingly. */
3696 unsigned cost1
= 0, cost2
= 0;
3697 rtx_insn
*seq
, *seq1
, *seq2
= NULL
;
3698 rtx temp_dest
= NULL_RTX
, temp_dest1
= NULL_RTX
, temp_dest2
= NULL_RTX
;
3699 bool read_comparison
= false;
3701 seq1
= try_emit_cmove_seq (if_info
, temp
, cond
,
3702 new_val
, old_val
, need_cmov
,
3703 &cost1
, &temp_dest1
);
3705 /* Here, we try to pass the backend a non-canonicalized cc comparison
3706 as well. This allows the backend to emit a cmov directly without
3707 creating an additional compare for each. If successful, costing
3708 is easier and this sequence is usually preferred. */
3711 seq2
= try_emit_cmove_seq (if_info
, temp
, cond
,
3712 new_val
, old_val
, need_cmov
,
3713 &cost2
, &temp_dest2
, cc_cmp
, rev_cc_cmp
);
3715 /* The if_then_else in SEQ2 may be affected when cc_cmp/rev_cc_cmp is
3716 clobbered. We can't safely use the sequence in this case. */
3717 for (rtx_insn
*iter
= seq2
; iter
; iter
= NEXT_INSN (iter
))
3718 if (modified_in_p (cc_cmp
, iter
)
3719 || (rev_cc_cmp
&& modified_in_p (rev_cc_cmp
, iter
)))
3726 /* The backend might have created a sequence that uses the
3727 condition as a value. Check this. */
3729 /* We cannot handle anything more complex than a reg or constant. */
3730 if (!REG_P (XEXP (cond
, 0)) && !CONSTANT_P (XEXP (cond
, 0)))
3731 read_comparison
= true;
3733 if (!REG_P (XEXP (cond
, 1)) && !CONSTANT_P (XEXP (cond
, 1)))
3734 read_comparison
= true;
3736 rtx_insn
*walk
= seq2
;
3737 int if_then_else_count
= 0;
3738 while (walk
&& !read_comparison
)
3740 rtx exprs_to_check
[2];
3741 unsigned int exprs_count
= 0;
3743 rtx set
= single_set (walk
);
3744 if (set
&& XEXP (set
, 1)
3745 && GET_CODE (XEXP (set
, 1)) == IF_THEN_ELSE
)
3747 /* We assume that this is the cmove created by the backend that
3748 naturally uses the condition. */
3749 exprs_to_check
[exprs_count
++] = XEXP (XEXP (set
, 1), 1);
3750 exprs_to_check
[exprs_count
++] = XEXP (XEXP (set
, 1), 2);
3751 if_then_else_count
++;
3753 else if (NONDEBUG_INSN_P (walk
))
3754 exprs_to_check
[exprs_count
++] = PATTERN (walk
);
3756 /* Bail if we get more than one if_then_else because the assumption
3757 above may be incorrect. */
3758 if (if_then_else_count
> 1)
3760 read_comparison
= true;
3764 for (unsigned int i
= 0; i
< exprs_count
; i
++)
3766 subrtx_iterator::array_type array
;
3767 FOR_EACH_SUBRTX (iter
, array
, exprs_to_check
[i
], NONCONST
)
3768 if (*iter
!= NULL_RTX
3769 && (reg_overlap_mentioned_p (XEXP (cond
, 0), *iter
)
3770 || reg_overlap_mentioned_p (XEXP (cond
, 1), *iter
)))
3772 read_comparison
= true;
3777 walk
= NEXT_INSN (walk
);
3780 /* Check which version is less expensive. */
3781 if (seq1
!= NULL_RTX
&& (cost1
<= cost2
|| seq2
== NULL_RTX
))
3784 temp_dest
= temp_dest1
;
3786 *last_needs_comparison
= count
;
3788 else if (seq2
!= NULL_RTX
)
3791 temp_dest
= temp_dest2
;
3792 if (!second_try
&& read_comparison
)
3793 *last_needs_comparison
= count
;
3797 /* Nothing worked, bail out. */
3802 /* Although we use temporaries if there is register overlap of COND and
3803 TARGET, it is possible that SEQ modifies COND anyway. For example,
3804 COND may use the flags register and if INSN clobbers flags then
3805 we may be unable to emit a valid sequence (e.g. in x86 that would
3806 require saving and restoring the flags register). */
3808 for (rtx_insn
*iter
= seq
; iter
; iter
= NEXT_INSN (iter
))
3809 if (modified_in_p (cond
, iter
))
3815 if (cc_cmp
&& seq
== seq1
)
3817 /* Check if SEQ can clobber registers mentioned in cc_cmp/rev_cc_cmp.
3818 If yes, we need to use only SEQ1 from that point on.
3819 Only check when we use SEQ1 since we have already tested SEQ2. */
3820 for (rtx_insn
*iter
= seq
; iter
; iter
= NEXT_INSN (iter
))
3821 if (modified_in_p (cc_cmp
, iter
)
3822 || (rev_cc_cmp
&& modified_in_p (rev_cc_cmp
, iter
)))
3825 rev_cc_cmp
= NULL_RTX
;
3830 /* End the sub sequence and emit to the main sequence. */
3836 info
->target
= target
;
3837 info
->temporary
= temp_dest
;
3838 info
->unmodified_insn
= insn
;
3841 /* Even if we did not actually need the comparison, we want to make sure
3842 to try a second time in order to get rid of the temporaries. */
3843 if (*last_needs_comparison
== -1)
3844 *last_needs_comparison
= 0;
3849 /* Find local swap-style idioms in BB and mark the first insn (1)
3850 that is only a temporary as not needing a conditional move as
3851 it is going to be dead afterwards anyway.
3861 a = cond ? b : a_old;
3862 b = cond ? tmp : b_old;
3864 Additionally, store the index of insns like (2) when a subsequent
3865 SET reads from their destination.
3873 c = cond ? a : c_old;
3874 d = cond ? d : c; // Need to use c rather than c_old here.
3878 init_noce_multiple_sets_info (basic_block bb
,
3879 auto_delete_vec
<noce_multiple_sets_info
> &insn_info
)
3883 auto_vec
<rtx
> dests
;
3884 bitmap bb_live_out
= df_get_live_out (bb
);
3886 /* Iterate over all SETs, storing the destinations in DEST.
3887 - If we encounter a previously changed register,
3888 rewire the read to the original source.
3889 - If we encounter a SET that writes to a destination
3890 that is not live after this block then the register
3891 does not need to be moved conditionally. */
3892 FOR_BB_INSNS (bb
, insn
)
3894 if (!active_insn_p (insn
))
3897 noce_multiple_sets_info
*info
= new noce_multiple_sets_info
;
3898 info
->target
= NULL_RTX
;
3899 info
->temporary
= NULL_RTX
;
3900 info
->unmodified_insn
= NULL
;
3901 insn_info
.safe_push (info
);
3903 rtx set
= single_set (insn
);
3904 gcc_checking_assert (set
);
3906 rtx src
= SET_SRC (set
);
3907 rtx dest
= SET_DEST (set
);
3909 gcc_checking_assert (REG_P (dest
));
3910 info
->need_cmov
= bitmap_bit_p (bb_live_out
, REGNO (dest
));
3912 /* Check if the current SET's source is the same
3913 as any previously seen destination.
3914 This is quadratic but the number of insns in BB
3915 is bounded by PARAM_MAX_RTL_IF_CONVERSION_INSNS. */
3916 for (int i
= count
- 1; i
>= 0; --i
)
3917 if (reg_mentioned_p (dests
[i
], src
))
3918 insn_info
[count
]->rewired_src
.safe_push (i
);
3920 dests
.safe_push (dest
);
3925 /* Return true iff basic block TEST_BB is suitable for conversion to a
3926 series of conditional moves. Also check that we have more than one
3927 set (other routines can handle a single set better than we would),
3928 and fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. While going
3929 through the insns store the sum of their potential costs in COST. */
3932 bb_ok_for_noce_convert_multiple_sets (basic_block test_bb
, unsigned *cost
)
3936 unsigned param
= param_max_rtl_if_conversion_insns
;
3937 bool speed_p
= optimize_bb_for_speed_p (test_bb
);
3938 unsigned potential_cost
= 0;
3940 FOR_BB_INSNS (test_bb
, insn
)
3942 /* Skip over notes etc. */
3943 if (!active_insn_p (insn
))
3946 /* We only handle SET insns. */
3947 rtx set
= single_set (insn
);
3948 if (set
== NULL_RTX
)
3951 rtx dest
= SET_DEST (set
);
3952 rtx src
= SET_SRC (set
);
3954 /* Do not handle anything involving memory loads/stores since it might
3955 violate data-race-freedom guarantees. Make sure we can force SRC
3956 to a register as that may be needed in try_emit_cmove_seq. */
3957 if (!REG_P (dest
) || contains_mem_rtx_p (src
)
3958 || !noce_can_force_operand (src
))
3961 /* Destination and source must be appropriate. */
3962 if (!noce_operand_ok (dest
) || !noce_operand_ok (src
))
3965 /* We must be able to conditionally move in this mode. */
3966 if (!can_conditionally_move_p (GET_MODE (dest
)))
3969 potential_cost
+= insn_cost (insn
, speed_p
);
3974 *cost
+= potential_cost
;
3976 /* If we would only put out one conditional move, the other strategies
3977 this pass tries are better optimized and will be more appropriate.
3978 Some targets want to strictly limit the number of conditional moves
3979 that are emitted, they set this through PARAM, we need to respect
3981 return count
> 1 && count
<= param
;
3984 /* Compute average of two given costs weighted by relative probabilities
3985 of respective basic blocks in an IF-THEN-ELSE. E is the IF-THEN edge.
3986 With P as the probability to take the IF-THEN branch, return
3987 P * THEN_COST + (1 - P) * ELSE_COST. */
3989 average_cost (unsigned then_cost
, unsigned else_cost
, edge e
)
3991 return else_cost
+ e
->probability
.apply ((signed) (then_cost
- else_cost
));
3994 /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
3995 it without using conditional execution. Return TRUE if we were successful
3996 at converting the block. */
3999 noce_process_if_block (struct noce_if_info
*if_info
)
4001 basic_block test_bb
= if_info
->test_bb
; /* test block */
4002 basic_block then_bb
= if_info
->then_bb
; /* THEN */
4003 basic_block else_bb
= if_info
->else_bb
; /* ELSE or NULL */
4004 basic_block join_bb
= if_info
->join_bb
; /* JOIN */
4005 rtx_insn
*jump
= if_info
->jump
;
4006 rtx cond
= if_info
->cond
;
4007 rtx_insn
*insn_a
, *insn_b
;
4009 rtx orig_x
, x
, a
, b
;
4011 /* We're looking for patterns of the form
4013 (1) if (...) x = a; else x = b;
4014 (2) x = b; if (...) x = a;
4015 (3) if (...) x = a; // as if with an initial x = x.
4016 (4) if (...) { x = a; y = b; z = c; } // Like 3, for multiple SETS.
4017 The later patterns require jumps to be more expensive.
4018 For the if (...) x = a; else x = b; case we allow multiple insns
4019 inside the then and else blocks as long as their only effect is
4020 to calculate a value for x.
4021 ??? For future expansion, further expand the "multiple X" rules. */
4023 /* First look for multiple SETS. The original costs already include
4024 a base cost of COSTS_N_INSNS (2): one instruction for the compare
4025 (which we will be needing either way) and one instruction for the
4026 branch. When comparing costs we want to use the branch instruction
4027 cost and the sets vs. the cmovs generated here. Therefore subtract
4028 the costs of the compare before checking.
4029 ??? Actually, instead of the branch instruction costs we might want
4030 to use COSTS_N_INSNS (BRANCH_COST ()) as in other places. */
4032 unsigned potential_cost
= if_info
->original_cost
- COSTS_N_INSNS (1);
4033 unsigned old_cost
= if_info
->original_cost
;
4035 && HAVE_conditional_move
4036 && bb_ok_for_noce_convert_multiple_sets (then_bb
, &potential_cost
))
4038 /* Temporarily set the original costs to what we estimated so
4039 we can determine if the transformation is worth it. */
4040 if_info
->original_cost
= potential_cost
;
4041 if (noce_convert_multiple_sets (if_info
))
4043 if (dump_file
&& if_info
->transform_name
)
4044 fprintf (dump_file
, "if-conversion succeeded through %s\n",
4045 if_info
->transform_name
);
4049 /* Restore the original costs. */
4050 if_info
->original_cost
= old_cost
;
4053 bool speed_p
= optimize_bb_for_speed_p (test_bb
);
4054 unsigned int then_cost
= 0, else_cost
= 0;
4055 if (!bb_valid_for_noce_process_p (then_bb
, cond
, &then_cost
,
4056 &if_info
->then_simple
))
4060 && !bb_valid_for_noce_process_p (else_bb
, cond
, &else_cost
,
4061 &if_info
->else_simple
))
4065 if_info
->original_cost
+= average_cost (then_cost
, else_cost
,
4066 find_edge (test_bb
, then_bb
));
4068 if_info
->original_cost
+= then_cost
+ else_cost
;
4070 insn_a
= last_active_insn (then_bb
, false);
4071 set_a
= single_set (insn_a
);
4074 x
= SET_DEST (set_a
);
4075 a
= SET_SRC (set_a
);
4077 /* Look for the other potential set. Make sure we've got equivalent
4079 /* ??? This is overconservative. Storing to two different mems is
4080 as easy as conditionally computing the address. Storing to a
4081 single mem merely requires a scratch memory to use as one of the
4082 destination addresses; often the memory immediately below the
4083 stack pointer is available for this. */
4087 insn_b
= last_active_insn (else_bb
, false);
4088 set_b
= single_set (insn_b
);
4091 if (!rtx_interchangeable_p (x
, SET_DEST (set_b
)))
4096 insn_b
= if_info
->cond_earliest
;
4098 insn_b
= prev_nonnote_nondebug_insn (insn_b
);
4100 && (BLOCK_FOR_INSN (insn_b
)
4101 == BLOCK_FOR_INSN (if_info
->cond_earliest
))
4102 && !modified_in_p (x
, insn_b
));
4104 /* We're going to be moving the evaluation of B down from above
4105 COND_EARLIEST to JUMP. Make sure the relevant data is still
4108 || BLOCK_FOR_INSN (insn_b
) != BLOCK_FOR_INSN (if_info
->cond_earliest
)
4109 || !NONJUMP_INSN_P (insn_b
)
4110 || (set_b
= single_set (insn_b
)) == NULL_RTX
4111 || ! rtx_interchangeable_p (x
, SET_DEST (set_b
))
4112 || ! noce_operand_ok (SET_SRC (set_b
))
4113 || reg_overlap_mentioned_p (x
, SET_SRC (set_b
))
4114 || modified_between_p (SET_SRC (set_b
), insn_b
, jump
)
4115 /* Avoid extending the lifetime of hard registers on small
4116 register class machines. */
4117 || (REG_P (SET_SRC (set_b
))
4118 && HARD_REGISTER_P (SET_SRC (set_b
))
4119 && targetm
.small_register_classes_for_mode_p
4120 (GET_MODE (SET_SRC (set_b
))))
4121 /* Likewise with X. In particular this can happen when
4122 noce_get_condition looks farther back in the instruction
4123 stream than one might expect. */
4124 || reg_overlap_mentioned_p (x
, cond
)
4125 || reg_overlap_mentioned_p (x
, a
)
4126 || modified_between_p (x
, insn_b
, jump
))
4133 /* If x has side effects then only the if-then-else form is safe to
4134 convert. But even in that case we would need to restore any notes
4135 (such as REG_INC) at then end. That can be tricky if
4136 noce_emit_move_insn expands to more than one insn, so disable the
4137 optimization entirely for now if there are side effects. */
4138 if (side_effects_p (x
))
4141 b
= (set_b
? SET_SRC (set_b
) : x
);
4143 /* Only operate on register destinations, and even then avoid extending
4144 the lifetime of hard registers on small register class machines. */
4146 if_info
->orig_x
= orig_x
;
4148 || (HARD_REGISTER_P (x
)
4149 && targetm
.small_register_classes_for_mode_p (GET_MODE (x
))))
4151 if (GET_MODE (x
) == BLKmode
)
4154 if (GET_CODE (x
) == ZERO_EXTRACT
4155 && (!CONST_INT_P (XEXP (x
, 1))
4156 || !CONST_INT_P (XEXP (x
, 2))))
4159 x
= gen_reg_rtx (GET_MODE (GET_CODE (x
) == STRICT_LOW_PART
4160 ? XEXP (x
, 0) : x
));
4163 /* Don't operate on sources that may trap or are volatile. */
4164 if (! noce_operand_ok (a
) || ! noce_operand_ok (b
))
4168 /* Set up the info block for our subroutines. */
4169 if_info
->insn_a
= insn_a
;
4170 if_info
->insn_b
= insn_b
;
4175 /* Try optimizations in some approximation of a useful order. */
4176 /* ??? Should first look to see if X is live incoming at all. If it
4177 isn't, we don't need anything but an unconditional set. */
4179 /* Look and see if A and B are really the same. Avoid creating silly
4180 cmove constructs that no one will fix up later. */
4181 if (noce_simple_bbs (if_info
)
4182 && rtx_interchangeable_p (a
, b
))
4184 /* If we have an INSN_B, we don't have to create any new rtl. Just
4185 move the instruction that we already have. If we don't have an
4186 INSN_B, that means that A == X, and we've got a noop move. In
4187 that case don't do anything and let the code below delete INSN_A. */
4188 if (insn_b
&& else_bb
)
4192 if (else_bb
&& insn_b
== BB_END (else_bb
))
4193 BB_END (else_bb
) = PREV_INSN (insn_b
);
4194 reorder_insns (insn_b
, insn_b
, PREV_INSN (jump
));
4196 /* If there was a REG_EQUAL note, delete it since it may have been
4197 true due to this insn being after a jump. */
4198 if ((note
= find_reg_note (insn_b
, REG_EQUAL
, NULL_RTX
)) != 0)
4199 remove_note (insn_b
, note
);
4203 /* If we have "x = b; if (...) x = a;", and x has side-effects, then
4204 x must be executed twice. */
4205 else if (insn_b
&& side_effects_p (orig_x
))
4212 if (!set_b
&& MEM_P (orig_x
))
4213 /* We want to avoid store speculation to avoid cases like
4214 if (pthread_mutex_trylock(mutex))
4216 Rather than go to much effort here, we rely on the SSA optimizers,
4217 which do a good enough job these days. */
4220 if (noce_try_move (if_info
))
4222 if (noce_try_ifelse_collapse (if_info
))
4224 if (noce_try_store_flag (if_info
))
4226 if (noce_try_bitop (if_info
))
4228 if (noce_try_minmax (if_info
))
4230 if (noce_try_abs (if_info
))
4232 if (noce_try_inverse_constants (if_info
))
4234 if (!targetm
.have_conditional_execution ()
4235 && noce_try_store_flag_constants (if_info
))
4237 if (HAVE_conditional_move
4238 && noce_try_cmove (if_info
))
4240 if (! targetm
.have_conditional_execution ())
4242 if (noce_try_addcc (if_info
))
4244 if (noce_try_store_flag_mask (if_info
))
4246 if (HAVE_conditional_move
4247 && noce_try_cond_zero_arith (if_info
))
4249 if (HAVE_conditional_move
4250 && noce_try_cmove_arith (if_info
))
4252 if (noce_try_sign_mask (if_info
))
4256 if (!else_bb
&& set_b
)
4267 if (dump_file
&& if_info
->transform_name
)
4268 fprintf (dump_file
, "if-conversion succeeded through %s\n",
4269 if_info
->transform_name
);
4271 /* If we used a temporary, fix it up now. */
4277 noce_emit_move_insn (orig_x
, x
);
4279 set_used_flags (orig_x
);
4280 unshare_all_rtl_in_chain (seq
);
4283 emit_insn_before_setloc (seq
, BB_END (test_bb
), INSN_LOCATION (insn_a
));
4286 /* The original THEN and ELSE blocks may now be removed. The test block
4287 must now jump to the join block. If the test block and the join block
4288 can be merged, do so. */
4291 delete_basic_block (else_bb
);
4295 remove_edge (find_edge (test_bb
, join_bb
));
4297 remove_edge (find_edge (then_bb
, join_bb
));
4298 redirect_edge_and_branch_force (single_succ_edge (test_bb
), join_bb
);
4299 delete_basic_block (then_bb
);
4302 if (can_merge_blocks_p (test_bb
, join_bb
))
4304 merge_blocks (test_bb
, join_bb
);
4308 num_updated_if_blocks
++;
4312 /* Check whether a block is suitable for conditional move conversion.
4313 Every insn must be a simple set of a register to a constant or a
4314 register. For each assignment, store the value in the pointer map
4315 VALS, keyed indexed by register pointer, then store the register
4316 pointer in REGS. COND is the condition we will test. */
4319 check_cond_move_block (basic_block bb
,
4320 hash_map
<rtx
, rtx
> *vals
,
4325 rtx cc
= cc_in_cond (cond
);
4327 /* We can only handle simple jumps at the end of the basic block.
4328 It is almost impossible to update the CFG otherwise. */
4330 if (JUMP_P (insn
) && !onlyjump_p (insn
))
4333 FOR_BB_INSNS (bb
, insn
)
4337 if (!NONDEBUG_INSN_P (insn
) || JUMP_P (insn
))
4339 set
= single_set (insn
);
4343 dest
= SET_DEST (set
);
4344 src
= SET_SRC (set
);
4346 || (HARD_REGISTER_P (dest
)
4347 && targetm
.small_register_classes_for_mode_p (GET_MODE (dest
))))
4350 if (!CONSTANT_P (src
) && !register_operand (src
, VOIDmode
))
4353 if (side_effects_p (src
) || side_effects_p (dest
))
4356 if (may_trap_p (src
) || may_trap_p (dest
))
4359 /* Don't try to handle this if the source register was
4360 modified earlier in the block. */
4363 || (GET_CODE (src
) == SUBREG
&& REG_P (SUBREG_REG (src
))
4364 && vals
->get (SUBREG_REG (src
))))
4367 /* Don't try to handle this if the destination register was
4368 modified earlier in the block. */
4369 if (vals
->get (dest
))
4372 /* Don't try to handle this if the condition uses the
4373 destination register. */
4374 if (reg_overlap_mentioned_p (dest
, cond
))
4377 /* Don't try to handle this if the source register is modified
4378 later in the block. */
4379 if (!CONSTANT_P (src
)
4380 && modified_between_p (src
, insn
, NEXT_INSN (BB_END (bb
))))
4383 /* Skip it if the instruction to be moved might clobber CC. */
4384 if (cc
&& set_of (cc
, insn
))
4387 vals
->put (dest
, src
);
4389 regs
->safe_push (dest
);
4395 /* Given a basic block BB suitable for conditional move conversion,
4396 a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing
4397 the register values depending on COND, emit the insns in the block as
4398 conditional moves. If ELSE_BLOCK is true, THEN_BB was already
4399 processed. The caller has started a sequence for the conversion.
4400 Return true if successful, false if something goes wrong. */
4403 cond_move_convert_if_block (struct noce_if_info
*if_infop
,
4404 basic_block bb
, rtx cond
,
4405 hash_map
<rtx
, rtx
> *then_vals
,
4406 hash_map
<rtx
, rtx
> *else_vals
,
4411 rtx cond_arg0
, cond_arg1
;
4413 code
= GET_CODE (cond
);
4414 cond_arg0
= XEXP (cond
, 0);
4415 cond_arg1
= XEXP (cond
, 1);
4417 FOR_BB_INSNS (bb
, insn
)
4419 rtx set
, target
, dest
, t
, e
;
4421 /* ??? Maybe emit conditional debug insn? */
4422 if (!NONDEBUG_INSN_P (insn
) || JUMP_P (insn
))
4424 set
= single_set (insn
);
4425 gcc_assert (set
&& REG_P (SET_DEST (set
)));
4427 dest
= SET_DEST (set
);
4429 rtx
*then_slot
= then_vals
->get (dest
);
4430 rtx
*else_slot
= else_vals
->get (dest
);
4431 t
= then_slot
? *then_slot
: NULL_RTX
;
4432 e
= else_slot
? *else_slot
: NULL_RTX
;
4436 /* If this register was set in the then block, we already
4437 handled this case there. */
4450 if (if_infop
->cond_inverted
)
4453 target
= noce_emit_cmove (if_infop
, dest
, code
, cond_arg0
, cond_arg1
,
4459 noce_emit_move_insn (dest
, target
);
4465 /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
4466 it using only conditional moves. Return TRUE if we were successful at
4467 converting the block. */
4470 cond_move_process_if_block (struct noce_if_info
*if_info
)
4472 basic_block test_bb
= if_info
->test_bb
;
4473 basic_block then_bb
= if_info
->then_bb
;
4474 basic_block else_bb
= if_info
->else_bb
;
4475 basic_block join_bb
= if_info
->join_bb
;
4476 rtx_insn
*jump
= if_info
->jump
;
4477 rtx cond
= if_info
->cond
;
4478 rtx_insn
*seq
, *loc_insn
;
4480 vec
<rtx
> then_regs
= vNULL
;
4481 vec
<rtx
> else_regs
= vNULL
;
4482 bool success_p
= false;
4483 int limit
= param_max_rtl_if_conversion_insns
;
4485 /* Build a mapping for each block to the value used for each
4487 hash_map
<rtx
, rtx
> then_vals
;
4488 hash_map
<rtx
, rtx
> else_vals
;
4490 /* Make sure the blocks are suitable. */
4491 if (!check_cond_move_block (then_bb
, &then_vals
, &then_regs
, cond
)
4493 && !check_cond_move_block (else_bb
, &else_vals
, &else_regs
, cond
)))
4496 /* Make sure the blocks can be used together. If the same register
4497 is set in both blocks, and is not set to a constant in both
4498 cases, then both blocks must set it to the same register. We
4499 have already verified that if it is set to a register, that the
4500 source register does not change after the assignment. Also count
4501 the number of registers set in only one of the blocks. */
4503 for (rtx reg
: then_regs
)
4505 rtx
*then_slot
= then_vals
.get (reg
);
4506 rtx
*else_slot
= else_vals
.get (reg
);
4508 gcc_checking_assert (then_slot
);
4513 rtx then_val
= *then_slot
;
4514 rtx else_val
= *else_slot
;
4515 if (!CONSTANT_P (then_val
) && !CONSTANT_P (else_val
)
4516 && !rtx_equal_p (then_val
, else_val
))
4521 /* Finish off c for MAX_CONDITIONAL_EXECUTE. */
4522 for (rtx reg
: else_regs
)
4524 gcc_checking_assert (else_vals
.get (reg
));
4525 if (!then_vals
.get (reg
))
4529 /* Make sure it is reasonable to convert this block. What matters
4530 is the number of assignments currently made in only one of the
4531 branches, since if we convert we are going to always execute
4533 if (c
> MAX_CONDITIONAL_EXECUTE
4537 /* Try to emit the conditional moves. First do the then block,
4538 then do anything left in the else blocks. */
4540 if (!cond_move_convert_if_block (if_info
, then_bb
, cond
,
4541 &then_vals
, &else_vals
, false)
4543 && !cond_move_convert_if_block (if_info
, else_bb
, cond
,
4544 &then_vals
, &else_vals
, true)))
4549 seq
= end_ifcvt_sequence (if_info
);
4550 if (!seq
|| !targetm
.noce_conversion_profitable_p (seq
, if_info
))
4553 loc_insn
= first_active_insn (then_bb
);
4556 loc_insn
= first_active_insn (else_bb
);
4557 gcc_assert (loc_insn
);
4559 emit_insn_before_setloc (seq
, jump
, INSN_LOCATION (loc_insn
));
4563 delete_basic_block (else_bb
);
4567 remove_edge (find_edge (test_bb
, join_bb
));
4569 remove_edge (find_edge (then_bb
, join_bb
));
4570 redirect_edge_and_branch_force (single_succ_edge (test_bb
), join_bb
);
4571 delete_basic_block (then_bb
);
4574 if (can_merge_blocks_p (test_bb
, join_bb
))
4576 merge_blocks (test_bb
, join_bb
);
4580 num_updated_if_blocks
++;
4584 then_regs
.release ();
4585 else_regs
.release ();
4590 /* Determine if a given basic block heads a simple IF-THEN-JOIN or an
4591 IF-THEN-ELSE-JOIN block.
4593 If so, we'll try to convert the insns to not require the branch,
4594 using only transformations that do not require conditional execution.
4596 Return TRUE if we were successful at converting the block. */
4599 noce_find_if_block (basic_block test_bb
, edge then_edge
, edge else_edge
,
4602 basic_block then_bb
, else_bb
, join_bb
;
4603 bool then_else_reversed
= false;
4605 rtx_insn
*cond_earliest
;
4606 struct noce_if_info if_info
;
4607 bool speed_p
= optimize_bb_for_speed_p (test_bb
);
4609 /* We only ever should get here before reload. */
4610 gcc_assert (!reload_completed
);
4612 /* Recognize an IF-THEN-ELSE-JOIN block. */
4613 if (single_pred_p (then_edge
->dest
)
4614 && single_succ_p (then_edge
->dest
)
4615 && single_pred_p (else_edge
->dest
)
4616 && single_succ_p (else_edge
->dest
)
4617 && single_succ (then_edge
->dest
) == single_succ (else_edge
->dest
))
4619 then_bb
= then_edge
->dest
;
4620 else_bb
= else_edge
->dest
;
4621 join_bb
= single_succ (then_bb
);
4623 /* Recognize an IF-THEN-JOIN block. */
4624 else if (single_pred_p (then_edge
->dest
)
4625 && single_succ_p (then_edge
->dest
)
4626 && single_succ (then_edge
->dest
) == else_edge
->dest
)
4628 then_bb
= then_edge
->dest
;
4629 else_bb
= NULL_BLOCK
;
4630 join_bb
= else_edge
->dest
;
4632 /* Recognize an IF-ELSE-JOIN block. We can have those because the order
4633 of basic blocks in cfglayout mode does not matter, so the fallthrough
4634 edge can go to any basic block (and not just to bb->next_bb, like in
4636 else if (single_pred_p (else_edge
->dest
)
4637 && single_succ_p (else_edge
->dest
)
4638 && single_succ (else_edge
->dest
) == then_edge
->dest
)
4640 /* The noce transformations do not apply to IF-ELSE-JOIN blocks.
4641 To make this work, we have to invert the THEN and ELSE blocks
4642 and reverse the jump condition. */
4643 then_bb
= else_edge
->dest
;
4644 else_bb
= NULL_BLOCK
;
4645 join_bb
= single_succ (then_bb
);
4646 then_else_reversed
= true;
4649 /* Not a form we can handle. */
4652 /* The edges of the THEN and ELSE blocks cannot have complex edges. */
4653 if (single_succ_edge (then_bb
)->flags
& EDGE_COMPLEX
)
4656 && single_succ_edge (else_bb
)->flags
& EDGE_COMPLEX
)
4659 num_possible_if_blocks
++;
4664 "\nIF-THEN%s-JOIN block found, pass %d, test %d, then %d",
4665 (else_bb
) ? "-ELSE" : "",
4666 pass
, test_bb
->index
, then_bb
->index
);
4669 fprintf (dump_file
, ", else %d", else_bb
->index
);
4671 fprintf (dump_file
, ", join %d\n", join_bb
->index
);
4674 /* If the conditional jump is more than just a conditional
4675 jump, then we cannot do if-conversion on this block. */
4676 jump
= BB_END (test_bb
);
4677 if (! onlyjump_p (jump
))
4680 /* Initialize an IF_INFO struct to pass around. */
4681 memset (&if_info
, 0, sizeof if_info
);
4682 if_info
.test_bb
= test_bb
;
4683 if_info
.then_bb
= then_bb
;
4684 if_info
.else_bb
= else_bb
;
4685 if_info
.join_bb
= join_bb
;
4686 if_info
.cond
= noce_get_condition (jump
, &cond_earliest
,
4687 then_else_reversed
);
4688 rtx_insn
*rev_cond_earliest
;
4689 if_info
.rev_cond
= noce_get_condition (jump
, &rev_cond_earliest
,
4690 !then_else_reversed
);
4691 if (!if_info
.cond
&& !if_info
.rev_cond
)
4695 std::swap (if_info
.cond
, if_info
.rev_cond
);
4696 std::swap (cond_earliest
, rev_cond_earliest
);
4697 if_info
.cond_inverted
= true;
4699 /* We must be comparing objects whose modes imply the size. */
4700 if (GET_MODE (XEXP (if_info
.cond
, 0)) == BLKmode
)
4702 gcc_assert (if_info
.rev_cond
== NULL_RTX
4703 || rev_cond_earliest
== cond_earliest
);
4704 if_info
.cond_earliest
= cond_earliest
;
4705 if_info
.jump
= jump
;
4706 if_info
.then_else_reversed
= then_else_reversed
;
4707 if_info
.speed_p
= speed_p
;
4708 if_info
.max_seq_cost
4709 = targetm
.max_noce_ifcvt_seq_cost (then_edge
);
4710 /* We'll add in the cost of THEN_BB and ELSE_BB later, when we check
4711 that they are valid to transform. We can't easily get back to the insn
4712 for COND (and it may not exist if we had to canonicalize to get COND),
4713 and jump_insns are always given a cost of 1 by seq_cost, so treat
4714 both instructions as having cost COSTS_N_INSNS (1). */
4715 if_info
.original_cost
= COSTS_N_INSNS (2);
4718 /* Do the real work. */
4720 /* ??? noce_process_if_block has not yet been updated to handle
4721 inverted conditions. */
4722 if (!if_info
.cond_inverted
&& noce_process_if_block (&if_info
))
4725 if (HAVE_conditional_move
4726 && cond_move_process_if_block (&if_info
))
4733 /* Merge the blocks and mark for local life update. */
4736 merge_if_block (struct ce_if_block
* ce_info
)
4738 basic_block test_bb
= ce_info
->test_bb
; /* last test block */
4739 basic_block then_bb
= ce_info
->then_bb
; /* THEN */
4740 basic_block else_bb
= ce_info
->else_bb
; /* ELSE or NULL */
4741 basic_block join_bb
= ce_info
->join_bb
; /* join block */
4742 basic_block combo_bb
;
4744 /* All block merging is done into the lower block numbers. */
4747 df_set_bb_dirty (test_bb
);
4749 /* Merge any basic blocks to handle && and || subtests. Each of
4750 the blocks are on the fallthru path from the predecessor block. */
4751 if (ce_info
->num_multiple_test_blocks
> 0)
4753 basic_block bb
= test_bb
;
4754 basic_block last_test_bb
= ce_info
->last_test_bb
;
4755 basic_block fallthru
= block_fallthru (bb
);
4760 fallthru
= block_fallthru (bb
);
4761 merge_blocks (combo_bb
, bb
);
4764 while (bb
!= last_test_bb
);
4767 /* Merge TEST block into THEN block. Normally the THEN block won't have a
4768 label, but it might if there were || tests. That label's count should be
4769 zero, and it normally should be removed. */
4773 /* If THEN_BB has no successors, then there's a BARRIER after it.
4774 If COMBO_BB has more than one successor (THEN_BB), then that BARRIER
4775 is no longer needed, and in fact it is incorrect to leave it in
4777 if (EDGE_COUNT (then_bb
->succs
) == 0
4778 && EDGE_COUNT (combo_bb
->succs
) > 1)
4780 rtx_insn
*end
= NEXT_INSN (BB_END (then_bb
));
4781 while (end
&& NOTE_P (end
) && !NOTE_INSN_BASIC_BLOCK_P (end
))
4782 end
= NEXT_INSN (end
);
4784 if (end
&& BARRIER_P (end
))
4787 merge_blocks (combo_bb
, then_bb
);
4791 /* The ELSE block, if it existed, had a label. That label count
4792 will almost always be zero, but odd things can happen when labels
4793 get their addresses taken. */
4796 /* If ELSE_BB has no successors, then there's a BARRIER after it.
4797 If COMBO_BB has more than one successor (ELSE_BB), then that BARRIER
4798 is no longer needed, and in fact it is incorrect to leave it in
4800 if (EDGE_COUNT (else_bb
->succs
) == 0
4801 && EDGE_COUNT (combo_bb
->succs
) > 1)
4803 rtx_insn
*end
= NEXT_INSN (BB_END (else_bb
));
4804 while (end
&& NOTE_P (end
) && !NOTE_INSN_BASIC_BLOCK_P (end
))
4805 end
= NEXT_INSN (end
);
4807 if (end
&& BARRIER_P (end
))
4810 merge_blocks (combo_bb
, else_bb
);
4814 /* If there was no join block reported, that means it was not adjacent
4815 to the others, and so we cannot merge them. */
4819 rtx_insn
*last
= BB_END (combo_bb
);
4821 /* The outgoing edge for the current COMBO block should already
4822 be correct. Verify this. */
4823 if (EDGE_COUNT (combo_bb
->succs
) == 0)
4824 gcc_assert (find_reg_note (last
, REG_NORETURN
, NULL
)
4825 || (NONJUMP_INSN_P (last
)
4826 && GET_CODE (PATTERN (last
)) == TRAP_IF
4827 && (TRAP_CONDITION (PATTERN (last
))
4828 == const_true_rtx
)));
4831 /* There should still be something at the end of the THEN or ELSE
4832 blocks taking us to our final destination. */
4833 gcc_assert (JUMP_P (last
)
4834 || (EDGE_SUCC (combo_bb
, 0)->dest
4835 == EXIT_BLOCK_PTR_FOR_FN (cfun
)
4837 && SIBLING_CALL_P (last
))
4838 || ((EDGE_SUCC (combo_bb
, 0)->flags
& EDGE_EH
)
4839 && can_throw_internal (last
)));
4842 /* The JOIN block may have had quite a number of other predecessors too.
4843 Since we've already merged the TEST, THEN and ELSE blocks, we should
4844 have only one remaining edge from our if-then-else diamond. If there
4845 is more than one remaining edge, it must come from elsewhere. There
4846 may be zero incoming edges if the THEN block didn't actually join
4847 back up (as with a call to a non-return function). */
4848 else if (EDGE_COUNT (join_bb
->preds
) < 2
4849 && join_bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
4851 /* We can merge the JOIN cleanly and update the dataflow try
4852 again on this pass.*/
4853 merge_blocks (combo_bb
, join_bb
);
4858 /* We cannot merge the JOIN. */
4860 /* The outgoing edge for the current COMBO block should already
4861 be correct. Verify this. */
4862 gcc_assert (single_succ_p (combo_bb
)
4863 && single_succ (combo_bb
) == join_bb
);
4865 /* Remove the jump and cruft from the end of the COMBO block. */
4866 if (join_bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
4867 tidy_fallthru_edge (single_succ_edge (combo_bb
));
4870 num_updated_if_blocks
++;
4873 /* Find a block ending in a simple IF condition and try to transform it
4874 in some way. When converting a multi-block condition, put the new code
4875 in the first such block and delete the rest. Return a pointer to this
4876 first block if some transformation was done. Return NULL otherwise. */
4879 find_if_header (basic_block test_bb
, int pass
)
4881 ce_if_block ce_info
;
4885 /* The kind of block we're looking for has exactly two successors. */
4886 if (EDGE_COUNT (test_bb
->succs
) != 2)
4889 then_edge
= EDGE_SUCC (test_bb
, 0);
4890 else_edge
= EDGE_SUCC (test_bb
, 1);
4892 if (df_get_bb_dirty (then_edge
->dest
))
4894 if (df_get_bb_dirty (else_edge
->dest
))
4897 /* Neither edge should be abnormal. */
4898 if ((then_edge
->flags
& EDGE_COMPLEX
)
4899 || (else_edge
->flags
& EDGE_COMPLEX
))
4902 /* Nor exit the loop. */
4903 if ((then_edge
->flags
& EDGE_LOOP_EXIT
)
4904 || (else_edge
->flags
& EDGE_LOOP_EXIT
))
4907 /* The THEN edge is canonically the one that falls through. */
4908 if (then_edge
->flags
& EDGE_FALLTHRU
)
4910 else if (else_edge
->flags
& EDGE_FALLTHRU
)
4911 std::swap (then_edge
, else_edge
);
4913 /* Otherwise this must be a multiway branch of some sort. */
4916 memset (&ce_info
, 0, sizeof (ce_info
));
4917 ce_info
.test_bb
= test_bb
;
4918 ce_info
.then_bb
= then_edge
->dest
;
4919 ce_info
.else_bb
= else_edge
->dest
;
4920 ce_info
.pass
= pass
;
4922 #ifdef IFCVT_MACHDEP_INIT
4923 IFCVT_MACHDEP_INIT (&ce_info
);
4926 if (!reload_completed
4927 && noce_find_if_block (test_bb
, then_edge
, else_edge
, pass
))
4930 if (reload_completed
4931 && targetm
.have_conditional_execution ()
4932 && cond_exec_find_if_block (&ce_info
))
4935 if (targetm
.have_trap ()
4936 && optab_handler (ctrap_optab
, word_mode
) != CODE_FOR_nothing
4937 && find_cond_trap (test_bb
, then_edge
, else_edge
))
4940 if (dom_info_state (CDI_POST_DOMINATORS
) >= DOM_NO_FAST_QUERY
4941 && (reload_completed
|| !targetm
.have_conditional_execution ()))
4943 if (find_if_case_1 (test_bb
, then_edge
, else_edge
))
4945 if (find_if_case_2 (test_bb
, then_edge
, else_edge
))
4953 fprintf (dump_file
, "Conversion succeeded on pass %d.\n", pass
);
4954 /* Set this so we continue looking. */
4955 cond_exec_changed_p
= true;
4956 return ce_info
.test_bb
;
4959 /* Return true if a block has two edges, one of which falls through to the next
4960 block, and the other jumps to a specific block, so that we can tell if the
4961 block is part of an && test or an || test. Returns either -1 or the number
4962 of non-note, non-jump, non-USE/CLOBBER insns in the block. */
4965 block_jumps_and_fallthru (basic_block cur_bb
, basic_block target_bb
)
4968 bool fallthru_p
= false;
4969 bool jump_p
= false;
4975 if (!cur_bb
|| !target_bb
)
4978 /* If no edges, obviously it doesn't jump or fallthru. */
4979 if (EDGE_COUNT (cur_bb
->succs
) == 0)
4982 FOR_EACH_EDGE (cur_edge
, ei
, cur_bb
->succs
)
4984 if (cur_edge
->flags
& EDGE_COMPLEX
)
4985 /* Anything complex isn't what we want. */
4988 else if (cur_edge
->flags
& EDGE_FALLTHRU
)
4991 else if (cur_edge
->dest
== target_bb
)
4998 if ((jump_p
& fallthru_p
) == 0)
5001 /* Don't allow calls in the block, since this is used to group && and ||
5002 together for conditional execution support. ??? we should support
5003 conditional execution support across calls for IA-64 some day, but
5004 for now it makes the code simpler. */
5005 end
= BB_END (cur_bb
);
5006 insn
= BB_HEAD (cur_bb
);
5008 while (insn
!= NULL_RTX
)
5015 && !DEBUG_INSN_P (insn
)
5016 && GET_CODE (PATTERN (insn
)) != USE
5017 && GET_CODE (PATTERN (insn
)) != CLOBBER
)
5023 insn
= NEXT_INSN (insn
);
5029 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
5030 block. If so, we'll try to convert the insns to not require the branch.
5031 Return TRUE if we were successful at converting the block. */
5034 cond_exec_find_if_block (struct ce_if_block
* ce_info
)
5036 basic_block test_bb
= ce_info
->test_bb
;
5037 basic_block then_bb
= ce_info
->then_bb
;
5038 basic_block else_bb
= ce_info
->else_bb
;
5039 basic_block join_bb
= NULL_BLOCK
;
5044 ce_info
->last_test_bb
= test_bb
;
5046 /* We only ever should get here after reload,
5047 and if we have conditional execution. */
5048 gcc_assert (reload_completed
&& targetm
.have_conditional_execution ());
5050 /* Discover if any fall through predecessors of the current test basic block
5051 were && tests (which jump to the else block) or || tests (which jump to
5053 if (single_pred_p (test_bb
)
5054 && single_pred_edge (test_bb
)->flags
== EDGE_FALLTHRU
)
5056 basic_block bb
= single_pred (test_bb
);
5057 basic_block target_bb
;
5058 int max_insns
= MAX_CONDITIONAL_EXECUTE
;
5061 /* Determine if the preceding block is an && or || block. */
5062 if ((n_insns
= block_jumps_and_fallthru (bb
, else_bb
)) >= 0)
5064 ce_info
->and_and_p
= true;
5065 target_bb
= else_bb
;
5067 else if ((n_insns
= block_jumps_and_fallthru (bb
, then_bb
)) >= 0)
5069 ce_info
->and_and_p
= false;
5070 target_bb
= then_bb
;
5073 target_bb
= NULL_BLOCK
;
5075 if (target_bb
&& n_insns
<= max_insns
)
5077 int total_insns
= 0;
5080 ce_info
->last_test_bb
= test_bb
;
5082 /* Found at least one && or || block, look for more. */
5085 ce_info
->test_bb
= test_bb
= bb
;
5086 total_insns
+= n_insns
;
5089 if (!single_pred_p (bb
))
5092 bb
= single_pred (bb
);
5093 n_insns
= block_jumps_and_fallthru (bb
, target_bb
);
5095 while (n_insns
>= 0 && (total_insns
+ n_insns
) <= max_insns
);
5097 ce_info
->num_multiple_test_blocks
= blocks
;
5098 ce_info
->num_multiple_test_insns
= total_insns
;
5100 if (ce_info
->and_and_p
)
5101 ce_info
->num_and_and_blocks
= blocks
;
5103 ce_info
->num_or_or_blocks
= blocks
;
5107 /* The THEN block of an IF-THEN combo must have exactly one predecessor,
5108 other than any || blocks which jump to the THEN block. */
5109 if ((EDGE_COUNT (then_bb
->preds
) - ce_info
->num_or_or_blocks
) != 1)
5112 /* The edges of the THEN and ELSE blocks cannot have complex edges. */
5113 FOR_EACH_EDGE (cur_edge
, ei
, then_bb
->preds
)
5115 if (cur_edge
->flags
& EDGE_COMPLEX
)
5119 FOR_EACH_EDGE (cur_edge
, ei
, else_bb
->preds
)
5121 if (cur_edge
->flags
& EDGE_COMPLEX
)
5125 /* The THEN block of an IF-THEN combo must have zero or one successors. */
5126 if (EDGE_COUNT (then_bb
->succs
) > 0
5127 && (!single_succ_p (then_bb
)
5128 || (single_succ_edge (then_bb
)->flags
& EDGE_COMPLEX
)
5129 || (epilogue_completed
5130 && tablejump_p (BB_END (then_bb
), NULL
, NULL
))))
5133 /* If the THEN block has no successors, conditional execution can still
5134 make a conditional call. Don't do this unless the ELSE block has
5135 only one incoming edge -- the CFG manipulation is too ugly otherwise.
5136 Check for the last insn of the THEN block being an indirect jump, which
5137 is listed as not having any successors, but confuses the rest of the CE
5138 code processing. ??? we should fix this in the future. */
5139 if (EDGE_COUNT (then_bb
->succs
) == 0)
5141 if (single_pred_p (else_bb
) && else_bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
5143 rtx_insn
*last_insn
= BB_END (then_bb
);
5146 && NOTE_P (last_insn
)
5147 && last_insn
!= BB_HEAD (then_bb
))
5148 last_insn
= PREV_INSN (last_insn
);
5151 && JUMP_P (last_insn
)
5152 && ! simplejump_p (last_insn
))
5156 else_bb
= NULL_BLOCK
;
5162 /* If the THEN block's successor is the other edge out of the TEST block,
5163 then we have an IF-THEN combo without an ELSE. */
5164 else if (single_succ (then_bb
) == else_bb
)
5167 else_bb
= NULL_BLOCK
;
5170 /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
5171 has exactly one predecessor and one successor, and the outgoing edge
5172 is not complex, then we have an IF-THEN-ELSE combo. */
5173 else if (single_succ_p (else_bb
)
5174 && single_succ (then_bb
) == single_succ (else_bb
)
5175 && single_pred_p (else_bb
)
5176 && !(single_succ_edge (else_bb
)->flags
& EDGE_COMPLEX
)
5177 && !(epilogue_completed
5178 && tablejump_p (BB_END (else_bb
), NULL
, NULL
)))
5179 join_bb
= single_succ (else_bb
);
5181 /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */
5185 num_possible_if_blocks
++;
5190 "\nIF-THEN%s block found, pass %d, start block %d "
5191 "[insn %d], then %d [%d]",
5192 (else_bb
) ? "-ELSE" : "",
5195 BB_HEAD (test_bb
) ? (int)INSN_UID (BB_HEAD (test_bb
)) : -1,
5197 BB_HEAD (then_bb
) ? (int)INSN_UID (BB_HEAD (then_bb
)) : -1);
5200 fprintf (dump_file
, ", else %d [%d]",
5202 BB_HEAD (else_bb
) ? (int)INSN_UID (BB_HEAD (else_bb
)) : -1);
5204 fprintf (dump_file
, ", join %d [%d]",
5206 BB_HEAD (join_bb
) ? (int)INSN_UID (BB_HEAD (join_bb
)) : -1);
5208 if (ce_info
->num_multiple_test_blocks
> 0)
5209 fprintf (dump_file
, ", %d %s block%s last test %d [%d]",
5210 ce_info
->num_multiple_test_blocks
,
5211 (ce_info
->and_and_p
) ? "&&" : "||",
5212 (ce_info
->num_multiple_test_blocks
== 1) ? "" : "s",
5213 ce_info
->last_test_bb
->index
,
5214 ((BB_HEAD (ce_info
->last_test_bb
))
5215 ? (int)INSN_UID (BB_HEAD (ce_info
->last_test_bb
))
5218 fputc ('\n', dump_file
);
5221 /* Make sure IF, THEN, and ELSE, blocks are adjacent. Actually, we get the
5222 first condition for free, since we've already asserted that there's a
5223 fallthru edge from IF to THEN. Likewise for the && and || blocks, since
5224 we checked the FALLTHRU flag, those are already adjacent to the last IF
5226 /* ??? As an enhancement, move the ELSE block. Have to deal with
5227 BLOCK notes, if by no other means than backing out the merge if they
5228 exist. Sticky enough I don't want to think about it now. */
5230 if (else_bb
&& (next
= next
->next_bb
) != else_bb
)
5232 if ((next
= next
->next_bb
) != join_bb
5233 && join_bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
5241 /* Do the real work. */
5243 ce_info
->else_bb
= else_bb
;
5244 ce_info
->join_bb
= join_bb
;
5246 /* If we have && and || tests, try to first handle combining the && and ||
5247 tests into the conditional code, and if that fails, go back and handle
5248 it without the && and ||, which at present handles the && case if there
5249 was no ELSE block. */
5250 if (cond_exec_process_if_block (ce_info
, true))
5253 if (ce_info
->num_multiple_test_blocks
)
5257 if (cond_exec_process_if_block (ce_info
, false))
5264 /* Convert a branch over a trap, or a branch
5265 to a trap, into a conditional trap. */
5268 find_cond_trap (basic_block test_bb
, edge then_edge
, edge else_edge
)
5270 basic_block then_bb
= then_edge
->dest
;
5271 basic_block else_bb
= else_edge
->dest
;
5272 basic_block other_bb
, trap_bb
;
5273 rtx_insn
*trap
, *jump
;
5275 rtx_insn
*cond_earliest
;
5277 /* Locate the block with the trap instruction. */
5278 /* ??? While we look for no successors, we really ought to allow
5279 EH successors. Need to fix merge_if_block for that to work. */
5280 if ((trap
= block_has_only_trap (then_bb
)) != NULL
)
5281 trap_bb
= then_bb
, other_bb
= else_bb
;
5282 else if ((trap
= block_has_only_trap (else_bb
)) != NULL
)
5283 trap_bb
= else_bb
, other_bb
= then_bb
;
5289 fprintf (dump_file
, "\nTRAP-IF block found, start %d, trap %d\n",
5290 test_bb
->index
, trap_bb
->index
);
5293 /* If this is not a standard conditional jump, we can't parse it. */
5294 jump
= BB_END (test_bb
);
5295 cond
= noce_get_condition (jump
, &cond_earliest
, then_bb
== trap_bb
);
5299 /* If the conditional jump is more than just a conditional jump, then
5300 we cannot do if-conversion on this block. Give up for returnjump_p,
5301 changing a conditional return followed by unconditional trap for
5302 conditional trap followed by unconditional return is likely not
5303 beneficial and harder to handle. */
5304 if (! onlyjump_p (jump
) || returnjump_p (jump
))
5307 /* We must be comparing objects whose modes imply the size. */
5308 if (GET_MODE (XEXP (cond
, 0)) == BLKmode
)
5311 /* Attempt to generate the conditional trap. */
5312 rtx_insn
*seq
= gen_cond_trap (GET_CODE (cond
), copy_rtx (XEXP (cond
, 0)),
5313 copy_rtx (XEXP (cond
, 1)),
5314 TRAP_CODE (PATTERN (trap
)));
5318 /* If that results in an invalid insn, back out. */
5319 for (rtx_insn
*x
= seq
; x
; x
= NEXT_INSN (x
))
5320 if (reload_completed
5322 : recog_memoized (x
) < 0)
5325 /* Emit the new insns before cond_earliest. */
5326 emit_insn_before_setloc (seq
, cond_earliest
, INSN_LOCATION (trap
));
5328 /* Delete the trap block if possible. */
5329 remove_edge (trap_bb
== then_bb
? then_edge
: else_edge
);
5330 df_set_bb_dirty (test_bb
);
5331 df_set_bb_dirty (then_bb
);
5332 df_set_bb_dirty (else_bb
);
5334 if (EDGE_COUNT (trap_bb
->preds
) == 0)
5336 delete_basic_block (trap_bb
);
5340 /* Wire together the blocks again. */
5341 if (current_ir_type () == IR_RTL_CFGLAYOUT
)
5342 single_succ_edge (test_bb
)->flags
|= EDGE_FALLTHRU
;
5343 else if (trap_bb
== then_bb
)
5345 rtx lab
= JUMP_LABEL (jump
);
5346 rtx_insn
*seq
= targetm
.gen_jump (lab
);
5347 rtx_jump_insn
*newjump
= emit_jump_insn_after (seq
, jump
);
5348 LABEL_NUSES (lab
) += 1;
5349 JUMP_LABEL (newjump
) = lab
;
5350 emit_barrier_after (newjump
);
5354 if (can_merge_blocks_p (test_bb
, other_bb
))
5356 merge_blocks (test_bb
, other_bb
);
5360 num_updated_if_blocks
++;
5364 /* Subroutine of find_cond_trap: if BB contains only a trap insn,
5368 block_has_only_trap (basic_block bb
)
5372 /* We're not the exit block. */
5373 if (bb
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
5376 /* The block must have no successors. */
5377 if (EDGE_COUNT (bb
->succs
) > 0)
5380 /* The only instruction in the THEN block must be the trap. */
5381 trap
= first_active_insn (bb
);
5382 if (! (trap
== BB_END (bb
)
5383 && GET_CODE (PATTERN (trap
)) == TRAP_IF
5384 && TRAP_CONDITION (PATTERN (trap
)) == const_true_rtx
))
5390 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
5391 transformable, but not necessarily the other. There need be no
5394 Return TRUE if we were successful at converting the block.
5396 Cases we'd like to look at:
5399 if (test) goto over; // x not live
5407 if (! test) goto label;
5410 if (test) goto E; // x not live
5424 (3) // This one's really only interesting for targets that can do
5425 // multiway branching, e.g. IA-64 BBB bundles. For other targets
5426 // it results in multiple branches on a cache line, which often
5427 // does not sit well with predictors.
5429 if (test1) goto E; // predicted not taken
5445 (A) Don't do (2) if the branch is predicted against the block we're
5446 eliminating. Do it anyway if we can eliminate a branch; this requires
5447 that the sole successor of the eliminated block postdominate the other
5450 (B) With CE, on (3) we can steal from both sides of the if, creating
5459 Again, this is most useful if J postdominates.
5461 (C) CE substitutes for helpful life information.
5463 (D) These heuristics need a lot of work. */
5465 /* Tests for case 1 above. */
5468 find_if_case_1 (basic_block test_bb
, edge then_edge
, edge else_edge
)
5470 basic_block then_bb
= then_edge
->dest
;
5471 basic_block else_bb
= else_edge
->dest
;
5474 profile_probability then_prob
;
5475 rtx else_target
= NULL_RTX
;
5477 /* If we are partitioning hot/cold basic blocks, we don't want to
5478 mess up unconditional or indirect jumps that cross between hot
5481 Basic block partitioning may result in some jumps that appear to
5482 be optimizable (or blocks that appear to be mergeable), but which really
5483 must be left untouched (they are required to make it safely across
5484 partition boundaries). See the comments at the top of
5485 bb-reorder.cc:partition_hot_cold_basic_blocks for complete details. */
5487 if ((BB_END (then_bb
)
5488 && JUMP_P (BB_END (then_bb
))
5489 && CROSSING_JUMP_P (BB_END (then_bb
)))
5490 || (JUMP_P (BB_END (test_bb
))
5491 && CROSSING_JUMP_P (BB_END (test_bb
)))
5492 || (BB_END (else_bb
)
5493 && JUMP_P (BB_END (else_bb
))
5494 && CROSSING_JUMP_P (BB_END (else_bb
))))
5497 /* Verify test_bb ends in a conditional jump with no other side-effects. */
5498 if (!onlyjump_p (BB_END (test_bb
)))
5501 /* THEN has one successor. */
5502 if (!single_succ_p (then_bb
))
5505 /* THEN does not fall through, but is not strange either. */
5506 if (single_succ_edge (then_bb
)->flags
& (EDGE_COMPLEX
| EDGE_FALLTHRU
))
5509 /* THEN has one predecessor. */
5510 if (!single_pred_p (then_bb
))
5513 /* THEN must do something. */
5514 if (forwarder_block_p (then_bb
))
5517 num_possible_if_blocks
++;
5520 "\nIF-CASE-1 found, start %d, then %d\n",
5521 test_bb
->index
, then_bb
->index
);
5523 then_prob
= then_edge
->probability
.invert ();
5525 /* We're speculating from the THEN path, we want to make sure the cost
5526 of speculation is within reason. */
5527 if (! cheap_bb_rtx_cost_p (then_bb
, then_prob
,
5528 COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (then_edge
->src
),
5529 predictable_edge_p (then_edge
)))))
5532 if (else_bb
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
5534 rtx_insn
*jump
= BB_END (else_edge
->src
);
5535 gcc_assert (JUMP_P (jump
));
5536 else_target
= JUMP_LABEL (jump
);
5539 /* Registers set are dead, or are predicable. */
5540 if (! dead_or_predicable (test_bb
, then_bb
, else_bb
,
5541 single_succ_edge (then_bb
), true))
5544 /* Conversion went ok, including moving the insns and fixing up the
5545 jump. Adjust the CFG to match. */
5547 /* We can avoid creating a new basic block if then_bb is immediately
5548 followed by else_bb, i.e. deleting then_bb allows test_bb to fall
5549 through to else_bb. */
5551 if (then_bb
->next_bb
== else_bb
5552 && then_bb
->prev_bb
== test_bb
5553 && else_bb
!= EXIT_BLOCK_PTR_FOR_FN (cfun
))
5555 redirect_edge_succ (FALLTHRU_EDGE (test_bb
), else_bb
);
5558 else if (else_bb
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
5559 new_bb
= force_nonfallthru_and_redirect (FALLTHRU_EDGE (test_bb
),
5560 else_bb
, else_target
);
5562 new_bb
= redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb
),
5565 df_set_bb_dirty (test_bb
);
5566 df_set_bb_dirty (else_bb
);
5568 then_bb_index
= then_bb
->index
;
5569 delete_basic_block (then_bb
);
5571 /* Make rest of code believe that the newly created block is the THEN_BB
5572 block we removed. */
5575 df_bb_replace (then_bb_index
, new_bb
);
5576 /* This should have been done above via force_nonfallthru_and_redirect
5577 (possibly called from redirect_edge_and_branch_force). */
5578 gcc_checking_assert (BB_PARTITION (new_bb
) == BB_PARTITION (test_bb
));
5582 num_updated_if_blocks
++;
5586 /* Test for case 2 above. */
5589 find_if_case_2 (basic_block test_bb
, edge then_edge
, edge else_edge
)
5591 basic_block then_bb
= then_edge
->dest
;
5592 basic_block else_bb
= else_edge
->dest
;
5594 profile_probability then_prob
, else_prob
;
5596 /* We do not want to speculate (empty) loop latches. */
5598 && else_bb
->loop_father
->latch
== else_bb
)
5601 /* If we are partitioning hot/cold basic blocks, we don't want to
5602 mess up unconditional or indirect jumps that cross between hot
5605 Basic block partitioning may result in some jumps that appear to
5606 be optimizable (or blocks that appear to be mergeable), but which really
5607 must be left untouched (they are required to make it safely across
5608 partition boundaries). See the comments at the top of
5609 bb-reorder.cc:partition_hot_cold_basic_blocks for complete details. */
5611 if ((BB_END (then_bb
)
5612 && JUMP_P (BB_END (then_bb
))
5613 && CROSSING_JUMP_P (BB_END (then_bb
)))
5614 || (JUMP_P (BB_END (test_bb
))
5615 && CROSSING_JUMP_P (BB_END (test_bb
)))
5616 || (BB_END (else_bb
)
5617 && JUMP_P (BB_END (else_bb
))
5618 && CROSSING_JUMP_P (BB_END (else_bb
))))
5621 /* Verify test_bb ends in a conditional jump with no other side-effects. */
5622 if (!onlyjump_p (BB_END (test_bb
)))
5625 /* ELSE has one successor. */
5626 if (!single_succ_p (else_bb
))
5629 else_succ
= single_succ_edge (else_bb
);
5631 /* ELSE outgoing edge is not complex. */
5632 if (else_succ
->flags
& EDGE_COMPLEX
)
5635 /* ELSE has one predecessor. */
5636 if (!single_pred_p (else_bb
))
5639 /* THEN is not EXIT. */
5640 if (then_bb
->index
< NUM_FIXED_BLOCKS
)
5643 else_prob
= else_edge
->probability
;
5644 then_prob
= else_prob
.invert ();
5646 /* ELSE is predicted or SUCC(ELSE) postdominates THEN. */
5647 if (else_prob
> then_prob
)
5649 else if (else_succ
->dest
->index
< NUM_FIXED_BLOCKS
5650 || dominated_by_p (CDI_POST_DOMINATORS
, then_bb
,
5656 num_possible_if_blocks
++;
5659 "\nIF-CASE-2 found, start %d, else %d\n",
5660 test_bb
->index
, else_bb
->index
);
5662 /* We're speculating from the ELSE path, we want to make sure the cost
5663 of speculation is within reason. */
5664 if (! cheap_bb_rtx_cost_p (else_bb
, else_prob
,
5665 COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge
->src
),
5666 predictable_edge_p (else_edge
)))))
5669 /* Registers set are dead, or are predicable. */
5670 if (! dead_or_predicable (test_bb
, else_bb
, then_bb
, else_succ
, false))
5673 /* Conversion went ok, including moving the insns and fixing up the
5674 jump. Adjust the CFG to match. */
5676 df_set_bb_dirty (test_bb
);
5677 df_set_bb_dirty (then_bb
);
5678 delete_basic_block (else_bb
);
5681 num_updated_if_blocks
++;
5683 /* ??? We may now fallthru from one of THEN's successors into a join
5684 block. Rerun cleanup_cfg? Examine things manually? Wait? */
5689 /* Used by the code above to perform the actual rtl transformations.
5690 Return TRUE if successful.
5692 TEST_BB is the block containing the conditional branch. MERGE_BB
5693 is the block containing the code to manipulate. DEST_EDGE is an
5694 edge representing a jump to the join block; after the conversion,
5695 TEST_BB should be branching to its destination.
5696 REVERSEP is true if the sense of the branch should be reversed. */
5699 dead_or_predicable (basic_block test_bb
, basic_block merge_bb
,
5700 basic_block other_bb
, edge dest_edge
, bool reversep
)
5702 basic_block new_dest
= dest_edge
->dest
;
5703 rtx_insn
*head
, *end
, *jump
;
5704 rtx_insn
*earliest
= NULL
;
5706 bitmap merge_set
= NULL
;
5707 /* Number of pending changes. */
5708 int n_validated_changes
= 0;
5709 rtx new_dest_label
= NULL_RTX
;
5711 jump
= BB_END (test_bb
);
5713 /* Find the extent of the real code in the merge block. */
5714 head
= BB_HEAD (merge_bb
);
5715 end
= BB_END (merge_bb
);
5717 while (DEBUG_INSN_P (end
) && end
!= head
)
5718 end
= PREV_INSN (end
);
5720 /* If merge_bb ends with a tablejump, predicating/moving insn's
5721 into test_bb and then deleting merge_bb will result in the jumptable
5722 that follows merge_bb being removed along with merge_bb and then we
5723 get an unresolved reference to the jumptable. */
5724 if (tablejump_p (end
, NULL
, NULL
))
5728 head
= NEXT_INSN (head
);
5729 while (DEBUG_INSN_P (head
) && head
!= end
)
5730 head
= NEXT_INSN (head
);
5738 head
= NEXT_INSN (head
);
5739 while (DEBUG_INSN_P (head
) && head
!= end
)
5740 head
= NEXT_INSN (head
);
5745 if (!onlyjump_p (end
))
5752 end
= PREV_INSN (end
);
5753 while (DEBUG_INSN_P (end
) && end
!= head
)
5754 end
= PREV_INSN (end
);
5757 /* Don't move frame-related insn across the conditional branch. This
5758 can lead to one of the paths of the branch having wrong unwind info. */
5759 if (epilogue_completed
)
5761 rtx_insn
*insn
= head
;
5764 if (INSN_P (insn
) && RTX_FRAME_RELATED_P (insn
))
5768 insn
= NEXT_INSN (insn
);
5772 /* Disable handling dead code by conditional execution if the machine needs
5773 to do anything funny with the tests, etc. */
5774 #ifndef IFCVT_MODIFY_TESTS
5775 if (targetm
.have_conditional_execution ())
5777 /* In the conditional execution case, we have things easy. We know
5778 the condition is reversible. We don't have to check life info
5779 because we're going to conditionally execute the code anyway.
5780 All that's left is making sure the insns involved can actually
5785 /* If the conditional jump is more than just a conditional jump,
5786 then we cannot do conditional execution conversion on this block. */
5787 if (!onlyjump_p (jump
))
5790 cond
= cond_exec_get_condition (jump
);
5794 rtx note
= find_reg_note (jump
, REG_BR_PROB
, NULL_RTX
);
5795 profile_probability prob_val
5796 = (note
? profile_probability::from_reg_br_prob_note (XINT (note
, 0))
5797 : profile_probability::uninitialized ());
5801 enum rtx_code rev
= reversed_comparison_code (cond
, jump
);
5804 cond
= gen_rtx_fmt_ee (rev
, GET_MODE (cond
), XEXP (cond
, 0),
5806 prob_val
= prob_val
.invert ();
5809 if (cond_exec_process_insns (NULL
, head
, end
, cond
, prob_val
, false)
5810 && verify_changes (0))
5811 n_validated_changes
= num_validated_changes ();
5820 /* If we allocated new pseudos (e.g. in the conditional move
5821 expander called from noce_emit_cmove), we must resize the
5823 if (max_regno
< max_reg_num ())
5824 max_regno
= max_reg_num ();
5826 /* Try the NCE path if the CE path did not result in any changes. */
5827 if (n_validated_changes
== 0)
5834 /* In the non-conditional execution case, we have to verify that there
5835 are no trapping operations, no calls, no references to memory, and
5836 that any registers modified are dead at the branch site. */
5838 if (!any_condjump_p (jump
))
5841 /* Find the extent of the conditional. */
5842 cond
= noce_get_condition (jump
, &earliest
, false);
5846 live
= BITMAP_ALLOC (®_obstack
);
5847 simulate_backwards_to_point (merge_bb
, live
, end
);
5848 success
= can_move_insns_across (head
, end
, earliest
, jump
,
5850 df_get_live_in (other_bb
), NULL
);
5855 /* Collect the set of registers set in MERGE_BB. */
5856 merge_set
= BITMAP_ALLOC (®_obstack
);
5858 FOR_BB_INSNS (merge_bb
, insn
)
5859 if (NONDEBUG_INSN_P (insn
))
5860 df_simulate_find_defs (insn
, merge_set
);
5862 /* If shrink-wrapping, disable this optimization when test_bb is
5863 the first basic block and merge_bb exits. The idea is to not
5864 move code setting up a return register as that may clobber a
5865 register used to pass function parameters, which then must be
5866 saved in caller-saved regs. A caller-saved reg requires the
5867 prologue, killing a shrink-wrap opportunity. */
5868 if ((SHRINK_WRAPPING_ENABLED
&& !epilogue_completed
)
5869 && ENTRY_BLOCK_PTR_FOR_FN (cfun
)->next_bb
== test_bb
5870 && single_succ_p (new_dest
)
5871 && single_succ (new_dest
) == EXIT_BLOCK_PTR_FOR_FN (cfun
)
5872 && bitmap_intersect_p (df_get_live_in (new_dest
), merge_set
))
5877 return_regs
= BITMAP_ALLOC (®_obstack
);
5879 /* Start off with the intersection of regs used to pass
5880 params and regs used to return values. */
5881 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
5882 if (FUNCTION_ARG_REGNO_P (i
)
5883 && targetm
.calls
.function_value_regno_p (i
))
5884 bitmap_set_bit (return_regs
, INCOMING_REGNO (i
));
5886 bitmap_and_into (return_regs
,
5887 df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun
)));
5888 bitmap_and_into (return_regs
,
5889 df_get_live_in (EXIT_BLOCK_PTR_FOR_FN (cfun
)));
5890 if (!bitmap_empty_p (return_regs
))
5892 FOR_BB_INSNS_REVERSE (new_dest
, insn
)
5893 if (NONDEBUG_INSN_P (insn
))
5897 /* If this insn sets any reg in return_regs, add all
5898 reg uses to the set of regs we're interested in. */
5899 FOR_EACH_INSN_DEF (def
, insn
)
5900 if (bitmap_bit_p (return_regs
, DF_REF_REGNO (def
)))
5902 df_simulate_uses (insn
, return_regs
);
5906 if (bitmap_intersect_p (merge_set
, return_regs
))
5908 BITMAP_FREE (return_regs
);
5909 BITMAP_FREE (merge_set
);
5913 BITMAP_FREE (return_regs
);
5918 /* We don't want to use normal invert_jump or redirect_jump because
5919 we don't want to delete_insn called. Also, we want to do our own
5920 change group management. */
5922 old_dest
= JUMP_LABEL (jump
);
5923 if (other_bb
!= new_dest
)
5925 if (!any_condjump_p (jump
))
5928 if (JUMP_P (BB_END (dest_edge
->src
)))
5929 new_dest_label
= JUMP_LABEL (BB_END (dest_edge
->src
));
5930 else if (new_dest
== EXIT_BLOCK_PTR_FOR_FN (cfun
))
5931 new_dest_label
= ret_rtx
;
5933 new_dest_label
= block_label (new_dest
);
5935 rtx_jump_insn
*jump_insn
= as_a
<rtx_jump_insn
*> (jump
);
5937 ? ! invert_jump_1 (jump_insn
, new_dest_label
)
5938 : ! redirect_jump_1 (jump_insn
, new_dest_label
))
5942 if (verify_changes (n_validated_changes
))
5943 confirm_change_group ();
5947 if (other_bb
!= new_dest
)
5949 redirect_jump_2 (as_a
<rtx_jump_insn
*> (jump
), old_dest
, new_dest_label
,
5952 redirect_edge_succ (BRANCH_EDGE (test_bb
), new_dest
);
5955 std::swap (BRANCH_EDGE (test_bb
)->probability
,
5956 FALLTHRU_EDGE (test_bb
)->probability
);
5957 update_br_prob_note (test_bb
);
5961 /* Move the insns out of MERGE_BB to before the branch. */
5966 if (end
== BB_END (merge_bb
))
5967 BB_END (merge_bb
) = PREV_INSN (head
);
5969 /* PR 21767: when moving insns above a conditional branch, the REG_EQUAL
5970 notes being moved might become invalid. */
5976 if (! INSN_P (insn
))
5978 note
= find_reg_note (insn
, REG_EQUAL
, NULL_RTX
);
5981 remove_note (insn
, note
);
5982 } while (insn
!= end
&& (insn
= NEXT_INSN (insn
)));
5984 /* PR46315: when moving insns above a conditional branch, the REG_EQUAL
5985 notes referring to the registers being set might become invalid. */
5991 EXECUTE_IF_SET_IN_BITMAP (merge_set
, 0, i
, bi
)
5992 remove_reg_equal_equiv_notes_for_regno (i
);
5994 BITMAP_FREE (merge_set
);
5997 reorder_insns (head
, end
, PREV_INSN (earliest
));
6000 /* Remove the jump and edge if we can. */
6001 if (other_bb
== new_dest
)
6004 remove_edge (BRANCH_EDGE (test_bb
));
6005 /* ??? Can't merge blocks here, as then_bb is still in use.
6006 At minimum, the merge will get done just before bb-reorder. */
6015 BITMAP_FREE (merge_set
);
6020 /* Main entry point for all if-conversion. AFTER_COMBINE is true if
6021 we are after combine pass. */
6024 if_convert (bool after_combine
)
6031 df_live_add_problem ();
6032 df_live_set_all_dirty ();
6035 /* Record whether we are after combine pass. */
6036 ifcvt_after_combine
= after_combine
;
6037 have_cbranchcc4
= (direct_optab_handler (cbranch_optab
, CCmode
)
6038 != CODE_FOR_nothing
);
6039 num_possible_if_blocks
= 0;
6040 num_updated_if_blocks
= 0;
6041 num_true_changes
= 0;
6043 loop_optimizer_init (AVOID_CFG_MODIFICATIONS
);
6044 mark_loop_exit_edges ();
6045 loop_optimizer_finalize ();
6046 free_dominance_info (CDI_DOMINATORS
);
6048 /* Compute postdominators. */
6049 calculate_dominance_info (CDI_POST_DOMINATORS
);
6051 df_set_flags (DF_LR_RUN_DCE
);
6053 /* Go through each of the basic blocks looking for things to convert. If we
6054 have conditional execution, we make multiple passes to allow us to handle
6055 IF-THEN{-ELSE} blocks within other IF-THEN{-ELSE} blocks. */
6060 /* Only need to do dce on the first pass. */
6061 df_clear_flags (DF_LR_RUN_DCE
);
6062 cond_exec_changed_p
= false;
6065 #ifdef IFCVT_MULTIPLE_DUMPS
6066 if (dump_file
&& pass
> 1)
6067 fprintf (dump_file
, "\n\n========== Pass %d ==========\n", pass
);
6070 FOR_EACH_BB_FN (bb
, cfun
)
6073 while (!df_get_bb_dirty (bb
)
6074 && (new_bb
= find_if_header (bb
, pass
)) != NULL
)
6078 #ifdef IFCVT_MULTIPLE_DUMPS
6079 if (dump_file
&& cond_exec_changed_p
)
6080 print_rtl_with_bb (dump_file
, get_insns (), dump_flags
);
6083 while (cond_exec_changed_p
);
6085 #ifdef IFCVT_MULTIPLE_DUMPS
6087 fprintf (dump_file
, "\n\n========== no more changes\n");
6090 free_dominance_info (CDI_POST_DOMINATORS
);
6095 clear_aux_for_blocks ();
6097 /* If we allocated new pseudos, we must resize the array for sched1. */
6098 if (max_regno
< max_reg_num ())
6099 max_regno
= max_reg_num ();
6101 /* Write the final stats. */
6102 if (dump_file
&& num_possible_if_blocks
> 0)
6105 "\n%d possible IF blocks searched.\n",
6106 num_possible_if_blocks
);
6108 "%d IF blocks converted.\n",
6109 num_updated_if_blocks
);
6111 "%d true changes made.\n\n\n",
6116 df_remove_problem (df_live
);
6118 /* Some non-cold blocks may now be only reachable from cold blocks.
6120 fixup_partitions ();
6122 checking_verify_flow_info ();
6125 /* If-conversion and CFG cleanup. */
6127 rest_of_handle_if_conversion (void)
6131 if (flag_if_conversion
)
6135 dump_reg_info (dump_file
);
6136 dump_flow_info (dump_file
, dump_flags
);
6138 cleanup_cfg (CLEANUP_EXPENSIVE
);
6140 if (num_updated_if_blocks
)
6141 /* Get rid of any dead CC-related instructions. */
6142 flags
|= CLEANUP_FORCE_FAST_DCE
;
6145 cleanup_cfg (flags
);
6150 const pass_data pass_data_rtl_ifcvt
=
6152 RTL_PASS
, /* type */
6154 OPTGROUP_NONE
, /* optinfo_flags */
6155 TV_IFCVT
, /* tv_id */
6156 0, /* properties_required */
6157 0, /* properties_provided */
6158 0, /* properties_destroyed */
6159 0, /* todo_flags_start */
6160 TODO_df_finish
, /* todo_flags_finish */
6163 class pass_rtl_ifcvt
: public rtl_opt_pass
6166 pass_rtl_ifcvt (gcc::context
*ctxt
)
6167 : rtl_opt_pass (pass_data_rtl_ifcvt
, ctxt
)
6170 /* opt_pass methods: */
6171 bool gate (function
*) final override
6173 return (optimize
> 0) && dbg_cnt (if_conversion
);
6176 unsigned int execute (function
*) final override
6178 rest_of_handle_if_conversion ();
6182 }; // class pass_rtl_ifcvt
6187 make_pass_rtl_ifcvt (gcc::context
*ctxt
)
6189 return new pass_rtl_ifcvt (ctxt
);
6193 /* Rerun if-conversion, as combine may have simplified things enough
6194 to now meet sequence length restrictions. */
6198 const pass_data pass_data_if_after_combine
=
6200 RTL_PASS
, /* type */
6202 OPTGROUP_NONE
, /* optinfo_flags */
6203 TV_IFCVT
, /* tv_id */
6204 0, /* properties_required */
6205 0, /* properties_provided */
6206 0, /* properties_destroyed */
6207 0, /* todo_flags_start */
6208 TODO_df_finish
, /* todo_flags_finish */
6211 class pass_if_after_combine
: public rtl_opt_pass
6214 pass_if_after_combine (gcc::context
*ctxt
)
6215 : rtl_opt_pass (pass_data_if_after_combine
, ctxt
)
6218 /* opt_pass methods: */
6219 bool gate (function
*) final override
6221 return optimize
> 0 && flag_if_conversion
6222 && dbg_cnt (if_after_combine
);
6225 unsigned int execute (function
*) final override
6231 }; // class pass_if_after_combine
6236 make_pass_if_after_combine (gcc::context
*ctxt
)
6238 return new pass_if_after_combine (ctxt
);
6244 const pass_data pass_data_if_after_reload
=
6246 RTL_PASS
, /* type */
6248 OPTGROUP_NONE
, /* optinfo_flags */
6249 TV_IFCVT2
, /* tv_id */
6250 0, /* properties_required */
6251 0, /* properties_provided */
6252 0, /* properties_destroyed */
6253 0, /* todo_flags_start */
6254 TODO_df_finish
, /* todo_flags_finish */
6257 class pass_if_after_reload
: public rtl_opt_pass
6260 pass_if_after_reload (gcc::context
*ctxt
)
6261 : rtl_opt_pass (pass_data_if_after_reload
, ctxt
)
6264 /* opt_pass methods: */
6265 bool gate (function
*) final override
6267 return optimize
> 0 && flag_if_conversion2
6268 && dbg_cnt (if_after_reload
);
6271 unsigned int execute (function
*) final override
6277 }; // class pass_if_after_reload
6282 make_pass_if_after_reload (gcc::context
*ctxt
)
6284 return new pass_if_after_reload (ctxt
);