OSDN Git Service

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