OSDN Git Service

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