OSDN Git Service

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