OSDN Git Service

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