OSDN Git Service

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