OSDN Git Service

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