OSDN Git Service

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