OSDN Git Service

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