OSDN Git Service

* alias.c (set_mem_alias_set): New function.
[pf3gnuchains/gcc-fork.git] / gcc / ifcvt.c
1 /* If-conversion support.
2    Copyright (C) 2000 Free Software Foundation, Inc.
3
4    This file is part of GNU CC.
5
6    GNU CC is free software; you can redistribute it and/or modify
7    it 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    GNU CC is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GNU CC; see the file COPYING.  If not, write to
18    the Free Software Foundation, 59 Temple Place - Suite 330,
19    Boston, MA 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 "hard-reg-set.h"
31 #include "basic-block.h"
32 #include "expr.h"
33 #include "real.h"
34 #include "output.h"
35 #include "toplev.h"
36 #include "tm_p.h"
37
38
39 #ifndef HAVE_conditional_execution
40 #define HAVE_conditional_execution 0
41 #endif
42 #ifndef HAVE_conditional_move
43 #define HAVE_conditional_move 0
44 #endif
45 #ifndef HAVE_incscc
46 #define HAVE_incscc 0
47 #endif
48 #ifndef HAVE_decscc
49 #define HAVE_decscc 0
50 #endif
51
52 #ifndef MAX_CONDITIONAL_EXECUTE
53 #define MAX_CONDITIONAL_EXECUTE   (BRANCH_COST + 1)
54 #endif
55
56 #define NULL_EDGE       ((struct edge_def *)NULL)
57 #define NULL_BLOCK      ((struct basic_block_def *)NULL)
58
59 /* # of IF-THEN or IF-THEN-ELSE blocks we looked at  */
60 static int num_possible_if_blocks;
61
62 /* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
63    execution.  */
64 static int num_updated_if_blocks;
65
66 /* # of basic blocks that were removed.  */
67 static int num_removed_blocks;
68
69 /* True if life data ok at present.  */
70 static bool life_data_ok;
71
72 /* The post-dominator relation on the original block numbers.  */
73 static sbitmap *post_dominators;
74
75 /* Forward references.  */
76 static int count_bb_insns               PARAMS ((basic_block));
77 static rtx first_active_insn            PARAMS ((basic_block));
78 static int last_active_insn_p           PARAMS ((basic_block, rtx));
79 static int seq_contains_jump            PARAMS ((rtx));
80
81 static int cond_exec_process_insns      PARAMS ((rtx, rtx, rtx, rtx, int));
82 static rtx cond_exec_get_condition      PARAMS ((rtx));
83 static int cond_exec_process_if_block   PARAMS ((basic_block, basic_block,
84                                                  basic_block, basic_block));
85
86 static rtx noce_get_condition           PARAMS ((rtx, rtx *));
87 static int noce_operand_ok              PARAMS ((rtx));
88 static int noce_process_if_block        PARAMS ((basic_block, basic_block,
89                                                  basic_block, basic_block));
90
91 static int process_if_block             PARAMS ((basic_block, basic_block,
92                                                  basic_block, basic_block));
93 static void merge_if_block              PARAMS ((basic_block, basic_block,
94                                                  basic_block, basic_block));
95
96 static int find_if_header               PARAMS ((basic_block));
97 static int find_if_block                PARAMS ((basic_block, edge, edge));
98 static int find_if_case_1               PARAMS ((basic_block, edge, edge));
99 static int find_if_case_2               PARAMS ((basic_block, edge, edge));
100 static int find_memory                  PARAMS ((rtx *, void *));
101 static int dead_or_predicable           PARAMS ((basic_block, basic_block,
102                                                  basic_block, rtx, int));
103 static void noce_emit_move_insn         PARAMS ((rtx, rtx));
104 \f
105 /* Abuse the basic_block AUX field to store the original block index,
106    as well as a flag indicating that the block should be rescaned for
107    life analysis.  */
108
109 #define SET_ORIG_INDEX(BB,I)    ((BB)->aux = (void *)((size_t)(I) << 1))
110 #define ORIG_INDEX(BB)          ((size_t)(BB)->aux >> 1)
111 #define SET_UPDATE_LIFE(BB)     ((BB)->aux = (void *)((size_t)(BB)->aux | 1))
112 #define UPDATE_LIFE(BB)         ((size_t)(BB)->aux & 1)
113
114 \f
115 /* Count the number of non-jump active insns in BB.  */
116
117 static int
118 count_bb_insns (bb)
119      basic_block bb;
120 {
121   int count = 0;
122   rtx insn = bb->head;
123
124   while (1)
125     {
126       if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
127         count++;
128
129       if (insn == bb->end)
130         break;
131       insn = NEXT_INSN (insn);
132     }
133
134   return count;
135 }
136
137 /* Return the first non-jump active insn in the basic block.  */
138
139 static rtx
140 first_active_insn (bb)
141      basic_block bb;
142 {
143   rtx insn = bb->head;
144
145   if (GET_CODE (insn) == CODE_LABEL)
146     {
147       if (insn == bb->end)
148         return NULL_RTX;
149       insn = NEXT_INSN (insn);
150     }
151
152   while (GET_CODE (insn) == NOTE)
153     {
154       if (insn == bb->end)
155         return NULL_RTX;
156       insn = NEXT_INSN (insn);
157     }
158
159   if (GET_CODE (insn) == JUMP_INSN)
160     return NULL_RTX;
161
162   return insn;
163 }
164
165 /* Return true if INSN is the last active non-jump insn in BB.  */
166
167 static int
168 last_active_insn_p (bb, insn)
169      basic_block bb;
170      rtx insn;
171 {
172   do
173     {
174       if (insn == bb->end)
175         return TRUE;
176       insn = NEXT_INSN (insn);
177     }
178   while (GET_CODE (insn) == NOTE);
179
180   return GET_CODE (insn) == JUMP_INSN;
181 }
182
183 /* It is possible, especially when having dealt with multi-word 
184    arithmetic, for the expanders to have emitted jumps.  Search
185    through the sequence and return TRUE if a jump exists so that
186    we can abort the conversion.  */
187
188 static int
189 seq_contains_jump (insn)
190      rtx insn;
191 {
192   while (insn)
193     {
194       if (GET_CODE (insn) == JUMP_INSN)
195         return 1;
196       insn = NEXT_INSN (insn);
197     }
198   return 0;
199 }
200 \f
201 /* Go through a bunch of insns, converting them to conditional
202    execution format if possible.  Return TRUE if all of the non-note
203    insns were processed.  */
204
205 static int
206 cond_exec_process_insns (start, end, test, prob_val, mod_ok)
207      rtx start;                 /* first insn to look at */
208      rtx end;                   /* last insn to look at */
209      rtx test;                  /* conditional execution test */
210      rtx prob_val;              /* probability of branch taken.  */
211      int mod_ok;                /* true if modifications ok last insn.  */
212 {
213   int must_be_last = FALSE;
214   rtx insn;
215   rtx pattern;
216
217   for (insn = start; ; insn = NEXT_INSN (insn))
218     {
219       if (GET_CODE (insn) == NOTE)
220         goto insn_done;
221
222       if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
223         abort ();
224
225       /* Remove USE insns that get in the way.  */
226       if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
227         {
228           /* ??? Ug.  Actually unlinking the thing is problematic, 
229              given what we'd have to coordinate with our callers.  */
230           PUT_CODE (insn, NOTE);
231           NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
232           NOTE_SOURCE_FILE (insn) = 0;
233           goto insn_done;
234         }
235
236       /* Last insn wasn't last?  */
237       if (must_be_last)
238         return FALSE;
239
240       if (modified_in_p (test, insn))
241         {
242           if (!mod_ok)
243             return FALSE;
244           must_be_last = TRUE;
245         }
246
247       /* Now build the conditional form of the instruction.  */
248       pattern = PATTERN (insn);
249
250       /* If the machine needs to modify the insn being conditionally executed,
251          say for example to force a constant integer operand into a temp
252          register, do so here.  */
253 #ifdef IFCVT_MODIFY_INSN
254       IFCVT_MODIFY_INSN (pattern, insn);
255       if (! pattern)
256         return FALSE;
257 #endif
258
259       validate_change (insn, &PATTERN (insn),
260                        gen_rtx_COND_EXEC (VOIDmode, copy_rtx (test),
261                                           pattern), 1);
262
263       if (GET_CODE (insn) == CALL_INSN && prob_val)
264         validate_change (insn, &REG_NOTES (insn),
265                          alloc_EXPR_LIST (REG_BR_PROB, prob_val,
266                                           REG_NOTES (insn)), 1);
267
268     insn_done:
269       if (insn == end)
270         break;
271     }
272
273   return TRUE;
274 }
275
276 /* Return the condition for a jump.  Do not do any special processing.  */
277
278 static rtx
279 cond_exec_get_condition (jump)
280      rtx jump;
281 {
282   rtx test_if, cond;
283
284   if (any_condjump_p (jump))
285     test_if = SET_SRC (pc_set (jump));
286   else
287     return NULL_RTX;
288   cond = XEXP (test_if, 0);
289
290   /* If this branches to JUMP_LABEL when the condition is false,
291      reverse the condition.  */
292   if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
293       && XEXP (XEXP (test_if, 2), 0) == JUMP_LABEL (jump))
294     {
295       enum rtx_code rev = reversed_comparison_code (cond, jump);
296       if (rev == UNKNOWN)
297         return NULL_RTX;
298
299       cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
300                              XEXP (cond, 1));
301     }
302
303   return cond;
304 }
305
306 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
307    to conditional execution.  Return TRUE if we were successful at
308    converting the the block.  */
309
310 static int
311 cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb)
312      basic_block test_bb;       /* Basic block test is in */
313      basic_block then_bb;       /* Basic block for THEN block */
314      basic_block else_bb;       /* Basic block for ELSE block */
315      basic_block join_bb;       /* Basic block the join label is in */
316 {
317   rtx test_expr;                /* expression in IF_THEN_ELSE that is tested */
318   rtx then_start;               /* first insn in THEN block */
319   rtx then_end;                 /* last insn + 1 in THEN block */
320   rtx else_start = NULL_RTX;    /* first insn in ELSE block or NULL */
321   rtx else_end = NULL_RTX;      /* last insn + 1 in ELSE block */
322   int max;                      /* max # of insns to convert. */
323   int then_mod_ok;              /* whether conditional mods are ok in THEN */
324   rtx true_expr;                /* test for else block insns */
325   rtx false_expr;               /* test for then block insns */
326   rtx true_prob_val;            /* probability of else block */
327   rtx false_prob_val;           /* probability of then block */
328   int n_insns;
329   enum rtx_code false_code;
330
331   /* Find the conditional jump to the ELSE or JOIN part, and isolate
332      the test.  */
333   test_expr = cond_exec_get_condition (test_bb->end);
334   if (! test_expr)
335     return FALSE;
336
337   /* If the conditional jump is more than just a conditional jump,
338      then we can not do conditional execution conversion on this block.  */
339   if (!onlyjump_p (test_bb->end))
340     return FALSE;
341
342   /* Collect the bounds of where we're to search.  */
343
344   then_start = then_bb->head;
345   then_end = then_bb->end;
346
347   /* Skip a label heading THEN block.  */
348   if (GET_CODE (then_start) == CODE_LABEL)
349     then_start = NEXT_INSN (then_start);
350
351   /* Skip a (use (const_int 0)) or branch as the final insn.  */
352   if (GET_CODE (then_end) == INSN
353       && GET_CODE (PATTERN (then_end)) == USE
354       && GET_CODE (XEXP (PATTERN (then_end), 0)) == CONST_INT)
355     then_end = PREV_INSN (then_end);
356   else if (GET_CODE (then_end) == JUMP_INSN)
357     then_end = PREV_INSN (then_end);
358
359   if (else_bb)
360     {
361       /* Skip the ELSE block's label.  */
362       else_start = NEXT_INSN (else_bb->head);
363       else_end = else_bb->end;
364
365       /* Skip a (use (const_int 0)) or branch as the final insn.  */
366       if (GET_CODE (else_end) == INSN
367           && GET_CODE (PATTERN (else_end)) == USE
368           && GET_CODE (XEXP (PATTERN (else_end), 0)) == CONST_INT)
369         else_end = PREV_INSN (else_end);
370       else if (GET_CODE (else_end) == JUMP_INSN)
371         else_end = PREV_INSN (else_end);
372     }
373
374   /* How many instructions should we convert in total?  */
375   n_insns = 0;
376   if (else_bb)
377     {
378       max = 2 * MAX_CONDITIONAL_EXECUTE;
379       n_insns = count_bb_insns (else_bb);
380     }
381   else
382     max = MAX_CONDITIONAL_EXECUTE;
383   n_insns += count_bb_insns (then_bb);
384   if (n_insns > max)
385     return FALSE;
386
387   /* Map test_expr/test_jump into the appropriate MD tests to use on
388      the conditionally executed code.  */
389   
390   true_expr = test_expr;
391
392   false_code = reversed_comparison_code (true_expr, test_bb->end);
393   if (false_code != UNKNOWN)
394     false_expr = gen_rtx_fmt_ee (false_code, GET_MODE (true_expr),
395                                  XEXP (true_expr, 0), XEXP (true_expr, 1));
396   else
397     false_expr = NULL_RTX;
398
399 #ifdef IFCVT_MODIFY_TESTS
400   /* If the machine description needs to modify the tests, such as setting a
401      conditional execution register from a comparison, it can do so here.  */
402   IFCVT_MODIFY_TESTS (true_expr, false_expr, test_bb, then_bb, else_bb,
403                       join_bb);
404
405   /* See if the conversion failed */
406   if (!true_expr || !false_expr)
407     goto fail;
408 #endif
409
410   true_prob_val = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
411   if (true_prob_val)
412     {
413       true_prob_val = XEXP (true_prob_val, 0);
414       false_prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (true_prob_val));
415     }
416   else
417     false_prob_val = NULL_RTX;
418
419   /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
420      on then THEN block.  */
421   then_mod_ok = (else_bb == NULL_BLOCK);
422
423   /* Go through the THEN and ELSE blocks converting the insns if possible
424      to conditional execution.  */
425
426   if (then_end
427       && (! false_expr
428           || ! cond_exec_process_insns (then_start, then_end, false_expr,
429                                         false_prob_val, then_mod_ok)))
430     goto fail;
431
432   if (else_bb
433       && ! cond_exec_process_insns (else_start, else_end,
434                                     true_expr, true_prob_val, TRUE))
435     goto fail;
436
437   if (! apply_change_group ())
438     return FALSE;
439
440 #ifdef IFCVT_MODIFY_FINAL
441   /* Do any machine dependent final modifications */
442   IFCVT_MODIFY_FINAL (test_bb, then_bb, else_bb, join_bb);
443 #endif
444
445   /* Conversion succeeded.  */
446   if (rtl_dump_file)
447     fprintf (rtl_dump_file, "%d insn%s converted to conditional execution.\n",
448              n_insns, (n_insns == 1) ? " was" : "s were");
449
450   /* Merge the blocks!  */
451   merge_if_block (test_bb, then_bb, else_bb, join_bb);
452   return TRUE;
453
454  fail:
455 #ifdef IFCVT_MODIFY_CANCEL
456   /* Cancel any machine dependent changes.  */
457   IFCVT_MODIFY_CANCEL (test_bb, then_bb, else_bb, join_bb);
458 #endif
459
460   cancel_changes (0);
461   return FALSE;
462 }
463 \f
464 /* Used by noce_process_if_block to communicate with its subroutines. 
465
466    The subroutines know that A and B may be evaluated freely.  They
467    know that X is a register.  They should insert new instructions 
468    before cond_earliest.  */
469
470 struct noce_if_info
471 {
472   basic_block test_bb;
473   rtx insn_a, insn_b;
474   rtx x, a, b;
475   rtx jump, cond, cond_earliest;
476 };
477
478 static rtx noce_emit_store_flag         PARAMS ((struct noce_if_info *,
479                                                  rtx, int, int));
480 static int noce_try_store_flag          PARAMS ((struct noce_if_info *));
481 static int noce_try_store_flag_inc      PARAMS ((struct noce_if_info *));
482 static int noce_try_store_flag_constants PARAMS ((struct noce_if_info *));
483 static int noce_try_store_flag_mask     PARAMS ((struct noce_if_info *));
484 static rtx noce_emit_cmove              PARAMS ((struct noce_if_info *,
485                                                  rtx, enum rtx_code, rtx,
486                                                  rtx, rtx, rtx));
487 static int noce_try_cmove               PARAMS ((struct noce_if_info *));
488 static int noce_try_cmove_arith         PARAMS ((struct noce_if_info *));
489 static rtx noce_get_alt_condition       PARAMS ((struct noce_if_info *,
490                                                  rtx, rtx *));
491 static int noce_try_minmax              PARAMS ((struct noce_if_info *));
492 static int noce_try_abs                 PARAMS ((struct noce_if_info *));
493
494 /* Helper function for noce_try_store_flag*.  */
495
496 static rtx
497 noce_emit_store_flag (if_info, x, reversep, normalize)
498      struct noce_if_info *if_info;
499      rtx x;
500      int reversep, normalize;
501 {
502   rtx cond = if_info->cond;
503   int cond_complex;
504   enum rtx_code code;
505
506   cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode)
507                   || ! general_operand (XEXP (cond, 1), VOIDmode));
508
509   /* If earliest == jump, or when the condition is complex, try to
510      build the store_flag insn directly.  */
511
512   if (cond_complex)
513     cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0);
514
515   if (reversep)
516     code = reversed_comparison_code (cond, if_info->jump);
517   else
518     code = GET_CODE (cond);
519
520   if ((if_info->cond_earliest == if_info->jump || cond_complex)
521       && (normalize == 0 || STORE_FLAG_VALUE == normalize))
522     {
523       rtx tmp;
524
525       tmp = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
526                             XEXP (cond, 1));
527       tmp = gen_rtx_SET (VOIDmode, x, tmp);
528
529       start_sequence ();
530       tmp = emit_insn (tmp);
531
532       if (recog_memoized (tmp) >= 0)
533         {
534           tmp = get_insns ();
535           end_sequence ();
536           emit_insns (tmp);
537
538           if_info->cond_earliest = if_info->jump;
539
540           return x;
541         }
542
543       end_sequence ();
544     }
545
546   /* Don't even try if the comparison operands are weird.  */
547   if (cond_complex)
548     return NULL_RTX;
549
550   return emit_store_flag (x, code, XEXP (cond, 0),
551                           XEXP (cond, 1), VOIDmode,
552                           (code == LTU || code == LEU
553                            || code == GEU || code == GTU), normalize);
554 }
555
556 /* Emit instruction to move a rtx into STRICT_LOW_PART.  */
557 static void
558 noce_emit_move_insn (x, y)
559      rtx x, y;
560 {
561   enum machine_mode outmode, inmode;
562   rtx outer, inner;
563   int bitpos;
564
565   if (GET_CODE (x) != STRICT_LOW_PART)
566     {
567       emit_move_insn (x, y);
568       return;
569     }
570
571   outer = XEXP (x, 0);
572   inner = XEXP (outer, 0);
573   outmode = GET_MODE (outer);
574   inmode = GET_MODE (inner);
575   bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
576   store_bit_field (inner, GET_MODE_BITSIZE (outmode),
577                    bitpos, outmode, y, GET_MODE_BITSIZE (inmode),
578                    GET_MODE_BITSIZE (inmode));
579 }
580
581 /* Convert "if (test) x = 1; else x = 0".
582
583    Only try 0 and STORE_FLAG_VALUE here.  Other combinations will be
584    tried in noce_try_store_flag_constants after noce_try_cmove has had
585    a go at the conversion.  */
586
587 static int
588 noce_try_store_flag (if_info)
589      struct noce_if_info *if_info;
590 {
591   int reversep;
592   rtx target, seq;
593
594   if (GET_CODE (if_info->b) == CONST_INT
595       && INTVAL (if_info->b) == STORE_FLAG_VALUE
596       && if_info->a == const0_rtx)
597     reversep = 0;
598   else if (if_info->b == const0_rtx
599            && GET_CODE (if_info->a) == CONST_INT
600            && INTVAL (if_info->a) == STORE_FLAG_VALUE
601            && (reversed_comparison_code (if_info->cond, if_info->jump)
602                != UNKNOWN))
603     reversep = 1;
604   else
605     return FALSE;
606
607   start_sequence ();
608
609   target = noce_emit_store_flag (if_info, if_info->x, reversep, 0);
610   if (target)
611     {
612       if (target != if_info->x)
613         noce_emit_move_insn (if_info->x, target);
614
615       seq = get_insns ();
616       end_sequence ();
617       emit_insns_before (seq, if_info->cond_earliest);
618
619       return TRUE;
620     }
621   else
622     {
623       end_sequence ();
624       return FALSE;
625     }
626 }
627
628 /* Convert "if (test) x = a; else x = b", for A and B constant.  */
629
630 static int
631 noce_try_store_flag_constants (if_info)
632      struct noce_if_info *if_info;
633 {
634   rtx target, seq;
635   int reversep;
636   HOST_WIDE_INT itrue, ifalse, diff, tmp;
637   int normalize, can_reverse;
638
639   if (! no_new_pseudos
640       && GET_CODE (if_info->a) == CONST_INT
641       && GET_CODE (if_info->b) == CONST_INT)
642     {
643       ifalse = INTVAL (if_info->a);
644       itrue = INTVAL (if_info->b);
645       diff = itrue - ifalse;
646
647       can_reverse = (reversed_comparison_code (if_info->cond, if_info->jump)
648                      != UNKNOWN);
649
650       reversep = 0;
651       if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
652         normalize = 0;
653       else if (ifalse == 0 && exact_log2 (itrue) >= 0
654                && (STORE_FLAG_VALUE == 1
655                    || BRANCH_COST >= 2))
656         normalize = 1;
657       else if (itrue == 0 && exact_log2 (ifalse) >= 0 && can_reverse
658                && (STORE_FLAG_VALUE == 1 || BRANCH_COST >= 2))
659         normalize = 1, reversep = 1;
660       else if (itrue == -1
661                && (STORE_FLAG_VALUE == -1
662                    || BRANCH_COST >= 2))
663         normalize = -1;
664       else if (ifalse == -1 && can_reverse
665                && (STORE_FLAG_VALUE == -1 || BRANCH_COST >= 2))
666         normalize = -1, reversep = 1;
667       else if ((BRANCH_COST >= 2 && STORE_FLAG_VALUE == -1)
668                || BRANCH_COST >= 3)
669         normalize = -1;
670       else
671         return FALSE;
672
673       if (reversep)
674         {
675           tmp = itrue; itrue = ifalse; ifalse = tmp;
676           diff = -diff;
677         }
678
679       start_sequence ();
680       target = noce_emit_store_flag (if_info, if_info->x, reversep, normalize);
681       if (! target)
682         {
683           end_sequence ();
684           return FALSE;
685         }
686
687       /* if (test) x = 3; else x = 4;
688          =>   x = 3 + (test == 0);  */
689       if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
690         {
691           target = expand_binop (GET_MODE (if_info->x),
692                                  (diff == STORE_FLAG_VALUE
693                                   ? add_optab : sub_optab),
694                                  GEN_INT (ifalse), target, if_info->x, 0,
695                                  OPTAB_WIDEN);
696         }
697
698       /* if (test) x = 8; else x = 0;
699          =>   x = (test != 0) << 3;  */
700       else if (ifalse == 0 && (tmp = exact_log2 (itrue)) >= 0)
701         {
702           target = expand_binop (GET_MODE (if_info->x), ashl_optab,
703                                  target, GEN_INT (tmp), if_info->x, 0,
704                                  OPTAB_WIDEN);
705         }
706
707       /* if (test) x = -1; else x = b;
708          =>   x = -(test != 0) | b;  */
709       else if (itrue == -1)
710         {
711           target = expand_binop (GET_MODE (if_info->x), ior_optab,
712                                  target, GEN_INT (ifalse), if_info->x, 0,
713                                  OPTAB_WIDEN);
714         }
715
716       /* if (test) x = a; else x = b;
717          =>   x = (-(test != 0) & (b - a)) + a;  */
718       else
719         {
720           target = expand_binop (GET_MODE (if_info->x), and_optab,
721                                  target, GEN_INT (diff), if_info->x, 0,
722                                  OPTAB_WIDEN);
723           if (target)
724             target = expand_binop (GET_MODE (if_info->x), add_optab,
725                                    target, GEN_INT (ifalse), if_info->x, 0,
726                                    OPTAB_WIDEN);
727         }
728
729       if (! target)
730         {
731           end_sequence ();
732           return FALSE;
733         }
734
735       if (target != if_info->x)
736         noce_emit_move_insn (if_info->x, target);
737
738       seq = get_insns ();
739       end_sequence ();
740
741       if (seq_contains_jump (seq))
742         return FALSE;
743
744       emit_insns_before (seq, if_info->cond_earliest);
745
746       return TRUE;
747     }
748
749   return FALSE;
750 }
751
752 /* Convert "if (test) foo++" into "foo += (test != 0)", and 
753    similarly for "foo--".  */
754
755 static int
756 noce_try_store_flag_inc (if_info)
757      struct noce_if_info *if_info;
758 {
759   rtx target, seq;
760   int subtract, normalize;
761
762   if (! no_new_pseudos
763       && (BRANCH_COST >= 2
764           || HAVE_incscc
765           || HAVE_decscc)
766       /* Should be no `else' case to worry about.  */
767       && if_info->b == if_info->x
768       && GET_CODE (if_info->a) == PLUS
769       && (XEXP (if_info->a, 1) == const1_rtx
770           || XEXP (if_info->a, 1) == constm1_rtx)
771       && rtx_equal_p (XEXP (if_info->a, 0), if_info->x)
772       && (reversed_comparison_code (if_info->cond, if_info->jump)
773           != UNKNOWN))
774     {
775       if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
776         subtract = 0, normalize = 0;
777       else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
778         subtract = 1, normalize = 0;
779       else
780         subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
781       
782       start_sequence ();
783
784       target = noce_emit_store_flag (if_info,
785                                      gen_reg_rtx (GET_MODE (if_info->x)),
786                                      1, normalize);
787
788       if (target)
789         target = expand_binop (GET_MODE (if_info->x),
790                                subtract ? sub_optab : add_optab,
791                                if_info->x, target, if_info->x, 0, OPTAB_WIDEN);
792       if (target)
793         {
794           if (target != if_info->x)
795             noce_emit_move_insn (if_info->x, target);
796
797           seq = get_insns ();
798           end_sequence ();
799
800           if (seq_contains_jump (seq))
801             return FALSE;
802
803           emit_insns_before (seq, if_info->cond_earliest);
804
805           return TRUE;
806         }
807
808       end_sequence ();
809     }
810
811   return FALSE;
812 }
813
814 /* Convert "if (test) x = 0;" to "x &= -(test == 0);"  */
815
816 static int
817 noce_try_store_flag_mask (if_info)
818      struct noce_if_info *if_info;
819 {
820   rtx target, seq;
821   int reversep;
822
823   reversep = 0;
824   if (! no_new_pseudos
825       && (BRANCH_COST >= 2
826           || STORE_FLAG_VALUE == -1)
827       && ((if_info->a == const0_rtx
828            && rtx_equal_p (if_info->b, if_info->x))
829           || ((reversep = (reversed_comparison_code (if_info->cond,
830                                                      if_info->jump)
831                            != UNKNOWN))
832               && if_info->b == const0_rtx
833               && rtx_equal_p (if_info->a, if_info->x))))
834     {
835       start_sequence ();
836       target = noce_emit_store_flag (if_info,
837                                      gen_reg_rtx (GET_MODE (if_info->x)),
838                                      reversep, -1);
839       if (target)
840         target = expand_binop (GET_MODE (if_info->x), and_optab,
841                                if_info->x, target, if_info->x, 0,
842                                OPTAB_WIDEN);
843
844       if (target)
845         {
846           if (target != if_info->x)
847             noce_emit_move_insn (if_info->x, target);
848
849           seq = get_insns ();
850           end_sequence ();
851
852           if (seq_contains_jump (seq))
853             return FALSE;
854
855           emit_insns_before (seq, if_info->cond_earliest);
856
857           return TRUE;
858         }
859
860       end_sequence ();
861     }
862
863   return FALSE;
864 }
865
866 /* Helper function for noce_try_cmove and noce_try_cmove_arith.  */
867
868 static rtx
869 noce_emit_cmove (if_info, x, code, cmp_a, cmp_b, vfalse, vtrue)
870      struct noce_if_info *if_info;
871      rtx x, cmp_a, cmp_b, vfalse, vtrue;
872      enum rtx_code code;
873 {
874   /* If earliest == jump, try to build the cmove insn directly.
875      This is helpful when combine has created some complex condition
876      (like for alpha's cmovlbs) that we can't hope to regenerate
877      through the normal interface.  */
878
879   if (if_info->cond_earliest == if_info->jump)
880     {
881       rtx tmp;
882
883       tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
884       tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
885       tmp = gen_rtx_SET (VOIDmode, x, tmp);
886
887       start_sequence ();
888       tmp = emit_insn (tmp);
889
890       if (recog_memoized (tmp) >= 0)
891         {
892           tmp = get_insns ();
893           end_sequence ();
894           emit_insns (tmp);
895
896           return x;
897         }
898
899       end_sequence ();
900     }
901
902   /* Don't even try if the comparison operands are weird.  */
903   if (! general_operand (cmp_a, GET_MODE (cmp_a))
904       || ! general_operand (cmp_b, GET_MODE (cmp_b)))
905     return NULL_RTX;
906
907 #if HAVE_conditional_move
908   return emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
909                                 vtrue, vfalse, GET_MODE (x),
910                                 (code == LTU || code == GEU
911                                  || code == LEU || code == GTU));
912 #else
913   /* We'll never get here, as noce_process_if_block doesn't call the
914      functions involved.  Ifdef code, however, should be discouraged
915      because it leads to typos in the code not selected.  However, 
916      emit_conditional_move won't exist either.  */
917   return NULL_RTX;
918 #endif
919 }
920
921 /* Try only simple constants and registers here.  More complex cases
922    are handled in noce_try_cmove_arith after noce_try_store_flag_arith
923    has had a go at it.  */
924
925 static int
926 noce_try_cmove (if_info)
927      struct noce_if_info *if_info;
928 {
929   enum rtx_code code;
930   rtx target, seq;
931
932   if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode))
933       && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode)))
934     {
935       start_sequence ();
936
937       code = GET_CODE (if_info->cond);
938       target = noce_emit_cmove (if_info, if_info->x, code,
939                                 XEXP (if_info->cond, 0),
940                                 XEXP (if_info->cond, 1),
941                                 if_info->a, if_info->b);
942
943       if (target)
944         {
945           if (target != if_info->x)
946             noce_emit_move_insn (if_info->x, target);
947
948           seq = get_insns ();
949           end_sequence ();
950           emit_insns_before (seq, if_info->cond_earliest);
951           return TRUE;
952         }
953       else
954         {
955           end_sequence ();
956           return FALSE;
957         }
958     }
959
960   return FALSE;
961 }
962
963 /* Try more complex cases involving conditional_move.  */
964
965 static int
966 noce_try_cmove_arith (if_info)
967      struct noce_if_info *if_info;
968 {
969   rtx a = if_info->a;
970   rtx b = if_info->b;
971   rtx x = if_info->x;
972   rtx insn_a, insn_b;
973   rtx tmp, target;
974   int is_mem = 0;
975   enum rtx_code code;
976
977   /* A conditional move from two memory sources is equivalent to a
978      conditional on their addresses followed by a load.  Don't do this
979      early because it'll screw alias analysis.  Note that we've
980      already checked for no side effects.  */
981   if (! no_new_pseudos && cse_not_expected
982       && GET_CODE (a) == MEM && GET_CODE (b) == MEM
983       && BRANCH_COST >= 5)
984     {
985       a = XEXP (a, 0);
986       b = XEXP (b, 0);
987       x = gen_reg_rtx (Pmode);
988       is_mem = 1;
989     }
990
991   /* ??? We could handle this if we knew that a load from A or B could
992      not fault.  This is also true if we've already loaded
993      from the address along the path from ENTRY.  */
994   else if (may_trap_p (a) || may_trap_p (b))
995     return FALSE;
996
997   /* if (test) x = a + b; else x = c - d;
998      => y = a + b;
999         x = c - d;
1000         if (test)
1001           x = y;
1002   */
1003   
1004   code = GET_CODE (if_info->cond);
1005   insn_a = if_info->insn_a;
1006   insn_b = if_info->insn_b;
1007
1008   /* Possibly rearrange operands to make things come out more natural.  */
1009   if (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN)
1010     {
1011       int reversep = 0;
1012       if (rtx_equal_p (b, x))
1013         reversep = 1;
1014       else if (general_operand (b, GET_MODE (b)))
1015         reversep = 1;
1016
1017       if (reversep)
1018         {
1019           code = reversed_comparison_code (if_info->cond, if_info->jump);
1020           tmp = a, a = b, b = tmp;
1021           tmp = insn_a, insn_a = insn_b, insn_b = tmp;
1022         }
1023     }
1024
1025   start_sequence ();
1026
1027   /* If either operand is complex, load it into a register first.
1028      The best way to do this is to copy the original insn.  In this
1029      way we preserve any clobbers etc that the insn may have had.  
1030      This is of course not possible in the IS_MEM case.  */
1031   if (! general_operand (a, GET_MODE (a)))
1032     {
1033       rtx set;
1034
1035       if (no_new_pseudos)
1036         goto end_seq_and_fail;
1037
1038       if (is_mem)
1039         {
1040           tmp = gen_reg_rtx (GET_MODE (a));
1041           tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, a));
1042         }
1043       else if (! insn_a)
1044         goto end_seq_and_fail;
1045       else
1046         {
1047           a = gen_reg_rtx (GET_MODE (a));
1048           tmp = copy_rtx (insn_a);
1049           set = single_set (tmp);
1050           SET_DEST (set) = a;
1051           tmp = emit_insn (PATTERN (tmp));
1052         }
1053       if (recog_memoized (tmp) < 0)
1054         goto end_seq_and_fail;
1055     }
1056   if (! general_operand (b, GET_MODE (b)))
1057     {
1058       rtx set;
1059
1060       if (no_new_pseudos)
1061         goto end_seq_and_fail;
1062
1063       if (is_mem)
1064         {
1065           tmp = gen_reg_rtx (GET_MODE (b));
1066           tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, b));
1067         }
1068       else if (! insn_b)
1069         goto end_seq_and_fail;
1070       else
1071         {
1072           b = gen_reg_rtx (GET_MODE (b));
1073           tmp = copy_rtx (insn_b);
1074           set = single_set (tmp);
1075           SET_DEST (set) = b;
1076           tmp = emit_insn (PATTERN (tmp));
1077         }
1078       if (recog_memoized (tmp) < 0)
1079         goto end_seq_and_fail;
1080     }
1081
1082   target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0),
1083                             XEXP (if_info->cond, 1), a, b);
1084
1085   if (! target)
1086     goto end_seq_and_fail;
1087
1088   /* If we're handling a memory for above, emit the load now.  */
1089   if (is_mem)
1090     {
1091       tmp = gen_rtx_MEM (GET_MODE (if_info->x), target);
1092
1093       /* Copy over flags as appropriate.  */
1094       if (MEM_VOLATILE_P (if_info->a) || MEM_VOLATILE_P (if_info->b))
1095         MEM_VOLATILE_P (tmp) = 1;
1096       if (MEM_IN_STRUCT_P (if_info->a) && MEM_IN_STRUCT_P (if_info->b))
1097         MEM_IN_STRUCT_P (tmp) = 1;
1098       if (MEM_SCALAR_P (if_info->a) && MEM_SCALAR_P (if_info->b))
1099         MEM_SCALAR_P (tmp) = 1;
1100       if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b))
1101         set_mem_alias_set (tmp, MEM_ALIAS_SET (if_info->a));
1102
1103       noce_emit_move_insn (if_info->x, tmp);
1104     }
1105   else if (target != x)
1106     noce_emit_move_insn (x, target);
1107
1108   tmp = get_insns ();
1109   end_sequence ();
1110   emit_insns_before (tmp, if_info->cond_earliest);
1111   return TRUE;
1112
1113  end_seq_and_fail:
1114   end_sequence ();
1115   return FALSE;
1116 }
1117
1118 /* For most cases, the simplified condition we found is the best
1119    choice, but this is not the case for the min/max/abs transforms.
1120    For these we wish to know that it is A or B in the condition.  */
1121
1122 static rtx
1123 noce_get_alt_condition (if_info, target, earliest)
1124      struct noce_if_info *if_info;
1125      rtx target;
1126      rtx *earliest;
1127 {
1128   rtx cond, set, insn;
1129   int reverse;
1130
1131   /* If target is already mentioned in the known condition, return it.  */
1132   if (reg_mentioned_p (target, if_info->cond))
1133     {
1134       *earliest = if_info->cond_earliest;
1135       return if_info->cond;
1136     }
1137
1138   set = pc_set (if_info->jump);
1139   cond = XEXP (SET_SRC (set), 0);
1140   reverse
1141     = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1142       && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump);
1143
1144   cond = canonicalize_condition (if_info->jump, cond, reverse,
1145                                  earliest, target);
1146   if (! cond || ! reg_mentioned_p (target, cond))
1147     return NULL;
1148
1149   /* We almost certainly searched back to a different place.
1150      Need to re-verify correct lifetimes.  */
1151
1152   /* X may not be mentioned in the range (cond_earliest, jump].  */
1153   for (insn = if_info->jump; insn != *earliest; insn = PREV_INSN (insn))
1154     if (INSN_P (insn) && reg_mentioned_p (if_info->x, insn))
1155       return NULL;
1156
1157   /* A and B may not be modified in the range [cond_earliest, jump).  */
1158   for (insn = *earliest; insn != if_info->jump; insn = NEXT_INSN (insn))
1159     if (INSN_P (insn)
1160         && (modified_in_p (if_info->a, insn)
1161             || modified_in_p (if_info->b, insn)))
1162       return NULL;
1163
1164   return cond;
1165 }
1166
1167 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc.  */
1168
1169 static int
1170 noce_try_minmax (if_info)
1171      struct noce_if_info *if_info;
1172
1173   rtx cond, earliest, target, seq;
1174   enum rtx_code code;
1175   int unsignedp;
1176   optab op;
1177
1178   /* ??? Can't guarantee that expand_binop won't create pseudos.  */
1179   if (no_new_pseudos)
1180     return FALSE;
1181
1182   /* ??? Reject FP modes since we don't know how 0 vs -0 or NaNs
1183      will be resolved with an SMIN/SMAX.  It wouldn't be too hard
1184      to get the target to tell us...  */
1185   if (FLOAT_MODE_P (GET_MODE (if_info->x))
1186       && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1187       && ! flag_unsafe_math_optimizations)
1188     return FALSE;
1189
1190   cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
1191   if (!cond)
1192     return FALSE;
1193
1194   /* Verify the condition is of the form we expect, and canonicalize
1195      the comparison code.  */
1196   code = GET_CODE (cond);
1197   if (rtx_equal_p (XEXP (cond, 0), if_info->a))
1198     {
1199       if (! rtx_equal_p (XEXP (cond, 1), if_info->b))
1200         return FALSE;
1201     }
1202   else if (rtx_equal_p (XEXP (cond, 1), if_info->a))
1203     {
1204       if (! rtx_equal_p (XEXP (cond, 0), if_info->b))
1205         return FALSE;
1206       code = swap_condition (code);
1207     }
1208   else
1209     return FALSE;
1210
1211   /* Determine what sort of operation this is.  Note that the code is for
1212      a taken branch, so the code->operation mapping appears backwards.  */
1213   switch (code)
1214     {
1215     case LT:
1216     case LE:
1217     case UNLT:
1218     case UNLE:
1219       op = smax_optab;
1220       unsignedp = 0;
1221       break;
1222     case GT:
1223     case GE:
1224     case UNGT:
1225     case UNGE:
1226       op = smin_optab;
1227       unsignedp = 0;
1228       break;
1229     case LTU:
1230     case LEU:
1231       op = umax_optab;
1232       unsignedp = 1;
1233       break;
1234     case GTU:
1235     case GEU:
1236       op = umin_optab;
1237       unsignedp = 1;
1238       break;
1239     default:
1240       return FALSE;
1241     }
1242
1243   start_sequence ();
1244
1245   target = expand_binop (GET_MODE (if_info->x), op, if_info->a, if_info->b,
1246                          if_info->x, unsignedp, OPTAB_WIDEN);
1247   if (! target)
1248     {
1249       end_sequence ();
1250       return FALSE;
1251     }
1252   if (target != if_info->x)
1253     noce_emit_move_insn (if_info->x, target);
1254
1255   seq = get_insns ();
1256   end_sequence ();  
1257
1258   if (seq_contains_jump (seq))
1259     return FALSE;
1260
1261   emit_insns_before (seq, earliest);
1262   if_info->cond = cond;
1263   if_info->cond_earliest = earliest;
1264
1265   return TRUE;
1266 }
1267
1268 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc.  */
1269
1270 static int
1271 noce_try_abs (if_info)
1272      struct noce_if_info *if_info;
1273
1274   rtx cond, earliest, target, seq, a, b, c;
1275   int negate;
1276
1277   /* ??? Can't guarantee that expand_binop won't create pseudos.  */
1278   if (no_new_pseudos)
1279     return FALSE;
1280
1281   /* Recognize A and B as constituting an ABS or NABS.  */
1282   a = if_info->a;
1283   b = if_info->b;
1284   if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b))
1285     negate = 0;
1286   else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a))
1287     {
1288       c = a; a = b; b = c;
1289       negate = 1;
1290     }
1291   else
1292     return FALSE;
1293    
1294   cond = noce_get_alt_condition (if_info, b, &earliest);
1295   if (!cond)
1296     return FALSE;
1297
1298   /* Verify the condition is of the form we expect.  */
1299   if (rtx_equal_p (XEXP (cond, 0), b))
1300     c = XEXP (cond, 1);
1301   else if (rtx_equal_p (XEXP (cond, 1), b))
1302     c = XEXP (cond, 0);
1303   else
1304     return FALSE;
1305
1306   /* Verify that C is zero.  Search backward through the block for
1307      a REG_EQUAL note if necessary.  */
1308   if (REG_P (c))
1309     {
1310       rtx insn, note = NULL;
1311       for (insn = earliest;
1312            insn != if_info->test_bb->head;
1313            insn = PREV_INSN (insn))
1314         if (INSN_P (insn) 
1315             && ((note = find_reg_note (insn, REG_EQUAL, c))
1316                 || (note = find_reg_note (insn, REG_EQUIV, c))))
1317           break;
1318       if (! note)
1319         return FALSE;
1320       c = XEXP (note, 0);
1321     }
1322   if (GET_CODE (c) == MEM
1323       && GET_CODE (XEXP (c, 0)) == SYMBOL_REF
1324       && CONSTANT_POOL_ADDRESS_P (XEXP (c, 0)))
1325     c = get_pool_constant (XEXP (c, 0));
1326
1327   /* Work around funny ideas get_condition has wrt canonicalization.
1328      Note that these rtx constants are known to be CONST_INT, and 
1329      therefore imply integer comparisons.  */
1330   if (c == constm1_rtx && GET_CODE (cond) == GT)
1331     ;
1332   else if (c == const1_rtx && GET_CODE (cond) == LT)
1333     ;
1334   else if (c != CONST0_RTX (GET_MODE (b)))
1335     return FALSE;
1336
1337   /* Determine what sort of operation this is.  */
1338   switch (GET_CODE (cond))
1339     {
1340     case LT:
1341     case LE:
1342     case UNLT:
1343     case UNLE:
1344       negate = !negate;
1345       break;
1346     case GT:
1347     case GE:
1348     case UNGT:
1349     case UNGE:
1350       break;
1351     default:
1352       return FALSE;
1353     }
1354
1355   start_sequence ();
1356
1357   target = expand_unop (GET_MODE (if_info->x), abs_optab, b, if_info->x, 0);
1358
1359   /* ??? It's a quandry whether cmove would be better here, especially
1360      for integers.  Perhaps combine will clean things up.  */
1361   if (target && negate)
1362     target = expand_unop (GET_MODE (target), neg_optab, target, if_info->x, 0);
1363
1364   if (! target)
1365     {
1366       end_sequence ();
1367       return FALSE;
1368     }
1369
1370   if (target != if_info->x)
1371     noce_emit_move_insn (if_info->x, target);
1372
1373   seq = get_insns ();
1374   end_sequence ();  
1375
1376   if (seq_contains_jump (seq))
1377     return FALSE;
1378
1379   emit_insns_before (seq, earliest);
1380   if_info->cond = cond;
1381   if_info->cond_earliest = earliest;
1382
1383   return TRUE;
1384 }
1385
1386 /* Look for the condition for the jump first.  We'd prefer to avoid
1387    get_condition if we can -- it tries to look back for the contents
1388    of an original compare.  On targets that use normal integers for
1389    comparisons, e.g. alpha, this is wasteful.  */
1390
1391 static rtx
1392 noce_get_condition (jump, earliest)
1393      rtx jump;
1394      rtx *earliest;
1395 {
1396   rtx cond;
1397   rtx set;
1398
1399   /* If the condition variable is a register and is MODE_INT, accept it.
1400      Otherwise, fall back on get_condition.  */
1401
1402   if (! any_condjump_p (jump))
1403     return NULL_RTX;
1404
1405   set = pc_set (jump);
1406
1407   cond = XEXP (SET_SRC (set), 0);
1408   if (GET_CODE (XEXP (cond, 0)) == REG
1409       && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT)
1410     {
1411       *earliest = jump;
1412
1413       /* If this branches to JUMP_LABEL when the condition is false,
1414          reverse the condition.  */
1415       if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1416           && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump))
1417         cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
1418                                GET_MODE (cond), XEXP (cond, 0),
1419                                XEXP (cond, 1));
1420     }
1421   else
1422     cond = get_condition (jump, earliest);
1423
1424   return cond;
1425 }
1426
1427 /* Return true if OP is ok for if-then-else processing.  */
1428
1429 static int
1430 noce_operand_ok (op)
1431      rtx op;
1432 {
1433   /* We special-case memories, so handle any of them with
1434      no address side effects.  */
1435   if (GET_CODE (op) == MEM)
1436     return ! side_effects_p (XEXP (op, 0));
1437
1438   if (side_effects_p (op))
1439     return FALSE;
1440
1441   /* ??? Unfortuantely may_trap_p can't look at flag_trapping_math, due to
1442      being linked into the genfoo programs.  This is probably a mistake.
1443      With finite operands, most fp operations don't trap.  */
1444   if (!flag_trapping_math && FLOAT_MODE_P (GET_MODE (op)))
1445     switch (GET_CODE (op))
1446       {
1447       case DIV:
1448       case MOD:
1449       case UDIV:
1450       case UMOD:
1451         /* ??? This is kinda lame -- almost every target will have forced
1452            the constant into a register first.  But given the expense of
1453            division, this is probably for the best.  */
1454         return (CONSTANT_P (XEXP (op, 1))
1455                 && XEXP (op, 1) != CONST0_RTX (GET_MODE (op))
1456                 && ! may_trap_p (XEXP (op, 0)));
1457
1458       default:
1459         switch (GET_RTX_CLASS (GET_CODE (op)))
1460           {
1461           case '1':
1462             return ! may_trap_p (XEXP (op, 0));
1463           case 'c':
1464           case '2':
1465             return ! may_trap_p (XEXP (op, 0)) && ! may_trap_p (XEXP (op, 1));
1466           }
1467         break;
1468       }
1469
1470   return ! may_trap_p (op);
1471 }
1472
1473 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
1474    without using conditional execution.  Return TRUE if we were
1475    successful at converting the the block.  */
1476
1477 static int
1478 noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
1479      basic_block test_bb;       /* Basic block test is in */
1480      basic_block then_bb;       /* Basic block for THEN block */
1481      basic_block else_bb;       /* Basic block for ELSE block */
1482      basic_block join_bb;       /* Basic block the join label is in */
1483 {
1484   /* We're looking for patterns of the form
1485
1486      (1) if (...) x = a; else x = b;
1487      (2) x = b; if (...) x = a;
1488      (3) if (...) x = a;   // as if with an initial x = x.
1489
1490      The later patterns require jumps to be more expensive.
1491
1492      ??? For future expansion, look for multiple X in such patterns.  */
1493
1494   struct noce_if_info if_info;
1495   rtx insn_a, insn_b;
1496   rtx set_a, set_b;
1497   rtx orig_x, x, a, b;
1498   rtx jump, cond, insn;
1499
1500   /* If this is not a standard conditional jump, we can't parse it.  */
1501   jump = test_bb->end;
1502   cond = noce_get_condition (jump, &if_info.cond_earliest);
1503   if (! cond)
1504     return FALSE;
1505
1506   /* If the conditional jump is more than just a conditional jump,
1507      then we can not do if-conversion on this block.  */
1508   if (! onlyjump_p (jump))
1509     return FALSE;
1510
1511   /* We must be comparing objects whose modes imply the size.  */
1512   if (GET_MODE (XEXP (cond, 0)) == BLKmode)
1513     return FALSE;
1514
1515   /* Look for one of the potential sets.  */
1516   insn_a = first_active_insn (then_bb);
1517   if (! insn_a
1518       || ! last_active_insn_p (then_bb, insn_a)
1519       || (set_a = single_set (insn_a)) == NULL_RTX)
1520     return FALSE;
1521
1522   x = SET_DEST (set_a);
1523   a = SET_SRC (set_a);
1524
1525   /* Look for the other potential set.  Make sure we've got equivalent
1526      destinations.  */
1527   /* ??? This is overconservative.  Storing to two different mems is
1528      as easy as conditionally computing the address.  Storing to a
1529      single mem merely requires a scratch memory to use as one of the
1530      destination addresses; often the memory immediately below the
1531      stack pointer is available for this.  */
1532   set_b = NULL_RTX;
1533   if (else_bb)
1534     {
1535       insn_b = first_active_insn (else_bb);
1536       if (! insn_b
1537           || ! last_active_insn_p (else_bb, insn_b)
1538           || (set_b = single_set (insn_b)) == NULL_RTX
1539           || ! rtx_equal_p (x, SET_DEST (set_b)))
1540         return FALSE;
1541     }
1542   else
1543     {
1544       insn_b = prev_nonnote_insn (if_info.cond_earliest);
1545       if (! insn_b
1546           || GET_CODE (insn_b) != INSN
1547           || (set_b = single_set (insn_b)) == NULL_RTX
1548           || ! rtx_equal_p (x, SET_DEST (set_b))
1549           || reg_mentioned_p (x, cond)
1550           || reg_mentioned_p (x, a)
1551           || reg_mentioned_p (x, SET_SRC (set_b)))
1552         insn_b = set_b = NULL_RTX;
1553     }
1554   b = (set_b ? SET_SRC (set_b) : x);
1555
1556   /* X may not be mentioned in the range (cond_earliest, jump].  */
1557   for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn))
1558     if (INSN_P (insn) && reg_mentioned_p (x, insn))
1559       return FALSE;
1560
1561   /* A and B may not be modified in the range [cond_earliest, jump).  */
1562   for (insn = if_info.cond_earliest; insn != jump; insn = NEXT_INSN (insn))
1563     if (INSN_P (insn)
1564         && (modified_in_p (a, insn) || modified_in_p (b, insn)))
1565       return FALSE;
1566
1567   /* Only operate on register destinations, and even then avoid extending
1568      the lifetime of hard registers on small register class machines.  */
1569   orig_x = x;
1570   if (GET_CODE (x) != REG
1571       || (SMALL_REGISTER_CLASSES
1572           && REGNO (x) < FIRST_PSEUDO_REGISTER))
1573     {
1574       if (no_new_pseudos)
1575         return FALSE;
1576       x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
1577                                  ? XEXP (x, 0) : x));
1578     }
1579
1580   /* Don't operate on sources that may trap or are volatile.  */
1581   if (! noce_operand_ok (a) || ! noce_operand_ok (b))
1582     return FALSE;
1583
1584   /* Set up the info block for our subroutines.  */
1585   if_info.test_bb = test_bb;
1586   if_info.cond = cond;
1587   if_info.jump = jump;
1588   if_info.insn_a = insn_a;
1589   if_info.insn_b = insn_b;
1590   if_info.x = x;
1591   if_info.a = a;
1592   if_info.b = b;
1593
1594   /* Try optimizations in some approximation of a useful order.  */
1595   /* ??? Should first look to see if X is live incoming at all.  If it
1596      isn't, we don't need anything but an unconditional set.  */
1597
1598   /* Look and see if A and B are really the same.  Avoid creating silly
1599      cmove constructs that no one will fix up later.  */
1600   if (rtx_equal_p (a, b))
1601     {
1602       /* If we have an INSN_B, we don't have to create any new rtl.  Just
1603          move the instruction that we already have.  If we don't have an
1604          INSN_B, that means that A == X, and we've got a noop move.  In
1605          that case don't do anything and let the code below delete INSN_A.  */
1606       if (insn_b && else_bb)
1607         {
1608           rtx note;
1609
1610           if (else_bb && insn_b == else_bb->end)
1611             else_bb->end = PREV_INSN (insn_b);
1612           reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest));
1613
1614           /* If there was a REG_EQUAL note, delete it since it may have been
1615              true due to this insn being after a jump.  */
1616           if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
1617             remove_note (insn_b, note);
1618
1619           insn_b = NULL_RTX;
1620         }
1621       /* If we have "x = b; if (...) x = a;", and x has side-effects, then
1622          x must be executed twice.  */
1623       else if (insn_b && side_effects_p (orig_x))
1624         return FALSE;
1625         
1626       x = orig_x;
1627       goto success;
1628     }
1629
1630   if (noce_try_store_flag (&if_info))
1631     goto success;
1632   if (noce_try_minmax (&if_info))
1633     goto success;
1634   if (noce_try_abs (&if_info))
1635     goto success;
1636   if (HAVE_conditional_move
1637       && noce_try_cmove (&if_info))
1638     goto success;
1639   if (! HAVE_conditional_execution)
1640     {
1641       if (noce_try_store_flag_constants (&if_info))
1642         goto success;
1643       if (noce_try_store_flag_inc (&if_info))
1644         goto success;
1645       if (noce_try_store_flag_mask (&if_info))
1646         goto success;
1647       if (HAVE_conditional_move
1648           && noce_try_cmove_arith (&if_info))
1649         goto success;
1650     }
1651
1652   return FALSE;
1653
1654  success:
1655   /* The original sets may now be killed.  */
1656   if (insn_a == then_bb->end)
1657     then_bb->end = PREV_INSN (insn_a);
1658   flow_delete_insn (insn_a);
1659
1660   /* Several special cases here: First, we may have reused insn_b above,
1661      in which case insn_b is now NULL.  Second, we want to delete insn_b
1662      if it came from the ELSE block, because follows the now correct
1663      write that appears in the TEST block.  However, if we got insn_b from
1664      the TEST block, it may in fact be loading data needed for the comparison.
1665      We'll let life_analysis remove the insn if it's really dead.  */
1666   if (insn_b && else_bb)
1667     {
1668       if (insn_b == else_bb->end)
1669         else_bb->end = PREV_INSN (insn_b);
1670       flow_delete_insn (insn_b);
1671     }
1672
1673   /* The new insns will have been inserted before cond_earliest.  We should
1674      be able to remove the jump with impunity, but the condition itself may
1675      have been modified by gcse to be shared across basic blocks.  */
1676   test_bb->end = PREV_INSN (jump);
1677   flow_delete_insn (jump);
1678
1679   /* If we used a temporary, fix it up now.  */
1680   if (orig_x != x)
1681     {
1682       start_sequence ();
1683       noce_emit_move_insn (orig_x, x);
1684       insn_b = gen_sequence ();
1685       end_sequence ();
1686
1687       test_bb->end = emit_insn_after (insn_b, test_bb->end);
1688     }
1689
1690   /* Merge the blocks!  */
1691   merge_if_block (test_bb, then_bb, else_bb, join_bb);
1692
1693   return TRUE;
1694 }
1695 \f
1696 /* Attempt to convert an IF-THEN or IF-THEN-ELSE block into
1697    straight line code.  Return true if successful.  */
1698
1699 static int
1700 process_if_block (test_bb, then_bb, else_bb, join_bb)
1701      basic_block test_bb;       /* Basic block test is in */
1702      basic_block then_bb;       /* Basic block for THEN block */
1703      basic_block else_bb;       /* Basic block for ELSE block */
1704      basic_block join_bb;       /* Basic block the join label is in */
1705 {
1706   if (! reload_completed
1707       && noce_process_if_block (test_bb, then_bb, else_bb, join_bb))
1708     return TRUE;
1709
1710   if (HAVE_conditional_execution
1711       && reload_completed
1712       && cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb))
1713     return TRUE;
1714
1715   return FALSE;
1716 }
1717
1718 /* Merge the blocks and mark for local life update.  */
1719
1720 static void
1721 merge_if_block (test_bb, then_bb, else_bb, join_bb)
1722      basic_block test_bb;       /* Basic block test is in */
1723      basic_block then_bb;       /* Basic block for THEN block */
1724      basic_block else_bb;       /* Basic block for ELSE block */
1725      basic_block join_bb;       /* Basic block the join label is in */
1726 {
1727   basic_block combo_bb;
1728
1729   /* All block merging is done into the lower block numbers.  */
1730
1731   combo_bb = test_bb;
1732
1733   /* First merge TEST block into THEN block.  This is a no-brainer since
1734      the THEN block did not have a code label to begin with.  */
1735
1736   if (life_data_ok)
1737     COPY_REG_SET (combo_bb->global_live_at_end, then_bb->global_live_at_end);
1738   merge_blocks_nomove (combo_bb, then_bb);
1739   num_removed_blocks++;
1740
1741   /* The ELSE block, if it existed, had a label.  That label count
1742      will almost always be zero, but odd things can happen when labels
1743      get their addresses taken.  */
1744   if (else_bb)
1745     {
1746       merge_blocks_nomove (combo_bb, else_bb);
1747       num_removed_blocks++;
1748     }
1749
1750   /* If there was no join block reported, that means it was not adjacent
1751      to the others, and so we cannot merge them.  */
1752
1753   if (! join_bb)
1754     {
1755       /* The outgoing edge for the current COMBO block should already
1756          be correct.  Verify this.  */
1757       if (combo_bb->succ == NULL_EDGE)
1758         abort ();
1759
1760       /* There should sill be a branch at the end of the THEN or ELSE
1761          blocks taking us to our final destination.  */
1762       if (! any_uncondjump_p (combo_bb->end)
1763           && ! returnjump_p (combo_bb->end))
1764         abort ();
1765     }
1766
1767   /* The JOIN block may have had quite a number of other predecessors too.
1768      Since we've already merged the TEST, THEN and ELSE blocks, we should
1769      have only one remaining edge from our if-then-else diamond.  If there
1770      is more than one remaining edge, it must come from elsewhere.  There
1771      may be zero incoming edges if the THEN block didn't actually join 
1772      back up (as with a call to abort).  */
1773   else if (join_bb->pred == NULL || join_bb->pred->pred_next == NULL)
1774     {
1775       /* We can merge the JOIN.  */
1776       if (life_data_ok)
1777         COPY_REG_SET (combo_bb->global_live_at_end,
1778                       join_bb->global_live_at_end);
1779       merge_blocks_nomove (combo_bb, join_bb);
1780       num_removed_blocks++;
1781     }
1782   else
1783     {
1784       /* We cannot merge the JOIN.  */
1785
1786       /* The outgoing edge for the current COMBO block should already
1787          be correct.  Verify this.  */
1788       if (combo_bb->succ->succ_next != NULL_EDGE
1789           || combo_bb->succ->dest != join_bb)
1790         abort ();
1791
1792       /* Remove the jump and cruft from the end of the COMBO block.  */
1793       tidy_fallthru_edge (combo_bb->succ, combo_bb, join_bb);
1794     }
1795
1796   /* Make sure we update life info properly.  */
1797   SET_UPDATE_LIFE (combo_bb);
1798
1799   num_updated_if_blocks++;
1800 }
1801 \f
1802 /* Find a block ending in a simple IF condition.  Return TRUE if
1803    we were able to transform it in some way.  */
1804
1805 static int
1806 find_if_header (test_bb)
1807      basic_block test_bb;
1808 {
1809   edge then_edge;
1810   edge else_edge;
1811
1812   /* The kind of block we're looking for has exactly two successors.  */
1813   if ((then_edge = test_bb->succ) == NULL_EDGE
1814       || (else_edge = then_edge->succ_next) == NULL_EDGE
1815       || else_edge->succ_next != NULL_EDGE)
1816     return FALSE;
1817
1818   /* Neither edge should be abnormal.  */
1819   if ((then_edge->flags & EDGE_COMPLEX)
1820       || (else_edge->flags & EDGE_COMPLEX))
1821     return FALSE;
1822
1823   /* The THEN edge is canonically the one that falls through.  */
1824   if (then_edge->flags & EDGE_FALLTHRU)
1825     ;
1826   else if (else_edge->flags & EDGE_FALLTHRU)
1827     {
1828       edge e = else_edge;
1829       else_edge = then_edge;
1830       then_edge = e;
1831     }
1832   else
1833     /* Otherwise this must be a multiway branch of some sort.  */
1834     return FALSE;
1835
1836   if (find_if_block (test_bb, then_edge, else_edge))
1837     goto success;
1838   if (post_dominators
1839       && (! HAVE_conditional_execution || reload_completed))
1840     {
1841       if (find_if_case_1 (test_bb, then_edge, else_edge))
1842         goto success;
1843       if (find_if_case_2 (test_bb, then_edge, else_edge))
1844         goto success;
1845     }
1846
1847   return FALSE;
1848
1849  success:
1850   if (rtl_dump_file)
1851     fprintf (rtl_dump_file, "Conversion succeeded.\n");
1852   return TRUE;
1853 }
1854
1855 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
1856    block.  If so, we'll try to convert the insns to not require the branch.
1857    Return TRUE if we were successful at converting the the block.  */
1858
1859 static int
1860 find_if_block (test_bb, then_edge, else_edge)
1861       basic_block test_bb;
1862       edge then_edge, else_edge;
1863 {
1864   basic_block then_bb = then_edge->dest;
1865   basic_block else_bb = else_edge->dest;
1866   basic_block join_bb = NULL_BLOCK;
1867   edge then_succ = then_bb->succ;
1868   edge else_succ = else_bb->succ;
1869   int next_index;
1870
1871   /* The THEN block of an IF-THEN combo must have exactly one predecessor.  */
1872   if (then_bb->pred->pred_next != NULL_EDGE)
1873     return FALSE;
1874
1875   /* The THEN block of an IF-THEN combo must have zero or one successors.  */
1876   if (then_succ != NULL_EDGE
1877       && (then_succ->succ_next != NULL_EDGE
1878           || (then_succ->flags & EDGE_COMPLEX)))
1879     return FALSE;
1880
1881   /* If the THEN block has no successors, conditional execution can still
1882      make a conditional call.  Don't do this unless the ELSE block has
1883      only one incoming edge -- the CFG manipulation is too ugly otherwise.
1884      Check for the last insn of the THEN block being an indirect jump, which
1885      is listed as not having any successors, but confuses the rest of the CE
1886      code processing.  XXX we should fix this in the future.  */
1887   if (then_succ == NULL)
1888     {
1889       if (else_bb->pred->pred_next == NULL_EDGE)
1890         {
1891           rtx last_insn = then_bb->end;
1892
1893           while (last_insn
1894                  && GET_CODE (last_insn) == NOTE
1895                  && last_insn != then_bb->head)
1896             last_insn = PREV_INSN (last_insn);
1897
1898           if (last_insn
1899               && GET_CODE (last_insn) == JUMP_INSN
1900               && ! simplejump_p (last_insn))
1901             return FALSE;
1902
1903           join_bb = else_bb;
1904           else_bb = NULL_BLOCK;
1905         }
1906       else
1907         return FALSE;
1908     }
1909
1910   /* If the THEN block's successor is the other edge out of the TEST block,
1911      then we have an IF-THEN combo without an ELSE.  */
1912   else if (then_succ->dest == else_bb)
1913     {
1914       join_bb = else_bb;
1915       else_bb = NULL_BLOCK;
1916     }
1917
1918   /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
1919      has exactly one predecessor and one successor, and the outgoing edge
1920      is not complex, then we have an IF-THEN-ELSE combo.  */
1921   else if (else_succ != NULL_EDGE
1922            && then_succ->dest == else_succ->dest
1923            && else_bb->pred->pred_next == NULL_EDGE
1924            && else_succ->succ_next == NULL_EDGE
1925            && ! (else_succ->flags & EDGE_COMPLEX))
1926     join_bb = else_succ->dest;
1927
1928   /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination.  */
1929   else
1930     return FALSE;          
1931
1932   num_possible_if_blocks++;
1933
1934   if (rtl_dump_file)
1935     {
1936       if (else_bb)
1937         fprintf (rtl_dump_file,
1938                  "\nIF-THEN-ELSE block found, start %d, then %d, else %d, join %d\n",
1939                  test_bb->index, then_bb->index, else_bb->index,
1940                  join_bb->index);
1941       else
1942         fprintf (rtl_dump_file,
1943                  "\nIF-THEN block found, start %d, then %d, join %d\n",
1944                  test_bb->index, then_bb->index, join_bb->index);
1945     }
1946
1947   /* Make sure IF, THEN, and ELSE, blocks are adjacent.  Actually, we
1948      get the first condition for free, since we've already asserted that
1949      there's a fallthru edge from IF to THEN.  */
1950   /* ??? As an enhancement, move the ELSE block.  Have to deal with
1951      BLOCK notes, if by no other means than aborting the merge if they
1952      exist.  Sticky enough I don't want to think about it now.  */
1953   next_index = then_bb->index;
1954   if (else_bb && ++next_index != else_bb->index)
1955     return FALSE;
1956   if (++next_index != join_bb->index)
1957     {
1958       if (else_bb)
1959         join_bb = NULL;
1960       else
1961         return FALSE;
1962     }
1963
1964   /* Do the real work.  */
1965   return process_if_block (test_bb, then_bb, else_bb, join_bb);
1966 }
1967
1968 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
1969    transformable, but not necessarily the other.  There need be no
1970    JOIN block.
1971
1972    Return TRUE if we were successful at converting the the block.
1973
1974    Cases we'd like to look at:
1975
1976    (1)
1977         if (test) goto over; // x not live
1978         x = a;
1979         goto label;
1980         over:
1981
1982    becomes
1983
1984         x = a;
1985         if (! test) goto label;
1986
1987    (2)
1988         if (test) goto E; // x not live
1989         x = big();
1990         goto L;
1991         E:
1992         x = b;
1993         goto M;
1994
1995    becomes
1996
1997         x = b;
1998         if (test) goto M;
1999         x = big();
2000         goto L;
2001
2002    (3) // This one's really only interesting for targets that can do
2003        // multiway branching, e.g. IA-64 BBB bundles.  For other targets
2004        // it results in multiple branches on a cache line, which often
2005        // does not sit well with predictors.
2006
2007         if (test1) goto E; // predicted not taken
2008         x = a;
2009         if (test2) goto F;
2010         ...
2011         E:
2012         x = b;
2013         J:
2014
2015    becomes
2016
2017         x = a;
2018         if (test1) goto E;
2019         if (test2) goto F;
2020
2021    Notes:
2022
2023    (A) Don't do (2) if the branch is predicted against the block we're
2024    eliminating.  Do it anyway if we can eliminate a branch; this requires
2025    that the sole successor of the eliminated block postdominate the other
2026    side of the if.
2027
2028    (B) With CE, on (3) we can steal from both sides of the if, creating
2029
2030         if (test1) x = a;
2031         if (!test1) x = b;
2032         if (test1) goto J;
2033         if (test2) goto F;
2034         ...
2035         J:
2036
2037    Again, this is most useful if J postdominates.
2038
2039    (C) CE substitutes for helpful life information.
2040
2041    (D) These heuristics need a lot of work.  */
2042
2043 /* Tests for case 1 above.  */
2044
2045 static int
2046 find_if_case_1 (test_bb, then_edge, else_edge)
2047       basic_block test_bb;
2048       edge then_edge, else_edge;
2049 {
2050   basic_block then_bb = then_edge->dest;
2051   basic_block else_bb = else_edge->dest;
2052   edge then_succ = then_bb->succ;
2053   rtx new_lab;
2054
2055   /* THEN has one successor.  */
2056   if (!then_succ || then_succ->succ_next != NULL)
2057     return FALSE;
2058
2059   /* THEN does not fall through, but is not strange either.  */
2060   if (then_succ->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
2061     return FALSE;
2062
2063   /* THEN has one predecessor.  */
2064   if (then_bb->pred->pred_next != NULL)
2065     return FALSE;
2066
2067   /* ELSE follows THEN.  (??? could be moved)  */
2068   if (else_bb->index != then_bb->index + 1)
2069     return FALSE;
2070
2071   num_possible_if_blocks++;
2072   if (rtl_dump_file)
2073     fprintf (rtl_dump_file,
2074              "\nIF-CASE-1 found, start %d, then %d\n",
2075              test_bb->index, then_bb->index);
2076
2077   /* THEN is small.  */
2078   if (count_bb_insns (then_bb) > BRANCH_COST)
2079     return FALSE;
2080
2081   /* Find the label for THEN's destination.  */
2082   if (then_succ->dest == EXIT_BLOCK_PTR)
2083     new_lab = NULL_RTX;
2084   else
2085     {
2086       new_lab = JUMP_LABEL (then_bb->end);
2087       if (! new_lab)
2088         abort ();
2089     }
2090
2091   /* Registers set are dead, or are predicable.  */
2092   if (! dead_or_predicable (test_bb, then_bb, else_bb, new_lab, 1))
2093     return FALSE;
2094
2095   /* Conversion went ok, including moving the insns and fixing up the
2096      jump.  Adjust the CFG to match.  */
2097
2098   SET_UPDATE_LIFE (test_bb);
2099   bitmap_operation (test_bb->global_live_at_end,
2100                     else_bb->global_live_at_start,
2101                     then_bb->global_live_at_end, BITMAP_IOR);
2102   
2103   make_edge (NULL, test_bb, then_succ->dest, 0);
2104   flow_delete_block (then_bb);
2105   tidy_fallthru_edge (else_edge, test_bb, else_bb);
2106
2107   num_removed_blocks++;
2108   num_updated_if_blocks++;
2109
2110   return TRUE;
2111 }
2112
2113 /* Test for case 2 above.  */
2114
2115 static int
2116 find_if_case_2 (test_bb, then_edge, else_edge)
2117       basic_block test_bb;
2118       edge then_edge, else_edge;
2119 {
2120   basic_block then_bb = then_edge->dest;
2121   basic_block else_bb = else_edge->dest;
2122   edge else_succ = else_bb->succ;
2123   rtx new_lab, note;
2124
2125   /* ELSE has one successor.  */
2126   if (!else_succ || else_succ->succ_next != NULL)
2127     return FALSE;
2128
2129   /* ELSE outgoing edge is not complex.  */
2130   if (else_succ->flags & EDGE_COMPLEX)
2131     return FALSE;
2132
2133   /* ELSE has one predecessor.  */
2134   if (else_bb->pred->pred_next != NULL)
2135     return FALSE;
2136
2137   /* THEN is not EXIT.  */
2138   if (then_bb->index < 0)
2139     return FALSE;
2140
2141   /* ELSE is predicted or SUCC(ELSE) postdominates THEN.  */
2142   note = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
2143   if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
2144     ;
2145   else if (else_succ->dest->index < 0
2146            || TEST_BIT (post_dominators[ORIG_INDEX (then_bb)], 
2147                         ORIG_INDEX (else_succ->dest)))
2148     ;
2149   else
2150     return FALSE;
2151
2152   num_possible_if_blocks++;
2153   if (rtl_dump_file)
2154     fprintf (rtl_dump_file,
2155              "\nIF-CASE-2 found, start %d, else %d\n",
2156              test_bb->index, else_bb->index);
2157
2158   /* ELSE is small.  */
2159   if (count_bb_insns (then_bb) > BRANCH_COST)
2160     return FALSE;
2161
2162   /* Find the label for ELSE's destination.  */
2163   if (else_succ->dest == EXIT_BLOCK_PTR)
2164     new_lab = NULL_RTX;
2165   else
2166     {
2167       if (else_succ->flags & EDGE_FALLTHRU)
2168         {
2169           new_lab = else_succ->dest->head;
2170           if (GET_CODE (new_lab) != CODE_LABEL)
2171             abort ();
2172         }
2173       else
2174         {
2175           new_lab = JUMP_LABEL (else_bb->end);
2176           if (! new_lab)
2177             abort ();
2178         }
2179     }
2180
2181   /* Registers set are dead, or are predicable.  */
2182   if (! dead_or_predicable (test_bb, else_bb, then_bb, new_lab, 0))
2183     return FALSE;
2184
2185   /* Conversion went ok, including moving the insns and fixing up the
2186      jump.  Adjust the CFG to match.  */
2187
2188   SET_UPDATE_LIFE (test_bb);
2189   bitmap_operation (test_bb->global_live_at_end,
2190                     then_bb->global_live_at_start,
2191                     else_bb->global_live_at_end, BITMAP_IOR);
2192   
2193   remove_edge (else_edge);
2194   make_edge (NULL, test_bb, else_succ->dest, 0);
2195   flow_delete_block (else_bb);
2196
2197   num_removed_blocks++;
2198   num_updated_if_blocks++;
2199
2200   /* ??? We may now fallthru from one of THEN's successors into a join
2201      block.  Rerun cleanup_cfg?  Examine things manually?  Wait?  */
2202
2203   return TRUE;
2204 }
2205
2206 /* A subroutine of dead_or_predicable called through for_each_rtx.
2207    Return 1 if a memory is found.  */
2208
2209 static int
2210 find_memory (px, data)
2211      rtx *px;
2212      void *data ATTRIBUTE_UNUSED;
2213 {
2214   return GET_CODE (*px) == MEM;
2215 }
2216
2217 /* Used by the code above to perform the actual rtl transformations.
2218    Return TRUE if successful.
2219
2220    TEST_BB is the block containing the conditional branch.  MERGE_BB
2221    is the block containing the code to manipulate.  NEW_DEST is the
2222    label TEST_BB should be branching to after the conversion.
2223    REVERSEP is true if the sense of the branch should be reversed.  */
2224
2225 static int
2226 dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
2227      basic_block test_bb, merge_bb, other_bb;
2228      rtx new_dest;
2229      int reversep;
2230 {
2231   rtx head, end, jump, earliest, old_dest;
2232
2233   jump = test_bb->end;
2234
2235   /* Find the extent of the real code in the merge block.  */
2236   head = merge_bb->head;
2237   end = merge_bb->end;
2238
2239   if (GET_CODE (head) == CODE_LABEL)
2240     head = NEXT_INSN (head);
2241   if (GET_CODE (head) == NOTE)
2242     {
2243       if (head == end)
2244         {
2245           head = end = NULL_RTX;
2246           goto no_body;
2247         }
2248       head = NEXT_INSN (head);
2249     }
2250
2251   if (GET_CODE (end) == JUMP_INSN)
2252     {
2253       if (head == end)
2254         {
2255           head = end = NULL_RTX;
2256           goto no_body;
2257         }
2258       end = PREV_INSN (end);
2259     }
2260
2261   /* Disable handling dead code by conditional execution if the machine needs
2262      to do anything funny with the tests, etc.  */
2263 #ifndef IFCVT_MODIFY_TESTS
2264   if (HAVE_conditional_execution)
2265     {
2266       /* In the conditional execution case, we have things easy.  We know
2267          the condition is reversable.  We don't have to check life info,
2268          becase we're going to conditionally execute the code anyway.
2269          All that's left is making sure the insns involved can actually
2270          be predicated.  */
2271
2272       rtx cond, prob_val;
2273
2274       cond = cond_exec_get_condition (jump);
2275       if (! cond)
2276         return FALSE;
2277
2278       prob_val = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
2279       if (prob_val)
2280         prob_val = XEXP (prob_val, 0);
2281
2282       if (reversep)
2283         {
2284           enum rtx_code rev = reversed_comparison_code (cond, jump);
2285           if (rev == UNKNOWN)
2286             return FALSE;
2287           cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
2288                                  XEXP (cond, 1));
2289           if (prob_val)
2290             prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val));
2291         }
2292
2293       if (! cond_exec_process_insns (head, end, cond, prob_val, 0))
2294         goto cancel;
2295
2296       earliest = jump;
2297     }
2298   else
2299 #endif
2300     {
2301       /* In the non-conditional execution case, we have to verify that there
2302          are no trapping operations, no calls, no references to memory, and
2303          that any registers modified are dead at the branch site.  */
2304
2305       rtx insn, cond, prev;
2306       regset_head merge_set_head, tmp_head, test_live_head, test_set_head;
2307       regset merge_set, tmp, test_live, test_set;
2308       struct propagate_block_info *pbi;
2309       int i, fail = 0;
2310
2311       /* Check for no calls or trapping operations.  */
2312       for (insn = head; ; insn = NEXT_INSN (insn))
2313         {
2314           if (GET_CODE (insn) == CALL_INSN)
2315             return FALSE;
2316           if (INSN_P (insn))
2317             {
2318               if (may_trap_p (PATTERN (insn)))
2319                 return FALSE;
2320
2321               /* ??? Even non-trapping memories such as stack frame
2322                  references must be avoided.  For stores, we collect
2323                  no lifetime info; for reads, we'd have to assert
2324                  true_dependance false against every store in the
2325                  TEST range.  */
2326               if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
2327                 return FALSE;
2328             }
2329           if (insn == end)
2330             break;
2331         }
2332
2333       if (! any_condjump_p (jump))
2334         return FALSE;
2335
2336       /* Find the extent of the conditional.  */
2337       cond = noce_get_condition (jump, &earliest);
2338       if (! cond)
2339         return FALSE;
2340
2341       /* Collect:
2342            MERGE_SET = set of registers set in MERGE_BB
2343            TEST_LIVE = set of registers live at EARLIEST
2344            TEST_SET  = set of registers set between EARLIEST and the
2345                        end of the block.  */
2346
2347       tmp = INITIALIZE_REG_SET (tmp_head);
2348       merge_set = INITIALIZE_REG_SET (merge_set_head);
2349       test_live = INITIALIZE_REG_SET (test_live_head);
2350       test_set = INITIALIZE_REG_SET (test_set_head);
2351
2352       /* ??? bb->local_set is only valid during calculate_global_regs_live,
2353          so we must recompute usage for MERGE_BB.  Not so bad, I suppose, 
2354          since we've already asserted that MERGE_BB is small.  */
2355       propagate_block (merge_bb, tmp, merge_set, merge_set, 0);
2356
2357       /* For small register class machines, don't lengthen lifetimes of
2358          hard registers before reload.  */
2359       if (SMALL_REGISTER_CLASSES && ! reload_completed)
2360         {
2361           EXECUTE_IF_SET_IN_BITMAP
2362             (merge_set, 0, i,
2363              {
2364                if (i < FIRST_PSEUDO_REGISTER
2365                    && ! fixed_regs[i]
2366                    && ! global_regs[i])
2367                 fail = 1;
2368              });
2369         }
2370
2371       /* For TEST, we're interested in a range of insns, not a whole block.
2372          Moreover, we're interested in the insns live from OTHER_BB.  */
2373
2374       COPY_REG_SET (test_live, other_bb->global_live_at_start);
2375       pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set,
2376                                        0);
2377
2378       for (insn = jump; ; insn = prev)
2379         {
2380           prev = propagate_one_insn (pbi, insn);
2381           if (insn == earliest)
2382             break;
2383         }
2384
2385       free_propagate_block_info (pbi);
2386
2387       /* We can perform the transformation if
2388            MERGE_SET & (TEST_SET | TEST_LIVE)
2389          and
2390            TEST_SET & merge_bb->global_live_at_start
2391          are empty.  */
2392
2393       bitmap_operation (tmp, test_set, test_live, BITMAP_IOR);
2394       bitmap_operation (tmp, tmp, merge_set, BITMAP_AND);
2395       EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
2396
2397       bitmap_operation (tmp, test_set, merge_bb->global_live_at_start,
2398                         BITMAP_AND);
2399       EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
2400
2401       FREE_REG_SET (tmp);
2402       FREE_REG_SET (merge_set);
2403       FREE_REG_SET (test_live);
2404       FREE_REG_SET (test_set);
2405
2406       if (fail)
2407         return FALSE;
2408     }
2409
2410  no_body:
2411   /* We don't want to use normal invert_jump or redirect_jump because
2412      we don't want to delete_insn called.  Also, we want to do our own
2413      change group management.  */
2414
2415   old_dest = JUMP_LABEL (jump);
2416   if (reversep
2417       ? ! invert_jump_1 (jump, new_dest)
2418       : ! redirect_jump_1 (jump, new_dest))
2419     goto cancel;
2420
2421   if (! apply_change_group ())
2422     return FALSE;
2423
2424   if (old_dest)
2425     LABEL_NUSES (old_dest) -= 1;
2426   if (new_dest)
2427     LABEL_NUSES (new_dest) += 1;
2428   JUMP_LABEL (jump) = new_dest;
2429
2430   if (reversep)
2431     invert_br_probabilities (jump);
2432
2433   /* Move the insns out of MERGE_BB to before the branch.  */
2434   if (head != NULL)
2435     {
2436       if (end == merge_bb->end)
2437         merge_bb->end = PREV_INSN (head);
2438
2439       head = squeeze_notes (head, end);
2440       if (GET_CODE (end) == NOTE
2441           && (NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_END
2442               || NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_BEG
2443               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_BEG
2444               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_END
2445               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_CONT
2446               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_VTOP))
2447         {
2448           if (head == end)
2449             return TRUE;
2450           end = PREV_INSN (end);
2451         }
2452
2453       reorder_insns (head, end, PREV_INSN (earliest));
2454     }
2455   return TRUE;
2456
2457  cancel:
2458   cancel_changes (0);
2459   return FALSE;
2460 }
2461 \f
2462 /* Main entry point for all if-conversion.  */
2463
2464 void
2465 if_convert (x_life_data_ok)
2466      int x_life_data_ok;
2467 {
2468   int block_num;
2469
2470   num_possible_if_blocks = 0;
2471   num_updated_if_blocks = 0;
2472   num_removed_blocks = 0;
2473   life_data_ok = (x_life_data_ok != 0);
2474
2475   /* Free up basic_block_for_insn so that we don't have to keep it 
2476      up to date, either here or in merge_blocks_nomove.  */
2477   free_basic_block_vars (1);
2478
2479   /* Compute postdominators if we think we'll use them.  */
2480   post_dominators = NULL;
2481   if (HAVE_conditional_execution || life_data_ok)
2482     {
2483       post_dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
2484       calculate_dominance_info (NULL, post_dominators, CDI_POST_DOMINATORS);
2485     }
2486
2487   /* Record initial block numbers.  */
2488   for (block_num = 0; block_num < n_basic_blocks; block_num++)
2489     SET_ORIG_INDEX (BASIC_BLOCK (block_num), block_num);
2490
2491   /* Go through each of the basic blocks looking for things to convert.  */
2492   for (block_num = 0; block_num < n_basic_blocks; )
2493     {
2494       basic_block bb = BASIC_BLOCK (block_num);
2495       if (find_if_header (bb))
2496         block_num = bb->index;
2497       else 
2498         block_num++;
2499     }
2500
2501   if (post_dominators)
2502     sbitmap_vector_free (post_dominators);
2503
2504   if (rtl_dump_file)
2505     fflush (rtl_dump_file);
2506
2507   /* Rebuild basic_block_for_insn for update_life_info and for gcse.  */
2508   compute_bb_for_insn (get_max_uid ());
2509
2510   /* Rebuild life info for basic blocks that require it.  */
2511   if (num_removed_blocks && life_data_ok)
2512     {
2513       sbitmap update_life_blocks = sbitmap_alloc (n_basic_blocks);
2514       sbitmap_zero (update_life_blocks);
2515
2516       /* If we allocated new pseudos, we must resize the array for sched1.  */
2517       if (max_regno < max_reg_num ())
2518         {
2519           max_regno = max_reg_num ();
2520           allocate_reg_info (max_regno, FALSE, FALSE);
2521         }
2522
2523       for (block_num = 0; block_num < n_basic_blocks; block_num++)
2524         if (UPDATE_LIFE (BASIC_BLOCK (block_num)))
2525           SET_BIT (update_life_blocks, block_num);
2526
2527       count_or_remove_death_notes (update_life_blocks, 1);
2528       /* ??? See about adding a mode that verifies that the initial
2529         set of blocks don't let registers come live.  */
2530       update_life_info (update_life_blocks, UPDATE_LIFE_GLOBAL,
2531                         PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
2532                         | PROP_KILL_DEAD_CODE);
2533
2534       sbitmap_free (update_life_blocks);
2535     }
2536
2537   /* Write the final stats.  */
2538   if (rtl_dump_file && num_possible_if_blocks > 0)
2539     {
2540       fprintf (rtl_dump_file,
2541                "\n%d possible IF blocks searched.\n",
2542                num_possible_if_blocks);
2543       fprintf (rtl_dump_file,
2544                "%d IF blocks converted.\n",
2545                num_updated_if_blocks);
2546       fprintf (rtl_dump_file,
2547                "%d basic blocks deleted.\n\n\n",
2548                num_removed_blocks);
2549     }
2550
2551 #ifdef ENABLE_CHECKING
2552   verify_flow_info ();
2553 #endif
2554 }