OSDN Git Service

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