OSDN Git Service

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