libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / ifcvt.cc
blob6487574c5149412e98ff49f286385ab2726fbc91
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)
9 any later version.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "cfghooks.h"
28 #include "df.h"
29 #include "memmodel.h"
30 #include "tm_p.h"
31 #include "expmed.h"
32 #include "optabs.h"
33 #include "regs.h"
34 #include "emit-rtl.h"
35 #include "recog.h"
37 #include "cfgrtl.h"
38 #include "cfganal.h"
39 #include "cfgcleanup.h"
40 #include "expr.h"
41 #include "output.h"
42 #include "cfgloop.h"
43 #include "tree-pass.h"
44 #include "dbgcnt.h"
45 #include "shrink-wrap.h"
46 #include "rtl-iter.h"
47 #include "ifcvt.h"
49 #ifndef MAX_CONDITIONAL_EXECUTE
50 #define MAX_CONDITIONAL_EXECUTE \
51 (BRANCH_COST (optimize_function_for_speed_p (cfun), false) \
52 + 1)
53 #endif
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
69 execution. */
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,
98 edge, bool);
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. */
108 static int
109 count_bb_insns (const_basic_block bb)
111 int count = 0;
112 rtx_insn *insn = BB_HEAD (bb);
114 while (1)
116 if (active_insn_p (insn) && !JUMP_P (insn))
117 count++;
119 if (insn == BB_END (bb))
120 break;
121 insn = NEXT_INSN (insn);
124 return count;
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. */
135 static bool
136 cheap_bb_rtx_cost_p (const_basic_block bb,
137 profile_probability prob, int max_cost)
139 int count = 0;
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 ()
143 : 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. */
159 else
160 scale += REG_BR_PROB_BASE / 8;
163 max_cost *= scale;
165 while (1)
167 if (NONJUMP_INSN_P (insn))
169 int cost = insn_cost (insn, speed) * REG_BR_PROB_BASE;
170 if (cost == 0)
171 return false;
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. */
180 #ifdef STACK_REGS
182 rtx set = single_set (insn);
183 if (set && STACK_REG_P (SET_DEST (set)))
184 return false;
186 #endif
188 count += cost;
189 if (count >= max_cost)
190 return false;
192 else if (CALL_P (insn))
193 return false;
195 if (insn == BB_END (bb))
196 break;
197 insn = NEXT_INSN (insn);
200 return true;
203 /* Return the first non-jump active insn in the basic block. */
205 static rtx_insn *
206 first_active_insn (basic_block bb)
208 rtx_insn *insn = BB_HEAD (bb);
210 if (LABEL_P (insn))
212 if (insn == BB_END (bb))
213 return NULL;
214 insn = NEXT_INSN (insn);
217 while (NOTE_P (insn) || DEBUG_INSN_P (insn))
219 if (insn == BB_END (bb))
220 return NULL;
221 insn = NEXT_INSN (insn);
224 if (JUMP_P (insn))
225 return NULL;
227 return insn;
230 /* Return the last non-jump active (non-jump) insn in the basic block. */
232 static rtx_insn *
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);
238 while (NOTE_P (insn)
239 || JUMP_P (insn)
240 || DEBUG_INSN_P (insn)
241 || (skip_use_p
242 && NONJUMP_INSN_P (insn)
243 && GET_CODE (PATTERN (insn)) == USE))
245 if (insn == head)
246 return NULL;
247 insn = PREV_INSN (insn);
250 if (LABEL_P (insn))
251 return NULL;
253 return insn;
256 /* Return the active insn before INSN inside basic block CURR_BB. */
258 static rtx_insn *
259 find_active_insn_before (basic_block curr_bb, rtx_insn *insn)
261 if (!insn || insn == BB_HEAD (curr_bb))
262 return NULL;
264 while ((insn = PREV_INSN (insn)) != NULL_RTX)
266 if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
267 break;
269 /* No other active insn all the way to the start of the basic block. */
270 if (insn == BB_HEAD (curr_bb))
271 return NULL;
274 return insn;
277 /* Return the active insn after INSN inside basic block CURR_BB. */
279 static rtx_insn *
280 find_active_insn_after (basic_block curr_bb, rtx_insn *insn)
282 if (!insn || insn == BB_END (curr_bb))
283 return NULL;
285 while ((insn = NEXT_INSN (insn)) != NULL_RTX)
287 if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
288 break;
290 /* No other active insn all the way to the end of the basic block. */
291 if (insn == BB_END (curr_bb))
292 return NULL;
295 return insn;
298 /* Return the basic block reached by falling though the basic block BB. */
300 static basic_block
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. */
310 static bool
311 rtx_interchangeable_p (const_rtx a, const_rtx b)
313 if (!rtx_equal_p (a, b))
314 return false;
316 if (GET_CODE (a) != MEM)
317 return true;
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. */
334 static bool
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
340 prob_val,
341 /* probability of branch taken. */bool mod_ok)
343 bool must_be_last = false;
344 rtx_insn *insn;
345 rtx xtest;
346 rtx pattern;
348 if (!start || !end)
349 return 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)
355 return false;
357 if (NOTE_P (insn) || DEBUG_INSN_P (insn))
358 goto insn_done;
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))
364 return false;
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);
372 goto insn_done;
375 /* Last insn wasn't last? */
376 if (must_be_last)
377 return false;
379 if (modified_in_p (test, insn))
381 if (!mod_ok)
382 return false;
383 must_be_last = true;
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
391 two conditions. */
392 if (GET_CODE (pattern) == COND_EXEC)
394 if (GET_MODE (xtest) != GET_MODE (COND_EXEC_TEST (pattern)))
395 return false;
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);
409 if (! pattern)
410 return false;
411 #endif
413 validate_change (insn, &PATTERN (insn), pattern, 1);
415 if (CALL_P (insn) && prob_val.initialized_p ())
416 validate_change (insn, &REG_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);
421 insn_done:
422 if (insn == end)
423 break;
426 return true;
429 /* Return the condition for a jump. Do not do any special processing. */
431 static rtx
432 cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false)
434 rtx test_if, cond;
436 if (any_condjump_p (jump))
437 test_if = SET_SRC (pc_set (jump));
438 else
439 return NULL_RTX;
440 cond = XEXP (test_if, 0);
442 /* If this branches to JUMP_LABEL when the condition is false,
443 reverse the condition. */
444 if (get_reversed
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);
450 if (rev == UNKNOWN)
451 return NULL_RTX;
453 cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
454 XEXP (cond, 1));
457 return cond;
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. */
464 static bool
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;
488 rtx note;
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)
496 return false;
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
505 the test. */
506 test_expr = cond_exec_get_condition (BB_END (test_bb));
507 if (! test_expr)
508 return false;
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)))
513 return false;
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;
524 if (else_bb)
526 int n_matching;
528 max *= 2;
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,
538 NULL);
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;
544 if (n_matching > 0)
546 if (then_end)
547 then_end = find_active_insn_before (then_bb, then_first_tail);
548 if (else_end)
549 else_end = find_active_insn_before (else_bb, else_first_tail);
550 n_insns -= 2 * n_matching;
553 if (then_start
554 && else_start
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);
560 n_matching
561 = flow_find_head_matching_sequence (then_bb, else_bb,
562 &then_last_head,
563 &else_last_head,
564 longest_match);
566 if (n_matching > 0)
568 rtx_insn *insn;
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))
579 return false;
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;
587 if (n_matching > 0)
589 if (then_start)
590 then_start = find_active_insn_after (then_bb, then_last_head);
591 if (else_start)
592 else_start = find_active_insn_after (else_bb, else_last_head);
593 n_insns -= 2 * n_matching;
598 if (n_insns > max)
599 return false;
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));
610 else
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)
620 goto fail;
621 #endif
623 note = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
624 if (note)
626 true_prob_val = profile_probability::from_reg_br_prob_note (XINT (note, 0));
627 false_prob_val = true_prob_val.invert ();
629 else
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;
642 if (! false_expr)
643 goto fail;
647 rtx_insn *start, *end;
648 rtx t, f;
649 enum rtx_code f_code;
651 bb = block_fallthru (bb);
652 start = first_active_insn (bb);
653 end = last_active_insn (bb, true);
654 if (start
655 && ! cond_exec_process_insns (ce_info, start, end, false_expr,
656 false_prob_val, false))
657 goto fail;
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)))
662 goto fail;
664 /* Find the conditional jump and isolate the test. */
665 t = cond_exec_get_condition (BB_END (bb));
666 if (! t)
667 goto fail;
669 f_code = reversed_comparison_code (t, BB_END (bb));
670 if (f_code == UNKNOWN)
671 goto fail;
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);
679 else
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
687 do so here. */
688 #ifdef IFCVT_MODIFY_MULTIPLE_TESTS
689 IFCVT_MODIFY_MULTIPLE_TESTS (ce_info, bb, t, f);
691 /* See if the conversion failed. */
692 if (!t || !f)
693 goto fail;
694 #endif
696 true_expr = t;
697 false_expr = f;
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. */
709 if (then_end
710 && (! false_expr
711 || ! cond_exec_process_insns (ce_info, then_start, then_end,
712 false_expr, false_prob_val,
713 then_mod_ok)))
714 goto fail;
716 if (else_bb && else_end
717 && ! cond_exec_process_insns (ce_info, else_start, else_end,
718 true_expr, true_prob_val, true))
719 goto fail;
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);
728 #endif
729 return false;
732 #ifdef IFCVT_MODIFY_FINAL
733 /* Do any machine dependent final modifications. */
734 IFCVT_MODIFY_FINAL (ce_info);
735 #endif
737 /* Conversion succeeded. */
738 if (dump_file)
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. */
747 if (then_first_tail)
749 rtx_insn *from = then_first_tail;
750 if (!INSN_P (from))
751 from = find_active_insn_after (then_bb, from);
752 delete_insn_chain (from, get_last_bb_insn (then_bb), false);
754 if (else_last_head)
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;
759 return true;
761 fail:
762 #ifdef IFCVT_MODIFY_CANCEL
763 /* Cancel any machine dependent changes. */
764 IFCVT_MODIFY_CANCEL (ce_info);
765 #endif
767 cancel_changes (0);
768 return false;
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. */
804 bool
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)
814 return true;
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*. */
823 static rtx
824 noce_emit_store_flag (struct noce_if_info *if_info, rtx x, bool reversep,
825 int normalize)
827 rtx cond = if_info->cond;
828 bool cond_complex;
829 enum rtx_code code;
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. */
837 if (cond_complex)
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;
847 else if (reversep
848 && if_info->rev_cond
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;
853 reversep = false;
856 if (reversep)
857 code = reversed_comparison_code (cond, if_info->jump);
858 else
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),
865 XEXP (cond, 1));
866 rtx set = gen_rtx_SET (x, src);
868 start_sequence ();
869 rtx_insn *insn = emit_insn (set);
871 if (recog_memoized (insn) >= 0)
873 rtx_insn *seq = get_insns ();
874 end_sequence ();
875 emit_insn (seq);
877 if_info->cond_earliest = if_info->jump;
879 return x;
882 end_sequence ();
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)))
887 return NULL_RTX;
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
896 / force_operand. */
898 static bool
899 noce_can_force_operand (rtx x)
901 if (general_operand (x, VOIDmode))
902 return true;
903 if (SUBREG_P (x))
905 if (!noce_can_force_operand (SUBREG_REG (x)))
906 return false;
907 return true;
909 if (ARITHMETIC_P (x))
911 if (!noce_can_force_operand (XEXP (x, 0))
912 || !noce_can_force_operand (XEXP (x, 1)))
913 return false;
914 switch (GET_CODE (x))
916 case MULT:
917 case DIV:
918 case MOD:
919 case UDIV:
920 case UMOD:
921 return true;
922 default:
923 return code_to_optab (GET_CODE (x));
926 if (UNARY_P (x))
928 if (!noce_can_force_operand (XEXP (x, 0)))
929 return false;
930 switch (GET_CODE (x))
932 case ZERO_EXTEND:
933 case SIGN_EXTEND:
934 case TRUNCATE:
935 case FLOAT_EXTEND:
936 case FLOAT_TRUNCATE:
937 case FIX:
938 case UNSIGNED_FIX:
939 case FLOAT:
940 case UNSIGNED_FLOAT:
941 return true;
942 default:
943 return code_to_optab (GET_CODE (x));
946 return false;
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. */
952 static void
953 noce_emit_move_insn (rtx x, rtx y)
955 machine_mode outmode;
956 rtx outer, inner;
957 poly_int64 bitpos;
959 if (GET_CODE (x) != STRICT_LOW_PART)
961 rtx_insn *seq, *insn;
962 rtx target;
963 optab ot;
965 start_sequence ();
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));
971 seq = get_insns ();
972 end_sequence ();
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)
989 if (MEM_P (op))
990 start = BITS_PER_UNIT - start - size;
991 else
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,
1000 false);
1001 return;
1004 switch (GET_RTX_CLASS (GET_CODE (y)))
1006 case RTX_UNARY:
1007 ot = code_to_optab (GET_CODE (y));
1008 if (ot && noce_can_force_operand (XEXP (y, 0)))
1010 start_sequence ();
1011 target = expand_unop (GET_MODE (y), ot, XEXP (y, 0), x, 0);
1012 if (target != NULL_RTX)
1014 if (target != x)
1015 emit_move_insn (x, target);
1016 seq = get_insns ();
1018 end_sequence ();
1020 break;
1022 case RTX_BIN_ARITH:
1023 case RTX_COMM_ARITH:
1024 ot = code_to_optab (GET_CODE (y));
1025 if (ot
1026 && noce_can_force_operand (XEXP (y, 0))
1027 && noce_can_force_operand (XEXP (y, 1)))
1029 start_sequence ();
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)
1035 if (target != x)
1036 emit_move_insn (x, target);
1037 seq = get_insns ();
1039 end_sequence ();
1041 break;
1043 default:
1044 break;
1048 emit_insn (seq);
1049 return;
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. */
1062 static rtx
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);
1069 return NULL_RTX;
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. */
1077 static rtx_insn *
1078 end_ifcvt_sequence (struct noce_if_info *if_info)
1080 rtx_insn *insn;
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);
1093 end_sequence ();
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))
1100 if (JUMP_P (insn)
1101 || recog_memoized (insn) == -1
1102 /* Make sure new generated code does not clobber CC. */
1103 || (cc && set_of (cc, insn)))
1104 return NULL;
1106 return seq;
1109 /* Return true iff the then and else basic block (if it exists)
1110 consist of a single simple set instruction. */
1112 static bool
1113 noce_simple_bbs (struct noce_if_info *if_info)
1115 if (!if_info->then_simple)
1116 return false;
1118 if (if_info->else_bb)
1119 return if_info->else_simple;
1121 return true;
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". */
1127 static bool
1128 noce_try_move (struct noce_if_info *if_info)
1130 rtx cond = if_info->cond;
1131 enum rtx_code code = GET_CODE (cond);
1132 rtx y;
1133 rtx_insn *seq;
1135 if (code != NE && code != EQ)
1136 return false;
1138 if (!noce_simple_bbs (if_info))
1139 return false;
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))
1145 return false;
1147 /* Check whether the operands of the comparison are A and in
1148 either order. */
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))
1155 return false;
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))
1162 start_sequence ();
1163 noce_emit_move_insn (if_info->x, y);
1164 seq = end_ifcvt_sequence (if_info);
1165 if (!seq)
1166 return false;
1168 emit_insn_before_setloc (seq, if_info->jump,
1169 INSN_LOCATION (if_info->insn_a));
1171 if_info->transform_name = "noce_try_move";
1172 return true;
1174 return false;
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. */
1181 static bool
1182 noce_try_ifelse_collapse (struct noce_if_info * if_info)
1184 if (!noce_simple_bbs (if_info))
1185 return false;
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,
1190 if_info->a);
1192 if (GET_CODE (if_then_else) == IF_THEN_ELSE)
1193 return false;
1195 rtx_insn *seq;
1196 start_sequence ();
1197 noce_emit_move_insn (if_info->x, if_then_else);
1198 seq = end_ifcvt_sequence (if_info);
1199 if (!seq)
1200 return false;
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";
1206 return true;
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. */
1216 static bool
1217 noce_try_store_flag (struct noce_if_info *if_info)
1219 bool reversep;
1220 rtx target;
1221 rtx_insn *seq;
1223 if (!noce_simple_bbs (if_info))
1224 return false;
1226 if (CONST_INT_P (if_info->b)
1227 && INTVAL (if_info->b) == STORE_FLAG_VALUE
1228 && if_info->a == const0_rtx)
1229 reversep = false;
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)
1234 reversep = true;
1235 else
1236 return false;
1238 start_sequence ();
1240 target = noce_emit_store_flag (if_info, if_info->x, reversep, 0);
1241 if (target)
1243 if (target != if_info->x)
1244 noce_emit_move_insn (if_info->x, target);
1246 seq = end_ifcvt_sequence (if_info);
1247 if (! seq)
1248 return false;
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";
1253 return true;
1255 else
1257 end_sequence ();
1258 return false;
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. */
1272 static bool
1273 noce_try_inverse_constants (struct noce_if_info *if_info)
1275 if (!noce_simple_bbs (if_info))
1276 return false;
1278 if (!CONST_INT_P (if_info->a)
1279 || !CONST_INT_P (if_info->b)
1280 || !REG_P (if_info->x))
1281 return false;
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;
1290 rtx x = if_info->x;
1291 rtx target;
1293 start_sequence ();
1295 rtx_code code;
1296 if (val_b != HOST_WIDE_INT_MIN && val_a == -val_b)
1297 code = NEG;
1298 else if (val_a == ~val_b)
1299 code = NOT;
1300 else
1302 end_sequence ();
1303 return false;
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);
1311 if (target)
1313 rtx_insn *seq = get_insns ();
1315 if (!seq)
1317 end_sequence ();
1318 return false;
1321 if (target != if_info->x)
1322 noce_emit_move_insn (if_info->x, target);
1324 seq = end_ifcvt_sequence (if_info);
1326 if (!seq)
1327 return false;
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";
1332 return true;
1335 end_sequence ();
1336 return false;
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
1342 and B. */
1344 static bool
1345 noce_try_store_flag_constants (struct noce_if_info *if_info)
1347 rtx target;
1348 rtx_insn *seq;
1349 bool reversep;
1350 HOST_WIDE_INT itrue, ifalse, diff, tmp;
1351 int normalize;
1352 bool can_reverse;
1353 machine_mode mode = GET_MODE (if_info->x);
1354 rtx common = NULL_RTX;
1356 rtx a = if_info->a;
1357 rtx b = if_info->b;
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);
1372 a = XEXP (a, 1);
1373 b = XEXP (b, 1);
1376 if (!noce_simple_bbs (if_info))
1377 return false;
1379 if (CONST_INT_P (a)
1380 && CONST_INT_P (b))
1382 ifalse = INTVAL (a);
1383 itrue = INTVAL (b);
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. */
1388 if ((diff > 0)
1389 != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
1390 return false;
1392 diff = trunc_int_for_mode (diff, mode);
1394 can_reverse = noce_reversed_cond_code (if_info) != UNKNOWN;
1395 reversep = false;
1396 if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
1398 normalize = 0;
1399 /* We could collapse these cases but it is easier to follow the
1400 diff/STORE_FLAG_VALUE combinations when they are listed
1401 explicitly. */
1403 /* test ? 3 : 4
1404 => 4 + (test != 0). */
1405 if (diff < 0 && STORE_FLAG_VALUE < 0)
1406 reversep = false;
1407 /* test ? 4 : 3
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
1416 here. */
1417 if (subtract_flag_p && common)
1418 return false;
1420 /* test ? 3 : 4
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
1429 here. */
1430 if (subtract_flag_p && common)
1431 return false;
1433 /* test ? 4 : 3
1434 => 4 + (test != 0). */
1435 else if (diff > 0 && STORE_FLAG_VALUE > 0)
1436 reversep = false;
1437 else
1438 gcc_unreachable ();
1440 /* Is this (cond) ? 2^n : 0? */
1441 else if (ifalse == 0 && pow2p_hwi (itrue)
1442 && STORE_FLAG_VALUE == 1)
1443 normalize = 1;
1444 /* Is this (cond) ? 0 : 2^n? */
1445 else if (itrue == 0 && pow2p_hwi (ifalse) && can_reverse
1446 && STORE_FLAG_VALUE == 1)
1448 normalize = 1;
1449 reversep = true;
1451 /* Is this (cond) ? -1 : x? */
1452 else if (itrue == -1
1453 && STORE_FLAG_VALUE == -1)
1454 normalize = -1;
1455 /* Is this (cond) ? x : -1? */
1456 else if (ifalse == -1 && can_reverse
1457 && STORE_FLAG_VALUE == -1)
1459 normalize = -1;
1460 reversep = true;
1462 else
1463 return false;
1465 if (reversep)
1467 std::swap (itrue, ifalse);
1468 diff = trunc_int_for_mode (-(unsigned HOST_WIDE_INT) diff, mode);
1471 start_sequence ();
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);
1482 if (! target)
1484 end_sequence ();
1485 return false;
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. */
1495 if (common)
1496 target = expand_simple_binop (mode, PLUS,
1497 target, common,
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
1507 expressions. */
1508 else if (common)
1510 end_sequence ();
1511 return false;
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,
1519 OPTAB_WIDEN);
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);
1530 else
1532 end_sequence ();
1533 return false;
1536 if (! target)
1538 end_sequence ();
1539 return false;
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))
1547 return false;
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";
1553 return true;
1556 return false;
1559 /* Convert "if (test) foo++" into "foo += (test != 0)", and
1560 similarly for "foo--". */
1562 static bool
1563 noce_try_addcc (struct noce_if_info *if_info)
1565 rtx target;
1566 rtx_insn *seq;
1567 bool subtract;
1568 int normalize;
1570 if (!noce_simple_bbs (if_info))
1571 return false;
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;
1578 enum rtx_code code;
1580 if (cond == NULL_RTX)
1582 cond = if_info->cond;
1583 code = reversed_comparison_code (cond, if_info->jump);
1585 else
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))
1592 start_sequence ();
1593 target = emit_conditional_add (if_info->x, code,
1594 XEXP (cond, 0),
1595 XEXP (cond, 1),
1596 VOIDmode,
1597 if_info->b,
1598 XEXP (if_info->a, 1),
1599 GET_MODE (if_info->x),
1600 (code == LTU || code == GEU
1601 || code == LEU || code == GTU));
1602 if (target)
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))
1609 return false;
1611 emit_insn_before_setloc (seq, if_info->jump,
1612 INSN_LOCATION (if_info->insn_a));
1613 if_info->transform_name = "noce_try_addcc";
1615 return true;
1617 end_sequence ();
1620 /* If that fails, construct conditional increment or decrement using
1621 setcc. We're changing a branch and an increment to a comparison and
1622 an ADD/SUB. */
1623 if (XEXP (if_info->a, 1) == const1_rtx
1624 || XEXP (if_info->a, 1) == constm1_rtx)
1626 start_sequence ();
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;
1631 else
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)),
1637 true, normalize);
1639 if (target)
1640 target = expand_simple_binop (GET_MODE (if_info->x),
1641 subtract ? MINUS : PLUS,
1642 if_info->b, target, if_info->x,
1643 0, OPTAB_WIDEN);
1644 if (target)
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))
1651 return false;
1653 emit_insn_before_setloc (seq, if_info->jump,
1654 INSN_LOCATION (if_info->insn_a));
1655 if_info->transform_name = "noce_try_addcc";
1656 return true;
1658 end_sequence ();
1662 return false;
1665 /* Convert "if (test) x = 0;" to "x &= -(test == 0);" */
1667 static bool
1668 noce_try_store_flag_mask (struct noce_if_info *if_info)
1670 rtx target;
1671 rtx_insn *seq;
1672 bool reversep;
1674 if (!noce_simple_bbs (if_info))
1675 return false;
1677 reversep = false;
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))))
1685 start_sequence ();
1686 target = noce_emit_store_flag (if_info,
1687 gen_reg_rtx (GET_MODE (if_info->x)),
1688 reversep, -1);
1689 if (target)
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,
1693 OPTAB_WIDEN);
1695 if (target)
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))
1702 return false;
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";
1708 return true;
1711 end_sequence ();
1714 return false;
1717 /* Helper function for noce_try_cmove and noce_try_cmove_arith. */
1719 static rtx
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,
1722 rtx rev_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);
1739 start_sequence ();
1740 rtx_insn *insn = emit_insn (set);
1742 if (recog_memoized (insn) >= 0)
1744 rtx_insn *seq = get_insns ();
1745 end_sequence ();
1746 emit_insn (seq);
1748 return x;
1751 end_sequence ();
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));
1760 else
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)
1770 return NULL_RTX;
1773 target = emit_conditional_move (x, { code, cmp_a, cmp_b, VOIDmode },
1774 vtrue, vfalse, GET_MODE (x),
1775 unsignedp);
1778 if (target)
1779 return target;
1781 /* We might be faced with a situation like:
1783 x = (reg:M TARGET)
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
1789 the result.
1791 If we can't create new pseudos, though, don't bother. */
1792 if (reload_completed)
1793 return NULL_RTX;
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)))
1809 return NULL_RTX;
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. */
1818 if (!target)
1819 return NULL_RTX;
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);
1825 return x;
1827 else
1828 return NULL_RTX;
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. */
1837 static rtx
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);
1843 rtx czero_cond
1844 = gen_rtx_fmt_ee (czero_code, GET_MODE (cond_op0), cond_op0, const0_rtx);
1845 rtx if_then_else
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)
1853 add_insn (insn);
1854 return target;
1857 return NULL_RTX;
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. */
1864 static bool
1865 noce_try_cmove (struct noce_if_info *if_info)
1867 enum rtx_code code;
1868 rtx target;
1869 rtx_insn *seq;
1871 if (!noce_simple_bbs (if_info))
1872 return false;
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)))
1877 start_sequence ();
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);
1885 if (target)
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))
1892 return false;
1894 emit_insn_before_setloc (seq, if_info->jump,
1895 INSN_LOCATION (if_info->insn_a));
1896 if_info->transform_name = "noce_try_cmove";
1898 return true;
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
1906 approach. */
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);
1914 if (!target)
1916 end_sequence ();
1917 return false;
1920 HOST_WIDE_INT diff = (unsigned HOST_WIDE_INT) itrue - ifalse;
1921 /* Make sure we can represent the difference
1922 between the two values. */
1923 if ((diff > 0)
1924 != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
1926 end_sequence ();
1927 return false;
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);
1934 if (target)
1935 target = expand_simple_binop (mode, PLUS,
1936 target, gen_int_mode (ifalse, mode),
1937 if_info->x, 0, OPTAB_WIDEN);
1938 if (target)
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))
1945 return false;
1947 emit_insn_before_setloc (seq, if_info->jump,
1948 INSN_LOCATION (if_info->insn_a));
1949 if_info->transform_name = "noce_try_cmove";
1950 return true;
1952 else
1954 end_sequence ();
1955 return false;
1958 else
1959 end_sequence ();
1962 return false;
1965 /* Return true if X contains a conditional code mode rtx. */
1967 static bool
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)
1973 return true;
1975 return false;
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
1981 if-conversion. */
1983 static bool
1984 insn_valid_noce_process_p (rtx_insn *insn, rtx cc)
1986 if (!insn
1987 || !NONJUMP_INSN_P (insn)
1988 || (cc && set_of (cc, insn)))
1989 return false;
1991 rtx sset = single_set (insn);
1993 /* Currently support only simple single sets in test_bb. */
1994 if (!sset
1995 || !noce_operand_ok (SET_DEST (sset))
1996 || contains_ccmode_rtx_p (SET_DEST (sset))
1997 || !noce_operand_ok (SET_SRC (sset)))
1998 return false;
2000 return true;
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. */
2009 static bool
2010 bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b, rtx to_rename)
2012 rtx_insn *a_insn;
2013 bitmap bba_sets = BITMAP_ALLOC (&reg_obstack);
2015 df_ref def;
2016 df_ref use;
2018 FOR_BB_INSNS (bb_a, a_insn)
2020 if (!active_insn_p (a_insn))
2021 continue;
2023 rtx sset_a = single_set (a_insn);
2025 if (!sset_a)
2027 BITMAP_FREE (bba_sets);
2028 return false;
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));
2036 rtx_insn *b_insn;
2038 FOR_BB_INSNS (bb_b, b_insn)
2040 if (!active_insn_p (b_insn))
2041 continue;
2043 rtx sset_b = single_set (b_insn);
2045 if (!sset_b)
2047 BITMAP_FREE (bba_sets);
2048 return false;
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);
2064 return false;
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);
2073 return false;
2079 BITMAP_FREE (bba_sets);
2080 return true;
2083 /* Emit copies of all the active instructions in BB except the last.
2084 This is a helper for noce_try_cmove_arith. */
2086 static void
2087 noce_emit_all_but_last (basic_block bb)
2089 rtx_insn *last = last_active_insn (bb, false);
2090 rtx_insn *insn;
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. */
2105 static rtx_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)
2112 return NULL;
2114 return insn;
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. */
2123 static bool
2124 noce_emit_bb (rtx last_insn, basic_block bb, bool simple)
2126 if (bb && !simple)
2127 noce_emit_all_but_last (bb);
2129 if (last_insn && !noce_emit_insn (last_insn))
2130 return false;
2132 return true;
2135 /* Try more complex cases involving conditional_move. */
2137 static bool
2138 noce_try_cmove_arith (struct noce_if_info *if_info)
2140 rtx a = if_info->a;
2141 rtx b = if_info->b;
2142 rtx x = if_info->x;
2143 rtx orig_a, orig_b;
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;
2149 rtx target;
2150 bool is_mem = false;
2151 enum rtx_code code;
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);
2165 a = XEXP (a, 0);
2166 b = XEXP (b, 0);
2167 x = gen_reg_rtx (address_mode);
2168 is_mem = true;
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))
2175 return false;
2177 /* if (test) x = a + b; else x = c - d;
2178 => y = a + b;
2179 x = c - d;
2180 if (test)
2181 x = y;
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))
2191 return false;
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))
2198 reversep = true;
2199 else if (general_operand (b, GET_MODE (b)))
2200 reversep = true;
2202 if (reversep)
2204 if (if_info->rev_cond)
2206 cond = if_info->rev_cond;
2207 code = GET_CODE (cond);
2209 else
2210 code = reversed_comparison_code (cond, if_info->jump);
2211 std::swap (a, b);
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)))
2221 return false;
2223 start_sequence ();
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
2228 first. */
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);
2239 orig_a = a;
2240 orig_b = b;
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)
2255 if (is_mem)
2257 rtx reg = gen_reg_rtx (GET_MODE (a));
2258 emit_a = gen_rtx_SET (reg, a);
2260 else
2262 if (insn_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);
2268 SET_DEST (set) = a;
2270 emit_a = PATTERN (copy_of_a);
2272 else
2274 rtx tmp_reg = tmp_a ? tmp_a : gen_reg_rtx (GET_MODE (a));
2275 emit_a = gen_rtx_SET (tmp_reg, a);
2276 a = tmp_reg;
2281 if (! general_operand (b, GET_MODE (b)) || tmp_b)
2283 if (is_mem)
2285 rtx reg = gen_reg_rtx (GET_MODE (b));
2286 emit_b = gen_rtx_SET (reg, b);
2288 else
2290 if (insn_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);
2296 SET_DEST (set) = b;
2297 emit_b = PATTERN (copy_of_b);
2299 else
2301 rtx tmp_reg = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b));
2302 emit_b = gen_rtx_SET (tmp_reg, b);
2303 b = tmp_reg;
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;
2318 break;
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;
2333 break;
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;
2356 else
2357 goto end_seq_and_fail;
2359 target = noce_emit_cmove (if_info, x, code, XEXP (cond, 0), XEXP (cond, 1),
2360 a, b);
2362 if (! target)
2363 goto end_seq_and_fail;
2365 /* If we're handling a memory for above, emit the load now. */
2366 if (is_mem)
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));
2375 set_mem_align (mem,
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))
2388 return false;
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";
2393 return true;
2395 end_seq_and_fail:
2396 end_sequence ();
2397 return false;
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. */
2404 static rtx
2405 noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
2406 rtx_insn **earliest)
2408 rtx cond, set;
2409 rtx_insn *insn;
2410 bool reverse;
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);
2421 reverse
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)
2425 reverse = !reverse;
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);
2450 if (prev_insn
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);
2457 if (!src)
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))))
2462 op_a = src;
2463 else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn))))
2464 op_b = src;
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);
2481 switch (code)
2483 case LT:
2484 if (desired_val != HOST_WIDE_INT_MAX
2485 && actual_val == desired_val + 1)
2487 code = LE;
2488 op_b = GEN_INT (desired_val);
2490 break;
2491 case LE:
2492 if (desired_val != HOST_WIDE_INT_MIN
2493 && actual_val == desired_val - 1)
2495 code = LT;
2496 op_b = GEN_INT (desired_val);
2498 break;
2499 case GT:
2500 if (desired_val != HOST_WIDE_INT_MIN
2501 && actual_val == desired_val - 1)
2503 code = GE;
2504 op_b = GEN_INT (desired_val);
2506 break;
2507 case GE:
2508 if (desired_val != HOST_WIDE_INT_MAX
2509 && actual_val == desired_val + 1)
2511 code = GT;
2512 op_b = GEN_INT (desired_val);
2514 break;
2515 default:
2516 break;
2520 /* If we made any changes, generate a new conditional that is
2521 equivalent to what we started with, but has the right
2522 constants in it. */
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;
2529 return cond;
2533 cond = canonicalize_condition (if_info->jump, cond, reverse,
2534 earliest, target, have_cbranchcc4, true);
2535 if (! cond || ! reg_mentioned_p (target, cond))
2536 return NULL;
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)))
2544 return NULL;
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))
2548 if (INSN_P (insn)
2549 && (modified_in_p (if_info->a, insn)
2550 || modified_in_p (if_info->b, insn)))
2551 return NULL;
2553 return cond;
2556 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc. */
2558 static bool
2559 noce_try_minmax (struct noce_if_info *if_info)
2561 rtx cond, target;
2562 rtx_insn *earliest, *seq;
2563 enum rtx_code code, op;
2564 bool unsignedp;
2566 if (!noce_simple_bbs (if_info))
2567 return false;
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))
2574 return false;
2576 cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
2577 if (!cond)
2578 return false;
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))
2586 return false;
2588 else if (rtx_equal_p (XEXP (cond, 1), if_info->a))
2590 if (! rtx_equal_p (XEXP (cond, 0), if_info->b))
2591 return false;
2592 code = swap_condition (code);
2594 else
2595 return false;
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. */
2599 switch (code)
2601 case LT:
2602 case LE:
2603 case UNLT:
2604 case UNLE:
2605 op = SMAX;
2606 unsignedp = false;
2607 break;
2608 case GT:
2609 case GE:
2610 case UNGT:
2611 case UNGE:
2612 op = SMIN;
2613 unsignedp = false;
2614 break;
2615 case LTU:
2616 case LEU:
2617 op = UMAX;
2618 unsignedp = true;
2619 break;
2620 case GTU:
2621 case GEU:
2622 op = UMIN;
2623 unsignedp = true;
2624 break;
2625 default:
2626 return false;
2629 start_sequence ();
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);
2634 if (! target)
2636 end_sequence ();
2637 return false;
2639 if (target != if_info->x)
2640 noce_emit_move_insn (if_info->x, target);
2642 seq = end_ifcvt_sequence (if_info);
2643 if (!seq)
2644 return false;
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";
2652 return true;
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);",
2657 etc. */
2659 static bool
2660 noce_try_abs (struct noce_if_info *if_info)
2662 rtx cond, target, a, b, c;
2663 rtx_insn *earliest, *seq;
2664 bool negate;
2665 bool one_cmpl = false;
2667 if (!noce_simple_bbs (if_info))
2668 return false;
2670 /* Reject modes with signed zeros. */
2671 if (HONOR_SIGNED_ZEROS (if_info->x))
2672 return false;
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. */
2677 a = if_info->a;
2678 b = if_info->b;
2679 if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b))
2680 negate = false;
2681 else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a))
2683 std::swap (a, b);
2684 negate = true;
2686 else if (GET_CODE (a) == NOT && rtx_equal_p (XEXP (a, 0), b))
2688 negate = false;
2689 one_cmpl = true;
2691 else if (GET_CODE (b) == NOT && rtx_equal_p (XEXP (b, 0), a))
2693 std::swap (a, b);
2694 negate = true;
2695 one_cmpl = true;
2697 else
2698 return false;
2700 cond = noce_get_alt_condition (if_info, b, &earliest);
2701 if (!cond)
2702 return false;
2704 /* Verify the condition is of the form we expect. */
2705 if (rtx_equal_p (XEXP (cond, 0), b))
2706 c = XEXP (cond, 1);
2707 else if (rtx_equal_p (XEXP (cond, 1), b))
2709 c = XEXP (cond, 0);
2710 negate = !negate;
2712 else
2713 return false;
2715 /* Verify that C is zero. Search one step backward for a
2716 REG_EQUAL note or a simple source if necessary. */
2717 if (REG_P (c))
2719 rtx set;
2720 rtx_insn *insn = prev_nonnote_nondebug_insn (earliest);
2721 if (insn
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);
2727 if (note)
2728 c = XEXP (note, 0);
2729 else
2730 c = SET_SRC (set);
2732 else
2733 return false;
2735 if (MEM_P (c)
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)
2751 if (one_cmpl)
2752 return false;
2754 else if (c == CONST0_RTX (GET_MODE (b)))
2756 if (one_cmpl
2757 && GET_CODE (cond) != GE
2758 && GET_CODE (cond) != LT)
2759 return false;
2761 else
2762 return false;
2764 /* Determine what sort of operation this is. */
2765 switch (GET_CODE (cond))
2767 case LT:
2768 case LE:
2769 case UNLT:
2770 case UNLE:
2771 negate = !negate;
2772 break;
2773 case GT:
2774 case GE:
2775 case UNGT:
2776 case UNGE:
2777 break;
2778 default:
2779 return false;
2782 start_sequence ();
2783 if (one_cmpl)
2784 target = expand_one_cmpl_abs_nojump (GET_MODE (if_info->x), b,
2785 if_info->x);
2786 else
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)
2793 if (one_cmpl)
2794 target = expand_simple_unop (GET_MODE (target), NOT, target,
2795 if_info->x, 0);
2796 else
2797 target = expand_simple_unop (GET_MODE (target), NEG, target,
2798 if_info->x, 0);
2801 if (! target)
2803 end_sequence ();
2804 return false;
2807 if (target != if_info->x)
2808 noce_emit_move_insn (if_info->x, target);
2810 seq = end_ifcvt_sequence (if_info);
2811 if (!seq)
2812 return false;
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";
2820 return true;
2823 /* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;". */
2825 static bool
2826 noce_try_sign_mask (struct noce_if_info *if_info)
2828 rtx cond, t, m, c;
2829 rtx_insn *seq;
2830 machine_mode mode;
2831 enum rtx_code code;
2832 bool t_unconditional;
2834 if (!noce_simple_bbs (if_info))
2835 return false;
2837 cond = if_info->cond;
2838 code = GET_CODE (cond);
2839 m = XEXP (cond, 0);
2840 c = XEXP (cond, 1);
2842 t = NULL_RTX;
2843 if (if_info->a == const0_rtx)
2845 if ((code == LT && c == const0_rtx)
2846 || (code == LE && c == constm1_rtx))
2847 t = if_info->b;
2849 else if (if_info->b == const0_rtx)
2851 if ((code == GE && c == const0_rtx)
2852 || (code == GT && c == constm1_rtx))
2853 t = if_info->a;
2856 if (! t || side_effects_p (t))
2857 return false;
2859 /* We currently don't handle different modes. */
2860 mode = GET_MODE (t);
2861 if (GET_MODE (m) != mode)
2862 return false;
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. */
2870 t_unconditional
2871 = (t == if_info->b
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))))
2878 return false;
2880 if (!noce_can_force_operand (t))
2881 return false;
2883 start_sequence ();
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)
2889 : NULL_RTX;
2891 if (!t)
2893 end_sequence ();
2894 return false;
2897 noce_emit_move_insn (if_info->x, t);
2899 seq = end_ifcvt_sequence (if_info);
2900 if (!seq)
2901 return false;
2903 emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
2904 if_info->transform_name = "noce_try_sign_mask";
2906 return true;
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. */
2914 static bool
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)
2922 return true;
2924 return false;
2927 /* Helper function to return REG itself,
2928 otherwise NULL_RTX for other RTX_CODE. */
2930 static rtx
2931 get_base_reg (rtx exp)
2933 if (REG_P (exp))
2934 return exp;
2936 return NULL_RTX;
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
2944 IF_INFO->B.
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. */
2949 static bool
2950 noce_bbs_ok_for_cond_zero_arith (struct noce_if_info *if_info, rtx *common_ptr,
2951 rtx *bin_exp_ptr,
2952 enum rtx_code *czero_code_ptr, rtx *a_ptr,
2953 rtx **to_replace)
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))
2965 return false;
2967 /* COND must be EQ or NE comparision of a reg and 0. */
2968 if (GET_CODE (cond) != NE && GET_CODE (cond) != EQ)
2969 return false;
2970 if (!REG_P (XEXP (cond, 0)) || !rtx_equal_p (XEXP (cond, 1), const0_rtx))
2971 return false;
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))
2976 std::swap (a, b);
2977 reverse = !reverse;
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)))
2982 return false;
2984 bin_exp = a;
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))
2994 common = b;
2995 bin_op1 = XEXP (bin_exp, 1);
2996 czero_code = (reverse ^ (GET_CODE (bin_exp) == AND))
2997 ? noce_reversed_cond_code (if_info)
2998 : GET_CODE (cond);
3000 else
3001 return false;
3003 if (czero_code == UNKNOWN)
3004 return false;
3006 if (REG_P (bin_op1))
3007 *to_replace = &XEXP (bin_exp, 1);
3008 else
3009 return false;
3011 *common_ptr = common;
3012 *bin_exp_ptr = bin_exp;
3013 *czero_code_ptr = czero_code;
3014 *a_ptr = a;
3016 return true;
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. */
3023 static int
3024 noce_try_cond_zero_arith (struct noce_if_info *if_info)
3026 rtx target, rtmp, a;
3027 rtx_insn *seq;
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,
3037 &a, &to_replace))
3038 return false;
3040 start_sequence ();
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);
3050 if (!target)
3052 end_sequence ();
3053 return false;
3056 target = expand_simple_binop (mode, IOR, rtmp, target, if_info->x, 0,
3057 OPTAB_WIDEN);
3058 if (!target)
3060 end_sequence ();
3061 return false;
3064 if (target != if_info->x)
3065 noce_emit_move_insn (if_info->x, target);
3067 else
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);
3074 else
3075 target = if_info->x;
3077 target = noce_emit_czero (if_info, czero_code, non_zero_op, target);
3078 if (!target || !to_replace)
3080 end_sequence ();
3081 return false;
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))
3090 return false;
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";
3094 return true;
3097 /* Optimize away "if (x & C) x |= C" and similar bit manipulation
3098 transformations. */
3100 static bool
3101 noce_try_bitop (struct noce_if_info *if_info)
3103 rtx cond, x, a, result;
3104 rtx_insn *seq;
3105 scalar_int_mode mode;
3106 enum rtx_code code;
3107 int bitnum;
3109 x = if_info->x;
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))
3115 return false;
3117 if (!noce_simple_bbs (if_info))
3118 return false;
3120 /* Check for no else condition. */
3121 if (! rtx_equal_p (x, if_info->b))
3122 return false;
3124 /* Check for a suitable condition. */
3125 if (code != NE && code != EQ)
3126 return false;
3127 if (XEXP (cond, 1) != const0_rtx)
3128 return false;
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)))
3137 return false;
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)
3142 return false;
3144 else
3145 return false;
3147 a = if_info->a;
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)
3155 return false;
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);
3167 else
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)))
3181 return false;
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;
3187 else
3188 return false;
3190 if (result)
3192 start_sequence ();
3193 noce_emit_move_insn (x, result);
3194 seq = end_ifcvt_sequence (if_info);
3195 if (!seq)
3196 return false;
3198 emit_insn_before_setloc (seq, if_info->jump,
3199 INSN_LOCATION (if_info->insn_a));
3201 if_info->transform_name = "noce_try_bitop";
3202 return true;
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. */
3212 static rtx
3213 noce_get_condition (rtx_insn *jump, rtx_insn **earliest,
3214 bool then_else_reversed)
3216 rtx cond, set, tmp;
3217 bool reverse;
3219 if (! any_condjump_p (jump))
3220 return NULL_RTX;
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)
3233 reverse = !reverse;
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)))
3243 *earliest = jump;
3245 if (reverse)
3246 cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
3247 GET_MODE (cond), tmp, XEXP (cond, 1));
3248 return cond;
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))
3259 return NULL_RTX;
3261 return tmp;
3264 /* Return true if OP is ok for if-then-else processing. */
3266 static bool
3267 noce_operand_ok (const_rtx op)
3269 if (side_effects_p (op))
3270 return false;
3272 /* We special-case memories, so handle any of them with
3273 no address side effects. */
3274 if (MEM_P (op))
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. */
3290 static bool
3291 bb_valid_for_noce_process_p (basic_block test_bb, rtx cond,
3292 unsigned int *cost, bool *simple_p)
3294 if (!test_bb)
3295 return false;
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))
3303 return false;
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)))
3308 return false;
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);
3316 if (!first_set)
3317 return false;
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);
3326 return *simple_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))
3334 return false;
3336 bitmap test_bb_temps = BITMAP_ALLOC (&reg_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);
3342 rtx_insn *insn;
3343 FOR_BB_INSNS (test_bb, insn)
3345 if (insn != last_insn)
3347 if (!active_insn_p (insn))
3348 continue;
3350 if (!insn_valid_noce_process_p (insn, cc))
3351 goto free_bitmap_and_fail;
3353 rtx sset = single_set (insn);
3354 gcc_assert (sset);
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))
3360 || !REG_P (dest)
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
3370 then fail. */
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;
3376 *simple_p = false;
3377 return true;
3379 free_bitmap_and_fail:
3380 BITMAP_FREE (test_bb_temps);
3381 return false;
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. */
3390 static rtx_insn*
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;
3397 *cost = 0;
3399 rtx x = XEXP (cond, 0);
3400 rtx y = XEXP (cond, 1);
3401 rtx_code cond_code = GET_CODE (cond);
3403 start_sequence ();
3405 if (need_cmov)
3406 *temp_dest = noce_emit_cmove (if_info, temp, cond_code,
3407 x, y, new_val, old_val, cc_cmp, rev_cc_cmp);
3408 else
3410 *temp_dest = temp;
3411 if (if_info->then_else_reversed)
3412 noce_emit_move_insn (temp, old_val);
3413 else
3414 noce_emit_move_insn (temp, new_val);
3417 if (*temp_dest != NULL_RTX)
3419 seq = get_insns ();
3420 *cost = seq_cost (seq, if_info->speed_p);
3423 end_sequence ();
3425 return seq;
3428 /* We have something like:
3430 if (x > y)
3431 { i = EXPR_A; j = EXPR_B; k = EXPR_C; }
3433 Make it:
3435 tmp_i = (x > y) ? EXPR_A : i;
3436 tmp_j = (x > y) ? EXPR_B : j;
3437 tmp_k = (x > y) ? EXPR_C : k;
3438 i = tmp_i;
3439 j = tmp_j;
3440 k = tmp_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
3446 similar.
3448 These look like:
3450 if (x > y)
3451 i = a;
3452 j = i;
3454 Which we want to rewrite to:
3456 tmp_i = (x > y) ? a : i;
3457 tmp_j = (x > y) ? tmp_i : j;
3458 i = tmp_i;
3459 j = tmp_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. */
3469 static bool
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;
3477 rtx_insn *insn;
3479 start_sequence ();
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);
3493 if (!ok)
3494 return false;
3496 /* If there are insns that overwrite part of the initial
3497 comparison, we can still omit creating temporaries for
3498 the last of them.
3499 As the second try will always create a less expensive,
3500 valid sequence, we do not need to compare and can discard
3501 the first one. */
3502 if (last_needs_comparison != -1)
3504 end_sequence ();
3505 start_sequence ();
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. */
3510 if (!ok)
3511 return false;
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. */
3522 unsigned i;
3523 noce_multiple_sets_info *info;
3524 bitmap set_targets = BITMAP_ALLOC (&reg_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))
3542 end_sequence ();
3543 return false;
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);
3557 set_used_flags (x);
3558 set_used_flags (y);
3560 unshare_all_rtl_in_chain (seq);
3561 end_sequence ();
3563 if (!seq)
3564 return false;
3566 for (insn = seq; insn; insn = NEXT_INSN (insn))
3567 if (JUMP_P (insn) || CALL_P (insn)
3568 || recog_memoized (insn) == -1)
3569 return false;
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);
3579 num_true_changes++;
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);
3585 num_true_changes++;
3588 num_updated_if_blocks++;
3589 if_info->transform_name = "noce_convert_multiple_sets";
3590 return true;
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. */
3596 static bool
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);
3609 if (cc_cmp)
3610 cc_cmp = copy_rtx (cc_cmp);
3611 rtx rev_cc_cmp = cond_exec_get_condition (jump, /* get_reversed */ true);
3612 if (rev_cc_cmp)
3613 rev_cc_cmp = copy_rtx (rev_cc_cmp);
3615 rtx_insn *insn;
3616 int count = 0;
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))
3623 continue;
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);
3631 rtx temp;
3633 rtx new_val = SET_SRC (set);
3635 int i, ii;
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
3643 if (x > y)
3645 a = b;
3646 c = d;
3648 into
3649 a = (x > y) ...
3650 c = (x > y) ...
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
3655 if (x > y)
3657 x = y;
3660 into
3661 x = (x > y) ...
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
3667 needed.
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));
3674 else
3675 temp = 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
3692 if (x > y)
3693 y = x;
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. */
3709 if (cc_cmp)
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)))
3721 seq2 = NULL;
3722 break;
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;
3761 break;
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;
3773 break;
3777 walk = NEXT_INSN (walk);
3780 /* Check which version is less expensive. */
3781 if (seq1 != NULL_RTX && (cost1 <= cost2 || seq2 == NULL_RTX))
3783 seq = seq1;
3784 temp_dest = temp_dest1;
3785 if (!second_try)
3786 *last_needs_comparison = count;
3788 else if (seq2 != NULL_RTX)
3790 seq = seq2;
3791 temp_dest = temp_dest2;
3792 if (!second_try && read_comparison)
3793 *last_needs_comparison = count;
3795 else
3797 /* Nothing worked, bail out. */
3798 end_sequence ();
3799 return false;
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). */
3807 if (!second_try)
3808 for (rtx_insn *iter = seq; iter; iter = NEXT_INSN (iter))
3809 if (modified_in_p (cond, iter))
3811 end_sequence ();
3812 return false;
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)))
3824 cc_cmp = NULL_RTX;
3825 rev_cc_cmp = NULL_RTX;
3826 break;
3830 /* End the sub sequence and emit to the main sequence. */
3831 emit_insn (seq);
3833 /* Bookkeeping. */
3834 count++;
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;
3846 return true;
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.
3853 (1) int tmp = a;
3854 a = b;
3855 b = tmp;
3857 ifcvt
3860 tmp = a;
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.
3867 (2) int c = a;
3868 int d = c;
3870 ifcvt
3873 c = cond ? a : c_old;
3874 d = cond ? d : c; // Need to use c rather than c_old here.
3877 static void
3878 init_noce_multiple_sets_info (basic_block bb,
3879 auto_delete_vec<noce_multiple_sets_info> &insn_info)
3881 rtx_insn *insn;
3882 int count = 0;
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))
3895 continue;
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);
3921 count++;
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. */
3931 static bool
3932 bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost)
3934 rtx_insn *insn;
3935 unsigned count = 0;
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))
3944 continue;
3946 /* We only handle SET insns. */
3947 rtx set = single_set (insn);
3948 if (set == NULL_RTX)
3949 return false;
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))
3959 return false;
3961 /* Destination and source must be appropriate. */
3962 if (!noce_operand_ok (dest) || !noce_operand_ok (src))
3963 return false;
3965 /* We must be able to conditionally move in this mode. */
3966 if (!can_conditionally_move_p (GET_MODE (dest)))
3967 return false;
3969 potential_cost += insn_cost (insn, speed_p);
3971 count++;
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
3980 that. */
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. */
3988 static unsigned
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. */
3998 static bool
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;
4008 rtx set_a, set_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;
4034 if (!else_bb
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);
4046 return true;
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))
4057 return false;
4059 if (else_bb
4060 && !bb_valid_for_noce_process_p (else_bb, cond, &else_cost,
4061 &if_info->else_simple))
4062 return false;
4064 if (speed_p)
4065 if_info->original_cost += average_cost (then_cost, else_cost,
4066 find_edge (test_bb, then_bb));
4067 else
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);
4072 gcc_assert (set_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
4078 destinations. */
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. */
4084 set_b = NULL_RTX;
4085 if (else_bb)
4087 insn_b = last_active_insn (else_bb, false);
4088 set_b = single_set (insn_b);
4089 gcc_assert (set_b);
4091 if (!rtx_interchangeable_p (x, SET_DEST (set_b)))
4092 return false;
4094 else
4096 insn_b = if_info->cond_earliest;
4098 insn_b = prev_nonnote_nondebug_insn (insn_b);
4099 while (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
4106 intact. */
4107 if (! insn_b
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))
4128 insn_b = NULL;
4129 set_b = NULL_RTX;
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))
4139 return false;
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. */
4145 orig_x = x;
4146 if_info->orig_x = orig_x;
4147 if (!REG_P (x)
4148 || (HARD_REGISTER_P (x)
4149 && targetm.small_register_classes_for_mode_p (GET_MODE (x))))
4151 if (GET_MODE (x) == BLKmode)
4152 return false;
4154 if (GET_CODE (x) == ZERO_EXTRACT
4155 && (!CONST_INT_P (XEXP (x, 1))
4156 || !CONST_INT_P (XEXP (x, 2))))
4157 return false;
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))
4165 return false;
4167 retry:
4168 /* Set up the info block for our subroutines. */
4169 if_info->insn_a = insn_a;
4170 if_info->insn_b = insn_b;
4171 if_info->x = x;
4172 if_info->a = a;
4173 if_info->b = 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)
4190 rtx note;
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);
4201 insn_b = NULL;
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))
4206 return false;
4208 x = orig_x;
4209 goto success;
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))
4215 ++global_variable;
4216 Rather than go to much effort here, we rely on the SSA optimizers,
4217 which do a good enough job these days. */
4218 return false;
4220 if (noce_try_move (if_info))
4221 goto success;
4222 if (noce_try_ifelse_collapse (if_info))
4223 goto success;
4224 if (noce_try_store_flag (if_info))
4225 goto success;
4226 if (noce_try_bitop (if_info))
4227 goto success;
4228 if (noce_try_minmax (if_info))
4229 goto success;
4230 if (noce_try_abs (if_info))
4231 goto success;
4232 if (noce_try_inverse_constants (if_info))
4233 goto success;
4234 if (!targetm.have_conditional_execution ()
4235 && noce_try_store_flag_constants (if_info))
4236 goto success;
4237 if (HAVE_conditional_move
4238 && noce_try_cmove (if_info))
4239 goto success;
4240 if (! targetm.have_conditional_execution ())
4242 if (noce_try_addcc (if_info))
4243 goto success;
4244 if (noce_try_store_flag_mask (if_info))
4245 goto success;
4246 if (HAVE_conditional_move
4247 && noce_try_cond_zero_arith (if_info))
4248 goto success;
4249 if (HAVE_conditional_move
4250 && noce_try_cmove_arith (if_info))
4251 goto success;
4252 if (noce_try_sign_mask (if_info))
4253 goto success;
4256 if (!else_bb && set_b)
4258 insn_b = NULL;
4259 set_b = NULL_RTX;
4260 b = orig_x;
4261 goto retry;
4264 return false;
4266 success:
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. */
4272 if (orig_x != x)
4274 rtx_insn *seq;
4276 start_sequence ();
4277 noce_emit_move_insn (orig_x, x);
4278 seq = get_insns ();
4279 set_used_flags (orig_x);
4280 unshare_all_rtl_in_chain (seq);
4281 end_sequence ();
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. */
4289 if (else_bb)
4291 delete_basic_block (else_bb);
4292 num_true_changes++;
4294 else
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);
4300 num_true_changes++;
4302 if (can_merge_blocks_p (test_bb, join_bb))
4304 merge_blocks (test_bb, join_bb);
4305 num_true_changes++;
4308 num_updated_if_blocks++;
4309 return true;
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. */
4318 static bool
4319 check_cond_move_block (basic_block bb,
4320 hash_map<rtx, rtx> *vals,
4321 vec<rtx> *regs,
4322 rtx cond)
4324 rtx_insn *insn;
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. */
4329 insn = BB_END (bb);
4330 if (JUMP_P (insn) && !onlyjump_p (insn))
4331 return false;
4333 FOR_BB_INSNS (bb, insn)
4335 rtx set, dest, src;
4337 if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
4338 continue;
4339 set = single_set (insn);
4340 if (!set)
4341 return false;
4343 dest = SET_DEST (set);
4344 src = SET_SRC (set);
4345 if (!REG_P (dest)
4346 || (HARD_REGISTER_P (dest)
4347 && targetm.small_register_classes_for_mode_p (GET_MODE (dest))))
4348 return false;
4350 if (!CONSTANT_P (src) && !register_operand (src, VOIDmode))
4351 return false;
4353 if (side_effects_p (src) || side_effects_p (dest))
4354 return false;
4356 if (may_trap_p (src) || may_trap_p (dest))
4357 return false;
4359 /* Don't try to handle this if the source register was
4360 modified earlier in the block. */
4361 if ((REG_P (src)
4362 && vals->get (src))
4363 || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
4364 && vals->get (SUBREG_REG (src))))
4365 return false;
4367 /* Don't try to handle this if the destination register was
4368 modified earlier in the block. */
4369 if (vals->get (dest))
4370 return false;
4372 /* Don't try to handle this if the condition uses the
4373 destination register. */
4374 if (reg_overlap_mentioned_p (dest, cond))
4375 return false;
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))))
4381 return false;
4383 /* Skip it if the instruction to be moved might clobber CC. */
4384 if (cc && set_of (cc, insn))
4385 return false;
4387 vals->put (dest, src);
4389 regs->safe_push (dest);
4392 return true;
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. */
4402 static bool
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,
4407 bool else_block_p)
4409 enum rtx_code code;
4410 rtx_insn *insn;
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))
4423 continue;
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;
4434 if (else_block_p)
4436 /* If this register was set in the then block, we already
4437 handled this case there. */
4438 if (t)
4439 continue;
4440 t = dest;
4441 gcc_assert (e);
4443 else
4445 gcc_assert (t);
4446 if (!e)
4447 e = dest;
4450 if (if_infop->cond_inverted)
4451 std::swap (t, e);
4453 target = noce_emit_cmove (if_infop, dest, code, cond_arg0, cond_arg1,
4454 t, e);
4455 if (!target)
4456 return false;
4458 if (target != dest)
4459 noce_emit_move_insn (dest, target);
4462 return true;
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. */
4469 static bool
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;
4479 int c;
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
4486 register. */
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)
4492 || (else_bb
4493 && !check_cond_move_block (else_bb, &else_vals, &else_regs, cond)))
4494 goto done;
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. */
4502 c = 0;
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);
4509 if (!else_slot)
4510 ++c;
4511 else
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))
4517 goto done;
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))
4526 ++c;
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
4532 them. */
4533 if (c > MAX_CONDITIONAL_EXECUTE
4534 || c > limit)
4535 goto done;
4537 /* Try to emit the conditional moves. First do the then block,
4538 then do anything left in the else blocks. */
4539 start_sequence ();
4540 if (!cond_move_convert_if_block (if_info, then_bb, cond,
4541 &then_vals, &else_vals, false)
4542 || (else_bb
4543 && !cond_move_convert_if_block (if_info, else_bb, cond,
4544 &then_vals, &else_vals, true)))
4546 end_sequence ();
4547 goto done;
4549 seq = end_ifcvt_sequence (if_info);
4550 if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
4551 goto done;
4553 loc_insn = first_active_insn (then_bb);
4554 if (!loc_insn)
4556 loc_insn = first_active_insn (else_bb);
4557 gcc_assert (loc_insn);
4559 emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));
4561 if (else_bb)
4563 delete_basic_block (else_bb);
4564 num_true_changes++;
4566 else
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);
4572 num_true_changes++;
4574 if (can_merge_blocks_p (test_bb, join_bb))
4576 merge_blocks (test_bb, join_bb);
4577 num_true_changes++;
4580 num_updated_if_blocks++;
4581 success_p = true;
4583 done:
4584 then_regs.release ();
4585 else_regs.release ();
4586 return success_p;
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. */
4598 static bool
4599 noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge,
4600 int pass)
4602 basic_block then_bb, else_bb, join_bb;
4603 bool then_else_reversed = false;
4604 rtx_insn *jump;
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
4635 cfgrtl mode). */
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;
4648 else
4649 /* Not a form we can handle. */
4650 return false;
4652 /* The edges of the THEN and ELSE blocks cannot have complex edges. */
4653 if (single_succ_edge (then_bb)->flags & EDGE_COMPLEX)
4654 return false;
4655 if (else_bb
4656 && single_succ_edge (else_bb)->flags & EDGE_COMPLEX)
4657 return false;
4659 num_possible_if_blocks++;
4661 if (dump_file)
4663 fprintf (dump_file,
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);
4668 if (else_bb)
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))
4678 return false;
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)
4692 return false;
4693 if (!if_info.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)
4701 return false;
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))
4723 return true;
4725 if (HAVE_conditional_move
4726 && cond_move_process_if_block (&if_info))
4727 return true;
4729 return false;
4733 /* Merge the blocks and mark for local life update. */
4735 static void
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. */
4746 combo_bb = test_bb;
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);
4759 bb = fallthru;
4760 fallthru = block_fallthru (bb);
4761 merge_blocks (combo_bb, bb);
4762 num_true_changes++;
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. */
4771 if (then_bb)
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
4776 the insn stream. */
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))
4785 delete_insn (end);
4787 merge_blocks (combo_bb, then_bb);
4788 num_true_changes++;
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. */
4794 if (else_bb)
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
4799 the insn stream. */
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))
4808 delete_insn (end);
4810 merge_blocks (combo_bb, else_bb);
4811 num_true_changes++;
4814 /* If there was no join block reported, that means it was not adjacent
4815 to the others, and so we cannot merge them. */
4817 if (! join_bb)
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)));
4830 else
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)
4836 && CALL_P (last)
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);
4854 num_true_changes++;
4856 else
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. */
4878 static basic_block
4879 find_if_header (basic_block test_bb, int pass)
4881 ce_if_block ce_info;
4882 edge then_edge;
4883 edge else_edge;
4885 /* The kind of block we're looking for has exactly two successors. */
4886 if (EDGE_COUNT (test_bb->succs) != 2)
4887 return NULL;
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))
4893 return NULL;
4894 if (df_get_bb_dirty (else_edge->dest))
4895 return NULL;
4897 /* Neither edge should be abnormal. */
4898 if ((then_edge->flags & EDGE_COMPLEX)
4899 || (else_edge->flags & EDGE_COMPLEX))
4900 return NULL;
4902 /* Nor exit the loop. */
4903 if ((then_edge->flags & EDGE_LOOP_EXIT)
4904 || (else_edge->flags & EDGE_LOOP_EXIT))
4905 return NULL;
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);
4912 else
4913 /* Otherwise this must be a multiway branch of some sort. */
4914 return NULL;
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);
4924 #endif
4926 if (!reload_completed
4927 && noce_find_if_block (test_bb, then_edge, else_edge, pass))
4928 goto success;
4930 if (reload_completed
4931 && targetm.have_conditional_execution ()
4932 && cond_exec_find_if_block (&ce_info))
4933 goto success;
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))
4938 goto success;
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))
4944 goto success;
4945 if (find_if_case_2 (test_bb, then_edge, else_edge))
4946 goto success;
4949 return NULL;
4951 success:
4952 if (dump_file)
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. */
4964 static int
4965 block_jumps_and_fallthru (basic_block cur_bb, basic_block target_bb)
4967 edge cur_edge;
4968 bool fallthru_p = false;
4969 bool jump_p = false;
4970 rtx_insn *insn;
4971 rtx_insn *end;
4972 int n_insns = 0;
4973 edge_iterator ei;
4975 if (!cur_bb || !target_bb)
4976 return -1;
4978 /* If no edges, obviously it doesn't jump or fallthru. */
4979 if (EDGE_COUNT (cur_bb->succs) == 0)
4980 return 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. */
4986 return -1;
4988 else if (cur_edge->flags & EDGE_FALLTHRU)
4989 fallthru_p = true;
4991 else if (cur_edge->dest == target_bb)
4992 jump_p = true;
4994 else
4995 return -1;
4998 if ((jump_p & fallthru_p) == 0)
4999 return -1;
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)
5010 if (CALL_P (insn))
5011 return -1;
5013 if (INSN_P (insn)
5014 && !JUMP_P (insn)
5015 && !DEBUG_INSN_P (insn)
5016 && GET_CODE (PATTERN (insn)) != USE
5017 && GET_CODE (PATTERN (insn)) != CLOBBER)
5018 n_insns++;
5020 if (insn == end)
5021 break;
5023 insn = NEXT_INSN (insn);
5026 return n_insns;
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. */
5033 static bool
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;
5040 edge cur_edge;
5041 basic_block next;
5042 edge_iterator ei;
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
5052 the then block). */
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;
5059 int n_insns;
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;
5072 else
5073 target_bb = NULL_BLOCK;
5075 if (target_bb && n_insns <= max_insns)
5077 int total_insns = 0;
5078 int blocks = 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;
5087 blocks++;
5089 if (!single_pred_p (bb))
5090 break;
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;
5102 else
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)
5110 return false;
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)
5116 return false;
5119 FOR_EACH_EDGE (cur_edge, ei, else_bb->preds)
5121 if (cur_edge->flags & EDGE_COMPLEX)
5122 return false;
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))))
5131 return false;
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);
5145 while (last_insn
5146 && NOTE_P (last_insn)
5147 && last_insn != BB_HEAD (then_bb))
5148 last_insn = PREV_INSN (last_insn);
5150 if (last_insn
5151 && JUMP_P (last_insn)
5152 && ! simplejump_p (last_insn))
5153 return false;
5155 join_bb = else_bb;
5156 else_bb = NULL_BLOCK;
5158 else
5159 return false;
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)
5166 join_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. */
5182 else
5183 return false;
5185 num_possible_if_blocks++;
5187 if (dump_file)
5189 fprintf (dump_file,
5190 "\nIF-THEN%s block found, pass %d, start block %d "
5191 "[insn %d], then %d [%d]",
5192 (else_bb) ? "-ELSE" : "",
5193 ce_info->pass,
5194 test_bb->index,
5195 BB_HEAD (test_bb) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
5196 then_bb->index,
5197 BB_HEAD (then_bb) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);
5199 if (else_bb)
5200 fprintf (dump_file, ", else %d [%d]",
5201 else_bb->index,
5202 BB_HEAD (else_bb) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);
5204 fprintf (dump_file, ", join %d [%d]",
5205 join_bb->index,
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))
5216 : -1));
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
5225 block. */
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. */
5229 next = then_bb;
5230 if (else_bb && (next = next->next_bb) != else_bb)
5231 return false;
5232 if ((next = next->next_bb) != join_bb
5233 && join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
5235 if (else_bb)
5236 join_bb = NULL;
5237 else
5238 return false;
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))
5251 return true;
5253 if (ce_info->num_multiple_test_blocks)
5255 cancel_changes (0);
5257 if (cond_exec_process_if_block (ce_info, false))
5258 return true;
5261 return false;
5264 /* Convert a branch over a trap, or a branch
5265 to a trap, into a conditional trap. */
5267 static bool
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;
5274 rtx cond;
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;
5284 else
5285 return false;
5287 if (dump_file)
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);
5296 if (! cond)
5297 return false;
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))
5305 return false;
5307 /* We must be comparing objects whose modes imply the size. */
5308 if (GET_MODE (XEXP (cond, 0)) == BLKmode)
5309 return false;
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)));
5315 if (seq == NULL)
5316 return false;
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
5321 ? !valid_insn_p (x)
5322 : recog_memoized (x) < 0)
5323 return false;
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);
5337 num_true_changes++;
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);
5352 delete_insn (jump);
5354 if (can_merge_blocks_p (test_bb, other_bb))
5356 merge_blocks (test_bb, other_bb);
5357 num_true_changes++;
5360 num_updated_if_blocks++;
5361 return true;
5364 /* Subroutine of find_cond_trap: if BB contains only a trap insn,
5365 return it. */
5367 static rtx_insn *
5368 block_has_only_trap (basic_block bb)
5370 rtx_insn *trap;
5372 /* We're not the exit block. */
5373 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
5374 return NULL;
5376 /* The block must have no successors. */
5377 if (EDGE_COUNT (bb->succs) > 0)
5378 return NULL;
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))
5385 return NULL;
5387 return trap;
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
5392 JOIN block.
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
5400 x = a;
5401 goto label;
5402 over:
5404 becomes
5406 x = a;
5407 if (! test) goto label;
5410 if (test) goto E; // x not live
5411 x = big();
5412 goto L;
5414 x = b;
5415 goto M;
5417 becomes
5419 x = b;
5420 if (test) goto M;
5421 x = big();
5422 goto L;
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
5430 x = a;
5431 if (test2) goto F;
5434 x = b;
5437 becomes
5439 x = a;
5440 if (test1) goto E;
5441 if (test2) goto F;
5443 Notes:
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
5448 side of the if.
5450 (B) With CE, on (3) we can steal from both sides of the if, creating
5452 if (test1) x = a;
5453 if (!test1) x = b;
5454 if (test1) goto J;
5455 if (test2) goto F;
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. */
5467 static bool
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;
5472 basic_block new_bb;
5473 int then_bb_index;
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
5479 and cold sections.
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))))
5495 return false;
5497 /* Verify test_bb ends in a conditional jump with no other side-effects. */
5498 if (!onlyjump_p (BB_END (test_bb)))
5499 return false;
5501 /* THEN has one successor. */
5502 if (!single_succ_p (then_bb))
5503 return false;
5505 /* THEN does not fall through, but is not strange either. */
5506 if (single_succ_edge (then_bb)->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
5507 return false;
5509 /* THEN has one predecessor. */
5510 if (!single_pred_p (then_bb))
5511 return false;
5513 /* THEN must do something. */
5514 if (forwarder_block_p (then_bb))
5515 return false;
5517 num_possible_if_blocks++;
5518 if (dump_file)
5519 fprintf (dump_file,
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)))))
5530 return false;
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))
5542 return false;
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);
5556 new_bb = 0;
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);
5561 else
5562 new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb),
5563 else_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. */
5573 if (new_bb)
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));
5581 num_true_changes++;
5582 num_updated_if_blocks++;
5583 return true;
5586 /* Test for case 2 above. */
5588 static bool
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;
5593 edge else_succ;
5594 profile_probability then_prob, else_prob;
5596 /* We do not want to speculate (empty) loop latches. */
5597 if (current_loops
5598 && else_bb->loop_father->latch == else_bb)
5599 return false;
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
5603 and cold sections.
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))))
5619 return false;
5621 /* Verify test_bb ends in a conditional jump with no other side-effects. */
5622 if (!onlyjump_p (BB_END (test_bb)))
5623 return false;
5625 /* ELSE has one successor. */
5626 if (!single_succ_p (else_bb))
5627 return false;
5628 else
5629 else_succ = single_succ_edge (else_bb);
5631 /* ELSE outgoing edge is not complex. */
5632 if (else_succ->flags & EDGE_COMPLEX)
5633 return false;
5635 /* ELSE has one predecessor. */
5636 if (!single_pred_p (else_bb))
5637 return false;
5639 /* THEN is not EXIT. */
5640 if (then_bb->index < NUM_FIXED_BLOCKS)
5641 return false;
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,
5651 else_succ->dest))
5653 else
5654 return false;
5656 num_possible_if_blocks++;
5657 if (dump_file)
5658 fprintf (dump_file,
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)))))
5667 return false;
5669 /* Registers set are dead, or are predicable. */
5670 if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, false))
5671 return 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);
5680 num_true_changes++;
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? */
5686 return true;
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. */
5698 static bool
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;
5705 rtx old_dest;
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))
5725 return false;
5727 if (LABEL_P (head))
5728 head = NEXT_INSN (head);
5729 while (DEBUG_INSN_P (head) && head != end)
5730 head = NEXT_INSN (head);
5731 if (NOTE_P (head))
5733 if (head == end)
5735 head = end = NULL;
5736 goto no_body;
5738 head = NEXT_INSN (head);
5739 while (DEBUG_INSN_P (head) && head != end)
5740 head = NEXT_INSN (head);
5743 if (JUMP_P (end))
5745 if (!onlyjump_p (end))
5746 return false;
5747 if (head == end)
5749 head = end = NULL;
5750 goto no_body;
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;
5762 while (1)
5764 if (INSN_P (insn) && RTX_FRAME_RELATED_P (insn))
5765 return false;
5766 if (insn == end)
5767 break;
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
5781 be predicated. */
5783 rtx cond;
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))
5788 goto nce;
5790 cond = cond_exec_get_condition (jump);
5791 if (! cond)
5792 goto nce;
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 ());
5799 if (reversep)
5801 enum rtx_code rev = reversed_comparison_code (cond, jump);
5802 if (rev == UNKNOWN)
5803 return false;
5804 cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
5805 XEXP (cond, 1));
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 ();
5812 else
5813 cancel_changes (0);
5815 earliest = jump;
5817 nce:
5818 #endif
5820 /* If we allocated new pseudos (e.g. in the conditional move
5821 expander called from noce_emit_cmove), we must resize the
5822 array first. */
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)
5829 rtx cond;
5830 rtx_insn *insn;
5831 regset live;
5832 bool success;
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))
5839 return false;
5841 /* Find the extent of the conditional. */
5842 cond = noce_get_condition (jump, &earliest, false);
5843 if (!cond)
5844 return false;
5846 live = BITMAP_ALLOC (&reg_obstack);
5847 simulate_backwards_to_point (merge_bb, live, end);
5848 success = can_move_insns_across (head, end, earliest, jump,
5849 merge_bb, live,
5850 df_get_live_in (other_bb), NULL);
5851 BITMAP_FREE (live);
5852 if (!success)
5853 return false;
5855 /* Collect the set of registers set in MERGE_BB. */
5856 merge_set = BITMAP_ALLOC (&reg_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))
5874 regset return_regs;
5875 unsigned int i;
5877 return_regs = BITMAP_ALLOC (&reg_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))
5895 df_ref def;
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);
5903 break;
5906 if (bitmap_intersect_p (merge_set, return_regs))
5908 BITMAP_FREE (return_regs);
5909 BITMAP_FREE (merge_set);
5910 return false;
5913 BITMAP_FREE (return_regs);
5917 no_body:
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))
5926 goto cancel;
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;
5932 else
5933 new_dest_label = block_label (new_dest);
5935 rtx_jump_insn *jump_insn = as_a <rtx_jump_insn *> (jump);
5936 if (reversep
5937 ? ! invert_jump_1 (jump_insn, new_dest_label)
5938 : ! redirect_jump_1 (jump_insn, new_dest_label))
5939 goto cancel;
5942 if (verify_changes (n_validated_changes))
5943 confirm_change_group ();
5944 else
5945 goto cancel;
5947 if (other_bb != new_dest)
5949 redirect_jump_2 (as_a <rtx_jump_insn *> (jump), old_dest, new_dest_label,
5950 0, reversep);
5952 redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
5953 if (reversep)
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. */
5962 if (head != NULL)
5964 rtx_insn *insn;
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. */
5971 insn = head;
5974 rtx note;
5976 if (! INSN_P (insn))
5977 continue;
5978 note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
5979 if (! note)
5980 continue;
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. */
5986 if (merge_set)
5988 unsigned i;
5989 bitmap_iterator bi;
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)
6003 delete_insn (jump);
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. */
6009 return true;
6011 cancel:
6012 cancel_changes (0);
6014 if (merge_set)
6015 BITMAP_FREE (merge_set);
6017 return false;
6020 /* Main entry point for all if-conversion. AFTER_COMBINE is true if
6021 we are after combine pass. */
6023 static void
6024 if_convert (bool after_combine)
6026 basic_block bb;
6027 int pass;
6029 if (optimize == 1)
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. */
6056 pass = 0;
6059 df_analyze ();
6060 /* Only need to do dce on the first pass. */
6061 df_clear_flags (DF_LR_RUN_DCE);
6062 cond_exec_changed_p = false;
6063 pass++;
6065 #ifdef IFCVT_MULTIPLE_DUMPS
6066 if (dump_file && pass > 1)
6067 fprintf (dump_file, "\n\n========== Pass %d ==========\n", pass);
6068 #endif
6070 FOR_EACH_BB_FN (bb, cfun)
6072 basic_block new_bb;
6073 while (!df_get_bb_dirty (bb)
6074 && (new_bb = find_if_header (bb, pass)) != NULL)
6075 bb = new_bb;
6078 #ifdef IFCVT_MULTIPLE_DUMPS
6079 if (dump_file && cond_exec_changed_p)
6080 print_rtl_with_bb (dump_file, get_insns (), dump_flags);
6081 #endif
6083 while (cond_exec_changed_p);
6085 #ifdef IFCVT_MULTIPLE_DUMPS
6086 if (dump_file)
6087 fprintf (dump_file, "\n\n========== no more changes\n");
6088 #endif
6090 free_dominance_info (CDI_POST_DOMINATORS);
6092 if (dump_file)
6093 fflush (dump_file);
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)
6104 fprintf (dump_file,
6105 "\n%d possible IF blocks searched.\n",
6106 num_possible_if_blocks);
6107 fprintf (dump_file,
6108 "%d IF blocks converted.\n",
6109 num_updated_if_blocks);
6110 fprintf (dump_file,
6111 "%d true changes made.\n\n\n",
6112 num_true_changes);
6115 if (optimize == 1)
6116 df_remove_problem (df_live);
6118 /* Some non-cold blocks may now be only reachable from cold blocks.
6119 Fix that up. */
6120 fixup_partitions ();
6122 checking_verify_flow_info ();
6125 /* If-conversion and CFG cleanup. */
6126 static void
6127 rest_of_handle_if_conversion (void)
6129 int flags = 0;
6131 if (flag_if_conversion)
6133 if (dump_file)
6135 dump_reg_info (dump_file);
6136 dump_flow_info (dump_file, dump_flags);
6138 cleanup_cfg (CLEANUP_EXPENSIVE);
6139 if_convert (false);
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);
6148 namespace {
6150 const pass_data pass_data_rtl_ifcvt =
6152 RTL_PASS, /* type */
6153 "ce1", /* name */
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
6165 public:
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 ();
6179 return 0;
6182 }; // class pass_rtl_ifcvt
6184 } // anon namespace
6186 rtl_opt_pass *
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. */
6196 namespace {
6198 const pass_data pass_data_if_after_combine =
6200 RTL_PASS, /* type */
6201 "ce2", /* name */
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
6213 public:
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
6227 if_convert (true);
6228 return 0;
6231 }; // class pass_if_after_combine
6233 } // anon namespace
6235 rtl_opt_pass *
6236 make_pass_if_after_combine (gcc::context *ctxt)
6238 return new pass_if_after_combine (ctxt);
6242 namespace {
6244 const pass_data pass_data_if_after_reload =
6246 RTL_PASS, /* type */
6247 "ce3", /* name */
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
6259 public:
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
6273 if_convert (true);
6274 return 0;
6277 }; // class pass_if_after_reload
6279 } // anon namespace
6281 rtl_opt_pass *
6282 make_pass_if_after_reload (gcc::context *ctxt)
6284 return new pass_if_after_reload (ctxt);