OSDN Git Service

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