ifcvt.c (struct noce_if_info): Add a Boolean b_unconditional field.
[gcc.git] / gcc / ifcvt.c
1 /* If-conversion support.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
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.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25
26 #include "rtl.h"
27 #include "regs.h"
28 #include "function.h"
29 #include "flags.h"
30 #include "insn-config.h"
31 #include "recog.h"
32 #include "except.h"
33 #include "hard-reg-set.h"
34 #include "basic-block.h"
35 #include "expr.h"
36 #include "real.h"
37 #include "output.h"
38 #include "optabs.h"
39 #include "toplev.h"
40 #include "tm_p.h"
41 #include "cfgloop.h"
42 #include "target.h"
43
44
45 #ifndef HAVE_conditional_execution
46 #define HAVE_conditional_execution 0
47 #endif
48 #ifndef HAVE_conditional_move
49 #define HAVE_conditional_move 0
50 #endif
51 #ifndef HAVE_incscc
52 #define HAVE_incscc 0
53 #endif
54 #ifndef HAVE_decscc
55 #define HAVE_decscc 0
56 #endif
57 #ifndef HAVE_trap
58 #define HAVE_trap 0
59 #endif
60 #ifndef HAVE_conditional_trap
61 #define HAVE_conditional_trap 0
62 #endif
63
64 #ifndef MAX_CONDITIONAL_EXECUTE
65 #define MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1)
66 #endif
67
68 #define NULL_EDGE ((struct edge_def *)NULL)
69 #define NULL_BLOCK ((struct basic_block_def *)NULL)
70
71 /* # of IF-THEN or IF-THEN-ELSE blocks we looked at */
72 static int num_possible_if_blocks;
73
74 /* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
75 execution. */
76 static int num_updated_if_blocks;
77
78 /* # of changes made which require life information to be updated. */
79 static int num_true_changes;
80
81 /* Whether conditional execution changes were made. */
82 static int cond_exec_changed_p;
83
84 /* True if life data ok at present. */
85 static bool life_data_ok;
86
87 /* Forward references. */
88 static int count_bb_insns (basic_block);
89 static rtx first_active_insn (basic_block);
90 static rtx last_active_insn (basic_block, int);
91 static basic_block block_fallthru (basic_block);
92 static int cond_exec_process_insns (ce_if_block_t *, rtx, rtx, rtx, rtx, int);
93 static rtx cond_exec_get_condition (rtx);
94 static int cond_exec_process_if_block (ce_if_block_t *, int);
95 static rtx noce_get_condition (rtx, rtx *);
96 static int noce_operand_ok (rtx);
97 static int noce_process_if_block (ce_if_block_t *);
98 static int process_if_block (ce_if_block_t *);
99 static void merge_if_block (ce_if_block_t *);
100 static int find_cond_trap (basic_block, edge, edge);
101 static basic_block find_if_header (basic_block, int);
102 static int block_jumps_and_fallthru_p (basic_block, basic_block);
103 static int find_if_block (ce_if_block_t *);
104 static int find_if_case_1 (basic_block, edge, edge);
105 static int find_if_case_2 (basic_block, edge, edge);
106 static int find_memory (rtx *, void *);
107 static int dead_or_predicable (basic_block, basic_block, basic_block,
108 basic_block, int);
109 static void noce_emit_move_insn (rtx, rtx);
110 static rtx block_has_only_trap (basic_block);
111 static void mark_loop_exit_edges (void);
112 \f
113 /* Sets EDGE_LOOP_EXIT flag for all loop exits. */
114 static void
115 mark_loop_exit_edges (void)
116 {
117 struct loops loops;
118 basic_block bb;
119 edge e;
120
121 flow_loops_find (&loops, LOOP_TREE);
122 free_dominance_info (CDI_DOMINATORS);
123
124 if (loops.num > 1)
125 {
126 FOR_EACH_BB (bb)
127 {
128 for (e = bb->succ; e; e = e->succ_next)
129 {
130 if (find_common_loop (bb->loop_father, e->dest->loop_father)
131 != bb->loop_father)
132 e->flags |= EDGE_LOOP_EXIT;
133 else
134 e->flags &= ~EDGE_LOOP_EXIT;
135 }
136 }
137 }
138
139 flow_loops_free (&loops);
140 }
141
142 /* Count the number of non-jump active insns in BB. */
143
144 static int
145 count_bb_insns (basic_block bb)
146 {
147 int count = 0;
148 rtx insn = BB_HEAD (bb);
149
150 while (1)
151 {
152 if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
153 count++;
154
155 if (insn == BB_END (bb))
156 break;
157 insn = NEXT_INSN (insn);
158 }
159
160 return count;
161 }
162
163 /* Return the first non-jump active insn in the basic block. */
164
165 static rtx
166 first_active_insn (basic_block bb)
167 {
168 rtx insn = BB_HEAD (bb);
169
170 if (GET_CODE (insn) == CODE_LABEL)
171 {
172 if (insn == BB_END (bb))
173 return NULL_RTX;
174 insn = NEXT_INSN (insn);
175 }
176
177 while (GET_CODE (insn) == NOTE)
178 {
179 if (insn == BB_END (bb))
180 return NULL_RTX;
181 insn = NEXT_INSN (insn);
182 }
183
184 if (GET_CODE (insn) == JUMP_INSN)
185 return NULL_RTX;
186
187 return insn;
188 }
189
190 /* Return the last non-jump active (non-jump) insn in the basic block. */
191
192 static rtx
193 last_active_insn (basic_block bb, int skip_use_p)
194 {
195 rtx insn = BB_END (bb);
196 rtx head = BB_HEAD (bb);
197
198 while (GET_CODE (insn) == NOTE
199 || GET_CODE (insn) == JUMP_INSN
200 || (skip_use_p
201 && GET_CODE (insn) == INSN
202 && GET_CODE (PATTERN (insn)) == USE))
203 {
204 if (insn == head)
205 return NULL_RTX;
206 insn = PREV_INSN (insn);
207 }
208
209 if (GET_CODE (insn) == CODE_LABEL)
210 return NULL_RTX;
211
212 return insn;
213 }
214
215 /* Return the basic block reached by falling though the basic block BB. */
216
217 static basic_block
218 block_fallthru (basic_block bb)
219 {
220 edge e;
221
222 for (e = bb->succ;
223 e != NULL_EDGE && (e->flags & EDGE_FALLTHRU) == 0;
224 e = e->succ_next)
225 ;
226
227 return (e) ? e->dest : NULL_BLOCK;
228 }
229 \f
230 /* Go through a bunch of insns, converting them to conditional
231 execution format if possible. Return TRUE if all of the non-note
232 insns were processed. */
233
234 static int
235 cond_exec_process_insns (ce_if_block_t *ce_info ATTRIBUTE_UNUSED,
236 /* if block information */rtx start,
237 /* first insn to look at */rtx end,
238 /* last insn to look at */rtx test,
239 /* conditional execution test */rtx prob_val,
240 /* probability of branch taken. */int mod_ok)
241 {
242 int must_be_last = FALSE;
243 rtx insn;
244 rtx xtest;
245 rtx pattern;
246
247 if (!start || !end)
248 return FALSE;
249
250 for (insn = start; ; insn = NEXT_INSN (insn))
251 {
252 if (GET_CODE (insn) == NOTE)
253 goto insn_done;
254
255 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
256 abort ();
257
258 /* Remove USE insns that get in the way. */
259 if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
260 {
261 /* ??? Ug. Actually unlinking the thing is problematic,
262 given what we'd have to coordinate with our callers. */
263 SET_INSN_DELETED (insn);
264 goto insn_done;
265 }
266
267 /* Last insn wasn't last? */
268 if (must_be_last)
269 return FALSE;
270
271 if (modified_in_p (test, insn))
272 {
273 if (!mod_ok)
274 return FALSE;
275 must_be_last = TRUE;
276 }
277
278 /* Now build the conditional form of the instruction. */
279 pattern = PATTERN (insn);
280 xtest = copy_rtx (test);
281
282 /* If this is already a COND_EXEC, rewrite the test to be an AND of the
283 two conditions. */
284 if (GET_CODE (pattern) == COND_EXEC)
285 {
286 if (GET_MODE (xtest) != GET_MODE (COND_EXEC_TEST (pattern)))
287 return FALSE;
288
289 xtest = gen_rtx_AND (GET_MODE (xtest), xtest,
290 COND_EXEC_TEST (pattern));
291 pattern = COND_EXEC_CODE (pattern);
292 }
293
294 pattern = gen_rtx_COND_EXEC (VOIDmode, xtest, pattern);
295
296 /* If the machine needs to modify the insn being conditionally executed,
297 say for example to force a constant integer operand into a temp
298 register, do so here. */
299 #ifdef IFCVT_MODIFY_INSN
300 IFCVT_MODIFY_INSN (ce_info, pattern, insn);
301 if (! pattern)
302 return FALSE;
303 #endif
304
305 validate_change (insn, &PATTERN (insn), pattern, 1);
306
307 if (GET_CODE (insn) == CALL_INSN && prob_val)
308 validate_change (insn, &REG_NOTES (insn),
309 alloc_EXPR_LIST (REG_BR_PROB, prob_val,
310 REG_NOTES (insn)), 1);
311
312 insn_done:
313 if (insn == end)
314 break;
315 }
316
317 return TRUE;
318 }
319
320 /* Return the condition for a jump. Do not do any special processing. */
321
322 static rtx
323 cond_exec_get_condition (rtx jump)
324 {
325 rtx test_if, cond;
326
327 if (any_condjump_p (jump))
328 test_if = SET_SRC (pc_set (jump));
329 else
330 return NULL_RTX;
331 cond = XEXP (test_if, 0);
332
333 /* If this branches to JUMP_LABEL when the condition is false,
334 reverse the condition. */
335 if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
336 && XEXP (XEXP (test_if, 2), 0) == JUMP_LABEL (jump))
337 {
338 enum rtx_code rev = reversed_comparison_code (cond, jump);
339 if (rev == UNKNOWN)
340 return NULL_RTX;
341
342 cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
343 XEXP (cond, 1));
344 }
345
346 return cond;
347 }
348
349 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
350 to conditional execution. Return TRUE if we were successful at
351 converting the block. */
352
353 static int
354 cond_exec_process_if_block (ce_if_block_t * ce_info,
355 /* if block information */int do_multiple_p)
356 {
357 basic_block test_bb = ce_info->test_bb; /* last test block */
358 basic_block then_bb = ce_info->then_bb; /* THEN */
359 basic_block else_bb = ce_info->else_bb; /* ELSE or NULL */
360 rtx test_expr; /* expression in IF_THEN_ELSE that is tested */
361 rtx then_start; /* first insn in THEN block */
362 rtx then_end; /* last insn + 1 in THEN block */
363 rtx else_start = NULL_RTX; /* first insn in ELSE block or NULL */
364 rtx else_end = NULL_RTX; /* last insn + 1 in ELSE block */
365 int max; /* max # of insns to convert. */
366 int then_mod_ok; /* whether conditional mods are ok in THEN */
367 rtx true_expr; /* test for else block insns */
368 rtx false_expr; /* test for then block insns */
369 rtx true_prob_val; /* probability of else block */
370 rtx false_prob_val; /* probability of then block */
371 int n_insns;
372 enum rtx_code false_code;
373
374 /* If test is comprised of && or || elements, and we've failed at handling
375 all of them together, just use the last test if it is the special case of
376 && elements without an ELSE block. */
377 if (!do_multiple_p && ce_info->num_multiple_test_blocks)
378 {
379 if (else_bb || ! ce_info->and_and_p)
380 return FALSE;
381
382 ce_info->test_bb = test_bb = ce_info->last_test_bb;
383 ce_info->num_multiple_test_blocks = 0;
384 ce_info->num_and_and_blocks = 0;
385 ce_info->num_or_or_blocks = 0;
386 }
387
388 /* Find the conditional jump to the ELSE or JOIN part, and isolate
389 the test. */
390 test_expr = cond_exec_get_condition (BB_END (test_bb));
391 if (! test_expr)
392 return FALSE;
393
394 /* If the conditional jump is more than just a conditional jump,
395 then we can not do conditional execution conversion on this block. */
396 if (! onlyjump_p (BB_END (test_bb)))
397 return FALSE;
398
399 /* Collect the bounds of where we're to search, skipping any labels, jumps
400 and notes at the beginning and end of the block. Then count the total
401 number of insns and see if it is small enough to convert. */
402 then_start = first_active_insn (then_bb);
403 then_end = last_active_insn (then_bb, TRUE);
404 n_insns = ce_info->num_then_insns = count_bb_insns (then_bb);
405 max = MAX_CONDITIONAL_EXECUTE;
406
407 if (else_bb)
408 {
409 max *= 2;
410 else_start = first_active_insn (else_bb);
411 else_end = last_active_insn (else_bb, TRUE);
412 n_insns += ce_info->num_else_insns = count_bb_insns (else_bb);
413 }
414
415 if (n_insns > max)
416 return FALSE;
417
418 /* Map test_expr/test_jump into the appropriate MD tests to use on
419 the conditionally executed code. */
420
421 true_expr = test_expr;
422
423 false_code = reversed_comparison_code (true_expr, BB_END (test_bb));
424 if (false_code != UNKNOWN)
425 false_expr = gen_rtx_fmt_ee (false_code, GET_MODE (true_expr),
426 XEXP (true_expr, 0), XEXP (true_expr, 1));
427 else
428 false_expr = NULL_RTX;
429
430 #ifdef IFCVT_MODIFY_TESTS
431 /* If the machine description needs to modify the tests, such as setting a
432 conditional execution register from a comparison, it can do so here. */
433 IFCVT_MODIFY_TESTS (ce_info, true_expr, false_expr);
434
435 /* See if the conversion failed. */
436 if (!true_expr || !false_expr)
437 goto fail;
438 #endif
439
440 true_prob_val = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
441 if (true_prob_val)
442 {
443 true_prob_val = XEXP (true_prob_val, 0);
444 false_prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (true_prob_val));
445 }
446 else
447 false_prob_val = NULL_RTX;
448
449 /* If we have && or || tests, do them here. These tests are in the adjacent
450 blocks after the first block containing the test. */
451 if (ce_info->num_multiple_test_blocks > 0)
452 {
453 basic_block bb = test_bb;
454 basic_block last_test_bb = ce_info->last_test_bb;
455
456 if (! false_expr)
457 goto fail;
458
459 do
460 {
461 rtx start, end;
462 rtx t, f;
463
464 bb = block_fallthru (bb);
465 start = first_active_insn (bb);
466 end = last_active_insn (bb, TRUE);
467 if (start
468 && ! cond_exec_process_insns (ce_info, start, end, false_expr,
469 false_prob_val, FALSE))
470 goto fail;
471
472 /* If the conditional jump is more than just a conditional jump, then
473 we can not do conditional execution conversion on this block. */
474 if (! onlyjump_p (BB_END (bb)))
475 goto fail;
476
477 /* Find the conditional jump and isolate the test. */
478 t = cond_exec_get_condition (BB_END (bb));
479 if (! t)
480 goto fail;
481
482 f = gen_rtx_fmt_ee (reverse_condition (GET_CODE (t)),
483 GET_MODE (t),
484 XEXP (t, 0),
485 XEXP (t, 1));
486
487 if (ce_info->and_and_p)
488 {
489 t = gen_rtx_AND (GET_MODE (t), true_expr, t);
490 f = gen_rtx_IOR (GET_MODE (t), false_expr, f);
491 }
492 else
493 {
494 t = gen_rtx_IOR (GET_MODE (t), true_expr, t);
495 f = gen_rtx_AND (GET_MODE (t), false_expr, f);
496 }
497
498 /* If the machine description needs to modify the tests, such as
499 setting a conditional execution register from a comparison, it can
500 do so here. */
501 #ifdef IFCVT_MODIFY_MULTIPLE_TESTS
502 IFCVT_MODIFY_MULTIPLE_TESTS (ce_info, bb, t, f);
503
504 /* See if the conversion failed. */
505 if (!t || !f)
506 goto fail;
507 #endif
508
509 true_expr = t;
510 false_expr = f;
511 }
512 while (bb != last_test_bb);
513 }
514
515 /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
516 on then THEN block. */
517 then_mod_ok = (else_bb == NULL_BLOCK);
518
519 /* Go through the THEN and ELSE blocks converting the insns if possible
520 to conditional execution. */
521
522 if (then_end
523 && (! false_expr
524 || ! cond_exec_process_insns (ce_info, then_start, then_end,
525 false_expr, false_prob_val,
526 then_mod_ok)))
527 goto fail;
528
529 if (else_bb && else_end
530 && ! cond_exec_process_insns (ce_info, else_start, else_end,
531 true_expr, true_prob_val, TRUE))
532 goto fail;
533
534 /* If we cannot apply the changes, fail. Do not go through the normal fail
535 processing, since apply_change_group will call cancel_changes. */
536 if (! apply_change_group ())
537 {
538 #ifdef IFCVT_MODIFY_CANCEL
539 /* Cancel any machine dependent changes. */
540 IFCVT_MODIFY_CANCEL (ce_info);
541 #endif
542 return FALSE;
543 }
544
545 #ifdef IFCVT_MODIFY_FINAL
546 /* Do any machine dependent final modifications. */
547 IFCVT_MODIFY_FINAL (ce_info);
548 #endif
549
550 /* Conversion succeeded. */
551 if (dump_file)
552 fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
553 n_insns, (n_insns == 1) ? " was" : "s were");
554
555 /* Merge the blocks! */
556 merge_if_block (ce_info);
557 cond_exec_changed_p = TRUE;
558 return TRUE;
559
560 fail:
561 #ifdef IFCVT_MODIFY_CANCEL
562 /* Cancel any machine dependent changes. */
563 IFCVT_MODIFY_CANCEL (ce_info);
564 #endif
565
566 cancel_changes (0);
567 return FALSE;
568 }
569 \f
570 /* Used by noce_process_if_block to communicate with its subroutines.
571
572 The subroutines know that A and B may be evaluated freely. They
573 know that X is a register. They should insert new instructions
574 before cond_earliest. */
575
576 struct noce_if_info
577 {
578 basic_block test_bb;
579 rtx insn_a, insn_b;
580 rtx x, a, b;
581 rtx jump, cond, cond_earliest;
582 /* True if "b" was originally evaluated unconditionally. */
583 bool b_unconditional;
584 };
585
586 static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
587 static int noce_try_move (struct noce_if_info *);
588 static int noce_try_store_flag (struct noce_if_info *);
589 static int noce_try_addcc (struct noce_if_info *);
590 static int noce_try_store_flag_constants (struct noce_if_info *);
591 static int noce_try_store_flag_mask (struct noce_if_info *);
592 static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
593 rtx, rtx, rtx);
594 static int noce_try_cmove (struct noce_if_info *);
595 static int noce_try_cmove_arith (struct noce_if_info *);
596 static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx *);
597 static int noce_try_minmax (struct noce_if_info *);
598 static int noce_try_abs (struct noce_if_info *);
599 static int noce_try_sign_mask (struct noce_if_info *);
600
601 /* Helper function for noce_try_store_flag*. */
602
603 static rtx
604 noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
605 int normalize)
606 {
607 rtx cond = if_info->cond;
608 int cond_complex;
609 enum rtx_code code;
610
611 cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode)
612 || ! general_operand (XEXP (cond, 1), VOIDmode));
613
614 /* If earliest == jump, or when the condition is complex, try to
615 build the store_flag insn directly. */
616
617 if (cond_complex)
618 cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0);
619
620 if (reversep)
621 code = reversed_comparison_code (cond, if_info->jump);
622 else
623 code = GET_CODE (cond);
624
625 if ((if_info->cond_earliest == if_info->jump || cond_complex)
626 && (normalize == 0 || STORE_FLAG_VALUE == normalize))
627 {
628 rtx tmp;
629
630 tmp = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
631 XEXP (cond, 1));
632 tmp = gen_rtx_SET (VOIDmode, x, tmp);
633
634 start_sequence ();
635 tmp = emit_insn (tmp);
636
637 if (recog_memoized (tmp) >= 0)
638 {
639 tmp = get_insns ();
640 end_sequence ();
641 emit_insn (tmp);
642
643 if_info->cond_earliest = if_info->jump;
644
645 return x;
646 }
647
648 end_sequence ();
649 }
650
651 /* Don't even try if the comparison operands or the mode of X are weird. */
652 if (cond_complex || !SCALAR_INT_MODE_P (GET_MODE (x)))
653 return NULL_RTX;
654
655 return emit_store_flag (x, code, XEXP (cond, 0),
656 XEXP (cond, 1), VOIDmode,
657 (code == LTU || code == LEU
658 || code == GEU || code == GTU), normalize);
659 }
660
661 /* Emit instruction to move an rtx, possibly into STRICT_LOW_PART.
662 X is the destination/target and Y is the value to copy. */
663
664 static void
665 noce_emit_move_insn (rtx x, rtx y)
666 {
667 enum machine_mode outmode, inmode;
668 rtx outer, inner;
669 int bitpos;
670
671 if (GET_CODE (x) != STRICT_LOW_PART)
672 {
673 emit_move_insn (x, y);
674 return;
675 }
676
677 outer = XEXP (x, 0);
678 inner = XEXP (outer, 0);
679 outmode = GET_MODE (outer);
680 inmode = GET_MODE (inner);
681 bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
682 store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos, outmode, y,
683 GET_MODE_BITSIZE (inmode));
684 }
685
686 /* Return sequence of instructions generated by if conversion. This
687 function calls end_sequence() to end the current stream, ensures
688 that are instructions are unshared, recognizable non-jump insns.
689 On failure, this function returns a NULL_RTX. */
690
691 static rtx
692 end_ifcvt_sequence (struct noce_if_info *if_info)
693 {
694 rtx insn;
695 rtx seq = get_insns ();
696
697 set_used_flags (if_info->x);
698 set_used_flags (if_info->cond);
699 unshare_all_rtl_in_chain (seq);
700 end_sequence ();
701
702 /* Make sure that all of the instructions emitted are recognizable,
703 and that we haven't introduced a new jump instruction.
704 As an exercise for the reader, build a general mechanism that
705 allows proper placement of required clobbers. */
706 for (insn = seq; insn; insn = NEXT_INSN (insn))
707 if (GET_CODE (insn) == JUMP_INSN
708 || recog_memoized (insn) == -1)
709 return NULL_RTX;
710
711 return seq;
712 }
713
714 /* Convert "if (a != b) x = a; else x = b" into "x = a" and
715 "if (a == b) x = a; else x = b" into "x = b". */
716
717 static int
718 noce_try_move (struct noce_if_info *if_info)
719 {
720 rtx cond = if_info->cond;
721 enum rtx_code code = GET_CODE (cond);
722 rtx y, seq;
723
724 if (code != NE && code != EQ)
725 return FALSE;
726
727 /* This optimization isn't valid if either A or B could be a NaN
728 or a signed zero. */
729 if (HONOR_NANS (GET_MODE (if_info->x))
730 || HONOR_SIGNED_ZEROS (GET_MODE (if_info->x)))
731 return FALSE;
732
733 /* Check whether the operands of the comparison are A and in
734 either order. */
735 if ((rtx_equal_p (if_info->a, XEXP (cond, 0))
736 && rtx_equal_p (if_info->b, XEXP (cond, 1)))
737 || (rtx_equal_p (if_info->a, XEXP (cond, 1))
738 && rtx_equal_p (if_info->b, XEXP (cond, 0))))
739 {
740 y = (code == EQ) ? if_info->a : if_info->b;
741
742 /* Avoid generating the move if the source is the destination. */
743 if (! rtx_equal_p (if_info->x, y))
744 {
745 start_sequence ();
746 noce_emit_move_insn (if_info->x, y);
747 seq = end_ifcvt_sequence (if_info);
748 if (!seq)
749 return FALSE;
750
751 emit_insn_before_setloc (seq, if_info->jump,
752 INSN_LOCATOR (if_info->insn_a));
753 }
754 return TRUE;
755 }
756 return FALSE;
757 }
758
759 /* Convert "if (test) x = 1; else x = 0".
760
761 Only try 0 and STORE_FLAG_VALUE here. Other combinations will be
762 tried in noce_try_store_flag_constants after noce_try_cmove has had
763 a go at the conversion. */
764
765 static int
766 noce_try_store_flag (struct noce_if_info *if_info)
767 {
768 int reversep;
769 rtx target, seq;
770
771 if (GET_CODE (if_info->b) == CONST_INT
772 && INTVAL (if_info->b) == STORE_FLAG_VALUE
773 && if_info->a == const0_rtx)
774 reversep = 0;
775 else if (if_info->b == const0_rtx
776 && GET_CODE (if_info->a) == CONST_INT
777 && INTVAL (if_info->a) == STORE_FLAG_VALUE
778 && (reversed_comparison_code (if_info->cond, if_info->jump)
779 != UNKNOWN))
780 reversep = 1;
781 else
782 return FALSE;
783
784 start_sequence ();
785
786 target = noce_emit_store_flag (if_info, if_info->x, reversep, 0);
787 if (target)
788 {
789 if (target != if_info->x)
790 noce_emit_move_insn (if_info->x, target);
791
792 seq = end_ifcvt_sequence (if_info);
793 if (! seq)
794 return FALSE;
795
796 emit_insn_before_setloc (seq, if_info->jump,
797 INSN_LOCATOR (if_info->insn_a));
798 return TRUE;
799 }
800 else
801 {
802 end_sequence ();
803 return FALSE;
804 }
805 }
806
807 /* Convert "if (test) x = a; else x = b", for A and B constant. */
808
809 static int
810 noce_try_store_flag_constants (struct noce_if_info *if_info)
811 {
812 rtx target, seq;
813 int reversep;
814 HOST_WIDE_INT itrue, ifalse, diff, tmp;
815 int normalize, can_reverse;
816 enum machine_mode mode;
817
818 if (! no_new_pseudos
819 && GET_CODE (if_info->a) == CONST_INT
820 && GET_CODE (if_info->b) == CONST_INT)
821 {
822 mode = GET_MODE (if_info->x);
823 ifalse = INTVAL (if_info->a);
824 itrue = INTVAL (if_info->b);
825
826 /* Make sure we can represent the difference between the two values. */
827 if ((itrue - ifalse > 0)
828 != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
829 return FALSE;
830
831 diff = trunc_int_for_mode (itrue - ifalse, mode);
832
833 can_reverse = (reversed_comparison_code (if_info->cond, if_info->jump)
834 != UNKNOWN);
835
836 reversep = 0;
837 if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
838 normalize = 0;
839 else if (ifalse == 0 && exact_log2 (itrue) >= 0
840 && (STORE_FLAG_VALUE == 1
841 || BRANCH_COST >= 2))
842 normalize = 1;
843 else if (itrue == 0 && exact_log2 (ifalse) >= 0 && can_reverse
844 && (STORE_FLAG_VALUE == 1 || BRANCH_COST >= 2))
845 normalize = 1, reversep = 1;
846 else if (itrue == -1
847 && (STORE_FLAG_VALUE == -1
848 || BRANCH_COST >= 2))
849 normalize = -1;
850 else if (ifalse == -1 && can_reverse
851 && (STORE_FLAG_VALUE == -1 || BRANCH_COST >= 2))
852 normalize = -1, reversep = 1;
853 else if ((BRANCH_COST >= 2 && STORE_FLAG_VALUE == -1)
854 || BRANCH_COST >= 3)
855 normalize = -1;
856 else
857 return FALSE;
858
859 if (reversep)
860 {
861 tmp = itrue; itrue = ifalse; ifalse = tmp;
862 diff = trunc_int_for_mode (-diff, mode);
863 }
864
865 start_sequence ();
866 target = noce_emit_store_flag (if_info, if_info->x, reversep, normalize);
867 if (! target)
868 {
869 end_sequence ();
870 return FALSE;
871 }
872
873 /* if (test) x = 3; else x = 4;
874 => x = 3 + (test == 0); */
875 if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
876 {
877 target = expand_simple_binop (mode,
878 (diff == STORE_FLAG_VALUE
879 ? PLUS : MINUS),
880 GEN_INT (ifalse), target, if_info->x, 0,
881 OPTAB_WIDEN);
882 }
883
884 /* if (test) x = 8; else x = 0;
885 => x = (test != 0) << 3; */
886 else if (ifalse == 0 && (tmp = exact_log2 (itrue)) >= 0)
887 {
888 target = expand_simple_binop (mode, ASHIFT,
889 target, GEN_INT (tmp), if_info->x, 0,
890 OPTAB_WIDEN);
891 }
892
893 /* if (test) x = -1; else x = b;
894 => x = -(test != 0) | b; */
895 else if (itrue == -1)
896 {
897 target = expand_simple_binop (mode, IOR,
898 target, GEN_INT (ifalse), if_info->x, 0,
899 OPTAB_WIDEN);
900 }
901
902 /* if (test) x = a; else x = b;
903 => x = (-(test != 0) & (b - a)) + a; */
904 else
905 {
906 target = expand_simple_binop (mode, AND,
907 target, GEN_INT (diff), if_info->x, 0,
908 OPTAB_WIDEN);
909 if (target)
910 target = expand_simple_binop (mode, PLUS,
911 target, GEN_INT (ifalse),
912 if_info->x, 0, OPTAB_WIDEN);
913 }
914
915 if (! target)
916 {
917 end_sequence ();
918 return FALSE;
919 }
920
921 if (target != if_info->x)
922 noce_emit_move_insn (if_info->x, target);
923
924 seq = end_ifcvt_sequence (if_info);
925 if (!seq)
926 return FALSE;
927
928 emit_insn_before_setloc (seq, if_info->jump,
929 INSN_LOCATOR (if_info->insn_a));
930 return TRUE;
931 }
932
933 return FALSE;
934 }
935
936 /* Convert "if (test) foo++" into "foo += (test != 0)", and
937 similarly for "foo--". */
938
939 static int
940 noce_try_addcc (struct noce_if_info *if_info)
941 {
942 rtx target, seq;
943 int subtract, normalize;
944
945 if (! no_new_pseudos
946 && GET_CODE (if_info->a) == PLUS
947 && rtx_equal_p (XEXP (if_info->a, 0), if_info->b)
948 && (reversed_comparison_code (if_info->cond, if_info->jump)
949 != UNKNOWN))
950 {
951 rtx cond = if_info->cond;
952 enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
953
954 /* First try to use addcc pattern. */
955 if (general_operand (XEXP (cond, 0), VOIDmode)
956 && general_operand (XEXP (cond, 1), VOIDmode))
957 {
958 start_sequence ();
959 target = emit_conditional_add (if_info->x, code,
960 XEXP (cond, 0),
961 XEXP (cond, 1),
962 VOIDmode,
963 if_info->b,
964 XEXP (if_info->a, 1),
965 GET_MODE (if_info->x),
966 (code == LTU || code == GEU
967 || code == LEU || code == GTU));
968 if (target)
969 {
970 if (target != if_info->x)
971 noce_emit_move_insn (if_info->x, target);
972
973 seq = end_ifcvt_sequence (if_info);
974 if (!seq)
975 return FALSE;
976
977 emit_insn_before_setloc (seq, if_info->jump,
978 INSN_LOCATOR (if_info->insn_a));
979 return TRUE;
980 }
981 end_sequence ();
982 }
983
984 /* If that fails, construct conditional increment or decrement using
985 setcc. */
986 if (BRANCH_COST >= 2
987 && (XEXP (if_info->a, 1) == const1_rtx
988 || XEXP (if_info->a, 1) == constm1_rtx))
989 {
990 start_sequence ();
991 if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
992 subtract = 0, normalize = 0;
993 else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
994 subtract = 1, normalize = 0;
995 else
996 subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
997
998
999 target = noce_emit_store_flag (if_info,
1000 gen_reg_rtx (GET_MODE (if_info->x)),
1001 1, normalize);
1002
1003 if (target)
1004 target = expand_simple_binop (GET_MODE (if_info->x),
1005 subtract ? MINUS : PLUS,
1006 if_info->b, target, if_info->x,
1007 0, OPTAB_WIDEN);
1008 if (target)
1009 {
1010 if (target != if_info->x)
1011 noce_emit_move_insn (if_info->x, target);
1012
1013 seq = end_ifcvt_sequence (if_info);
1014 if (!seq)
1015 return FALSE;
1016
1017 emit_insn_before_setloc (seq, if_info->jump,
1018 INSN_LOCATOR (if_info->insn_a));
1019 return TRUE;
1020 }
1021 end_sequence ();
1022 }
1023 }
1024
1025 return FALSE;
1026 }
1027
1028 /* Convert "if (test) x = 0;" to "x &= -(test == 0);" */
1029
1030 static int
1031 noce_try_store_flag_mask (struct noce_if_info *if_info)
1032 {
1033 rtx target, seq;
1034 int reversep;
1035
1036 reversep = 0;
1037 if (! no_new_pseudos
1038 && (BRANCH_COST >= 2
1039 || STORE_FLAG_VALUE == -1)
1040 && ((if_info->a == const0_rtx
1041 && rtx_equal_p (if_info->b, if_info->x))
1042 || ((reversep = (reversed_comparison_code (if_info->cond,
1043 if_info->jump)
1044 != UNKNOWN))
1045 && if_info->b == const0_rtx
1046 && rtx_equal_p (if_info->a, if_info->x))))
1047 {
1048 start_sequence ();
1049 target = noce_emit_store_flag (if_info,
1050 gen_reg_rtx (GET_MODE (if_info->x)),
1051 reversep, -1);
1052 if (target)
1053 target = expand_simple_binop (GET_MODE (if_info->x), AND,
1054 if_info->x,
1055 target, if_info->x, 0,
1056 OPTAB_WIDEN);
1057
1058 if (target)
1059 {
1060 if (target != if_info->x)
1061 noce_emit_move_insn (if_info->x, target);
1062
1063 seq = end_ifcvt_sequence (if_info);
1064 if (!seq)
1065 return FALSE;
1066
1067 emit_insn_before_setloc (seq, if_info->jump,
1068 INSN_LOCATOR (if_info->insn_a));
1069 return TRUE;
1070 }
1071
1072 end_sequence ();
1073 }
1074
1075 return FALSE;
1076 }
1077
1078 /* Helper function for noce_try_cmove and noce_try_cmove_arith. */
1079
1080 static rtx
1081 noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
1082 rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
1083 {
1084 /* If earliest == jump, try to build the cmove insn directly.
1085 This is helpful when combine has created some complex condition
1086 (like for alpha's cmovlbs) that we can't hope to regenerate
1087 through the normal interface. */
1088
1089 if (if_info->cond_earliest == if_info->jump)
1090 {
1091 rtx tmp;
1092
1093 tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
1094 tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
1095 tmp = gen_rtx_SET (VOIDmode, x, tmp);
1096
1097 start_sequence ();
1098 tmp = emit_insn (tmp);
1099
1100 if (recog_memoized (tmp) >= 0)
1101 {
1102 tmp = get_insns ();
1103 end_sequence ();
1104 emit_insn (tmp);
1105
1106 return x;
1107 }
1108
1109 end_sequence ();
1110 }
1111
1112 /* Don't even try if the comparison operands are weird. */
1113 if (! general_operand (cmp_a, GET_MODE (cmp_a))
1114 || ! general_operand (cmp_b, GET_MODE (cmp_b)))
1115 return NULL_RTX;
1116
1117 #if HAVE_conditional_move
1118 return emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
1119 vtrue, vfalse, GET_MODE (x),
1120 (code == LTU || code == GEU
1121 || code == LEU || code == GTU));
1122 #else
1123 /* We'll never get here, as noce_process_if_block doesn't call the
1124 functions involved. Ifdef code, however, should be discouraged
1125 because it leads to typos in the code not selected. However,
1126 emit_conditional_move won't exist either. */
1127 return NULL_RTX;
1128 #endif
1129 }
1130
1131 /* Try only simple constants and registers here. More complex cases
1132 are handled in noce_try_cmove_arith after noce_try_store_flag_arith
1133 has had a go at it. */
1134
1135 static int
1136 noce_try_cmove (struct noce_if_info *if_info)
1137 {
1138 enum rtx_code code;
1139 rtx target, seq;
1140
1141 if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode))
1142 && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode)))
1143 {
1144 start_sequence ();
1145
1146 code = GET_CODE (if_info->cond);
1147 target = noce_emit_cmove (if_info, if_info->x, code,
1148 XEXP (if_info->cond, 0),
1149 XEXP (if_info->cond, 1),
1150 if_info->a, if_info->b);
1151
1152 if (target)
1153 {
1154 if (target != if_info->x)
1155 noce_emit_move_insn (if_info->x, target);
1156
1157 seq = end_ifcvt_sequence (if_info);
1158 if (!seq)
1159 return FALSE;
1160
1161 emit_insn_before_setloc (seq, if_info->jump,
1162 INSN_LOCATOR (if_info->insn_a));
1163 return TRUE;
1164 }
1165 else
1166 {
1167 end_sequence ();
1168 return FALSE;
1169 }
1170 }
1171
1172 return FALSE;
1173 }
1174
1175 /* Try more complex cases involving conditional_move. */
1176
1177 static int
1178 noce_try_cmove_arith (struct noce_if_info *if_info)
1179 {
1180 rtx a = if_info->a;
1181 rtx b = if_info->b;
1182 rtx x = if_info->x;
1183 rtx insn_a, insn_b;
1184 rtx tmp, target;
1185 int is_mem = 0;
1186 enum rtx_code code;
1187
1188 /* A conditional move from two memory sources is equivalent to a
1189 conditional on their addresses followed by a load. Don't do this
1190 early because it'll screw alias analysis. Note that we've
1191 already checked for no side effects. */
1192 if (! no_new_pseudos && cse_not_expected
1193 && MEM_P (a) && MEM_P (b)
1194 && BRANCH_COST >= 5)
1195 {
1196 a = XEXP (a, 0);
1197 b = XEXP (b, 0);
1198 x = gen_reg_rtx (Pmode);
1199 is_mem = 1;
1200 }
1201
1202 /* ??? We could handle this if we knew that a load from A or B could
1203 not fault. This is also true if we've already loaded
1204 from the address along the path from ENTRY. */
1205 else if (may_trap_p (a) || may_trap_p (b))
1206 return FALSE;
1207
1208 /* if (test) x = a + b; else x = c - d;
1209 => y = a + b;
1210 x = c - d;
1211 if (test)
1212 x = y;
1213 */
1214
1215 code = GET_CODE (if_info->cond);
1216 insn_a = if_info->insn_a;
1217 insn_b = if_info->insn_b;
1218
1219 /* Possibly rearrange operands to make things come out more natural. */
1220 if (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN)
1221 {
1222 int reversep = 0;
1223 if (rtx_equal_p (b, x))
1224 reversep = 1;
1225 else if (general_operand (b, GET_MODE (b)))
1226 reversep = 1;
1227
1228 if (reversep)
1229 {
1230 code = reversed_comparison_code (if_info->cond, if_info->jump);
1231 tmp = a, a = b, b = tmp;
1232 tmp = insn_a, insn_a = insn_b, insn_b = tmp;
1233 }
1234 }
1235
1236 start_sequence ();
1237
1238 /* If either operand is complex, load it into a register first.
1239 The best way to do this is to copy the original insn. In this
1240 way we preserve any clobbers etc that the insn may have had.
1241 This is of course not possible in the IS_MEM case. */
1242 if (! general_operand (a, GET_MODE (a)))
1243 {
1244 rtx set;
1245
1246 if (no_new_pseudos)
1247 goto end_seq_and_fail;
1248
1249 if (is_mem)
1250 {
1251 tmp = gen_reg_rtx (GET_MODE (a));
1252 tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, a));
1253 }
1254 else if (! insn_a)
1255 goto end_seq_and_fail;
1256 else
1257 {
1258 a = gen_reg_rtx (GET_MODE (a));
1259 tmp = copy_rtx (insn_a);
1260 set = single_set (tmp);
1261 SET_DEST (set) = a;
1262 tmp = emit_insn (PATTERN (tmp));
1263 }
1264 if (recog_memoized (tmp) < 0)
1265 goto end_seq_and_fail;
1266 }
1267 if (! general_operand (b, GET_MODE (b)))
1268 {
1269 rtx set;
1270
1271 if (no_new_pseudos)
1272 goto end_seq_and_fail;
1273
1274 if (is_mem)
1275 {
1276 tmp = gen_reg_rtx (GET_MODE (b));
1277 tmp = emit_insn (gen_rtx_SET (VOIDmode,
1278 tmp,
1279 b));
1280 }
1281 else if (! insn_b)
1282 goto end_seq_and_fail;
1283 else
1284 {
1285 b = gen_reg_rtx (GET_MODE (b));
1286 tmp = copy_rtx (insn_b);
1287 set = single_set (tmp);
1288 SET_DEST (set) = b;
1289 tmp = emit_insn (PATTERN (tmp));
1290 }
1291 if (recog_memoized (tmp) < 0)
1292 goto end_seq_and_fail;
1293 }
1294
1295 target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0),
1296 XEXP (if_info->cond, 1), a, b);
1297
1298 if (! target)
1299 goto end_seq_and_fail;
1300
1301 /* If we're handling a memory for above, emit the load now. */
1302 if (is_mem)
1303 {
1304 tmp = gen_rtx_MEM (GET_MODE (if_info->x), target);
1305
1306 /* Copy over flags as appropriate. */
1307 if (MEM_VOLATILE_P (if_info->a) || MEM_VOLATILE_P (if_info->b))
1308 MEM_VOLATILE_P (tmp) = 1;
1309 if (MEM_IN_STRUCT_P (if_info->a) && MEM_IN_STRUCT_P (if_info->b))
1310 MEM_IN_STRUCT_P (tmp) = 1;
1311 if (MEM_SCALAR_P (if_info->a) && MEM_SCALAR_P (if_info->b))
1312 MEM_SCALAR_P (tmp) = 1;
1313 if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b))
1314 set_mem_alias_set (tmp, MEM_ALIAS_SET (if_info->a));
1315 set_mem_align (tmp,
1316 MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b)));
1317
1318 noce_emit_move_insn (if_info->x, tmp);
1319 }
1320 else if (target != x)
1321 noce_emit_move_insn (x, target);
1322
1323 tmp = end_ifcvt_sequence (if_info);
1324 if (!tmp)
1325 return FALSE;
1326
1327 emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1328 return TRUE;
1329
1330 end_seq_and_fail:
1331 end_sequence ();
1332 return FALSE;
1333 }
1334
1335 /* For most cases, the simplified condition we found is the best
1336 choice, but this is not the case for the min/max/abs transforms.
1337 For these we wish to know that it is A or B in the condition. */
1338
1339 static rtx
1340 noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
1341 rtx *earliest)
1342 {
1343 rtx cond, set, insn;
1344 int reverse;
1345
1346 /* If target is already mentioned in the known condition, return it. */
1347 if (reg_mentioned_p (target, if_info->cond))
1348 {
1349 *earliest = if_info->cond_earliest;
1350 return if_info->cond;
1351 }
1352
1353 set = pc_set (if_info->jump);
1354 cond = XEXP (SET_SRC (set), 0);
1355 reverse
1356 = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1357 && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump);
1358
1359 /* If we're looking for a constant, try to make the conditional
1360 have that constant in it. There are two reasons why it may
1361 not have the constant we want:
1362
1363 1. GCC may have needed to put the constant in a register, because
1364 the target can't compare directly against that constant. For
1365 this case, we look for a SET immediately before the comparison
1366 that puts a constant in that register.
1367
1368 2. GCC may have canonicalized the conditional, for example
1369 replacing "if x < 4" with "if x <= 3". We can undo that (or
1370 make equivalent types of changes) to get the constants we need
1371 if they're off by one in the right direction. */
1372
1373 if (GET_CODE (target) == CONST_INT)
1374 {
1375 enum rtx_code code = GET_CODE (if_info->cond);
1376 rtx op_a = XEXP (if_info->cond, 0);
1377 rtx op_b = XEXP (if_info->cond, 1);
1378 rtx prev_insn;
1379
1380 /* First, look to see if we put a constant in a register. */
1381 prev_insn = PREV_INSN (if_info->cond_earliest);
1382 if (prev_insn
1383 && INSN_P (prev_insn)
1384 && GET_CODE (PATTERN (prev_insn)) == SET)
1385 {
1386 rtx src = find_reg_equal_equiv_note (prev_insn);
1387 if (!src)
1388 src = SET_SRC (PATTERN (prev_insn));
1389 if (GET_CODE (src) == CONST_INT)
1390 {
1391 if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn))))
1392 op_a = src;
1393 else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn))))
1394 op_b = src;
1395
1396 if (GET_CODE (op_a) == CONST_INT)
1397 {
1398 rtx tmp = op_a;
1399 op_a = op_b;
1400 op_b = tmp;
1401 code = swap_condition (code);
1402 }
1403 }
1404 }
1405
1406 /* Now, look to see if we can get the right constant by
1407 adjusting the conditional. */
1408 if (GET_CODE (op_b) == CONST_INT)
1409 {
1410 HOST_WIDE_INT desired_val = INTVAL (target);
1411 HOST_WIDE_INT actual_val = INTVAL (op_b);
1412
1413 switch (code)
1414 {
1415 case LT:
1416 if (actual_val == desired_val + 1)
1417 {
1418 code = LE;
1419 op_b = GEN_INT (desired_val);
1420 }
1421 break;
1422 case LE:
1423 if (actual_val == desired_val - 1)
1424 {
1425 code = LT;
1426 op_b = GEN_INT (desired_val);
1427 }
1428 break;
1429 case GT:
1430 if (actual_val == desired_val - 1)
1431 {
1432 code = GE;
1433 op_b = GEN_INT (desired_val);
1434 }
1435 break;
1436 case GE:
1437 if (actual_val == desired_val + 1)
1438 {
1439 code = GT;
1440 op_b = GEN_INT (desired_val);
1441 }
1442 break;
1443 default:
1444 break;
1445 }
1446 }
1447
1448 /* If we made any changes, generate a new conditional that is
1449 equivalent to what we started with, but has the right
1450 constants in it. */
1451 if (code != GET_CODE (if_info->cond)
1452 || op_a != XEXP (if_info->cond, 0)
1453 || op_b != XEXP (if_info->cond, 1))
1454 {
1455 cond = gen_rtx_fmt_ee (code, GET_MODE (cond), op_a, op_b);
1456 *earliest = if_info->cond_earliest;
1457 return cond;
1458 }
1459 }
1460
1461 cond = canonicalize_condition (if_info->jump, cond, reverse,
1462 earliest, target, false);
1463 if (! cond || ! reg_mentioned_p (target, cond))
1464 return NULL;
1465
1466 /* We almost certainly searched back to a different place.
1467 Need to re-verify correct lifetimes. */
1468
1469 /* X may not be mentioned in the range (cond_earliest, jump]. */
1470 for (insn = if_info->jump; insn != *earliest; insn = PREV_INSN (insn))
1471 if (INSN_P (insn) && reg_overlap_mentioned_p (if_info->x, PATTERN (insn)))
1472 return NULL;
1473
1474 /* A and B may not be modified in the range [cond_earliest, jump). */
1475 for (insn = *earliest; insn != if_info->jump; insn = NEXT_INSN (insn))
1476 if (INSN_P (insn)
1477 && (modified_in_p (if_info->a, insn)
1478 || modified_in_p (if_info->b, insn)))
1479 return NULL;
1480
1481 return cond;
1482 }
1483
1484 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc. */
1485
1486 static int
1487 noce_try_minmax (struct noce_if_info *if_info)
1488 {
1489 rtx cond, earliest, target, seq;
1490 enum rtx_code code, op;
1491 int unsignedp;
1492
1493 /* ??? Can't guarantee that expand_binop won't create pseudos. */
1494 if (no_new_pseudos)
1495 return FALSE;
1496
1497 /* ??? Reject modes with NaNs or signed zeros since we don't know how
1498 they will be resolved with an SMIN/SMAX. It wouldn't be too hard
1499 to get the target to tell us... */
1500 if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x))
1501 || HONOR_NANS (GET_MODE (if_info->x)))
1502 return FALSE;
1503
1504 cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
1505 if (!cond)
1506 return FALSE;
1507
1508 /* Verify the condition is of the form we expect, and canonicalize
1509 the comparison code. */
1510 code = GET_CODE (cond);
1511 if (rtx_equal_p (XEXP (cond, 0), if_info->a))
1512 {
1513 if (! rtx_equal_p (XEXP (cond, 1), if_info->b))
1514 return FALSE;
1515 }
1516 else if (rtx_equal_p (XEXP (cond, 1), if_info->a))
1517 {
1518 if (! rtx_equal_p (XEXP (cond, 0), if_info->b))
1519 return FALSE;
1520 code = swap_condition (code);
1521 }
1522 else
1523 return FALSE;
1524
1525 /* Determine what sort of operation this is. Note that the code is for
1526 a taken branch, so the code->operation mapping appears backwards. */
1527 switch (code)
1528 {
1529 case LT:
1530 case LE:
1531 case UNLT:
1532 case UNLE:
1533 op = SMAX;
1534 unsignedp = 0;
1535 break;
1536 case GT:
1537 case GE:
1538 case UNGT:
1539 case UNGE:
1540 op = SMIN;
1541 unsignedp = 0;
1542 break;
1543 case LTU:
1544 case LEU:
1545 op = UMAX;
1546 unsignedp = 1;
1547 break;
1548 case GTU:
1549 case GEU:
1550 op = UMIN;
1551 unsignedp = 1;
1552 break;
1553 default:
1554 return FALSE;
1555 }
1556
1557 start_sequence ();
1558
1559 target = expand_simple_binop (GET_MODE (if_info->x), op,
1560 if_info->a, if_info->b,
1561 if_info->x, unsignedp, OPTAB_WIDEN);
1562 if (! target)
1563 {
1564 end_sequence ();
1565 return FALSE;
1566 }
1567 if (target != if_info->x)
1568 noce_emit_move_insn (if_info->x, target);
1569
1570 seq = end_ifcvt_sequence (if_info);
1571 if (!seq)
1572 return FALSE;
1573
1574 emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1575 if_info->cond = cond;
1576 if_info->cond_earliest = earliest;
1577
1578 return TRUE;
1579 }
1580
1581 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc. */
1582
1583 static int
1584 noce_try_abs (struct noce_if_info *if_info)
1585 {
1586 rtx cond, earliest, target, seq, a, b, c;
1587 int negate;
1588
1589 /* ??? Can't guarantee that expand_binop won't create pseudos. */
1590 if (no_new_pseudos)
1591 return FALSE;
1592
1593 /* Recognize A and B as constituting an ABS or NABS. */
1594 a = if_info->a;
1595 b = if_info->b;
1596 if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b))
1597 negate = 0;
1598 else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a))
1599 {
1600 c = a; a = b; b = c;
1601 negate = 1;
1602 }
1603 else
1604 return FALSE;
1605
1606 cond = noce_get_alt_condition (if_info, b, &earliest);
1607 if (!cond)
1608 return FALSE;
1609
1610 /* Verify the condition is of the form we expect. */
1611 if (rtx_equal_p (XEXP (cond, 0), b))
1612 c = XEXP (cond, 1);
1613 else if (rtx_equal_p (XEXP (cond, 1), b))
1614 c = XEXP (cond, 0);
1615 else
1616 return FALSE;
1617
1618 /* Verify that C is zero. Search backward through the block for
1619 a REG_EQUAL note if necessary. */
1620 if (REG_P (c))
1621 {
1622 rtx insn, note = NULL;
1623 for (insn = earliest;
1624 insn != BB_HEAD (if_info->test_bb);
1625 insn = PREV_INSN (insn))
1626 if (INSN_P (insn)
1627 && ((note = find_reg_note (insn, REG_EQUAL, c))
1628 || (note = find_reg_note (insn, REG_EQUIV, c))))
1629 break;
1630 if (! note)
1631 return FALSE;
1632 c = XEXP (note, 0);
1633 }
1634 if (MEM_P (c)
1635 && GET_CODE (XEXP (c, 0)) == SYMBOL_REF
1636 && CONSTANT_POOL_ADDRESS_P (XEXP (c, 0)))
1637 c = get_pool_constant (XEXP (c, 0));
1638
1639 /* Work around funny ideas get_condition has wrt canonicalization.
1640 Note that these rtx constants are known to be CONST_INT, and
1641 therefore imply integer comparisons. */
1642 if (c == constm1_rtx && GET_CODE (cond) == GT)
1643 ;
1644 else if (c == const1_rtx && GET_CODE (cond) == LT)
1645 ;
1646 else if (c != CONST0_RTX (GET_MODE (b)))
1647 return FALSE;
1648
1649 /* Determine what sort of operation this is. */
1650 switch (GET_CODE (cond))
1651 {
1652 case LT:
1653 case LE:
1654 case UNLT:
1655 case UNLE:
1656 negate = !negate;
1657 break;
1658 case GT:
1659 case GE:
1660 case UNGT:
1661 case UNGE:
1662 break;
1663 default:
1664 return FALSE;
1665 }
1666
1667 start_sequence ();
1668
1669 target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1);
1670
1671 /* ??? It's a quandary whether cmove would be better here, especially
1672 for integers. Perhaps combine will clean things up. */
1673 if (target && negate)
1674 target = expand_simple_unop (GET_MODE (target), NEG, target, if_info->x, 0);
1675
1676 if (! target)
1677 {
1678 end_sequence ();
1679 return FALSE;
1680 }
1681
1682 if (target != if_info->x)
1683 noce_emit_move_insn (if_info->x, target);
1684
1685 seq = end_ifcvt_sequence (if_info);
1686 if (!seq)
1687 return FALSE;
1688
1689 emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1690 if_info->cond = cond;
1691 if_info->cond_earliest = earliest;
1692
1693 return TRUE;
1694 }
1695
1696 /* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;". */
1697
1698 static int
1699 noce_try_sign_mask (struct noce_if_info *if_info)
1700 {
1701 rtx cond, t, m, c, seq;
1702 enum machine_mode mode;
1703 enum rtx_code code;
1704
1705 if (no_new_pseudos)
1706 return FALSE;
1707
1708 cond = if_info->cond;
1709 code = GET_CODE (cond);
1710 m = XEXP (cond, 0);
1711 c = XEXP (cond, 1);
1712
1713 t = NULL_RTX;
1714 if (if_info->a == const0_rtx)
1715 {
1716 if ((code == LT && c == const0_rtx)
1717 || (code == LE && c == constm1_rtx))
1718 t = if_info->b;
1719 }
1720 else if (if_info->b == const0_rtx)
1721 {
1722 if ((code == GE && c == const0_rtx)
1723 || (code == GT && c == constm1_rtx))
1724 t = if_info->a;
1725 }
1726
1727 if (! t || side_effects_p (t))
1728 return FALSE;
1729
1730 /* We currently don't handle different modes. */
1731 mode = GET_MODE (t);
1732 if (GET_MODE (m) != mode)
1733 return FALSE;
1734
1735 /* This is only profitable if T is cheap, or T is unconditionally
1736 executed/evaluated in the original insn sequence. */
1737 if (rtx_cost (t, SET) >= COSTS_N_INSNS (2)
1738 && (!if_info->b_unconditional
1739 || t != if_info->b))
1740 return FALSE;
1741
1742 start_sequence ();
1743 /* Use emit_store_flag to generate "m < 0 ? -1 : 0" instead of expanding
1744 "(signed) m >> 31" directly. This benefits targets with specialized
1745 insns to obtain the signmask, but still uses ashr_optab otherwise. */
1746 m = emit_store_flag (gen_reg_rtx (mode), LT, m, const0_rtx, mode, 0, -1);
1747 t = m ? expand_binop (mode, and_optab, m, t, NULL_RTX, 0, OPTAB_DIRECT)
1748 : NULL_RTX;
1749
1750 if (!t)
1751 {
1752 end_sequence ();
1753 return FALSE;
1754 }
1755
1756 noce_emit_move_insn (if_info->x, t);
1757
1758 seq = end_ifcvt_sequence (if_info);
1759 if (!seq)
1760 return FALSE;
1761
1762 emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1763 return TRUE;
1764 }
1765
1766
1767 /* Similar to get_condition, only the resulting condition must be
1768 valid at JUMP, instead of at EARLIEST. */
1769
1770 static rtx
1771 noce_get_condition (rtx jump, rtx *earliest)
1772 {
1773 rtx cond, set, tmp, insn;
1774 bool reverse;
1775
1776 if (! any_condjump_p (jump))
1777 return NULL_RTX;
1778
1779 set = pc_set (jump);
1780
1781 /* If this branches to JUMP_LABEL when the condition is false,
1782 reverse the condition. */
1783 reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1784 && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump));
1785
1786 /* If the condition variable is a register and is MODE_INT, accept it. */
1787
1788 cond = XEXP (SET_SRC (set), 0);
1789 tmp = XEXP (cond, 0);
1790 if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT)
1791 {
1792 *earliest = jump;
1793
1794 if (reverse)
1795 cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
1796 GET_MODE (cond), tmp, XEXP (cond, 1));
1797 return cond;
1798 }
1799
1800 /* Otherwise, fall back on canonicalize_condition to do the dirty
1801 work of manipulating MODE_CC values and COMPARE rtx codes. */
1802
1803 tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
1804 false);
1805 if (!tmp)
1806 return NULL_RTX;
1807
1808 /* We are going to insert code before JUMP, not before EARLIEST.
1809 We must therefore be certain that the given condition is valid
1810 at JUMP by virtue of not having been modified since. */
1811 for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn))
1812 if (INSN_P (insn) && modified_in_p (tmp, insn))
1813 break;
1814 if (insn == jump)
1815 return tmp;
1816
1817 /* The condition was modified. See if we can get a partial result
1818 that doesn't follow all the reversals. Perhaps combine can fold
1819 them together later. */
1820 tmp = XEXP (tmp, 0);
1821 if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
1822 return NULL_RTX;
1823 tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp,
1824 false);
1825 if (!tmp)
1826 return NULL_RTX;
1827
1828 /* For sanity's sake, re-validate the new result. */
1829 for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn))
1830 if (INSN_P (insn) && modified_in_p (tmp, insn))
1831 return NULL_RTX;
1832
1833 return tmp;
1834 }
1835
1836 /* Return true if OP is ok for if-then-else processing. */
1837
1838 static int
1839 noce_operand_ok (rtx op)
1840 {
1841 /* We special-case memories, so handle any of them with
1842 no address side effects. */
1843 if (MEM_P (op))
1844 return ! side_effects_p (XEXP (op, 0));
1845
1846 if (side_effects_p (op))
1847 return FALSE;
1848
1849 return ! may_trap_p (op);
1850 }
1851
1852 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
1853 without using conditional execution. Return TRUE if we were
1854 successful at converting the block. */
1855
1856 static int
1857 noce_process_if_block (struct ce_if_block * ce_info)
1858 {
1859 basic_block test_bb = ce_info->test_bb; /* test block */
1860 basic_block then_bb = ce_info->then_bb; /* THEN */
1861 basic_block else_bb = ce_info->else_bb; /* ELSE or NULL */
1862 struct noce_if_info if_info;
1863 rtx insn_a, insn_b;
1864 rtx set_a, set_b;
1865 rtx orig_x, x, a, b;
1866 rtx jump, cond;
1867
1868 /* We're looking for patterns of the form
1869
1870 (1) if (...) x = a; else x = b;
1871 (2) x = b; if (...) x = a;
1872 (3) if (...) x = a; // as if with an initial x = x.
1873
1874 The later patterns require jumps to be more expensive.
1875
1876 ??? For future expansion, look for multiple X in such patterns. */
1877
1878 /* If test is comprised of && or || elements, don't handle it unless it is
1879 the special case of && elements without an ELSE block. */
1880 if (ce_info->num_multiple_test_blocks)
1881 {
1882 if (else_bb || ! ce_info->and_and_p)
1883 return FALSE;
1884
1885 ce_info->test_bb = test_bb = ce_info->last_test_bb;
1886 ce_info->num_multiple_test_blocks = 0;
1887 ce_info->num_and_and_blocks = 0;
1888 ce_info->num_or_or_blocks = 0;
1889 }
1890
1891 /* If this is not a standard conditional jump, we can't parse it. */
1892 jump = BB_END (test_bb);
1893 cond = noce_get_condition (jump, &if_info.cond_earliest);
1894 if (! cond)
1895 return FALSE;
1896
1897 /* If the conditional jump is more than just a conditional
1898 jump, then we can not do if-conversion on this block. */
1899 if (! onlyjump_p (jump))
1900 return FALSE;
1901
1902 /* We must be comparing objects whose modes imply the size. */
1903 if (GET_MODE (XEXP (cond, 0)) == BLKmode)
1904 return FALSE;
1905
1906 /* Look for one of the potential sets. */
1907 insn_a = first_active_insn (then_bb);
1908 if (! insn_a
1909 || insn_a != last_active_insn (then_bb, FALSE)
1910 || (set_a = single_set (insn_a)) == NULL_RTX)
1911 return FALSE;
1912
1913 x = SET_DEST (set_a);
1914 a = SET_SRC (set_a);
1915
1916 /* Look for the other potential set. Make sure we've got equivalent
1917 destinations. */
1918 /* ??? This is overconservative. Storing to two different mems is
1919 as easy as conditionally computing the address. Storing to a
1920 single mem merely requires a scratch memory to use as one of the
1921 destination addresses; often the memory immediately below the
1922 stack pointer is available for this. */
1923 set_b = NULL_RTX;
1924 if (else_bb)
1925 {
1926 insn_b = first_active_insn (else_bb);
1927 if (! insn_b
1928 || insn_b != last_active_insn (else_bb, FALSE)
1929 || (set_b = single_set (insn_b)) == NULL_RTX
1930 || ! rtx_equal_p (x, SET_DEST (set_b)))
1931 return FALSE;
1932 }
1933 else
1934 {
1935 insn_b = prev_nonnote_insn (if_info.cond_earliest);
1936 /* We're going to be moving the evaluation of B down from above
1937 COND_EARLIEST to JUMP. Make sure the relevant data is still
1938 intact. */
1939 if (! insn_b
1940 || GET_CODE (insn_b) != INSN
1941 || (set_b = single_set (insn_b)) == NULL_RTX
1942 || ! rtx_equal_p (x, SET_DEST (set_b))
1943 || reg_overlap_mentioned_p (x, SET_SRC (set_b))
1944 || modified_between_p (SET_SRC (set_b),
1945 PREV_INSN (if_info.cond_earliest), jump)
1946 /* Likewise with X. In particular this can happen when
1947 noce_get_condition looks farther back in the instruction
1948 stream than one might expect. */
1949 || reg_overlap_mentioned_p (x, cond)
1950 || reg_overlap_mentioned_p (x, a)
1951 || modified_between_p (x, PREV_INSN (if_info.cond_earliest), jump))
1952 insn_b = set_b = NULL_RTX;
1953 }
1954
1955 /* If x has side effects then only the if-then-else form is safe to
1956 convert. But even in that case we would need to restore any notes
1957 (such as REG_INC) at then end. That can be tricky if
1958 noce_emit_move_insn expands to more than one insn, so disable the
1959 optimization entirely for now if there are side effects. */
1960 if (side_effects_p (x))
1961 return FALSE;
1962
1963 b = (set_b ? SET_SRC (set_b) : x);
1964
1965 /* Only operate on register destinations, and even then avoid extending
1966 the lifetime of hard registers on small register class machines. */
1967 orig_x = x;
1968 if (!REG_P (x)
1969 || (SMALL_REGISTER_CLASSES
1970 && REGNO (x) < FIRST_PSEUDO_REGISTER))
1971 {
1972 if (no_new_pseudos || GET_MODE (x) == BLKmode)
1973 return FALSE;
1974 x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
1975 ? XEXP (x, 0) : x));
1976 }
1977
1978 /* Don't operate on sources that may trap or are volatile. */
1979 if (! noce_operand_ok (a) || ! noce_operand_ok (b))
1980 return FALSE;
1981
1982 /* Set up the info block for our subroutines. */
1983 if_info.test_bb = test_bb;
1984 if_info.cond = cond;
1985 if_info.jump = jump;
1986 if_info.insn_a = insn_a;
1987 if_info.insn_b = insn_b;
1988 if_info.x = x;
1989 if_info.a = a;
1990 if_info.b = b;
1991 if_info.b_unconditional = else_bb == 0;
1992
1993 /* Try optimizations in some approximation of a useful order. */
1994 /* ??? Should first look to see if X is live incoming at all. If it
1995 isn't, we don't need anything but an unconditional set. */
1996
1997 /* Look and see if A and B are really the same. Avoid creating silly
1998 cmove constructs that no one will fix up later. */
1999 if (rtx_equal_p (a, b))
2000 {
2001 /* If we have an INSN_B, we don't have to create any new rtl. Just
2002 move the instruction that we already have. If we don't have an
2003 INSN_B, that means that A == X, and we've got a noop move. In
2004 that case don't do anything and let the code below delete INSN_A. */
2005 if (insn_b && else_bb)
2006 {
2007 rtx note;
2008
2009 if (else_bb && insn_b == BB_END (else_bb))
2010 BB_END (else_bb) = PREV_INSN (insn_b);
2011 reorder_insns (insn_b, insn_b, PREV_INSN (jump));
2012
2013 /* If there was a REG_EQUAL note, delete it since it may have been
2014 true due to this insn being after a jump. */
2015 if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
2016 remove_note (insn_b, note);
2017
2018 insn_b = NULL_RTX;
2019 }
2020 /* If we have "x = b; if (...) x = a;", and x has side-effects, then
2021 x must be executed twice. */
2022 else if (insn_b && side_effects_p (orig_x))
2023 return FALSE;
2024
2025 x = orig_x;
2026 goto success;
2027 }
2028
2029 /* Disallow the "if (...) x = a;" form (with an implicit "else x = x;")
2030 for most optimizations if writing to x may trap, i.e. it's a memory
2031 other than a static var or a stack slot. */
2032 if (! set_b
2033 && MEM_P (orig_x)
2034 && ! MEM_NOTRAP_P (orig_x)
2035 && rtx_addr_can_trap_p (XEXP (orig_x, 0)))
2036 {
2037 if (HAVE_conditional_move)
2038 {
2039 if (noce_try_cmove (&if_info))
2040 goto success;
2041 if (! HAVE_conditional_execution
2042 && noce_try_cmove_arith (&if_info))
2043 goto success;
2044 }
2045 return FALSE;
2046 }
2047
2048 if (noce_try_move (&if_info))
2049 goto success;
2050 if (noce_try_store_flag (&if_info))
2051 goto success;
2052 if (noce_try_minmax (&if_info))
2053 goto success;
2054 if (noce_try_abs (&if_info))
2055 goto success;
2056 if (HAVE_conditional_move
2057 && noce_try_cmove (&if_info))
2058 goto success;
2059 if (! HAVE_conditional_execution)
2060 {
2061 if (noce_try_store_flag_constants (&if_info))
2062 goto success;
2063 if (noce_try_addcc (&if_info))
2064 goto success;
2065 if (noce_try_store_flag_mask (&if_info))
2066 goto success;
2067 if (HAVE_conditional_move
2068 && noce_try_cmove_arith (&if_info))
2069 goto success;
2070 if (noce_try_sign_mask (&if_info))
2071 goto success;
2072 }
2073
2074 return FALSE;
2075
2076 success:
2077 /* The original sets may now be killed. */
2078 delete_insn (insn_a);
2079
2080 /* Several special cases here: First, we may have reused insn_b above,
2081 in which case insn_b is now NULL. Second, we want to delete insn_b
2082 if it came from the ELSE block, because follows the now correct
2083 write that appears in the TEST block. However, if we got insn_b from
2084 the TEST block, it may in fact be loading data needed for the comparison.
2085 We'll let life_analysis remove the insn if it's really dead. */
2086 if (insn_b && else_bb)
2087 delete_insn (insn_b);
2088
2089 /* The new insns will have been inserted immediately before the jump. We
2090 should be able to remove the jump with impunity, but the condition itself
2091 may have been modified by gcse to be shared across basic blocks. */
2092 delete_insn (jump);
2093
2094 /* If we used a temporary, fix it up now. */
2095 if (orig_x != x)
2096 {
2097 start_sequence ();
2098 noce_emit_move_insn (orig_x, x);
2099 insn_b = get_insns ();
2100 set_used_flags (orig_x);
2101 unshare_all_rtl_in_chain (insn_b);
2102 end_sequence ();
2103
2104 emit_insn_after_setloc (insn_b, BB_END (test_bb), INSN_LOCATOR (insn_a));
2105 }
2106
2107 /* Merge the blocks! */
2108 merge_if_block (ce_info);
2109
2110 return TRUE;
2111 }
2112 \f
2113 /* Attempt to convert an IF-THEN or IF-THEN-ELSE block into
2114 straight line code. Return true if successful. */
2115
2116 static int
2117 process_if_block (struct ce_if_block * ce_info)
2118 {
2119 if (! reload_completed
2120 && noce_process_if_block (ce_info))
2121 return TRUE;
2122
2123 if (HAVE_conditional_execution && reload_completed)
2124 {
2125 /* If we have && and || tests, try to first handle combining the && and
2126 || tests into the conditional code, and if that fails, go back and
2127 handle it without the && and ||, which at present handles the && case
2128 if there was no ELSE block. */
2129 if (cond_exec_process_if_block (ce_info, TRUE))
2130 return TRUE;
2131
2132 if (ce_info->num_multiple_test_blocks)
2133 {
2134 cancel_changes (0);
2135
2136 if (cond_exec_process_if_block (ce_info, FALSE))
2137 return TRUE;
2138 }
2139 }
2140
2141 return FALSE;
2142 }
2143
2144 /* Merge the blocks and mark for local life update. */
2145
2146 static void
2147 merge_if_block (struct ce_if_block * ce_info)
2148 {
2149 basic_block test_bb = ce_info->test_bb; /* last test block */
2150 basic_block then_bb = ce_info->then_bb; /* THEN */
2151 basic_block else_bb = ce_info->else_bb; /* ELSE or NULL */
2152 basic_block join_bb = ce_info->join_bb; /* join block */
2153 basic_block combo_bb;
2154
2155 /* All block merging is done into the lower block numbers. */
2156
2157 combo_bb = test_bb;
2158
2159 /* Merge any basic blocks to handle && and || subtests. Each of
2160 the blocks are on the fallthru path from the predecessor block. */
2161 if (ce_info->num_multiple_test_blocks > 0)
2162 {
2163 basic_block bb = test_bb;
2164 basic_block last_test_bb = ce_info->last_test_bb;
2165 basic_block fallthru = block_fallthru (bb);
2166
2167 do
2168 {
2169 bb = fallthru;
2170 fallthru = block_fallthru (bb);
2171 merge_blocks (combo_bb, bb);
2172 num_true_changes++;
2173 }
2174 while (bb != last_test_bb);
2175 }
2176
2177 /* Merge TEST block into THEN block. Normally the THEN block won't have a
2178 label, but it might if there were || tests. That label's count should be
2179 zero, and it normally should be removed. */
2180
2181 if (then_bb)
2182 {
2183 if (combo_bb->global_live_at_end)
2184 COPY_REG_SET (combo_bb->global_live_at_end,
2185 then_bb->global_live_at_end);
2186 merge_blocks (combo_bb, then_bb);
2187 num_true_changes++;
2188 }
2189
2190 /* The ELSE block, if it existed, had a label. That label count
2191 will almost always be zero, but odd things can happen when labels
2192 get their addresses taken. */
2193 if (else_bb)
2194 {
2195 merge_blocks (combo_bb, else_bb);
2196 num_true_changes++;
2197 }
2198
2199 /* If there was no join block reported, that means it was not adjacent
2200 to the others, and so we cannot merge them. */
2201
2202 if (! join_bb)
2203 {
2204 rtx last = BB_END (combo_bb);
2205
2206 /* The outgoing edge for the current COMBO block should already
2207 be correct. Verify this. */
2208 if (combo_bb->succ == NULL_EDGE)
2209 {
2210 if (find_reg_note (last, REG_NORETURN, NULL))
2211 ;
2212 else if (GET_CODE (last) == INSN
2213 && GET_CODE (PATTERN (last)) == TRAP_IF
2214 && TRAP_CONDITION (PATTERN (last)) == const_true_rtx)
2215 ;
2216 else
2217 abort ();
2218 }
2219
2220 /* There should still be something at the end of the THEN or ELSE
2221 blocks taking us to our final destination. */
2222 else if (GET_CODE (last) == JUMP_INSN)
2223 ;
2224 else if (combo_bb->succ->dest == EXIT_BLOCK_PTR
2225 && GET_CODE (last) == CALL_INSN
2226 && SIBLING_CALL_P (last))
2227 ;
2228 else if ((combo_bb->succ->flags & EDGE_EH)
2229 && can_throw_internal (last))
2230 ;
2231 else
2232 abort ();
2233 }
2234
2235 /* The JOIN block may have had quite a number of other predecessors too.
2236 Since we've already merged the TEST, THEN and ELSE blocks, we should
2237 have only one remaining edge from our if-then-else diamond. If there
2238 is more than one remaining edge, it must come from elsewhere. There
2239 may be zero incoming edges if the THEN block didn't actually join
2240 back up (as with a call to abort). */
2241 else if ((join_bb->pred == NULL
2242 || join_bb->pred->pred_next == NULL)
2243 && join_bb != EXIT_BLOCK_PTR)
2244 {
2245 /* We can merge the JOIN. */
2246 if (combo_bb->global_live_at_end)
2247 COPY_REG_SET (combo_bb->global_live_at_end,
2248 join_bb->global_live_at_end);
2249
2250 merge_blocks (combo_bb, join_bb);
2251 num_true_changes++;
2252 }
2253 else
2254 {
2255 /* We cannot merge the JOIN. */
2256
2257 /* The outgoing edge for the current COMBO block should already
2258 be correct. Verify this. */
2259 if (combo_bb->succ->succ_next != NULL_EDGE
2260 || combo_bb->succ->dest != join_bb)
2261 abort ();
2262
2263 /* Remove the jump and cruft from the end of the COMBO block. */
2264 if (join_bb != EXIT_BLOCK_PTR)
2265 tidy_fallthru_edge (combo_bb->succ);
2266 }
2267
2268 num_updated_if_blocks++;
2269 }
2270 \f
2271 /* Find a block ending in a simple IF condition and try to transform it
2272 in some way. When converting a multi-block condition, put the new code
2273 in the first such block and delete the rest. Return a pointer to this
2274 first block if some transformation was done. Return NULL otherwise. */
2275
2276 static basic_block
2277 find_if_header (basic_block test_bb, int pass)
2278 {
2279 ce_if_block_t ce_info;
2280 edge then_edge;
2281 edge else_edge;
2282
2283 /* The kind of block we're looking for has exactly two successors. */
2284 if ((then_edge = test_bb->succ) == NULL_EDGE
2285 || (else_edge = then_edge->succ_next) == NULL_EDGE
2286 || else_edge->succ_next != NULL_EDGE)
2287 return NULL;
2288
2289 /* Neither edge should be abnormal. */
2290 if ((then_edge->flags & EDGE_COMPLEX)
2291 || (else_edge->flags & EDGE_COMPLEX))
2292 return NULL;
2293
2294 /* Nor exit the loop. */
2295 if ((then_edge->flags & EDGE_LOOP_EXIT)
2296 || (else_edge->flags & EDGE_LOOP_EXIT))
2297 return NULL;
2298
2299 /* The THEN edge is canonically the one that falls through. */
2300 if (then_edge->flags & EDGE_FALLTHRU)
2301 ;
2302 else if (else_edge->flags & EDGE_FALLTHRU)
2303 {
2304 edge e = else_edge;
2305 else_edge = then_edge;
2306 then_edge = e;
2307 }
2308 else
2309 /* Otherwise this must be a multiway branch of some sort. */
2310 return NULL;
2311
2312 memset (&ce_info, '\0', sizeof (ce_info));
2313 ce_info.test_bb = test_bb;
2314 ce_info.then_bb = then_edge->dest;
2315 ce_info.else_bb = else_edge->dest;
2316 ce_info.pass = pass;
2317
2318 #ifdef IFCVT_INIT_EXTRA_FIELDS
2319 IFCVT_INIT_EXTRA_FIELDS (&ce_info);
2320 #endif
2321
2322 if (find_if_block (&ce_info))
2323 goto success;
2324
2325 if (HAVE_trap && HAVE_conditional_trap
2326 && find_cond_trap (test_bb, then_edge, else_edge))
2327 goto success;
2328
2329 if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY
2330 && (! HAVE_conditional_execution || reload_completed))
2331 {
2332 if (find_if_case_1 (test_bb, then_edge, else_edge))
2333 goto success;
2334 if (find_if_case_2 (test_bb, then_edge, else_edge))
2335 goto success;
2336 }
2337
2338 return NULL;
2339
2340 success:
2341 if (dump_file)
2342 fprintf (dump_file, "Conversion succeeded on pass %d.\n", pass);
2343 return ce_info.test_bb;
2344 }
2345
2346 /* Return true if a block has two edges, one of which falls through to the next
2347 block, and the other jumps to a specific block, so that we can tell if the
2348 block is part of an && test or an || test. Returns either -1 or the number
2349 of non-note, non-jump, non-USE/CLOBBER insns in the block. */
2350
2351 static int
2352 block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
2353 {
2354 edge cur_edge;
2355 int fallthru_p = FALSE;
2356 int jump_p = FALSE;
2357 rtx insn;
2358 rtx end;
2359 int n_insns = 0;
2360
2361 if (!cur_bb || !target_bb)
2362 return -1;
2363
2364 /* If no edges, obviously it doesn't jump or fallthru. */
2365 if (cur_bb->succ == NULL_EDGE)
2366 return FALSE;
2367
2368 for (cur_edge = cur_bb->succ;
2369 cur_edge != NULL_EDGE;
2370 cur_edge = cur_edge->succ_next)
2371 {
2372 if (cur_edge->flags & EDGE_COMPLEX)
2373 /* Anything complex isn't what we want. */
2374 return -1;
2375
2376 else if (cur_edge->flags & EDGE_FALLTHRU)
2377 fallthru_p = TRUE;
2378
2379 else if (cur_edge->dest == target_bb)
2380 jump_p = TRUE;
2381
2382 else
2383 return -1;
2384 }
2385
2386 if ((jump_p & fallthru_p) == 0)
2387 return -1;
2388
2389 /* Don't allow calls in the block, since this is used to group && and ||
2390 together for conditional execution support. ??? we should support
2391 conditional execution support across calls for IA-64 some day, but
2392 for now it makes the code simpler. */
2393 end = BB_END (cur_bb);
2394 insn = BB_HEAD (cur_bb);
2395
2396 while (insn != NULL_RTX)
2397 {
2398 if (GET_CODE (insn) == CALL_INSN)
2399 return -1;
2400
2401 if (INSN_P (insn)
2402 && GET_CODE (insn) != JUMP_INSN
2403 && GET_CODE (PATTERN (insn)) != USE
2404 && GET_CODE (PATTERN (insn)) != CLOBBER)
2405 n_insns++;
2406
2407 if (insn == end)
2408 break;
2409
2410 insn = NEXT_INSN (insn);
2411 }
2412
2413 return n_insns;
2414 }
2415
2416 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
2417 block. If so, we'll try to convert the insns to not require the branch.
2418 Return TRUE if we were successful at converting the block. */
2419
2420 static int
2421 find_if_block (struct ce_if_block * ce_info)
2422 {
2423 basic_block test_bb = ce_info->test_bb;
2424 basic_block then_bb = ce_info->then_bb;
2425 basic_block else_bb = ce_info->else_bb;
2426 basic_block join_bb = NULL_BLOCK;
2427 edge then_succ = then_bb->succ;
2428 edge else_succ = else_bb->succ;
2429 int then_predecessors;
2430 int else_predecessors;
2431 edge cur_edge;
2432 basic_block next;
2433
2434 ce_info->last_test_bb = test_bb;
2435
2436 /* Discover if any fall through predecessors of the current test basic block
2437 were && tests (which jump to the else block) or || tests (which jump to
2438 the then block). */
2439 if (HAVE_conditional_execution && reload_completed
2440 && test_bb->pred != NULL_EDGE
2441 && test_bb->pred->pred_next == NULL_EDGE
2442 && test_bb->pred->flags == EDGE_FALLTHRU)
2443 {
2444 basic_block bb = test_bb->pred->src;
2445 basic_block target_bb;
2446 int max_insns = MAX_CONDITIONAL_EXECUTE;
2447 int n_insns;
2448
2449 /* Determine if the preceding block is an && or || block. */
2450 if ((n_insns = block_jumps_and_fallthru_p (bb, else_bb)) >= 0)
2451 {
2452 ce_info->and_and_p = TRUE;
2453 target_bb = else_bb;
2454 }
2455 else if ((n_insns = block_jumps_and_fallthru_p (bb, then_bb)) >= 0)
2456 {
2457 ce_info->and_and_p = FALSE;
2458 target_bb = then_bb;
2459 }
2460 else
2461 target_bb = NULL_BLOCK;
2462
2463 if (target_bb && n_insns <= max_insns)
2464 {
2465 int total_insns = 0;
2466 int blocks = 0;
2467
2468 ce_info->last_test_bb = test_bb;
2469
2470 /* Found at least one && or || block, look for more. */
2471 do
2472 {
2473 ce_info->test_bb = test_bb = bb;
2474 total_insns += n_insns;
2475 blocks++;
2476
2477 if (bb->pred == NULL_EDGE || bb->pred->pred_next != NULL_EDGE)
2478 break;
2479
2480 bb = bb->pred->src;
2481 n_insns = block_jumps_and_fallthru_p (bb, target_bb);
2482 }
2483 while (n_insns >= 0 && (total_insns + n_insns) <= max_insns);
2484
2485 ce_info->num_multiple_test_blocks = blocks;
2486 ce_info->num_multiple_test_insns = total_insns;
2487
2488 if (ce_info->and_and_p)
2489 ce_info->num_and_and_blocks = blocks;
2490 else
2491 ce_info->num_or_or_blocks = blocks;
2492 }
2493 }
2494
2495 /* Count the number of edges the THEN and ELSE blocks have. */
2496 then_predecessors = 0;
2497 for (cur_edge = then_bb->pred;
2498 cur_edge != NULL_EDGE;
2499 cur_edge = cur_edge->pred_next)
2500 {
2501 then_predecessors++;
2502 if (cur_edge->flags & EDGE_COMPLEX)
2503 return FALSE;
2504 }
2505
2506 else_predecessors = 0;
2507 for (cur_edge = else_bb->pred;
2508 cur_edge != NULL_EDGE;
2509 cur_edge = cur_edge->pred_next)
2510 {
2511 else_predecessors++;
2512 if (cur_edge->flags & EDGE_COMPLEX)
2513 return FALSE;
2514 }
2515
2516 /* The THEN block of an IF-THEN combo must have exactly one predecessor,
2517 other than any || blocks which jump to the THEN block. */
2518 if ((then_predecessors - ce_info->num_or_or_blocks) != 1)
2519 return FALSE;
2520
2521 /* The THEN block of an IF-THEN combo must have zero or one successors. */
2522 if (then_succ != NULL_EDGE
2523 && (then_succ->succ_next != NULL_EDGE
2524 || (then_succ->flags & EDGE_COMPLEX)
2525 || (flow2_completed && tablejump_p (BB_END (then_bb), NULL, NULL))))
2526 return FALSE;
2527
2528 /* If the THEN block has no successors, conditional execution can still
2529 make a conditional call. Don't do this unless the ELSE block has
2530 only one incoming edge -- the CFG manipulation is too ugly otherwise.
2531 Check for the last insn of the THEN block being an indirect jump, which
2532 is listed as not having any successors, but confuses the rest of the CE
2533 code processing. ??? we should fix this in the future. */
2534 if (then_succ == NULL)
2535 {
2536 if (else_bb->pred->pred_next == NULL_EDGE)
2537 {
2538 rtx last_insn = BB_END (then_bb);
2539
2540 while (last_insn
2541 && GET_CODE (last_insn) == NOTE
2542 && last_insn != BB_HEAD (then_bb))
2543 last_insn = PREV_INSN (last_insn);
2544
2545 if (last_insn
2546 && GET_CODE (last_insn) == JUMP_INSN
2547 && ! simplejump_p (last_insn))
2548 return FALSE;
2549
2550 join_bb = else_bb;
2551 else_bb = NULL_BLOCK;
2552 }
2553 else
2554 return FALSE;
2555 }
2556
2557 /* If the THEN block's successor is the other edge out of the TEST block,
2558 then we have an IF-THEN combo without an ELSE. */
2559 else if (then_succ->dest == else_bb)
2560 {
2561 join_bb = else_bb;
2562 else_bb = NULL_BLOCK;
2563 }
2564
2565 /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
2566 has exactly one predecessor and one successor, and the outgoing edge
2567 is not complex, then we have an IF-THEN-ELSE combo. */
2568 else if (else_succ != NULL_EDGE
2569 && then_succ->dest == else_succ->dest
2570 && else_bb->pred->pred_next == NULL_EDGE
2571 && else_succ->succ_next == NULL_EDGE
2572 && ! (else_succ->flags & EDGE_COMPLEX)
2573 && ! (flow2_completed && tablejump_p (BB_END (else_bb), NULL, NULL)))
2574 join_bb = else_succ->dest;
2575
2576 /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */
2577 else
2578 return FALSE;
2579
2580 num_possible_if_blocks++;
2581
2582 if (dump_file)
2583 {
2584 fprintf (dump_file,
2585 "\nIF-THEN%s block found, pass %d, start block %d "
2586 "[insn %d], then %d [%d]",
2587 (else_bb) ? "-ELSE" : "",
2588 ce_info->pass,
2589 test_bb->index,
2590 BB_HEAD (test_bb) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
2591 then_bb->index,
2592 BB_HEAD (then_bb) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);
2593
2594 if (else_bb)
2595 fprintf (dump_file, ", else %d [%d]",
2596 else_bb->index,
2597 BB_HEAD (else_bb) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);
2598
2599 fprintf (dump_file, ", join %d [%d]",
2600 join_bb->index,
2601 BB_HEAD (join_bb) ? (int)INSN_UID (BB_HEAD (join_bb)) : -1);
2602
2603 if (ce_info->num_multiple_test_blocks > 0)
2604 fprintf (dump_file, ", %d %s block%s last test %d [%d]",
2605 ce_info->num_multiple_test_blocks,
2606 (ce_info->and_and_p) ? "&&" : "||",
2607 (ce_info->num_multiple_test_blocks == 1) ? "" : "s",
2608 ce_info->last_test_bb->index,
2609 ((BB_HEAD (ce_info->last_test_bb))
2610 ? (int)INSN_UID (BB_HEAD (ce_info->last_test_bb))
2611 : -1));
2612
2613 fputc ('\n', dump_file);
2614 }
2615
2616 /* Make sure IF, THEN, and ELSE, blocks are adjacent. Actually, we get the
2617 first condition for free, since we've already asserted that there's a
2618 fallthru edge from IF to THEN. Likewise for the && and || blocks, since
2619 we checked the FALLTHRU flag, those are already adjacent to the last IF
2620 block. */
2621 /* ??? As an enhancement, move the ELSE block. Have to deal with
2622 BLOCK notes, if by no other means than aborting the merge if they
2623 exist. Sticky enough I don't want to think about it now. */
2624 next = then_bb;
2625 if (else_bb && (next = next->next_bb) != else_bb)
2626 return FALSE;
2627 if ((next = next->next_bb) != join_bb && join_bb != EXIT_BLOCK_PTR)
2628 {
2629 if (else_bb)
2630 join_bb = NULL;
2631 else
2632 return FALSE;
2633 }
2634
2635 /* Do the real work. */
2636 ce_info->else_bb = else_bb;
2637 ce_info->join_bb = join_bb;
2638
2639 return process_if_block (ce_info);
2640 }
2641
2642 /* Convert a branch over a trap, or a branch
2643 to a trap, into a conditional trap. */
2644
2645 static int
2646 find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
2647 {
2648 basic_block then_bb = then_edge->dest;
2649 basic_block else_bb = else_edge->dest;
2650 basic_block other_bb, trap_bb;
2651 rtx trap, jump, cond, cond_earliest, seq;
2652 enum rtx_code code;
2653
2654 /* Locate the block with the trap instruction. */
2655 /* ??? While we look for no successors, we really ought to allow
2656 EH successors. Need to fix merge_if_block for that to work. */
2657 if ((trap = block_has_only_trap (then_bb)) != NULL)
2658 trap_bb = then_bb, other_bb = else_bb;
2659 else if ((trap = block_has_only_trap (else_bb)) != NULL)
2660 trap_bb = else_bb, other_bb = then_bb;
2661 else
2662 return FALSE;
2663
2664 if (dump_file)
2665 {
2666 fprintf (dump_file, "\nTRAP-IF block found, start %d, trap %d\n",
2667 test_bb->index, trap_bb->index);
2668 }
2669
2670 /* If this is not a standard conditional jump, we can't parse it. */
2671 jump = BB_END (test_bb);
2672 cond = noce_get_condition (jump, &cond_earliest);
2673 if (! cond)
2674 return FALSE;
2675
2676 /* If the conditional jump is more than just a conditional jump, then
2677 we can not do if-conversion on this block. */
2678 if (! onlyjump_p (jump))
2679 return FALSE;
2680
2681 /* We must be comparing objects whose modes imply the size. */
2682 if (GET_MODE (XEXP (cond, 0)) == BLKmode)
2683 return FALSE;
2684
2685 /* Reverse the comparison code, if necessary. */
2686 code = GET_CODE (cond);
2687 if (then_bb == trap_bb)
2688 {
2689 code = reversed_comparison_code (cond, jump);
2690 if (code == UNKNOWN)
2691 return FALSE;
2692 }
2693
2694 /* Attempt to generate the conditional trap. */
2695 seq = gen_cond_trap (code, XEXP (cond, 0),
2696 XEXP (cond, 1),
2697 TRAP_CODE (PATTERN (trap)));
2698 if (seq == NULL)
2699 return FALSE;
2700
2701 num_true_changes++;
2702
2703 /* Emit the new insns before cond_earliest. */
2704 emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));
2705
2706 /* Delete the trap block if possible. */
2707 remove_edge (trap_bb == then_bb ? then_edge : else_edge);
2708 if (trap_bb->pred == NULL)
2709 delete_basic_block (trap_bb);
2710
2711 /* If the non-trap block and the test are now adjacent, merge them.
2712 Otherwise we must insert a direct branch. */
2713 if (test_bb->next_bb == other_bb)
2714 {
2715 struct ce_if_block new_ce_info;
2716 delete_insn (jump);
2717 memset (&new_ce_info, '\0', sizeof (new_ce_info));
2718 new_ce_info.test_bb = test_bb;
2719 new_ce_info.then_bb = NULL;
2720 new_ce_info.else_bb = NULL;
2721 new_ce_info.join_bb = other_bb;
2722 merge_if_block (&new_ce_info);
2723 }
2724 else
2725 {
2726 rtx lab, newjump;
2727
2728 lab = JUMP_LABEL (jump);
2729 newjump = emit_jump_insn_after (gen_jump (lab), jump);
2730 LABEL_NUSES (lab) += 1;
2731 JUMP_LABEL (newjump) = lab;
2732 emit_barrier_after (newjump);
2733
2734 delete_insn (jump);
2735 }
2736
2737 return TRUE;
2738 }
2739
2740 /* Subroutine of find_cond_trap: if BB contains only a trap insn,
2741 return it. */
2742
2743 static rtx
2744 block_has_only_trap (basic_block bb)
2745 {
2746 rtx trap;
2747
2748 /* We're not the exit block. */
2749 if (bb == EXIT_BLOCK_PTR)
2750 return NULL_RTX;
2751
2752 /* The block must have no successors. */
2753 if (bb->succ)
2754 return NULL_RTX;
2755
2756 /* The only instruction in the THEN block must be the trap. */
2757 trap = first_active_insn (bb);
2758 if (! (trap == BB_END (bb)
2759 && GET_CODE (PATTERN (trap)) == TRAP_IF
2760 && TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
2761 return NULL_RTX;
2762
2763 return trap;
2764 }
2765
2766 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
2767 transformable, but not necessarily the other. There need be no
2768 JOIN block.
2769
2770 Return TRUE if we were successful at converting the block.
2771
2772 Cases we'd like to look at:
2773
2774 (1)
2775 if (test) goto over; // x not live
2776 x = a;
2777 goto label;
2778 over:
2779
2780 becomes
2781
2782 x = a;
2783 if (! test) goto label;
2784
2785 (2)
2786 if (test) goto E; // x not live
2787 x = big();
2788 goto L;
2789 E:
2790 x = b;
2791 goto M;
2792
2793 becomes
2794
2795 x = b;
2796 if (test) goto M;
2797 x = big();
2798 goto L;
2799
2800 (3) // This one's really only interesting for targets that can do
2801 // multiway branching, e.g. IA-64 BBB bundles. For other targets
2802 // it results in multiple branches on a cache line, which often
2803 // does not sit well with predictors.
2804
2805 if (test1) goto E; // predicted not taken
2806 x = a;
2807 if (test2) goto F;
2808 ...
2809 E:
2810 x = b;
2811 J:
2812
2813 becomes
2814
2815 x = a;
2816 if (test1) goto E;
2817 if (test2) goto F;
2818
2819 Notes:
2820
2821 (A) Don't do (2) if the branch is predicted against the block we're
2822 eliminating. Do it anyway if we can eliminate a branch; this requires
2823 that the sole successor of the eliminated block postdominate the other
2824 side of the if.
2825
2826 (B) With CE, on (3) we can steal from both sides of the if, creating
2827
2828 if (test1) x = a;
2829 if (!test1) x = b;
2830 if (test1) goto J;
2831 if (test2) goto F;
2832 ...
2833 J:
2834
2835 Again, this is most useful if J postdominates.
2836
2837 (C) CE substitutes for helpful life information.
2838
2839 (D) These heuristics need a lot of work. */
2840
2841 /* Tests for case 1 above. */
2842
2843 static int
2844 find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
2845 {
2846 basic_block then_bb = then_edge->dest;
2847 basic_block else_bb = else_edge->dest, new_bb;
2848 edge then_succ = then_bb->succ;
2849 int then_bb_index;
2850
2851 /* If we are partitioning hot/cold basic blocks, we don't want to
2852 mess up unconditional or indirect jumps that cross between hot
2853 and cold sections. */
2854
2855 if (flag_reorder_blocks_and_partition
2856 && ((BB_END (then_bb)
2857 && find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
2858 || (BB_END (else_bb)
2859 && find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP,
2860 NULL_RTX))))
2861 return FALSE;
2862
2863 /* THEN has one successor. */
2864 if (!then_succ || then_succ->succ_next != NULL)
2865 return FALSE;
2866
2867 /* THEN does not fall through, but is not strange either. */
2868 if (then_succ->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
2869 return FALSE;
2870
2871 /* THEN has one predecessor. */
2872 if (then_bb->pred->pred_next != NULL)
2873 return FALSE;
2874
2875 /* THEN must do something. */
2876 if (forwarder_block_p (then_bb))
2877 return FALSE;
2878
2879 num_possible_if_blocks++;
2880 if (dump_file)
2881 fprintf (dump_file,
2882 "\nIF-CASE-1 found, start %d, then %d\n",
2883 test_bb->index, then_bb->index);
2884
2885 /* THEN is small. */
2886 if (count_bb_insns (then_bb) > BRANCH_COST)
2887 return FALSE;
2888
2889 /* Registers set are dead, or are predicable. */
2890 if (! dead_or_predicable (test_bb, then_bb, else_bb,
2891 then_bb->succ->dest, 1))
2892 return FALSE;
2893
2894 /* Conversion went ok, including moving the insns and fixing up the
2895 jump. Adjust the CFG to match. */
2896
2897 bitmap_operation (test_bb->global_live_at_end,
2898 else_bb->global_live_at_start,
2899 then_bb->global_live_at_end, BITMAP_IOR);
2900
2901 new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb), else_bb);
2902 then_bb_index = then_bb->index;
2903 delete_basic_block (then_bb);
2904
2905 /* Make rest of code believe that the newly created block is the THEN_BB
2906 block we removed. */
2907 if (new_bb)
2908 {
2909 new_bb->index = then_bb_index;
2910 BASIC_BLOCK (then_bb_index) = new_bb;
2911 }
2912 /* We've possibly created jump to next insn, cleanup_cfg will solve that
2913 later. */
2914
2915 num_true_changes++;
2916 num_updated_if_blocks++;
2917
2918 return TRUE;
2919 }
2920
2921 /* Test for case 2 above. */
2922
2923 static int
2924 find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
2925 {
2926 basic_block then_bb = then_edge->dest;
2927 basic_block else_bb = else_edge->dest;
2928 edge else_succ = else_bb->succ;
2929 rtx note;
2930
2931 /* If we are partitioning hot/cold basic blocks, we don't want to
2932 mess up unconditional or indirect jumps that cross between hot
2933 and cold sections. */
2934
2935 if (flag_reorder_blocks_and_partition
2936 && ((BB_END (then_bb)
2937 && find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
2938 || (BB_END (else_bb)
2939 && find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP,
2940 NULL_RTX))))
2941 return FALSE;
2942
2943 /* ELSE has one successor. */
2944 if (!else_succ || else_succ->succ_next != NULL)
2945 return FALSE;
2946
2947 /* ELSE outgoing edge is not complex. */
2948 if (else_succ->flags & EDGE_COMPLEX)
2949 return FALSE;
2950
2951 /* ELSE has one predecessor. */
2952 if (else_bb->pred->pred_next != NULL)
2953 return FALSE;
2954
2955 /* THEN is not EXIT. */
2956 if (then_bb->index < 0)
2957 return FALSE;
2958
2959 /* ELSE is predicted or SUCC(ELSE) postdominates THEN. */
2960 note = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
2961 if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
2962 ;
2963 else if (else_succ->dest->index < 0
2964 || dominated_by_p (CDI_POST_DOMINATORS, then_bb,
2965 else_succ->dest))
2966 ;
2967 else
2968 return FALSE;
2969
2970 num_possible_if_blocks++;
2971 if (dump_file)
2972 fprintf (dump_file,
2973 "\nIF-CASE-2 found, start %d, else %d\n",
2974 test_bb->index, else_bb->index);
2975
2976 /* ELSE is small. */
2977 if (count_bb_insns (else_bb) > BRANCH_COST)
2978 return FALSE;
2979
2980 /* Registers set are dead, or are predicable. */
2981 if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ->dest, 0))
2982 return FALSE;
2983
2984 /* Conversion went ok, including moving the insns and fixing up the
2985 jump. Adjust the CFG to match. */
2986
2987 bitmap_operation (test_bb->global_live_at_end,
2988 then_bb->global_live_at_start,
2989 else_bb->global_live_at_end, BITMAP_IOR);
2990
2991 delete_basic_block (else_bb);
2992
2993 num_true_changes++;
2994 num_updated_if_blocks++;
2995
2996 /* ??? We may now fallthru from one of THEN's successors into a join
2997 block. Rerun cleanup_cfg? Examine things manually? Wait? */
2998
2999 return TRUE;
3000 }
3001
3002 /* A subroutine of dead_or_predicable called through for_each_rtx.
3003 Return 1 if a memory is found. */
3004
3005 static int
3006 find_memory (rtx *px, void *data ATTRIBUTE_UNUSED)
3007 {
3008 return MEM_P (*px);
3009 }
3010
3011 /* Used by the code above to perform the actual rtl transformations.
3012 Return TRUE if successful.
3013
3014 TEST_BB is the block containing the conditional branch. MERGE_BB
3015 is the block containing the code to manipulate. NEW_DEST is the
3016 label TEST_BB should be branching to after the conversion.
3017 REVERSEP is true if the sense of the branch should be reversed. */
3018
3019 static int
3020 dead_or_predicable (basic_block test_bb, basic_block merge_bb,
3021 basic_block other_bb, basic_block new_dest, int reversep)
3022 {
3023 rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
3024
3025 jump = BB_END (test_bb);
3026
3027 /* Find the extent of the real code in the merge block. */
3028 head = BB_HEAD (merge_bb);
3029 end = BB_END (merge_bb);
3030
3031 if (GET_CODE (head) == CODE_LABEL)
3032 head = NEXT_INSN (head);
3033 if (GET_CODE (head) == NOTE)
3034 {
3035 if (head == end)
3036 {
3037 head = end = NULL_RTX;
3038 goto no_body;
3039 }
3040 head = NEXT_INSN (head);
3041 }
3042
3043 if (GET_CODE (end) == JUMP_INSN)
3044 {
3045 if (head == end)
3046 {
3047 head = end = NULL_RTX;
3048 goto no_body;
3049 }
3050 end = PREV_INSN (end);
3051 }
3052
3053 /* Disable handling dead code by conditional execution if the machine needs
3054 to do anything funny with the tests, etc. */
3055 #ifndef IFCVT_MODIFY_TESTS
3056 if (HAVE_conditional_execution)
3057 {
3058 /* In the conditional execution case, we have things easy. We know
3059 the condition is reversible. We don't have to check life info
3060 because we're going to conditionally execute the code anyway.
3061 All that's left is making sure the insns involved can actually
3062 be predicated. */
3063
3064 rtx cond, prob_val;
3065
3066 cond = cond_exec_get_condition (jump);
3067 if (! cond)
3068 return FALSE;
3069
3070 prob_val = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
3071 if (prob_val)
3072 prob_val = XEXP (prob_val, 0);
3073
3074 if (reversep)
3075 {
3076 enum rtx_code rev = reversed_comparison_code (cond, jump);
3077 if (rev == UNKNOWN)
3078 return FALSE;
3079 cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
3080 XEXP (cond, 1));
3081 if (prob_val)
3082 prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val));
3083 }
3084
3085 if (! cond_exec_process_insns ((ce_if_block_t *)0, head, end, cond,
3086 prob_val, 0))
3087 goto cancel;
3088
3089 earliest = jump;
3090 }
3091 else
3092 #endif
3093 {
3094 /* In the non-conditional execution case, we have to verify that there
3095 are no trapping operations, no calls, no references to memory, and
3096 that any registers modified are dead at the branch site. */
3097
3098 rtx insn, cond, prev;
3099 regset_head merge_set_head, tmp_head, test_live_head, test_set_head;
3100 regset merge_set, tmp, test_live, test_set;
3101 struct propagate_block_info *pbi;
3102 int i, fail = 0;
3103
3104 /* Check for no calls or trapping operations. */
3105 for (insn = head; ; insn = NEXT_INSN (insn))
3106 {
3107 if (GET_CODE (insn) == CALL_INSN)
3108 return FALSE;
3109 if (INSN_P (insn))
3110 {
3111 if (may_trap_p (PATTERN (insn)))
3112 return FALSE;
3113
3114 /* ??? Even non-trapping memories such as stack frame
3115 references must be avoided. For stores, we collect
3116 no lifetime info; for reads, we'd have to assert
3117 true_dependence false against every store in the
3118 TEST range. */
3119 if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
3120 return FALSE;
3121 }
3122 if (insn == end)
3123 break;
3124 }
3125
3126 if (! any_condjump_p (jump))
3127 return FALSE;
3128
3129 /* Find the extent of the conditional. */
3130 cond = noce_get_condition (jump, &earliest);
3131 if (! cond)
3132 return FALSE;
3133
3134 /* Collect:
3135 MERGE_SET = set of registers set in MERGE_BB
3136 TEST_LIVE = set of registers live at EARLIEST
3137 TEST_SET = set of registers set between EARLIEST and the
3138 end of the block. */
3139
3140 tmp = INITIALIZE_REG_SET (tmp_head);
3141 merge_set = INITIALIZE_REG_SET (merge_set_head);
3142 test_live = INITIALIZE_REG_SET (test_live_head);
3143 test_set = INITIALIZE_REG_SET (test_set_head);
3144
3145 /* ??? bb->local_set is only valid during calculate_global_regs_live,
3146 so we must recompute usage for MERGE_BB. Not so bad, I suppose,
3147 since we've already asserted that MERGE_BB is small. */
3148 propagate_block (merge_bb, tmp, merge_set, merge_set, 0);
3149
3150 /* For small register class machines, don't lengthen lifetimes of
3151 hard registers before reload. */
3152 if (SMALL_REGISTER_CLASSES && ! reload_completed)
3153 {
3154 EXECUTE_IF_SET_IN_BITMAP
3155 (merge_set, 0, i,
3156 {
3157 if (i < FIRST_PSEUDO_REGISTER
3158 && ! fixed_regs[i]
3159 && ! global_regs[i])
3160 fail = 1;
3161 });
3162 }
3163
3164 /* For TEST, we're interested in a range of insns, not a whole block.
3165 Moreover, we're interested in the insns live from OTHER_BB. */
3166
3167 COPY_REG_SET (test_live, other_bb->global_live_at_start);
3168 pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set,
3169 0);
3170
3171 for (insn = jump; ; insn = prev)
3172 {
3173 prev = propagate_one_insn (pbi, insn);
3174 if (insn == earliest)
3175 break;
3176 }
3177
3178 free_propagate_block_info (pbi);
3179
3180 /* We can perform the transformation if
3181 MERGE_SET & (TEST_SET | TEST_LIVE)
3182 and
3183 TEST_SET & merge_bb->global_live_at_start
3184 are empty. */
3185
3186 bitmap_operation (tmp, test_set, test_live, BITMAP_IOR);
3187 bitmap_operation (tmp, tmp, merge_set, BITMAP_AND);
3188 EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
3189
3190 bitmap_operation (tmp, test_set, merge_bb->global_live_at_start,
3191 BITMAP_AND);
3192 EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
3193
3194 FREE_REG_SET (tmp);
3195 FREE_REG_SET (merge_set);
3196 FREE_REG_SET (test_live);
3197 FREE_REG_SET (test_set);
3198
3199 if (fail)
3200 return FALSE;
3201 }
3202
3203 no_body:
3204 /* We don't want to use normal invert_jump or redirect_jump because
3205 we don't want to delete_insn called. Also, we want to do our own
3206 change group management. */
3207
3208 old_dest = JUMP_LABEL (jump);
3209 if (other_bb != new_dest)
3210 {
3211 new_label = block_label (new_dest);
3212 if (reversep
3213 ? ! invert_jump_1 (jump, new_label)
3214 : ! redirect_jump_1 (jump, new_label))
3215 goto cancel;
3216 }
3217
3218 if (! apply_change_group ())
3219 return FALSE;
3220
3221 if (other_bb != new_dest)
3222 {
3223 if (old_dest)
3224 LABEL_NUSES (old_dest) -= 1;
3225 if (new_label)
3226 LABEL_NUSES (new_label) += 1;
3227 JUMP_LABEL (jump) = new_label;
3228 if (reversep)
3229 invert_br_probabilities (jump);
3230
3231 redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
3232 if (reversep)
3233 {
3234 gcov_type count, probability;
3235 count = BRANCH_EDGE (test_bb)->count;
3236 BRANCH_EDGE (test_bb)->count = FALLTHRU_EDGE (test_bb)->count;
3237 FALLTHRU_EDGE (test_bb)->count = count;
3238 probability = BRANCH_EDGE (test_bb)->probability;
3239 BRANCH_EDGE (test_bb)->probability
3240 = FALLTHRU_EDGE (test_bb)->probability;
3241 FALLTHRU_EDGE (test_bb)->probability = probability;
3242 update_br_prob_note (test_bb);
3243 }
3244 }
3245
3246 /* Move the insns out of MERGE_BB to before the branch. */
3247 if (head != NULL)
3248 {
3249 if (end == BB_END (merge_bb))
3250 BB_END (merge_bb) = PREV_INSN (head);
3251
3252 if (squeeze_notes (&head, &end))
3253 return TRUE;
3254
3255 reorder_insns (head, end, PREV_INSN (earliest));
3256 }
3257
3258 /* Remove the jump and edge if we can. */
3259 if (other_bb == new_dest)
3260 {
3261 delete_insn (jump);
3262 remove_edge (BRANCH_EDGE (test_bb));
3263 /* ??? Can't merge blocks here, as then_bb is still in use.
3264 At minimum, the merge will get done just before bb-reorder. */
3265 }
3266
3267 return TRUE;
3268
3269 cancel:
3270 cancel_changes (0);
3271 return FALSE;
3272 }
3273 \f
3274 /* Main entry point for all if-conversion. */
3275
3276 void
3277 if_convert (int x_life_data_ok)
3278 {
3279 basic_block bb;
3280 int pass;
3281
3282 num_possible_if_blocks = 0;
3283 num_updated_if_blocks = 0;
3284 num_true_changes = 0;
3285 life_data_ok = (x_life_data_ok != 0);
3286
3287 if ((! targetm.cannot_modify_jumps_p ())
3288 && (!flag_reorder_blocks_and_partition || !no_new_pseudos))
3289 mark_loop_exit_edges ();
3290
3291 /* Compute postdominators if we think we'll use them. */
3292 if (HAVE_conditional_execution || life_data_ok)
3293 calculate_dominance_info (CDI_POST_DOMINATORS);
3294
3295 if (life_data_ok)
3296 clear_bb_flags ();
3297
3298 /* Go through each of the basic blocks looking for things to convert. If we
3299 have conditional execution, we make multiple passes to allow us to handle
3300 IF-THEN{-ELSE} blocks within other IF-THEN{-ELSE} blocks. */
3301 pass = 0;
3302 do
3303 {
3304 cond_exec_changed_p = FALSE;
3305 pass++;
3306
3307 #ifdef IFCVT_MULTIPLE_DUMPS
3308 if (dump_file && pass > 1)
3309 fprintf (dump_file, "\n\n========== Pass %d ==========\n", pass);
3310 #endif
3311
3312 FOR_EACH_BB (bb)
3313 {
3314 basic_block new_bb;
3315 while ((new_bb = find_if_header (bb, pass)))
3316 bb = new_bb;
3317 }
3318
3319 #ifdef IFCVT_MULTIPLE_DUMPS
3320 if (dump_file && cond_exec_changed_p)
3321 print_rtl_with_bb (dump_file, get_insns ());
3322 #endif
3323 }
3324 while (cond_exec_changed_p);
3325
3326 #ifdef IFCVT_MULTIPLE_DUMPS
3327 if (dump_file)
3328 fprintf (dump_file, "\n\n========== no more changes\n");
3329 #endif
3330
3331 free_dominance_info (CDI_POST_DOMINATORS);
3332
3333 if (dump_file)
3334 fflush (dump_file);
3335
3336 clear_aux_for_blocks ();
3337
3338 /* Rebuild life info for basic blocks that require it. */
3339 if (num_true_changes && life_data_ok)
3340 {
3341 /* If we allocated new pseudos, we must resize the array for sched1. */
3342 if (max_regno < max_reg_num ())
3343 {
3344 max_regno = max_reg_num ();
3345 allocate_reg_info (max_regno, FALSE, FALSE);
3346 }
3347 update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
3348 PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
3349 | PROP_KILL_DEAD_CODE);
3350 }
3351
3352 /* Write the final stats. */
3353 if (dump_file && num_possible_if_blocks > 0)
3354 {
3355 fprintf (dump_file,
3356 "\n%d possible IF blocks searched.\n",
3357 num_possible_if_blocks);
3358 fprintf (dump_file,
3359 "%d IF blocks converted.\n",
3360 num_updated_if_blocks);
3361 fprintf (dump_file,
3362 "%d true changes made.\n\n\n",
3363 num_true_changes);
3364 }
3365
3366 #ifdef ENABLE_CHECKING
3367 verify_flow_info ();
3368 #endif
3369 }