OSDN Git Service

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