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