OSDN Git Service

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