OSDN Git Service

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