OSDN Git Service

* ifcvt.c (noce_operand_ok): Handle properly unarry operations.
[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 '1':
1421             return ! may_trap_p (XEXP (op, 0));
1422           case 'c':
1423           case '2':
1424             return ! may_trap_p (XEXP (op, 0)) && ! may_trap_p (XEXP (op, 1));
1425           }
1426         break;
1427       }
1428
1429   return ! may_trap_p (op);
1430 }
1431
1432 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
1433    without using conditional execution.  Return TRUE if we were
1434    successful at converting the the block.  */
1435
1436 static int
1437 noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
1438      basic_block test_bb;       /* Basic block test is in */
1439      basic_block then_bb;       /* Basic block for THEN block */
1440      basic_block else_bb;       /* Basic block for ELSE block */
1441      basic_block join_bb;       /* Basic block the join label is in */
1442 {
1443   /* We're looking for patterns of the form
1444
1445      (1) if (...) x = a; else x = b;
1446      (2) x = b; if (...) x = a;
1447      (3) if (...) x = a;   // as if with an initial x = x.
1448
1449      The later patterns require jumps to be more expensive.
1450
1451      ??? For future expansion, look for multiple X in such patterns.  */
1452
1453   struct noce_if_info if_info;
1454   rtx insn_a, insn_b;
1455   rtx set_a, set_b;
1456   rtx orig_x, x, a, b;
1457   rtx jump, cond, insn;
1458
1459   /* If this is not a standard conditional jump, we can't parse it.  */
1460   jump = test_bb->end;
1461   cond = noce_get_condition (jump, &if_info.cond_earliest);
1462   if (! cond)
1463     return FALSE;
1464
1465   /* If the conditional jump is more than just a conditional jump,
1466      then we can not do if-conversion on this block.  */
1467   if (! onlyjump_p (jump))
1468     return FALSE;
1469
1470   /* We must be comparing objects whose modes imply the size.  */
1471   if (GET_MODE (XEXP (cond, 0)) == BLKmode)
1472     return FALSE;
1473
1474   /* Look for one of the potential sets.  */
1475   insn_a = first_active_insn (then_bb);
1476   if (! insn_a
1477       || ! last_active_insn_p (then_bb, insn_a)
1478       || (set_a = single_set (insn_a)) == NULL_RTX)
1479     return FALSE;
1480
1481   x = SET_DEST (set_a);
1482   a = SET_SRC (set_a);
1483
1484   /* Look for the other potential set.  Make sure we've got equivalent
1485      destinations.  */
1486   /* ??? This is overconservative.  Storing to two different mems is
1487      as easy as conditionally computing the address.  Storing to a
1488      single mem merely requires a scratch memory to use as one of the
1489      destination addresses; often the memory immediately below the
1490      stack pointer is available for this.  */
1491   set_b = NULL_RTX;
1492   if (else_bb)
1493     {
1494       insn_b = first_active_insn (else_bb);
1495       if (! insn_b
1496           || ! last_active_insn_p (else_bb, insn_b)
1497           || (set_b = single_set (insn_b)) == NULL_RTX
1498           || ! rtx_equal_p (x, SET_DEST (set_b)))
1499         return FALSE;
1500     }
1501   else
1502     {
1503       insn_b = prev_nonnote_insn (if_info.cond_earliest);
1504       if (! insn_b
1505           || GET_CODE (insn_b) != INSN
1506           || (set_b = single_set (insn_b)) == NULL_RTX
1507           || ! rtx_equal_p (x, SET_DEST (set_b))
1508           || reg_mentioned_p (x, cond)
1509           || reg_mentioned_p (x, a)
1510           || reg_mentioned_p (x, SET_SRC (set_b)))
1511         insn_b = set_b = NULL_RTX;
1512     }
1513   b = (set_b ? SET_SRC (set_b) : x);
1514
1515   /* X may not be mentioned in the range (cond_earliest, jump].  */
1516   for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn))
1517     if (INSN_P (insn) && reg_mentioned_p (x, insn))
1518       return FALSE;
1519
1520   /* A and B may not be modified in the range [cond_earliest, jump).  */
1521   for (insn = if_info.cond_earliest; insn != jump; insn = NEXT_INSN (insn))
1522     if (INSN_P (insn)
1523         && (modified_in_p (a, insn) || modified_in_p (b, insn)))
1524       return FALSE;
1525
1526   /* Only operate on register destinations, and even then avoid extending
1527      the lifetime of hard registers on small register class machines.  */
1528   orig_x = x;
1529   if (GET_CODE (x) != REG
1530       || (SMALL_REGISTER_CLASSES
1531           && REGNO (x) < FIRST_PSEUDO_REGISTER))
1532     {
1533       if (no_new_pseudos)
1534         return FALSE;
1535       x = gen_reg_rtx (GET_MODE (x));
1536     }
1537
1538   /* Don't operate on sources that may trap or are volatile.  */
1539   if (! noce_operand_ok (a) || ! noce_operand_ok (b))
1540     return FALSE;
1541
1542   /* Set up the info block for our subroutines.  */
1543   if_info.test_bb = test_bb;
1544   if_info.cond = cond;
1545   if_info.jump = jump;
1546   if_info.insn_a = insn_a;
1547   if_info.insn_b = insn_b;
1548   if_info.x = x;
1549   if_info.a = a;
1550   if_info.b = b;
1551
1552   /* Try optimizations in some approximation of a useful order.  */
1553   /* ??? Should first look to see if X is live incoming at all.  If it
1554      isn't, we don't need anything but an unconditional set.  */
1555
1556   /* Look and see if A and B are really the same.  Avoid creating silly
1557      cmove constructs that no one will fix up later.  */
1558   if (rtx_equal_p (a, b))
1559     {
1560       /* If we have an INSN_B, we don't have to create any new rtl.  Just
1561          move the instruction that we already have.  If we don't have an
1562          INSN_B, that means that A == X, and we've got a noop move.  In
1563          that case don't do anything and let the code below delete INSN_A.  */
1564       if (insn_b && else_bb)
1565         {
1566           if (else_bb && insn_b == else_bb->end)
1567             else_bb->end = PREV_INSN (insn_b);
1568           reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest));
1569           insn_b = NULL_RTX;
1570         }
1571       /* If we have "x = b; if (...) x = a;", and x has side-effects, then
1572          x must be executed twice.  */
1573       else if (insn_b && side_effects_p (orig_x))
1574         return FALSE;
1575         
1576       x = orig_x;
1577       goto success;
1578     }
1579
1580   if (noce_try_store_flag (&if_info))
1581     goto success;
1582   if (noce_try_minmax (&if_info))
1583     goto success;
1584   if (noce_try_abs (&if_info))
1585     goto success;
1586   if (HAVE_conditional_move
1587       && noce_try_cmove (&if_info))
1588     goto success;
1589   if (! HAVE_conditional_execution)
1590     {
1591       if (noce_try_store_flag_constants (&if_info))
1592         goto success;
1593       if (noce_try_store_flag_inc (&if_info))
1594         goto success;
1595       if (noce_try_store_flag_mask (&if_info))
1596         goto success;
1597       if (HAVE_conditional_move
1598           && noce_try_cmove_arith (&if_info))
1599         goto success;
1600     }
1601
1602   return FALSE;
1603
1604  success:
1605   /* The original sets may now be killed.  */
1606   if (insn_a == then_bb->end)
1607     then_bb->end = PREV_INSN (insn_a);
1608   flow_delete_insn (insn_a);
1609
1610   /* Several special cases here: First, we may have reused insn_b above,
1611      in which case insn_b is now NULL.  Second, we want to delete insn_b
1612      if it came from the ELSE block, because follows the now correct
1613      write that appears in the TEST block.  However, if we got insn_b from
1614      the TEST block, it may in fact be loading data needed for the comparison.
1615      We'll let life_analysis remove the insn if it's really dead.  */
1616   if (insn_b && else_bb)
1617     {
1618       if (insn_b == else_bb->end)
1619         else_bb->end = PREV_INSN (insn_b);
1620       flow_delete_insn (insn_b);
1621     }
1622
1623   /* The new insns will have been inserted before cond_earliest.  We should
1624      be able to remove the jump with impunity, but the condition itself may
1625      have been modified by gcse to be shared across basic blocks.  */
1626   test_bb->end = PREV_INSN (jump);
1627   flow_delete_insn (jump);
1628
1629   /* If we used a temporary, fix it up now.  */
1630   if (orig_x != x)
1631     {
1632       start_sequence ();
1633       emit_move_insn (orig_x, x);
1634       insn_b = gen_sequence ();
1635       end_sequence ();
1636
1637       test_bb->end = emit_insn_after (insn_b, test_bb->end);
1638     }
1639
1640   /* Merge the blocks!  */
1641   merge_if_block (test_bb, then_bb, else_bb, join_bb);
1642
1643   return TRUE;
1644 }
1645 \f
1646 /* Attempt to convert an IF-THEN or IF-THEN-ELSE block into
1647    straight line code.  Return true if successful.  */
1648
1649 static int
1650 process_if_block (test_bb, then_bb, else_bb, join_bb)
1651      basic_block test_bb;       /* Basic block test is in */
1652      basic_block then_bb;       /* Basic block for THEN block */
1653      basic_block else_bb;       /* Basic block for ELSE block */
1654      basic_block join_bb;       /* Basic block the join label is in */
1655 {
1656   if (! reload_completed
1657       && noce_process_if_block (test_bb, then_bb, else_bb, join_bb))
1658     return TRUE;
1659
1660   if (HAVE_conditional_execution
1661       && reload_completed
1662       && cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb))
1663     return TRUE;
1664
1665   return FALSE;
1666 }
1667
1668 /* Merge the blocks and mark for local life update.  */
1669
1670 static void
1671 merge_if_block (test_bb, then_bb, else_bb, join_bb)
1672      basic_block test_bb;       /* Basic block test is in */
1673      basic_block then_bb;       /* Basic block for THEN block */
1674      basic_block else_bb;       /* Basic block for ELSE block */
1675      basic_block join_bb;       /* Basic block the join label is in */
1676 {
1677   basic_block combo_bb;
1678
1679   /* All block merging is done into the lower block numbers.  */
1680
1681   combo_bb = test_bb;
1682
1683   /* First merge TEST block into THEN block.  This is a no-brainer since
1684      the THEN block did not have a code label to begin with.  */
1685
1686   if (combo_bb->global_live_at_end)
1687     COPY_REG_SET (combo_bb->global_live_at_end, then_bb->global_live_at_end);
1688   merge_blocks_nomove (combo_bb, then_bb);
1689   num_removed_blocks++;
1690
1691   /* The ELSE block, if it existed, had a label.  That label count
1692      will almost always be zero, but odd things can happen when labels
1693      get their addresses taken.  */
1694   if (else_bb)
1695     {
1696       merge_blocks_nomove (combo_bb, else_bb);
1697       num_removed_blocks++;
1698     }
1699
1700   /* If there was no join block reported, that means it was not adjacent
1701      to the others, and so we cannot merge them.  */
1702
1703   if (! join_bb)
1704     {
1705       /* The outgoing edge for the current COMBO block should already
1706          be correct.  Verify this.  */
1707       if (combo_bb->succ == NULL_EDGE)
1708         abort ();
1709
1710       /* There should sill be a branch at the end of the THEN or ELSE
1711          blocks taking us to our final destination.  */
1712       if (! simplejump_p (combo_bb->end)
1713           && ! returnjump_p (combo_bb->end))
1714         abort ();
1715     }
1716
1717   /* The JOIN block may have had quite a number of other predecessors too.
1718      Since we've already merged the TEST, THEN and ELSE blocks, we should
1719      have only one remaining edge from our if-then-else diamond.  If there
1720      is more than one remaining edge, it must come from elsewhere.  There
1721      may be zero incoming edges if the THEN block didn't actually join 
1722      back up (as with a call to abort).  */
1723   else if (join_bb->pred == NULL || join_bb->pred->pred_next == NULL)
1724     {
1725       /* We can merge the JOIN.  */
1726       if (combo_bb->global_live_at_end)
1727         COPY_REG_SET (combo_bb->global_live_at_end,
1728                       join_bb->global_live_at_end);
1729       merge_blocks_nomove (combo_bb, join_bb);
1730       num_removed_blocks++;
1731     }
1732   else
1733     {
1734       /* We cannot merge the JOIN.  */
1735
1736       /* The outgoing edge for the current COMBO block should already
1737          be correct.  Verify this.  */
1738       if (combo_bb->succ->succ_next != NULL_EDGE
1739           || combo_bb->succ->dest != join_bb)
1740         abort ();
1741
1742       /* Remove the jump and cruft from the end of the COMBO block.  */
1743       tidy_fallthru_edge (combo_bb->succ, combo_bb, join_bb);
1744     }
1745
1746   /* Make sure we update life info properly.  */
1747   SET_UPDATE_LIFE (combo_bb);
1748
1749   num_updated_if_blocks++;
1750 }
1751 \f
1752 /* Find a block ending in a simple IF condition.  Return TRUE if
1753    we were able to transform it in some way.  */
1754
1755 static int
1756 find_if_header (test_bb)
1757      basic_block test_bb;
1758 {
1759   edge then_edge;
1760   edge else_edge;
1761
1762   /* The kind of block we're looking for has exactly two successors.  */
1763   if ((then_edge = test_bb->succ) == NULL_EDGE
1764       || (else_edge = then_edge->succ_next) == NULL_EDGE
1765       || else_edge->succ_next != NULL_EDGE)
1766     return FALSE;
1767
1768   /* Neither edge should be abnormal.  */
1769   if ((then_edge->flags & EDGE_COMPLEX)
1770       || (else_edge->flags & EDGE_COMPLEX))
1771     return FALSE;
1772
1773   /* The THEN edge is canonically the one that falls through.  */
1774   if (then_edge->flags & EDGE_FALLTHRU)
1775     ;
1776   else if (else_edge->flags & EDGE_FALLTHRU)
1777     {
1778       edge e = else_edge;
1779       else_edge = then_edge;
1780       then_edge = e;
1781     }
1782   else
1783     /* Otherwise this must be a multiway branch of some sort.  */
1784     return FALSE;
1785
1786   if (find_if_block (test_bb, then_edge, else_edge))
1787     goto success;
1788   if (post_dominators
1789       && (! HAVE_conditional_execution || reload_completed))
1790     {
1791       if (find_if_case_1 (test_bb, then_edge, else_edge))
1792         goto success;
1793       if (find_if_case_2 (test_bb, then_edge, else_edge))
1794         goto success;
1795     }
1796
1797   return FALSE;
1798
1799  success:
1800   if (rtl_dump_file)
1801     fprintf (rtl_dump_file, "Conversion succeeded.\n");
1802   return TRUE;
1803 }
1804
1805 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
1806    block.  If so, we'll try to convert the insns to not require the branch.
1807    Return TRUE if we were successful at converting the the block.  */
1808
1809 static int
1810 find_if_block (test_bb, then_edge, else_edge)
1811       basic_block test_bb;
1812       edge then_edge, else_edge;
1813 {
1814   basic_block then_bb = then_edge->dest;
1815   basic_block else_bb = else_edge->dest;
1816   basic_block join_bb = NULL_BLOCK;
1817   edge then_succ = then_bb->succ;
1818   edge else_succ = else_bb->succ;
1819   int next_index;
1820
1821   /* The THEN block of an IF-THEN combo must have exactly one predecessor.  */
1822   if (then_bb->pred->pred_next != NULL_EDGE)
1823     return FALSE;
1824
1825   /* The THEN block of an IF-THEN combo must have zero or one successors.  */
1826   if (then_succ != NULL_EDGE
1827       && (then_succ->succ_next != NULL_EDGE
1828           || (then_succ->flags & EDGE_COMPLEX)))
1829     return FALSE;
1830
1831   /* If the THEN block has no successors, conditional execution can still
1832      make a conditional call.  Don't do this unless the ELSE block has
1833      only one incoming edge -- the CFG manipulation is too ugly otherwise.
1834      Check for the last insn of the THEN block being an indirect jump, which
1835      is listed as not having any successors, but confuses the rest of the CE
1836      code processing.  XXX we should fix this in the future.  */
1837   if (then_succ == NULL)
1838     {
1839       if (else_bb->pred->pred_next == NULL_EDGE)
1840         {
1841           rtx last_insn = then_bb->end;
1842
1843           while (last_insn
1844                  && GET_CODE (last_insn) == NOTE
1845                  && last_insn != then_bb->head)
1846             last_insn = PREV_INSN (last_insn);
1847
1848           if (last_insn
1849               && GET_CODE (last_insn) == JUMP_INSN
1850               && ! simplejump_p (last_insn))
1851             return FALSE;
1852
1853           join_bb = else_bb;
1854           else_bb = NULL_BLOCK;
1855         }
1856       else
1857         return FALSE;
1858     }
1859
1860   /* If the THEN block's successor is the other edge out of the TEST block,
1861      then we have an IF-THEN combo without an ELSE.  */
1862   else if (then_succ->dest == else_bb)
1863     {
1864       join_bb = else_bb;
1865       else_bb = NULL_BLOCK;
1866     }
1867
1868   /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
1869      has exactly one predecessor and one successor, and the outgoing edge
1870      is not complex, then we have an IF-THEN-ELSE combo.  */
1871   else if (else_succ != NULL_EDGE
1872            && then_succ->dest == else_succ->dest
1873            && else_bb->pred->pred_next == NULL_EDGE
1874            && else_succ->succ_next == NULL_EDGE
1875            && ! (else_succ->flags & EDGE_COMPLEX))
1876     join_bb = else_succ->dest;
1877
1878   /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination.  */
1879   else
1880     return FALSE;          
1881
1882   num_possible_if_blocks++;
1883
1884   if (rtl_dump_file)
1885     {
1886       if (else_bb)
1887         fprintf (rtl_dump_file,
1888                  "\nIF-THEN-ELSE block found, start %d, then %d, else %d, join %d\n",
1889                  test_bb->index, then_bb->index, else_bb->index,
1890                  join_bb->index);
1891       else
1892         fprintf (rtl_dump_file,
1893                  "\nIF-THEN block found, start %d, then %d, join %d\n",
1894                  test_bb->index, then_bb->index, join_bb->index);
1895     }
1896
1897   /* Make sure IF, THEN, and ELSE, blocks are adjacent.  Actually, we
1898      get the first condition for free, since we've already asserted that
1899      there's a fallthru edge from IF to THEN.  */
1900   /* ??? As an enhancement, move the ELSE block.  Have to deal with EH and
1901      BLOCK notes, if by no other means than aborting the merge if they
1902      exist.  Sticky enough I don't want to think about it now.  */
1903   next_index = then_bb->index;
1904   if (else_bb && ++next_index != else_bb->index)
1905     return FALSE;
1906   if (++next_index != join_bb->index)
1907     {
1908       if (else_bb)
1909         join_bb = NULL;
1910       else
1911         return FALSE;
1912     }
1913
1914   /* Do the real work.  */
1915   return process_if_block (test_bb, then_bb, else_bb, join_bb);
1916 }
1917
1918 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
1919    transformable, but not necessarily the other.  There need be no
1920    JOIN block.
1921
1922    Return TRUE if we were successful at converting the the block.
1923
1924    Cases we'd like to look at:
1925
1926    (1)
1927         if (test) goto over; // x not live
1928         x = a;
1929         goto label;
1930         over:
1931
1932    becomes
1933
1934         x = a;
1935         if (! test) goto label;
1936
1937    (2)
1938         if (test) goto E; // x not live
1939         x = big();
1940         goto L;
1941         E:
1942         x = b;
1943         goto M;
1944
1945    becomes
1946
1947         x = b;
1948         if (test) goto M;
1949         x = big();
1950         goto L;
1951
1952    (3) // This one's really only interesting for targets that can do
1953        // multiway branching, e.g. IA-64 BBB bundles.  For other targets
1954        // it results in multiple branches on a cache line, which often
1955        // does not sit well with predictors.
1956
1957         if (test1) goto E; // predicted not taken
1958         x = a;
1959         if (test2) goto F;
1960         ...
1961         E:
1962         x = b;
1963         J:
1964
1965    becomes
1966
1967         x = a;
1968         if (test1) goto E;
1969         if (test2) goto F;
1970
1971    Notes:
1972
1973    (A) Don't do (2) if the branch is predicted against the block we're
1974    eliminating.  Do it anyway if we can eliminate a branch; this requires
1975    that the sole successor of the eliminated block postdominate the other
1976    side of the if.
1977
1978    (B) With CE, on (3) we can steal from both sides of the if, creating
1979
1980         if (test1) x = a;
1981         if (!test1) x = b;
1982         if (test1) goto J;
1983         if (test2) goto F;
1984         ...
1985         J:
1986
1987    Again, this is most useful if J postdominates.
1988
1989    (C) CE substitutes for helpful life information.
1990
1991    (D) These heuristics need a lot of work.  */
1992
1993 /* Tests for case 1 above.  */
1994
1995 static int
1996 find_if_case_1 (test_bb, then_edge, else_edge)
1997       basic_block test_bb;
1998       edge then_edge, else_edge;
1999 {
2000   basic_block then_bb = then_edge->dest;
2001   basic_block else_bb = else_edge->dest;
2002   edge then_succ = then_bb->succ;
2003   rtx new_lab;
2004
2005   /* THEN has one successor.  */
2006   if (!then_succ || then_succ->succ_next != NULL)
2007     return FALSE;
2008
2009   /* THEN does not fall through, but is not strange either.  */
2010   if (then_succ->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
2011     return FALSE;
2012
2013   /* THEN has one predecessor.  */
2014   if (then_bb->pred->pred_next != NULL)
2015     return FALSE;
2016
2017   /* ELSE follows THEN.  (??? could be moved)  */
2018   if (else_bb->index != then_bb->index + 1)
2019     return FALSE;
2020
2021   num_possible_if_blocks++;
2022   if (rtl_dump_file)
2023     fprintf (rtl_dump_file,
2024              "\nIF-CASE-1 found, start %d, then %d\n",
2025              test_bb->index, then_bb->index);
2026
2027   /* THEN is small.  */
2028   if (count_bb_insns (then_bb) > BRANCH_COST)
2029     return FALSE;
2030
2031   /* Find the label for THEN's destination.  */
2032   if (then_succ->dest == EXIT_BLOCK_PTR)
2033     new_lab = NULL_RTX;
2034   else
2035     {
2036       new_lab = JUMP_LABEL (then_bb->end);
2037       if (! new_lab)
2038         abort ();
2039     }
2040
2041   /* Registers set are dead, or are predicable.  */
2042   if (! dead_or_predicable (test_bb, then_bb, else_bb, new_lab, 1))
2043     return FALSE;
2044
2045   /* Conversion went ok, including moving the insns and fixing up the
2046      jump.  Adjust the CFG to match.  */
2047
2048   SET_UPDATE_LIFE (test_bb);
2049   bitmap_operation (test_bb->global_live_at_end,
2050                     else_bb->global_live_at_start,
2051                     then_bb->global_live_at_end, BITMAP_IOR);
2052   
2053   make_edge (NULL, test_bb, then_succ->dest, 0);
2054   flow_delete_block (then_bb);
2055   tidy_fallthru_edge (else_edge, test_bb, else_bb);
2056
2057   num_removed_blocks++;
2058   num_updated_if_blocks++;
2059
2060   return TRUE;
2061 }
2062
2063 /* Test for case 2 above.  */
2064
2065 static int
2066 find_if_case_2 (test_bb, then_edge, else_edge)
2067       basic_block test_bb;
2068       edge then_edge, else_edge;
2069 {
2070   basic_block then_bb = then_edge->dest;
2071   basic_block else_bb = else_edge->dest;
2072   edge else_succ = else_bb->succ;
2073   rtx new_lab, note;
2074
2075   /* ELSE has one successor.  */
2076   if (!else_succ || else_succ->succ_next != NULL)
2077     return FALSE;
2078
2079   /* ELSE outgoing edge is not complex.  */
2080   if (else_succ->flags & EDGE_COMPLEX)
2081     return FALSE;
2082
2083   /* ELSE has one predecessor.  */
2084   if (else_bb->pred->pred_next != NULL)
2085     return FALSE;
2086
2087   /* THEN is not EXIT.  */
2088   if (then_bb->index < 0)
2089     return FALSE;
2090
2091   /* ELSE is predicted or SUCC(ELSE) postdominates THEN.  */
2092   note = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
2093   if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
2094     ;
2095   else if (else_succ->dest->index < 0
2096            || TEST_BIT (post_dominators[ORIG_INDEX (then_bb)], 
2097                         ORIG_INDEX (else_succ->dest)))
2098     ;
2099   else
2100     return FALSE;
2101
2102   num_possible_if_blocks++;
2103   if (rtl_dump_file)
2104     fprintf (rtl_dump_file,
2105              "\nIF-CASE-2 found, start %d, else %d\n",
2106              test_bb->index, else_bb->index);
2107
2108   /* ELSE is small.  */
2109   if (count_bb_insns (then_bb) > BRANCH_COST)
2110     return FALSE;
2111
2112   /* Find the label for ELSE's destination.  */
2113   if (else_succ->dest == EXIT_BLOCK_PTR)
2114     new_lab = NULL_RTX;
2115   else
2116     {
2117       if (else_succ->flags & EDGE_FALLTHRU)
2118         {
2119           new_lab = else_succ->dest->head;
2120           if (GET_CODE (new_lab) != CODE_LABEL)
2121             abort ();
2122         }
2123       else
2124         {
2125           new_lab = JUMP_LABEL (else_bb->end);
2126           if (! new_lab)
2127             abort ();
2128         }
2129     }
2130
2131   /* Registers set are dead, or are predicable.  */
2132   if (! dead_or_predicable (test_bb, else_bb, then_bb, new_lab, 0))
2133     return FALSE;
2134
2135   /* Conversion went ok, including moving the insns and fixing up the
2136      jump.  Adjust the CFG to match.  */
2137
2138   SET_UPDATE_LIFE (test_bb);
2139   bitmap_operation (test_bb->global_live_at_end,
2140                     then_bb->global_live_at_start,
2141                     else_bb->global_live_at_end, BITMAP_IOR);
2142   
2143   remove_edge (else_edge);
2144   make_edge (NULL, test_bb, else_succ->dest, 0);
2145   flow_delete_block (else_bb);
2146
2147   num_removed_blocks++;
2148   num_updated_if_blocks++;
2149
2150   /* ??? We may now fallthru from one of THEN's successors into a join
2151      block.  Rerun cleanup_cfg?  Examine things manually?  Wait?  */
2152
2153   return TRUE;
2154 }
2155
2156 /* A subroutine of dead_or_predicable called through for_each_rtx.
2157    Return 1 if a memory is found.  */
2158
2159 static int
2160 find_memory (px, data)
2161      rtx *px;
2162      void *data ATTRIBUTE_UNUSED;
2163 {
2164   return GET_CODE (*px) == MEM;
2165 }
2166
2167 /* Used by the code above to perform the actual rtl transformations.
2168    Return TRUE if successful.
2169
2170    TEST_BB is the block containing the conditional branch.  MERGE_BB
2171    is the block containing the code to manipulate.  NEW_DEST is the
2172    label TEST_BB should be branching to after the conversion.
2173    REVERSEP is true if the sense of the branch should be reversed.  */
2174
2175 static int
2176 dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
2177      basic_block test_bb, merge_bb, other_bb;
2178      rtx new_dest;
2179      int reversep;
2180 {
2181   rtx head, end, jump, earliest, old_dest;
2182
2183   /* No code movement can occur if we'd be scrogging EH regions.
2184      Within MERGE_BB, ensure that we've not got stray EH_BEG or EH_END
2185      notes within the block.  Between the blocks, checking that the end
2186      region numbers match ensures that we won't disrupt the nesting
2187      between regions.  */
2188   if (merge_bb->eh_beg != merge_bb->eh_end
2189       || merge_bb->eh_end != test_bb->eh_end)
2190     return FALSE;
2191
2192   jump = test_bb->end;
2193
2194   /* Find the extent of the real code in the merge block.  */
2195   head = merge_bb->head;
2196   end = merge_bb->end;
2197
2198   if (GET_CODE (head) == CODE_LABEL)
2199     head = NEXT_INSN (head);
2200   if (GET_CODE (head) == NOTE)
2201     {
2202       if (head == end)
2203         {
2204           head = end = NULL_RTX;
2205           goto no_body;
2206         }
2207       head = NEXT_INSN (head);
2208     }
2209
2210   if (GET_CODE (end) == JUMP_INSN)
2211     {
2212       if (head == end)
2213         {
2214           head = end = NULL_RTX;
2215           goto no_body;
2216         }
2217       end = PREV_INSN (end);
2218     }
2219
2220   /* Disable handling dead code by conditional execution if the machine needs
2221      to do anything funny with the tests, etc.  */
2222 #ifndef IFCVT_MODIFY_TESTS
2223   if (HAVE_conditional_execution)
2224     {
2225       /* In the conditional execution case, we have things easy.  We know
2226          the condition is reversable.  We don't have to check life info,
2227          becase we're going to conditionally execute the code anyway.
2228          All that's left is making sure the insns involved can actually
2229          be predicated.  */
2230
2231       rtx cond, prob_val;
2232
2233       cond = cond_exec_get_condition (jump);
2234
2235       prob_val = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
2236       if (prob_val)
2237         prob_val = XEXP (prob_val, 0);
2238
2239       if (reversep)
2240         {
2241           cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
2242                                  GET_MODE (cond), XEXP (cond, 0),
2243                                  XEXP (cond, 1));
2244           if (prob_val)
2245             prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val));
2246         }
2247
2248       if (! cond_exec_process_insns (head, end, cond, prob_val, 0))
2249         goto cancel;
2250
2251       earliest = jump;
2252     }
2253   else
2254 #endif
2255     {
2256       /* In the non-conditional execution case, we have to verify that there
2257          are no trapping operations, no calls, no references to memory, and
2258          that any registers modified are dead at the branch site.  */
2259
2260       rtx insn, cond, prev;
2261       regset_head merge_set_head, tmp_head, test_live_head, test_set_head;
2262       regset merge_set, tmp, test_live, test_set;
2263       struct propagate_block_info *pbi;
2264       int i, fail = 0;
2265
2266       /* Check for no calls or trapping operations.  */
2267       for (insn = head; ; insn = NEXT_INSN (insn))
2268         {
2269           if (GET_CODE (insn) == CALL_INSN)
2270             return FALSE;
2271           if (INSN_P (insn))
2272             {
2273               if (may_trap_p (PATTERN (insn)))
2274                 return FALSE;
2275
2276               /* ??? Even non-trapping memories such as stack frame
2277                  references must be avoided.  For stores, we collect
2278                  no lifetime info; for reads, we'd have to assert
2279                  true_dependance false against every store in the
2280                  TEST range.  */
2281               if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
2282                 return FALSE;
2283             }
2284           if (insn == end)
2285             break;
2286         }
2287
2288       if (! any_condjump_p (jump))
2289         return FALSE;
2290
2291       /* Find the extent of the conditional.  */
2292       cond = noce_get_condition (jump, &earliest);
2293       if (! cond)
2294         return FALSE;
2295
2296       /* Collect:
2297            MERGE_SET = set of registers set in MERGE_BB
2298            TEST_LIVE = set of registers live at EARLIEST
2299            TEST_SET  = set of registers set between EARLIEST and the
2300                        end of the block.  */
2301
2302       tmp = INITIALIZE_REG_SET (tmp_head);
2303       merge_set = INITIALIZE_REG_SET (merge_set_head);
2304       test_live = INITIALIZE_REG_SET (test_live_head);
2305       test_set = INITIALIZE_REG_SET (test_set_head);
2306
2307       /* ??? bb->local_set is only valid during calculate_global_regs_live,
2308          so we must recompute usage for MERGE_BB.  Not so bad, I suppose, 
2309          since we've already asserted that MERGE_BB is small.  */
2310       propagate_block (merge_bb, tmp, merge_set, merge_set, 0);
2311
2312       /* For small register class machines, don't lengthen lifetimes of
2313          hard registers before reload.  */
2314       if (SMALL_REGISTER_CLASSES && ! reload_completed)
2315         {
2316           EXECUTE_IF_SET_IN_BITMAP
2317             (merge_set, 0, i,
2318              {
2319                if (i < FIRST_PSEUDO_REGISTER
2320                    && ! fixed_regs[i]
2321                    && ! global_regs[i])
2322                 fail = 1;
2323              });
2324         }
2325
2326       /* For TEST, we're interested in a range of insns, not a whole block.
2327          Moreover, we're interested in the insns live from OTHER_BB.  */
2328
2329       COPY_REG_SET (test_live, other_bb->global_live_at_start);
2330       pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set,
2331                                        0);
2332
2333       for (insn = jump; ; insn = prev)
2334         {
2335           prev = propagate_one_insn (pbi, insn);
2336           if (insn == earliest)
2337             break;
2338         }
2339
2340       free_propagate_block_info (pbi);
2341
2342       /* We can perform the transformation if
2343            MERGE_SET & (TEST_SET | TEST_LIVE)
2344          and
2345            TEST_SET & merge_bb->global_live_at_start
2346          are empty.  */
2347
2348       bitmap_operation (tmp, test_set, test_live, BITMAP_IOR);
2349       bitmap_operation (tmp, tmp, merge_set, BITMAP_AND);
2350       EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
2351
2352       bitmap_operation (tmp, test_set, merge_bb->global_live_at_start,
2353                         BITMAP_AND);
2354       EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
2355
2356       FREE_REG_SET (tmp);
2357       FREE_REG_SET (merge_set);
2358       FREE_REG_SET (test_live);
2359       FREE_REG_SET (test_set);
2360
2361       if (fail)
2362         return FALSE;
2363     }
2364
2365  no_body:
2366   /* We don't want to use normal invert_jump or redirect_jump because
2367      we don't want to delete_insn called.  Also, we want to do our own
2368      change group management.  */
2369
2370   old_dest = JUMP_LABEL (jump);
2371   if (reversep
2372       ? ! invert_jump_1 (jump, new_dest)
2373       : ! redirect_jump_1 (jump, new_dest))
2374     goto cancel;
2375
2376   if (! apply_change_group ())
2377     return FALSE;
2378
2379   if (old_dest)
2380     LABEL_NUSES (old_dest) -= 1;
2381   if (new_dest)
2382     LABEL_NUSES (new_dest) += 1;
2383   JUMP_LABEL (jump) = new_dest;
2384
2385   if (reversep)
2386     {
2387       rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
2388       if (note)
2389         XEXP (note, 0) = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (note, 0)));
2390     }
2391
2392   /* Move the insns out of MERGE_BB to before the branch.  */
2393   if (head != NULL)
2394     {
2395       if (end == merge_bb->end)
2396         merge_bb->end = PREV_INSN (head);
2397
2398       head = squeeze_notes (head, end);
2399       if (GET_CODE (end) == NOTE
2400           && (NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_END
2401               || NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_BEG
2402               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_BEG
2403               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_END
2404               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_CONT
2405               || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_VTOP))
2406         {
2407           if (head == end)
2408             return TRUE;
2409           end = PREV_INSN (end);
2410         }
2411
2412       reorder_insns (head, end, PREV_INSN (earliest));
2413     }
2414   return TRUE;
2415
2416  cancel:
2417   cancel_changes (0);
2418   return FALSE;
2419 }
2420 \f
2421 /* Main entry point for all if-conversion.  */
2422
2423 void
2424 if_convert (life_data_ok)
2425      int life_data_ok;
2426 {
2427   int block_num;
2428
2429   num_possible_if_blocks = 0;
2430   num_updated_if_blocks = 0;
2431   num_removed_blocks = 0;
2432
2433   /* Free up basic_block_for_insn so that we don't have to keep it 
2434      up to date, either here or in merge_blocks_nomove.  */
2435   free_basic_block_vars (1);
2436
2437   /* Compute postdominators if we think we'll use them.  */
2438   post_dominators = NULL;
2439   if (HAVE_conditional_execution || life_data_ok)
2440     {
2441       post_dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
2442       calculate_dominance_info (NULL, post_dominators, CDI_POST_DOMINATORS);
2443     }
2444
2445   /* Record initial block numbers.  */
2446   for (block_num = 0; block_num < n_basic_blocks; block_num++)
2447     SET_ORIG_INDEX (BASIC_BLOCK (block_num), block_num);
2448
2449   /* Go through each of the basic blocks looking for things to convert.  */
2450   for (block_num = 0; block_num < n_basic_blocks; )
2451     {
2452       basic_block bb = BASIC_BLOCK (block_num);
2453       if (find_if_header (bb))
2454         block_num = bb->index;
2455       else 
2456         block_num++;
2457     }
2458
2459   if (post_dominators)
2460     sbitmap_vector_free (post_dominators);
2461
2462   if (rtl_dump_file)
2463     fflush (rtl_dump_file);
2464
2465   /* Rebuild basic_block_for_insn for update_life_info and for gcse.  */
2466   compute_bb_for_insn (get_max_uid ());
2467
2468   /* Rebuild life info for basic blocks that require it.  */
2469   if (num_removed_blocks && life_data_ok)
2470     {
2471       sbitmap update_life_blocks = sbitmap_alloc (n_basic_blocks);
2472       sbitmap_zero (update_life_blocks);
2473
2474       /* If we allocated new pseudos, we must resize the array for sched1.  */
2475       if (max_regno < max_reg_num ())
2476         {
2477           max_regno = max_reg_num ();
2478           allocate_reg_info (max_regno, FALSE, FALSE);
2479         }
2480
2481       for (block_num = 0; block_num < n_basic_blocks; block_num++)
2482         if (UPDATE_LIFE (BASIC_BLOCK (block_num)))
2483           SET_BIT (update_life_blocks, block_num);
2484
2485       count_or_remove_death_notes (update_life_blocks, 1);
2486       /* ??? See about adding a mode that verifies that the initial
2487         set of blocks don't let registers come live.  */
2488       update_life_info (update_life_blocks, UPDATE_LIFE_GLOBAL,
2489                         PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
2490                         | PROP_KILL_DEAD_CODE);
2491
2492       sbitmap_free (update_life_blocks);
2493     }
2494
2495   /* Write the final stats.  */
2496   if (rtl_dump_file && num_possible_if_blocks > 0)
2497     {
2498       fprintf (rtl_dump_file,
2499                "\n%d possible IF blocks searched.\n",
2500                num_possible_if_blocks);
2501       fprintf (rtl_dump_file,
2502                "%d IF blocks converted.\n",
2503                num_updated_if_blocks);
2504       fprintf (rtl_dump_file,
2505                "%d basic blocks deleted.\n\n\n",
2506                num_removed_blocks);
2507     }
2508
2509 #ifdef ENABLE_CHECKING
2510   verify_flow_info ();
2511 #endif
2512 }