OSDN Git Service

s/just/used/, stupid me keep on using "just" instead of "used".
[pf3gnuchains/gcc-fork.git] / gcc / ifcvt.c
1 /* If-conversion support.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4
5    This file is part of GCC.
6
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    GCC is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING.  If not, write to the Free
19    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26
27 #include "rtl.h"
28 #include "regs.h"
29 #include "function.h"
30 #include "flags.h"
31 #include "insn-config.h"
32 #include "recog.h"
33 #include "except.h"
34 #include "hard-reg-set.h"
35 #include "basic-block.h"
36 #include "expr.h"
37 #include "real.h"
38 #include "output.h"
39 #include "optabs.h"
40 #include "toplev.h"
41 #include "tm_p.h"
42 #include "cfgloop.h"
43 #include "target.h"
44
45
46 #ifndef HAVE_conditional_execution
47 #define HAVE_conditional_execution 0
48 #endif
49 #ifndef HAVE_conditional_move
50 #define HAVE_conditional_move 0
51 #endif
52 #ifndef HAVE_incscc
53 #define HAVE_incscc 0
54 #endif
55 #ifndef HAVE_decscc
56 #define HAVE_decscc 0
57 #endif
58 #ifndef HAVE_trap
59 #define HAVE_trap 0
60 #endif
61 #ifndef HAVE_conditional_trap
62 #define HAVE_conditional_trap 0
63 #endif
64
65 #ifndef MAX_CONDITIONAL_EXECUTE
66 #define MAX_CONDITIONAL_EXECUTE   (BRANCH_COST + 1)
67 #endif
68
69 #define NULL_EDGE       ((edge) NULL)
70 #define NULL_BLOCK      ((basic_block) NULL)
71
72 /* # of IF-THEN or IF-THEN-ELSE blocks we looked at  */
73 static int num_possible_if_blocks;
74
75 /* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
76    execution.  */
77 static int num_updated_if_blocks;
78
79 /* # of changes made which require life information to be updated.  */
80 static int num_true_changes;
81
82 /* Whether conditional execution changes were made.  */
83 static int cond_exec_changed_p;
84
85 /* True if life data ok at present.  */
86 static bool life_data_ok;
87
88 /* Forward references.  */
89 static int count_bb_insns (basic_block);
90 static bool cheap_bb_rtx_cost_p (basic_block, int);
91 static rtx first_active_insn (basic_block);
92 static rtx last_active_insn (basic_block, int);
93 static basic_block block_fallthru (basic_block);
94 static int cond_exec_process_insns (ce_if_block_t *, rtx, rtx, rtx, rtx, int);
95 static rtx cond_exec_get_condition (rtx);
96 static int cond_exec_process_if_block (ce_if_block_t *, int);
97 static rtx noce_get_condition (rtx, rtx *);
98 static int noce_operand_ok (rtx);
99 static int noce_process_if_block (ce_if_block_t *);
100 static int process_if_block (ce_if_block_t *);
101 static void merge_if_block (ce_if_block_t *);
102 static int find_cond_trap (basic_block, edge, edge);
103 static basic_block find_if_header (basic_block, int);
104 static int block_jumps_and_fallthru_p (basic_block, basic_block);
105 static int find_if_block (ce_if_block_t *);
106 static int find_if_case_1 (basic_block, edge, edge);
107 static int find_if_case_2 (basic_block, edge, edge);
108 static int find_memory (rtx *, void *);
109 static int dead_or_predicable (basic_block, basic_block, basic_block,
110                                basic_block, int);
111 static void noce_emit_move_insn (rtx, rtx);
112 static rtx block_has_only_trap (basic_block);
113 static void mark_loop_exit_edges (void);
114 \f
115 /* Sets EDGE_LOOP_EXIT flag for all loop exits.  */
116 static void
117 mark_loop_exit_edges (void)
118 {
119   struct loops loops;
120   basic_block bb;
121   edge e;
122   
123   flow_loops_find (&loops, LOOP_TREE);
124   free_dominance_info (CDI_DOMINATORS);
125   
126   if (loops.num > 1)
127     {
128       FOR_EACH_BB (bb)
129         {
130           edge_iterator ei;
131           FOR_EACH_EDGE (e, ei, bb->succs)
132             {
133               if (find_common_loop (bb->loop_father, e->dest->loop_father)
134                   != bb->loop_father)
135                 e->flags |= EDGE_LOOP_EXIT;
136               else
137                 e->flags &= ~EDGE_LOOP_EXIT;
138             }
139         }
140     }
141
142   flow_loops_free (&loops);
143 }
144
145 /* Count the number of non-jump active insns in BB.  */
146
147 static int
148 count_bb_insns (basic_block bb)
149 {
150   int count = 0;
151   rtx insn = BB_HEAD (bb);
152
153   while (1)
154     {
155       if (CALL_P (insn) || NONJUMP_INSN_P (insn))
156         count++;
157
158       if (insn == BB_END (bb))
159         break;
160       insn = NEXT_INSN (insn);
161     }
162
163   return count;
164 }
165
166 /* Determine whether the total insn_rtx_cost on non-jump insns in
167    basic block BB is less than MAX_COST.  This function returns
168    false if the cost of any instruction could not be estimated.  */
169
170 static bool
171 cheap_bb_rtx_cost_p (basic_block bb, int max_cost)
172 {
173   int count = 0;
174   rtx insn = BB_HEAD (bb);
175
176   while (1)
177     {
178       if (NONJUMP_INSN_P (insn))
179         {
180           int cost = insn_rtx_cost (PATTERN (insn));
181           if (cost == 0)
182             return false;
183
184           /* If this instruction is the load or set of a "stack" register,
185              such as a floating point register on x87, then the cost of
186              speculatively executing this instruction needs to include
187              the additional cost of popping this register off of the
188              register stack.  */
189 #ifdef STACK_REGS
190           {
191             rtx set = single_set (insn);
192             if (set && STACK_REG_P (SET_DEST (set)))
193               cost += COSTS_N_INSNS (1);
194           }
195 #endif
196
197           count += cost;
198           if (count >= max_cost)
199             return false;
200         }
201       else if (CALL_P (insn))
202         return false;
203  
204       if (insn == BB_END (bb))
205         break;
206       insn = NEXT_INSN (insn);
207     }
208
209   return true;
210 }
211
212 /* Return the first non-jump active insn in the basic block.  */
213
214 static rtx
215 first_active_insn (basic_block bb)
216 {
217   rtx insn = BB_HEAD (bb);
218
219   if (LABEL_P (insn))
220     {
221       if (insn == BB_END (bb))
222         return NULL_RTX;
223       insn = NEXT_INSN (insn);
224     }
225
226   while (NOTE_P (insn))
227     {
228       if (insn == BB_END (bb))
229         return NULL_RTX;
230       insn = NEXT_INSN (insn);
231     }
232
233   if (JUMP_P (insn))
234     return NULL_RTX;
235
236   return insn;
237 }
238
239 /* Return the last non-jump active (non-jump) insn in the basic block.  */
240
241 static rtx
242 last_active_insn (basic_block bb, int skip_use_p)
243 {
244   rtx insn = BB_END (bb);
245   rtx head = BB_HEAD (bb);
246
247   while (NOTE_P (insn)
248          || JUMP_P (insn)
249          || (skip_use_p
250              && NONJUMP_INSN_P (insn)
251              && GET_CODE (PATTERN (insn)) == USE))
252     {
253       if (insn == head)
254         return NULL_RTX;
255       insn = PREV_INSN (insn);
256     }
257
258   if (LABEL_P (insn))
259     return NULL_RTX;
260
261   return insn;
262 }
263
264 /* Return the basic block reached by falling though the basic block BB.  */
265
266 static basic_block
267 block_fallthru (basic_block bb)
268 {
269   edge e;
270   edge_iterator ei;
271
272   FOR_EACH_EDGE (e, ei, bb->succs)
273     if (e->flags & EDGE_FALLTHRU)
274       break;
275
276   return (e) ? e->dest : NULL_BLOCK;
277 }
278 \f
279 /* Go through a bunch of insns, converting them to conditional
280    execution format if possible.  Return TRUE if all of the non-note
281    insns were processed.  */
282
283 static int
284 cond_exec_process_insns (ce_if_block_t *ce_info ATTRIBUTE_UNUSED,
285                          /* if block information */rtx start,
286                          /* first insn to look at */rtx end,
287                          /* last insn to look at */rtx test,
288                          /* conditional execution test */rtx prob_val,
289                          /* probability of branch taken. */int mod_ok)
290 {
291   int must_be_last = FALSE;
292   rtx insn;
293   rtx xtest;
294   rtx pattern;
295
296   if (!start || !end)
297     return FALSE;
298
299   for (insn = start; ; insn = NEXT_INSN (insn))
300     {
301       if (NOTE_P (insn))
302         goto insn_done;
303
304       if (!NONJUMP_INSN_P (insn) && !CALL_P (insn))
305         abort ();
306
307       /* Remove USE insns that get in the way.  */
308       if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
309         {
310           /* ??? Ug.  Actually unlinking the thing is problematic,
311              given what we'd have to coordinate with our callers.  */
312           SET_INSN_DELETED (insn);
313           goto insn_done;
314         }
315
316       /* Last insn wasn't last?  */
317       if (must_be_last)
318         return FALSE;
319
320       if (modified_in_p (test, insn))
321         {
322           if (!mod_ok)
323             return FALSE;
324           must_be_last = TRUE;
325         }
326
327       /* Now build the conditional form of the instruction.  */
328       pattern = PATTERN (insn);
329       xtest = copy_rtx (test);
330
331       /* If this is already a COND_EXEC, rewrite the test to be an AND of the
332          two conditions.  */
333       if (GET_CODE (pattern) == COND_EXEC)
334         {
335           if (GET_MODE (xtest) != GET_MODE (COND_EXEC_TEST (pattern)))
336             return FALSE;
337
338           xtest = gen_rtx_AND (GET_MODE (xtest), xtest,
339                                COND_EXEC_TEST (pattern));
340           pattern = COND_EXEC_CODE (pattern);
341         }
342
343       pattern = gen_rtx_COND_EXEC (VOIDmode, xtest, pattern);
344
345       /* If the machine needs to modify the insn being conditionally executed,
346          say for example to force a constant integer operand into a temp
347          register, do so here.  */
348 #ifdef IFCVT_MODIFY_INSN
349       IFCVT_MODIFY_INSN (ce_info, pattern, insn);
350       if (! pattern)
351         return FALSE;
352 #endif
353
354       validate_change (insn, &PATTERN (insn), pattern, 1);
355
356       if (CALL_P (insn) && prob_val)
357         validate_change (insn, &REG_NOTES (insn),
358                          alloc_EXPR_LIST (REG_BR_PROB, prob_val,
359                                           REG_NOTES (insn)), 1);
360
361     insn_done:
362       if (insn == end)
363         break;
364     }
365
366   return TRUE;
367 }
368
369 /* Return the condition for a jump.  Do not do any special processing.  */
370
371 static rtx
372 cond_exec_get_condition (rtx jump)
373 {
374   rtx test_if, cond;
375
376   if (any_condjump_p (jump))
377     test_if = SET_SRC (pc_set (jump));
378   else
379     return NULL_RTX;
380   cond = XEXP (test_if, 0);
381
382   /* If this branches to JUMP_LABEL when the condition is false,
383      reverse the condition.  */
384   if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
385       && XEXP (XEXP (test_if, 2), 0) == JUMP_LABEL (jump))
386     {
387       enum rtx_code rev = reversed_comparison_code (cond, jump);
388       if (rev == UNKNOWN)
389         return NULL_RTX;
390
391       cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
392                              XEXP (cond, 1));
393     }
394
395   return cond;
396 }
397
398 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
399    to conditional execution.  Return TRUE if we were successful at
400    converting the block.  */
401
402 static int
403 cond_exec_process_if_block (ce_if_block_t * ce_info,
404                             /* if block information */int do_multiple_p)
405 {
406   basic_block test_bb = ce_info->test_bb;       /* last test block */
407   basic_block then_bb = ce_info->then_bb;       /* THEN */
408   basic_block else_bb = ce_info->else_bb;       /* ELSE or NULL */
409   rtx test_expr;                /* expression in IF_THEN_ELSE that is tested */
410   rtx then_start;               /* first insn in THEN block */
411   rtx then_end;                 /* last insn + 1 in THEN block */
412   rtx else_start = NULL_RTX;    /* first insn in ELSE block or NULL */
413   rtx else_end = NULL_RTX;      /* last insn + 1 in ELSE block */
414   int max;                      /* max # of insns to convert.  */
415   int then_mod_ok;              /* whether conditional mods are ok in THEN */
416   rtx true_expr;                /* test for else block insns */
417   rtx false_expr;               /* test for then block insns */
418   rtx true_prob_val;            /* probability of else block */
419   rtx false_prob_val;           /* probability of then block */
420   int n_insns;
421   enum rtx_code false_code;
422
423   /* If test is comprised of && or || elements, and we've failed at handling
424      all of them together, just use the last test if it is the special case of
425      && elements without an ELSE block.  */
426   if (!do_multiple_p && ce_info->num_multiple_test_blocks)
427     {
428       if (else_bb || ! ce_info->and_and_p)
429         return FALSE;
430
431       ce_info->test_bb = test_bb = ce_info->last_test_bb;
432       ce_info->num_multiple_test_blocks = 0;
433       ce_info->num_and_and_blocks = 0;
434       ce_info->num_or_or_blocks = 0;
435     }
436
437   /* Find the conditional jump to the ELSE or JOIN part, and isolate
438      the test.  */
439   test_expr = cond_exec_get_condition (BB_END (test_bb));
440   if (! test_expr)
441     return FALSE;
442
443   /* If the conditional jump is more than just a conditional jump,
444      then we can not do conditional execution conversion on this block.  */
445   if (! onlyjump_p (BB_END (test_bb)))
446     return FALSE;
447
448   /* Collect the bounds of where we're to search, skipping any labels, jumps
449      and notes at the beginning and end of the block.  Then count the total
450      number of insns and see if it is small enough to convert.  */
451   then_start = first_active_insn (then_bb);
452   then_end = last_active_insn (then_bb, TRUE);
453   n_insns = ce_info->num_then_insns = count_bb_insns (then_bb);
454   max = MAX_CONDITIONAL_EXECUTE;
455
456   if (else_bb)
457     {
458       max *= 2;
459       else_start = first_active_insn (else_bb);
460       else_end = last_active_insn (else_bb, TRUE);
461       n_insns += ce_info->num_else_insns = count_bb_insns (else_bb);
462     }
463
464   if (n_insns > max)
465     return FALSE;
466
467   /* Map test_expr/test_jump into the appropriate MD tests to use on
468      the conditionally executed code.  */
469
470   true_expr = test_expr;
471
472   false_code = reversed_comparison_code (true_expr, BB_END (test_bb));
473   if (false_code != UNKNOWN)
474     false_expr = gen_rtx_fmt_ee (false_code, GET_MODE (true_expr),
475                                  XEXP (true_expr, 0), XEXP (true_expr, 1));
476   else
477     false_expr = NULL_RTX;
478
479 #ifdef IFCVT_MODIFY_TESTS
480   /* If the machine description needs to modify the tests, such as setting a
481      conditional execution register from a comparison, it can do so here.  */
482   IFCVT_MODIFY_TESTS (ce_info, true_expr, false_expr);
483
484   /* See if the conversion failed.  */
485   if (!true_expr || !false_expr)
486     goto fail;
487 #endif
488
489   true_prob_val = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
490   if (true_prob_val)
491     {
492       true_prob_val = XEXP (true_prob_val, 0);
493       false_prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (true_prob_val));
494     }
495   else
496     false_prob_val = NULL_RTX;
497
498   /* If we have && or || tests, do them here.  These tests are in the adjacent
499      blocks after the first block containing the test.  */
500   if (ce_info->num_multiple_test_blocks > 0)
501     {
502       basic_block bb = test_bb;
503       basic_block last_test_bb = ce_info->last_test_bb;
504
505       if (! false_expr)
506         goto fail;
507
508       do
509         {
510           rtx start, end;
511           rtx t, f;
512           enum rtx_code f_code;
513
514           bb = block_fallthru (bb);
515           start = first_active_insn (bb);
516           end = last_active_insn (bb, TRUE);
517           if (start
518               && ! cond_exec_process_insns (ce_info, start, end, false_expr,
519                                             false_prob_val, FALSE))
520             goto fail;
521
522           /* If the conditional jump is more than just a conditional jump, then
523              we can not do conditional execution conversion on this block.  */
524           if (! onlyjump_p (BB_END (bb)))
525             goto fail;
526
527           /* Find the conditional jump and isolate the test.  */
528           t = cond_exec_get_condition (BB_END (bb));
529           if (! t)
530             goto fail;
531
532           f_code = reversed_comparison_code (t, BB_END (bb));
533           if (f_code == UNKNOWN)
534             goto fail;
535
536           f = gen_rtx_fmt_ee (f_code, GET_MODE (t), XEXP (t, 0), XEXP (t, 1));
537           if (ce_info->and_and_p)
538             {
539               t = gen_rtx_AND (GET_MODE (t), true_expr, t);
540               f = gen_rtx_IOR (GET_MODE (t), false_expr, f);
541             }
542           else
543             {
544               t = gen_rtx_IOR (GET_MODE (t), true_expr, t);
545               f = gen_rtx_AND (GET_MODE (t), false_expr, f);
546             }
547
548           /* If the machine description needs to modify the tests, such as
549              setting a conditional execution register from a comparison, it can
550              do so here.  */
551 #ifdef IFCVT_MODIFY_MULTIPLE_TESTS
552           IFCVT_MODIFY_MULTIPLE_TESTS (ce_info, bb, t, f);
553
554           /* See if the conversion failed.  */
555           if (!t || !f)
556             goto fail;
557 #endif
558
559           true_expr = t;
560           false_expr = f;
561         }
562       while (bb != last_test_bb);
563     }
564
565   /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
566      on then THEN block.  */
567   then_mod_ok = (else_bb == NULL_BLOCK);
568
569   /* Go through the THEN and ELSE blocks converting the insns if possible
570      to conditional execution.  */
571
572   if (then_end
573       && (! false_expr
574           || ! cond_exec_process_insns (ce_info, then_start, then_end,
575                                         false_expr, false_prob_val,
576                                         then_mod_ok)))
577     goto fail;
578
579   if (else_bb && else_end
580       && ! cond_exec_process_insns (ce_info, else_start, else_end,
581                                     true_expr, true_prob_val, TRUE))
582     goto fail;
583
584   /* If we cannot apply the changes, fail.  Do not go through the normal fail
585      processing, since apply_change_group will call cancel_changes.  */
586   if (! apply_change_group ())
587     {
588 #ifdef IFCVT_MODIFY_CANCEL
589       /* Cancel any machine dependent changes.  */
590       IFCVT_MODIFY_CANCEL (ce_info);
591 #endif
592       return FALSE;
593     }
594
595 #ifdef IFCVT_MODIFY_FINAL
596   /* Do any machine dependent final modifications.  */
597   IFCVT_MODIFY_FINAL (ce_info);
598 #endif
599
600   /* Conversion succeeded.  */
601   if (dump_file)
602     fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
603              n_insns, (n_insns == 1) ? " was" : "s were");
604
605   /* Merge the blocks!  */
606   merge_if_block (ce_info);
607   cond_exec_changed_p = TRUE;
608   return TRUE;
609
610  fail:
611 #ifdef IFCVT_MODIFY_CANCEL
612   /* Cancel any machine dependent changes.  */
613   IFCVT_MODIFY_CANCEL (ce_info);
614 #endif
615
616   cancel_changes (0);
617   return FALSE;
618 }
619 \f
620 /* Used by noce_process_if_block to communicate with its subroutines.
621
622    The subroutines know that A and B may be evaluated freely.  They
623    know that X is a register.  They should insert new instructions
624    before cond_earliest.  */
625
626 struct noce_if_info
627 {
628   basic_block test_bb;
629   rtx insn_a, insn_b;
630   rtx x, a, b;
631   rtx jump, cond, cond_earliest;
632   /* True if "b" was originally evaluated unconditionally.  */
633   bool b_unconditional;
634 };
635
636 static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
637 static int noce_try_move (struct noce_if_info *);
638 static int noce_try_store_flag (struct noce_if_info *);
639 static int noce_try_addcc (struct noce_if_info *);
640 static int noce_try_store_flag_constants (struct noce_if_info *);
641 static int noce_try_store_flag_mask (struct noce_if_info *);
642 static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
643                             rtx, rtx, rtx);
644 static int noce_try_cmove (struct noce_if_info *);
645 static int noce_try_cmove_arith (struct noce_if_info *);
646 static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx *);
647 static int noce_try_minmax (struct noce_if_info *);
648 static int noce_try_abs (struct noce_if_info *);
649 static int noce_try_sign_mask (struct noce_if_info *);
650
651 /* Helper function for noce_try_store_flag*.  */
652
653 static rtx
654 noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
655                       int normalize)
656 {
657   rtx cond = if_info->cond;
658   int cond_complex;
659   enum rtx_code code;
660
661   cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode)
662                   || ! general_operand (XEXP (cond, 1), VOIDmode));
663
664   /* If earliest == jump, or when the condition is complex, try to
665      build the store_flag insn directly.  */
666
667   if (cond_complex)
668     cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0);
669
670   if (reversep)
671     code = reversed_comparison_code (cond, if_info->jump);
672   else
673     code = GET_CODE (cond);
674
675   if ((if_info->cond_earliest == if_info->jump || cond_complex)
676       && (normalize == 0 || STORE_FLAG_VALUE == normalize))
677     {
678       rtx tmp;
679
680       tmp = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
681                             XEXP (cond, 1));
682       tmp = gen_rtx_SET (VOIDmode, x, tmp);
683
684       start_sequence ();
685       tmp = emit_insn (tmp);
686
687       if (recog_memoized (tmp) >= 0)
688         {
689           tmp = get_insns ();
690           end_sequence ();
691           emit_insn (tmp);
692
693           if_info->cond_earliest = if_info->jump;
694
695           return x;
696         }
697
698       end_sequence ();
699     }
700
701   /* Don't even try if the comparison operands or the mode of X are weird.  */
702   if (cond_complex || !SCALAR_INT_MODE_P (GET_MODE (x)))
703     return NULL_RTX;
704
705   return emit_store_flag (x, code, XEXP (cond, 0),
706                           XEXP (cond, 1), VOIDmode,
707                           (code == LTU || code == LEU
708                            || code == GEU || code == GTU), normalize);
709 }
710
711 /* Emit instruction to move an rtx, possibly into STRICT_LOW_PART.
712    X is the destination/target and Y is the value to copy.  */
713
714 static void
715 noce_emit_move_insn (rtx x, rtx y)
716 {
717   enum machine_mode outmode, inmode;
718   rtx outer, inner;
719   int bitpos;
720
721   if (GET_CODE (x) != STRICT_LOW_PART)
722     {
723       emit_move_insn (x, y);
724       return;
725     }
726
727   outer = XEXP (x, 0);
728   inner = XEXP (outer, 0);
729   outmode = GET_MODE (outer);
730   inmode = GET_MODE (inner);
731   bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
732   store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos, outmode, y);
733 }
734
735 /* Return sequence of instructions generated by if conversion.  This
736    function calls end_sequence() to end the current stream, ensures
737    that are instructions are unshared, recognizable non-jump insns.
738    On failure, this function returns a NULL_RTX.  */
739
740 static rtx
741 end_ifcvt_sequence (struct noce_if_info *if_info)
742 {
743   rtx insn;
744   rtx seq = get_insns ();
745
746   set_used_flags (if_info->x);
747   set_used_flags (if_info->cond);
748   unshare_all_rtl_in_chain (seq);
749   end_sequence ();
750
751   /* Make sure that all of the instructions emitted are recognizable,
752      and that we haven't introduced a new jump instruction.
753      As an exercise for the reader, build a general mechanism that
754      allows proper placement of required clobbers.  */
755   for (insn = seq; insn; insn = NEXT_INSN (insn))
756     if (JUMP_P (insn)
757         || recog_memoized (insn) == -1)
758       return NULL_RTX;
759
760   return seq;
761 }
762
763 /* Convert "if (a != b) x = a; else x = b" into "x = a" and
764    "if (a == b) x = a; else x = b" into "x = b".  */
765
766 static int
767 noce_try_move (struct noce_if_info *if_info)
768 {
769   rtx cond = if_info->cond;
770   enum rtx_code code = GET_CODE (cond);
771   rtx y, seq;
772
773   if (code != NE && code != EQ)
774     return FALSE;
775
776   /* This optimization isn't valid if either A or B could be a NaN
777      or a signed zero.  */
778   if (HONOR_NANS (GET_MODE (if_info->x))
779       || HONOR_SIGNED_ZEROS (GET_MODE (if_info->x)))
780     return FALSE;
781
782   /* Check whether the operands of the comparison are A and in
783      either order.  */
784   if ((rtx_equal_p (if_info->a, XEXP (cond, 0))
785        && rtx_equal_p (if_info->b, XEXP (cond, 1)))
786       || (rtx_equal_p (if_info->a, XEXP (cond, 1))
787           && rtx_equal_p (if_info->b, XEXP (cond, 0))))
788     {
789       y = (code == EQ) ? if_info->a : if_info->b;
790
791       /* Avoid generating the move if the source is the destination.  */
792       if (! rtx_equal_p (if_info->x, y))
793         {
794           start_sequence ();
795           noce_emit_move_insn (if_info->x, y);
796           seq = end_ifcvt_sequence (if_info);
797           if (!seq)
798             return FALSE;
799
800           emit_insn_before_setloc (seq, if_info->jump,
801                                    INSN_LOCATOR (if_info->insn_a));
802         }
803       return TRUE;
804     }
805   return FALSE;
806 }
807
808 /* Convert "if (test) x = 1; else x = 0".
809
810    Only try 0 and STORE_FLAG_VALUE here.  Other combinations will be
811    tried in noce_try_store_flag_constants after noce_try_cmove has had
812    a go at the conversion.  */
813
814 static int
815 noce_try_store_flag (struct noce_if_info *if_info)
816 {
817   int reversep;
818   rtx target, seq;
819
820   if (GET_CODE (if_info->b) == CONST_INT
821       && INTVAL (if_info->b) == STORE_FLAG_VALUE
822       && if_info->a == const0_rtx)
823     reversep = 0;
824   else if (if_info->b == const0_rtx
825            && GET_CODE (if_info->a) == CONST_INT
826            && INTVAL (if_info->a) == STORE_FLAG_VALUE
827            && (reversed_comparison_code (if_info->cond, if_info->jump)
828                != UNKNOWN))
829     reversep = 1;
830   else
831     return FALSE;
832
833   start_sequence ();
834
835   target = noce_emit_store_flag (if_info, if_info->x, reversep, 0);
836   if (target)
837     {
838       if (target != if_info->x)
839         noce_emit_move_insn (if_info->x, target);
840
841       seq = end_ifcvt_sequence (if_info);
842       if (! seq)
843         return FALSE;
844
845       emit_insn_before_setloc (seq, if_info->jump,
846                                INSN_LOCATOR (if_info->insn_a));
847       return TRUE;
848     }
849   else
850     {
851       end_sequence ();
852       return FALSE;
853     }
854 }
855
856 /* Convert "if (test) x = a; else x = b", for A and B constant.  */
857
858 static int
859 noce_try_store_flag_constants (struct noce_if_info *if_info)
860 {
861   rtx target, seq;
862   int reversep;
863   HOST_WIDE_INT itrue, ifalse, diff, tmp;
864   int normalize, can_reverse;
865   enum machine_mode mode;
866
867   if (! no_new_pseudos
868       && GET_CODE (if_info->a) == CONST_INT
869       && GET_CODE (if_info->b) == CONST_INT)
870     {
871       mode = GET_MODE (if_info->x);
872       ifalse = INTVAL (if_info->a);
873       itrue = INTVAL (if_info->b);
874
875       /* Make sure we can represent the difference between the two values.  */
876       if ((itrue - ifalse > 0)
877           != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
878         return FALSE;
879
880       diff = trunc_int_for_mode (itrue - ifalse, mode);
881
882       can_reverse = (reversed_comparison_code (if_info->cond, if_info->jump)
883                      != UNKNOWN);
884
885       reversep = 0;
886       if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
887         normalize = 0;
888       else if (ifalse == 0 && exact_log2 (itrue) >= 0
889                && (STORE_FLAG_VALUE == 1
890                    || BRANCH_COST >= 2))
891         normalize = 1;
892       else if (itrue == 0 && exact_log2 (ifalse) >= 0 && can_reverse
893                && (STORE_FLAG_VALUE == 1 || BRANCH_COST >= 2))
894         normalize = 1, reversep = 1;
895       else if (itrue == -1
896                && (STORE_FLAG_VALUE == -1
897                    || BRANCH_COST >= 2))
898         normalize = -1;
899       else if (ifalse == -1 && can_reverse
900                && (STORE_FLAG_VALUE == -1 || BRANCH_COST >= 2))
901         normalize = -1, reversep = 1;
902       else if ((BRANCH_COST >= 2 && STORE_FLAG_VALUE == -1)
903                || BRANCH_COST >= 3)
904         normalize = -1;
905       else
906         return FALSE;
907
908       if (reversep)
909         {
910           tmp = itrue; itrue = ifalse; ifalse = tmp;
911           diff = trunc_int_for_mode (-diff, mode);
912         }
913
914       start_sequence ();
915       target = noce_emit_store_flag (if_info, if_info->x, reversep, normalize);
916       if (! target)
917         {
918           end_sequence ();
919           return FALSE;
920         }
921
922       /* if (test) x = 3; else x = 4;
923          =>   x = 3 + (test == 0);  */
924       if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
925         {
926           target = expand_simple_binop (mode,
927                                         (diff == STORE_FLAG_VALUE
928                                          ? PLUS : MINUS),
929                                         GEN_INT (ifalse), target, if_info->x, 0,
930                                         OPTAB_WIDEN);
931         }
932
933       /* if (test) x = 8; else x = 0;
934          =>   x = (test != 0) << 3;  */
935       else if (ifalse == 0 && (tmp = exact_log2 (itrue)) >= 0)
936         {
937           target = expand_simple_binop (mode, ASHIFT,
938                                         target, GEN_INT (tmp), if_info->x, 0,
939                                         OPTAB_WIDEN);
940         }
941
942       /* if (test) x = -1; else x = b;
943          =>   x = -(test != 0) | b;  */
944       else if (itrue == -1)
945         {
946           target = expand_simple_binop (mode, IOR,
947                                         target, GEN_INT (ifalse), if_info->x, 0,
948                                         OPTAB_WIDEN);
949         }
950
951       /* if (test) x = a; else x = b;
952          =>   x = (-(test != 0) & (b - a)) + a;  */
953       else
954         {
955           target = expand_simple_binop (mode, AND,
956                                         target, GEN_INT (diff), if_info->x, 0,
957                                         OPTAB_WIDEN);
958           if (target)
959             target = expand_simple_binop (mode, PLUS,
960                                           target, GEN_INT (ifalse),
961                                           if_info->x, 0, OPTAB_WIDEN);
962         }
963
964       if (! target)
965         {
966           end_sequence ();
967           return FALSE;
968         }
969
970       if (target != if_info->x)
971         noce_emit_move_insn (if_info->x, target);
972
973       seq = end_ifcvt_sequence (if_info);
974       if (!seq)
975         return FALSE;
976
977       emit_insn_before_setloc (seq, if_info->jump,
978                                INSN_LOCATOR (if_info->insn_a));
979       return TRUE;
980     }
981
982   return FALSE;
983 }
984
985 /* Convert "if (test) foo++" into "foo += (test != 0)", and
986    similarly for "foo--".  */
987
988 static int
989 noce_try_addcc (struct noce_if_info *if_info)
990 {
991   rtx target, seq;
992   int subtract, normalize;
993
994   if (! no_new_pseudos
995       && GET_CODE (if_info->a) == PLUS
996       && rtx_equal_p (XEXP (if_info->a, 0), if_info->b)
997       && (reversed_comparison_code (if_info->cond, if_info->jump)
998           != UNKNOWN))
999     {
1000       rtx cond = if_info->cond;
1001       enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
1002
1003       /* First try to use addcc pattern.  */
1004       if (general_operand (XEXP (cond, 0), VOIDmode)
1005           && general_operand (XEXP (cond, 1), VOIDmode))
1006         {
1007           start_sequence ();
1008           target = emit_conditional_add (if_info->x, code,
1009                                          XEXP (cond, 0),
1010                                          XEXP (cond, 1),
1011                                          VOIDmode,
1012                                          if_info->b,
1013                                          XEXP (if_info->a, 1),
1014                                          GET_MODE (if_info->x),
1015                                          (code == LTU || code == GEU
1016                                           || code == LEU || code == GTU));
1017           if (target)
1018             {
1019               if (target != if_info->x)
1020                 noce_emit_move_insn (if_info->x, target);
1021
1022               seq = end_ifcvt_sequence (if_info);
1023               if (!seq)
1024                 return FALSE;
1025
1026               emit_insn_before_setloc (seq, if_info->jump,
1027                                        INSN_LOCATOR (if_info->insn_a));
1028               return TRUE;
1029             }
1030           end_sequence ();
1031         }
1032
1033       /* If that fails, construct conditional increment or decrement using
1034          setcc.  */
1035       if (BRANCH_COST >= 2
1036           && (XEXP (if_info->a, 1) == const1_rtx
1037               || XEXP (if_info->a, 1) == constm1_rtx))
1038         {
1039           start_sequence ();
1040           if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
1041             subtract = 0, normalize = 0;
1042           else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
1043             subtract = 1, normalize = 0;
1044           else
1045             subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
1046
1047
1048           target = noce_emit_store_flag (if_info,
1049                                          gen_reg_rtx (GET_MODE (if_info->x)),
1050                                          1, normalize);
1051
1052           if (target)
1053             target = expand_simple_binop (GET_MODE (if_info->x),
1054                                           subtract ? MINUS : PLUS,
1055                                           if_info->b, target, if_info->x,
1056                                           0, OPTAB_WIDEN);
1057           if (target)
1058             {
1059               if (target != if_info->x)
1060                 noce_emit_move_insn (if_info->x, target);
1061
1062               seq = end_ifcvt_sequence (if_info);
1063               if (!seq)
1064                 return FALSE;
1065
1066               emit_insn_before_setloc (seq, if_info->jump,
1067                                        INSN_LOCATOR (if_info->insn_a));
1068               return TRUE;
1069             }
1070           end_sequence ();
1071         }
1072     }
1073
1074   return FALSE;
1075 }
1076
1077 /* Convert "if (test) x = 0;" to "x &= -(test == 0);"  */
1078
1079 static int
1080 noce_try_store_flag_mask (struct noce_if_info *if_info)
1081 {
1082   rtx target, seq;
1083   int reversep;
1084
1085   reversep = 0;
1086   if (! no_new_pseudos
1087       && (BRANCH_COST >= 2
1088           || STORE_FLAG_VALUE == -1)
1089       && ((if_info->a == const0_rtx
1090            && rtx_equal_p (if_info->b, if_info->x))
1091           || ((reversep = (reversed_comparison_code (if_info->cond,
1092                                                      if_info->jump)
1093                            != UNKNOWN))
1094               && if_info->b == const0_rtx
1095               && rtx_equal_p (if_info->a, if_info->x))))
1096     {
1097       start_sequence ();
1098       target = noce_emit_store_flag (if_info,
1099                                      gen_reg_rtx (GET_MODE (if_info->x)),
1100                                      reversep, -1);
1101       if (target)
1102         target = expand_simple_binop (GET_MODE (if_info->x), AND,
1103                                       if_info->x,
1104                                       target, if_info->x, 0,
1105                                       OPTAB_WIDEN);
1106
1107       if (target)
1108         {
1109           if (target != if_info->x)
1110             noce_emit_move_insn (if_info->x, target);
1111
1112           seq = end_ifcvt_sequence (if_info);
1113           if (!seq)
1114             return FALSE;
1115
1116           emit_insn_before_setloc (seq, if_info->jump,
1117                                    INSN_LOCATOR (if_info->insn_a));
1118           return TRUE;
1119         }
1120
1121       end_sequence ();
1122     }
1123
1124   return FALSE;
1125 }
1126
1127 /* Helper function for noce_try_cmove and noce_try_cmove_arith.  */
1128
1129 static rtx
1130 noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
1131                  rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
1132 {
1133   /* If earliest == jump, try to build the cmove insn directly.
1134      This is helpful when combine has created some complex condition
1135      (like for alpha's cmovlbs) that we can't hope to regenerate
1136      through the normal interface.  */
1137
1138   if (if_info->cond_earliest == if_info->jump)
1139     {
1140       rtx tmp;
1141
1142       tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
1143       tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
1144       tmp = gen_rtx_SET (VOIDmode, x, tmp);
1145
1146       start_sequence ();
1147       tmp = emit_insn (tmp);
1148
1149       if (recog_memoized (tmp) >= 0)
1150         {
1151           tmp = get_insns ();
1152           end_sequence ();
1153           emit_insn (tmp);
1154
1155           return x;
1156         }
1157
1158       end_sequence ();
1159     }
1160
1161   /* Don't even try if the comparison operands are weird.  */
1162   if (! general_operand (cmp_a, GET_MODE (cmp_a))
1163       || ! general_operand (cmp_b, GET_MODE (cmp_b)))
1164     return NULL_RTX;
1165
1166 #if HAVE_conditional_move
1167   return emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
1168                                 vtrue, vfalse, GET_MODE (x),
1169                                 (code == LTU || code == GEU
1170                                  || code == LEU || code == GTU));
1171 #else
1172   /* We'll never get here, as noce_process_if_block doesn't call the
1173      functions involved.  Ifdef code, however, should be discouraged
1174      because it leads to typos in the code not selected.  However,
1175      emit_conditional_move won't exist either.  */
1176   return NULL_RTX;
1177 #endif
1178 }
1179
1180 /* Try only simple constants and registers here.  More complex cases
1181    are handled in noce_try_cmove_arith after noce_try_store_flag_arith
1182    has had a go at it.  */
1183
1184 static int
1185 noce_try_cmove (struct noce_if_info *if_info)
1186 {
1187   enum rtx_code code;
1188   rtx target, seq;
1189
1190   if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode))
1191       && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode)))
1192     {
1193       start_sequence ();
1194
1195       code = GET_CODE (if_info->cond);
1196       target = noce_emit_cmove (if_info, if_info->x, code,
1197                                 XEXP (if_info->cond, 0),
1198                                 XEXP (if_info->cond, 1),
1199                                 if_info->a, if_info->b);
1200
1201       if (target)
1202         {
1203           if (target != if_info->x)
1204             noce_emit_move_insn (if_info->x, target);
1205
1206           seq = end_ifcvt_sequence (if_info);
1207           if (!seq)
1208             return FALSE;
1209
1210           emit_insn_before_setloc (seq, if_info->jump,
1211                                    INSN_LOCATOR (if_info->insn_a));
1212           return TRUE;
1213         }
1214       else
1215         {
1216           end_sequence ();
1217           return FALSE;
1218         }
1219     }
1220
1221   return FALSE;
1222 }
1223
1224 /* Try more complex cases involving conditional_move.  */
1225
1226 static int
1227 noce_try_cmove_arith (struct noce_if_info *if_info)
1228 {
1229   rtx a = if_info->a;
1230   rtx b = if_info->b;
1231   rtx x = if_info->x;
1232   rtx insn_a, insn_b;
1233   rtx tmp, target;
1234   int is_mem = 0;
1235   int insn_cost;
1236   enum rtx_code code;
1237
1238   /* A conditional move from two memory sources is equivalent to a
1239      conditional on their addresses followed by a load.  Don't do this
1240      early because it'll screw alias analysis.  Note that we've
1241      already checked for no side effects.  */
1242   if (! no_new_pseudos && cse_not_expected
1243       && MEM_P (a) && MEM_P (b)
1244       && BRANCH_COST >= 5)
1245     {
1246       a = XEXP (a, 0);
1247       b = XEXP (b, 0);
1248       x = gen_reg_rtx (Pmode);
1249       is_mem = 1;
1250     }
1251
1252   /* ??? We could handle this if we knew that a load from A or B could
1253      not fault.  This is also true if we've already loaded
1254      from the address along the path from ENTRY.  */
1255   else if (may_trap_p (a) || may_trap_p (b))
1256     return FALSE;
1257
1258   /* if (test) x = a + b; else x = c - d;
1259      => y = a + b;
1260         x = c - d;
1261         if (test)
1262           x = y;
1263   */
1264
1265   code = GET_CODE (if_info->cond);
1266   insn_a = if_info->insn_a;
1267   insn_b = if_info->insn_b;
1268
1269   /* Total insn_rtx_cost should be smaller than branch cost.  Exit
1270      if insn_rtx_cost can't be estimated.  */
1271   if (insn_a)
1272     {
1273       insn_cost = insn_rtx_cost (PATTERN (insn_a));
1274       if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (BRANCH_COST))
1275         return FALSE;
1276     }
1277   else
1278     {
1279       insn_cost = 0;
1280     }
1281
1282   if (insn_b) {
1283     insn_cost += insn_rtx_cost (PATTERN (insn_b));
1284     if (insn_cost == 0 || insn_cost > COSTS_N_INSNS (BRANCH_COST))
1285       return FALSE;
1286   }
1287
1288   /* Possibly rearrange operands to make things come out more natural.  */
1289   if (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN)
1290     {
1291       int reversep = 0;
1292       if (rtx_equal_p (b, x))
1293         reversep = 1;
1294       else if (general_operand (b, GET_MODE (b)))
1295         reversep = 1;
1296
1297       if (reversep)
1298         {
1299           code = reversed_comparison_code (if_info->cond, if_info->jump);
1300           tmp = a, a = b, b = tmp;
1301           tmp = insn_a, insn_a = insn_b, insn_b = tmp;
1302         }
1303     }
1304
1305   start_sequence ();
1306
1307   /* If either operand is complex, load it into a register first.
1308      The best way to do this is to copy the original insn.  In this
1309      way we preserve any clobbers etc that the insn may have had.
1310      This is of course not possible in the IS_MEM case.  */
1311   if (! general_operand (a, GET_MODE (a)))
1312     {
1313       rtx set;
1314
1315       if (no_new_pseudos)
1316         goto end_seq_and_fail;
1317
1318       if (is_mem)
1319         {
1320           tmp = gen_reg_rtx (GET_MODE (a));
1321           tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, a));
1322         }
1323       else if (! insn_a)
1324         goto end_seq_and_fail;
1325       else
1326         {
1327           a = gen_reg_rtx (GET_MODE (a));
1328           tmp = copy_rtx (insn_a);
1329           set = single_set (tmp);
1330           SET_DEST (set) = a;
1331           tmp = emit_insn (PATTERN (tmp));
1332         }
1333       if (recog_memoized (tmp) < 0)
1334         goto end_seq_and_fail;
1335     }
1336   if (! general_operand (b, GET_MODE (b)))
1337     {
1338       rtx set;
1339
1340       if (no_new_pseudos)
1341         goto end_seq_and_fail;
1342
1343       if (is_mem)
1344         {
1345           tmp = gen_reg_rtx (GET_MODE (b));
1346           tmp = emit_insn (gen_rtx_SET (VOIDmode,
1347                                         tmp,
1348                                         b));
1349         }
1350       else if (! insn_b)
1351         goto end_seq_and_fail;
1352       else
1353         {
1354           b = gen_reg_rtx (GET_MODE (b));
1355           tmp = copy_rtx (insn_b);
1356           set = single_set (tmp);
1357           SET_DEST (set) = b;
1358           tmp = emit_insn (PATTERN (tmp));
1359         }
1360       if (recog_memoized (tmp) < 0)
1361         goto end_seq_and_fail;
1362     }
1363
1364   target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0),
1365                             XEXP (if_info->cond, 1), a, b);
1366
1367   if (! target)
1368     goto end_seq_and_fail;
1369
1370   /* If we're handling a memory for above, emit the load now.  */
1371   if (is_mem)
1372     {
1373       tmp = gen_rtx_MEM (GET_MODE (if_info->x), target);
1374
1375       /* Copy over flags as appropriate.  */
1376       if (MEM_VOLATILE_P (if_info->a) || MEM_VOLATILE_P (if_info->b))
1377         MEM_VOLATILE_P (tmp) = 1;
1378       if (MEM_IN_STRUCT_P (if_info->a) && MEM_IN_STRUCT_P (if_info->b))
1379         MEM_IN_STRUCT_P (tmp) = 1;
1380       if (MEM_SCALAR_P (if_info->a) && MEM_SCALAR_P (if_info->b))
1381         MEM_SCALAR_P (tmp) = 1;
1382       if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b))
1383         set_mem_alias_set (tmp, MEM_ALIAS_SET (if_info->a));
1384       set_mem_align (tmp,
1385                      MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b)));
1386
1387       noce_emit_move_insn (if_info->x, tmp);
1388     }
1389   else if (target != x)
1390     noce_emit_move_insn (x, target);
1391
1392   tmp = end_ifcvt_sequence (if_info);
1393   if (!tmp)
1394     return FALSE;
1395
1396   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1397   return TRUE;
1398
1399  end_seq_and_fail:
1400   end_sequence ();
1401   return FALSE;
1402 }
1403
1404 /* For most cases, the simplified condition we found is the best
1405    choice, but this is not the case for the min/max/abs transforms.
1406    For these we wish to know that it is A or B in the condition.  */
1407
1408 static rtx
1409 noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
1410                         rtx *earliest)
1411 {
1412   rtx cond, set, insn;
1413   int reverse;
1414
1415   /* If target is already mentioned in the known condition, return it.  */
1416   if (reg_mentioned_p (target, if_info->cond))
1417     {
1418       *earliest = if_info->cond_earliest;
1419       return if_info->cond;
1420     }
1421
1422   set = pc_set (if_info->jump);
1423   cond = XEXP (SET_SRC (set), 0);
1424   reverse
1425     = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1426       && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump);
1427
1428   /* If we're looking for a constant, try to make the conditional
1429      have that constant in it.  There are two reasons why it may
1430      not have the constant we want:
1431
1432      1. GCC may have needed to put the constant in a register, because
1433         the target can't compare directly against that constant.  For
1434         this case, we look for a SET immediately before the comparison
1435         that puts a constant in that register.
1436
1437      2. GCC may have canonicalized the conditional, for example
1438         replacing "if x < 4" with "if x <= 3".  We can undo that (or
1439         make equivalent types of changes) to get the constants we need
1440         if they're off by one in the right direction.  */
1441
1442   if (GET_CODE (target) == CONST_INT)
1443     {
1444       enum rtx_code code = GET_CODE (if_info->cond);
1445       rtx op_a = XEXP (if_info->cond, 0);
1446       rtx op_b = XEXP (if_info->cond, 1);
1447       rtx prev_insn;
1448
1449       /* First, look to see if we put a constant in a register.  */
1450       prev_insn = PREV_INSN (if_info->cond_earliest);
1451       if (prev_insn
1452           && INSN_P (prev_insn)
1453           && GET_CODE (PATTERN (prev_insn)) == SET)
1454         {
1455           rtx src = find_reg_equal_equiv_note (prev_insn);
1456           if (!src)
1457             src = SET_SRC (PATTERN (prev_insn));
1458           if (GET_CODE (src) == CONST_INT)
1459             {
1460               if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn))))
1461                 op_a = src;
1462               else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn))))
1463                 op_b = src;
1464
1465               if (GET_CODE (op_a) == CONST_INT)
1466                 {
1467                   rtx tmp = op_a;
1468                   op_a = op_b;
1469                   op_b = tmp;
1470                   code = swap_condition (code);
1471                 }
1472             }
1473         }
1474
1475       /* Now, look to see if we can get the right constant by
1476          adjusting the conditional.  */
1477       if (GET_CODE (op_b) == CONST_INT)
1478         {
1479           HOST_WIDE_INT desired_val = INTVAL (target);
1480           HOST_WIDE_INT actual_val = INTVAL (op_b);
1481
1482           switch (code)
1483             {
1484             case LT:
1485               if (actual_val == desired_val + 1)
1486                 {
1487                   code = LE;
1488                   op_b = GEN_INT (desired_val);
1489                 }
1490               break;
1491             case LE:
1492               if (actual_val == desired_val - 1)
1493                 {
1494                   code = LT;
1495                   op_b = GEN_INT (desired_val);
1496                 }
1497               break;
1498             case GT:
1499               if (actual_val == desired_val - 1)
1500                 {
1501                   code = GE;
1502                   op_b = GEN_INT (desired_val);
1503                 }
1504               break;
1505             case GE:
1506               if (actual_val == desired_val + 1)
1507                 {
1508                   code = GT;
1509                   op_b = GEN_INT (desired_val);
1510                 }
1511               break;
1512             default:
1513               break;
1514             }
1515         }
1516
1517       /* If we made any changes, generate a new conditional that is
1518          equivalent to what we started with, but has the right
1519          constants in it.  */
1520       if (code != GET_CODE (if_info->cond)
1521           || op_a != XEXP (if_info->cond, 0)
1522           || op_b != XEXP (if_info->cond, 1))
1523         {
1524           cond = gen_rtx_fmt_ee (code, GET_MODE (cond), op_a, op_b);
1525           *earliest = if_info->cond_earliest;
1526           return cond;
1527         }
1528     }
1529
1530   cond = canonicalize_condition (if_info->jump, cond, reverse,
1531                                  earliest, target, false, true);
1532   if (! cond || ! reg_mentioned_p (target, cond))
1533     return NULL;
1534
1535   /* We almost certainly searched back to a different place.
1536      Need to re-verify correct lifetimes.  */
1537
1538   /* X may not be mentioned in the range (cond_earliest, jump].  */
1539   for (insn = if_info->jump; insn != *earliest; insn = PREV_INSN (insn))
1540     if (INSN_P (insn) && reg_overlap_mentioned_p (if_info->x, PATTERN (insn)))
1541       return NULL;
1542
1543   /* A and B may not be modified in the range [cond_earliest, jump).  */
1544   for (insn = *earliest; insn != if_info->jump; insn = NEXT_INSN (insn))
1545     if (INSN_P (insn)
1546         && (modified_in_p (if_info->a, insn)
1547             || modified_in_p (if_info->b, insn)))
1548       return NULL;
1549
1550   return cond;
1551 }
1552
1553 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc.  */
1554
1555 static int
1556 noce_try_minmax (struct noce_if_info *if_info)
1557 {
1558   rtx cond, earliest, target, seq;
1559   enum rtx_code code, op;
1560   int unsignedp;
1561
1562   /* ??? Can't guarantee that expand_binop won't create pseudos.  */
1563   if (no_new_pseudos)
1564     return FALSE;
1565
1566   /* ??? Reject modes with NaNs or signed zeros since we don't know how
1567      they will be resolved with an SMIN/SMAX.  It wouldn't be too hard
1568      to get the target to tell us...  */
1569   if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x))
1570       || HONOR_NANS (GET_MODE (if_info->x)))
1571     return FALSE;
1572
1573   cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
1574   if (!cond)
1575     return FALSE;
1576
1577   /* Verify the condition is of the form we expect, and canonicalize
1578      the comparison code.  */
1579   code = GET_CODE (cond);
1580   if (rtx_equal_p (XEXP (cond, 0), if_info->a))
1581     {
1582       if (! rtx_equal_p (XEXP (cond, 1), if_info->b))
1583         return FALSE;
1584     }
1585   else if (rtx_equal_p (XEXP (cond, 1), if_info->a))
1586     {
1587       if (! rtx_equal_p (XEXP (cond, 0), if_info->b))
1588         return FALSE;
1589       code = swap_condition (code);
1590     }
1591   else
1592     return FALSE;
1593
1594   /* Determine what sort of operation this is.  Note that the code is for
1595      a taken branch, so the code->operation mapping appears backwards.  */
1596   switch (code)
1597     {
1598     case LT:
1599     case LE:
1600     case UNLT:
1601     case UNLE:
1602       op = SMAX;
1603       unsignedp = 0;
1604       break;
1605     case GT:
1606     case GE:
1607     case UNGT:
1608     case UNGE:
1609       op = SMIN;
1610       unsignedp = 0;
1611       break;
1612     case LTU:
1613     case LEU:
1614       op = UMAX;
1615       unsignedp = 1;
1616       break;
1617     case GTU:
1618     case GEU:
1619       op = UMIN;
1620       unsignedp = 1;
1621       break;
1622     default:
1623       return FALSE;
1624     }
1625
1626   start_sequence ();
1627
1628   target = expand_simple_binop (GET_MODE (if_info->x), op,
1629                                 if_info->a, if_info->b,
1630                                 if_info->x, unsignedp, OPTAB_WIDEN);
1631   if (! target)
1632     {
1633       end_sequence ();
1634       return FALSE;
1635     }
1636   if (target != if_info->x)
1637     noce_emit_move_insn (if_info->x, target);
1638
1639   seq = end_ifcvt_sequence (if_info);
1640   if (!seq)
1641     return FALSE;
1642
1643   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1644   if_info->cond = cond;
1645   if_info->cond_earliest = earliest;
1646
1647   return TRUE;
1648 }
1649
1650 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc.  */
1651
1652 static int
1653 noce_try_abs (struct noce_if_info *if_info)
1654 {
1655   rtx cond, earliest, target, seq, a, b, c;
1656   int negate;
1657
1658   /* ??? Can't guarantee that expand_binop won't create pseudos.  */
1659   if (no_new_pseudos)
1660     return FALSE;
1661
1662   /* Recognize A and B as constituting an ABS or NABS.  */
1663   a = if_info->a;
1664   b = if_info->b;
1665   if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b))
1666     negate = 0;
1667   else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a))
1668     {
1669       c = a; a = b; b = c;
1670       negate = 1;
1671     }
1672   else
1673     return FALSE;
1674
1675   cond = noce_get_alt_condition (if_info, b, &earliest);
1676   if (!cond)
1677     return FALSE;
1678
1679   /* Verify the condition is of the form we expect.  */
1680   if (rtx_equal_p (XEXP (cond, 0), b))
1681     c = XEXP (cond, 1);
1682   else if (rtx_equal_p (XEXP (cond, 1), b))
1683     c = XEXP (cond, 0);
1684   else
1685     return FALSE;
1686
1687   /* Verify that C is zero.  Search backward through the block for
1688      a REG_EQUAL note if necessary.  */
1689   if (REG_P (c))
1690     {
1691       rtx insn, note = NULL;
1692       for (insn = earliest;
1693            insn != BB_HEAD (if_info->test_bb);
1694            insn = PREV_INSN (insn))
1695         if (INSN_P (insn)
1696             && ((note = find_reg_note (insn, REG_EQUAL, c))
1697                 || (note = find_reg_note (insn, REG_EQUIV, c))))
1698           break;
1699       if (! note)
1700         return FALSE;
1701       c = XEXP (note, 0);
1702     }
1703   if (MEM_P (c)
1704       && GET_CODE (XEXP (c, 0)) == SYMBOL_REF
1705       && CONSTANT_POOL_ADDRESS_P (XEXP (c, 0)))
1706     c = get_pool_constant (XEXP (c, 0));
1707
1708   /* Work around funny ideas get_condition has wrt canonicalization.
1709      Note that these rtx constants are known to be CONST_INT, and
1710      therefore imply integer comparisons.  */
1711   if (c == constm1_rtx && GET_CODE (cond) == GT)
1712     ;
1713   else if (c == const1_rtx && GET_CODE (cond) == LT)
1714     ;
1715   else if (c != CONST0_RTX (GET_MODE (b)))
1716     return FALSE;
1717
1718   /* Determine what sort of operation this is.  */
1719   switch (GET_CODE (cond))
1720     {
1721     case LT:
1722     case LE:
1723     case UNLT:
1724     case UNLE:
1725       negate = !negate;
1726       break;
1727     case GT:
1728     case GE:
1729     case UNGT:
1730     case UNGE:
1731       break;
1732     default:
1733       return FALSE;
1734     }
1735
1736   start_sequence ();
1737
1738   target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1);
1739
1740   /* ??? It's a quandary whether cmove would be better here, especially
1741      for integers.  Perhaps combine will clean things up.  */
1742   if (target && negate)
1743     target = expand_simple_unop (GET_MODE (target), NEG, target, if_info->x, 0);
1744
1745   if (! target)
1746     {
1747       end_sequence ();
1748       return FALSE;
1749     }
1750
1751   if (target != if_info->x)
1752     noce_emit_move_insn (if_info->x, target);
1753
1754   seq = end_ifcvt_sequence (if_info);
1755   if (!seq)
1756     return FALSE;
1757
1758   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1759   if_info->cond = cond;
1760   if_info->cond_earliest = earliest;
1761
1762   return TRUE;
1763 }
1764
1765 /* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;".  */
1766
1767 static int
1768 noce_try_sign_mask (struct noce_if_info *if_info)
1769 {
1770   rtx cond, t, m, c, seq;
1771   enum machine_mode mode;
1772   enum rtx_code code;
1773
1774   if (no_new_pseudos)
1775     return FALSE;
1776
1777   cond = if_info->cond;
1778   code = GET_CODE (cond);
1779   m = XEXP (cond, 0);
1780   c = XEXP (cond, 1);
1781
1782   t = NULL_RTX;
1783   if (if_info->a == const0_rtx)
1784     {
1785       if ((code == LT && c == const0_rtx)
1786           || (code == LE && c == constm1_rtx))
1787         t = if_info->b;
1788     }
1789   else if (if_info->b == const0_rtx)
1790     {
1791       if ((code == GE && c == const0_rtx)
1792           || (code == GT && c == constm1_rtx))
1793         t = if_info->a;
1794     }
1795
1796   if (! t || side_effects_p (t))
1797     return FALSE;
1798
1799   /* We currently don't handle different modes.  */
1800   mode = GET_MODE (t);
1801   if (GET_MODE (m) != mode)
1802     return FALSE;
1803
1804   /* This is only profitable if T is cheap, or T is unconditionally
1805      executed/evaluated in the original insn sequence.  */
1806   if (rtx_cost (t, SET) >= COSTS_N_INSNS (2)
1807       && (!if_info->b_unconditional
1808           || t != if_info->b))
1809     return FALSE;
1810
1811   start_sequence ();
1812   /* Use emit_store_flag to generate "m < 0 ? -1 : 0" instead of expanding
1813      "(signed) m >> 31" directly.  This benefits targets with specialized
1814      insns to obtain the signmask, but still uses ashr_optab otherwise.  */
1815   m = emit_store_flag (gen_reg_rtx (mode), LT, m, const0_rtx, mode, 0, -1);
1816   t = m ? expand_binop (mode, and_optab, m, t, NULL_RTX, 0, OPTAB_DIRECT)
1817         : NULL_RTX;
1818
1819   if (!t)
1820     {
1821       end_sequence ();
1822       return FALSE;
1823     }
1824
1825   noce_emit_move_insn (if_info->x, t);
1826
1827   seq = end_ifcvt_sequence (if_info);
1828   if (!seq)
1829     return FALSE;
1830
1831   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
1832   return TRUE;
1833 }
1834
1835
1836 /* Similar to get_condition, only the resulting condition must be
1837    valid at JUMP, instead of at EARLIEST.  */
1838
1839 static rtx
1840 noce_get_condition (rtx jump, rtx *earliest)
1841 {
1842   rtx cond, set, tmp;
1843   bool reverse;
1844
1845   if (! any_condjump_p (jump))
1846     return NULL_RTX;
1847
1848   set = pc_set (jump);
1849
1850   /* If this branches to JUMP_LABEL when the condition is false,
1851      reverse the condition.  */
1852   reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1853              && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump));
1854
1855   /* If the condition variable is a register and is MODE_INT, accept it.  */
1856
1857   cond = XEXP (SET_SRC (set), 0);
1858   tmp = XEXP (cond, 0);
1859   if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT)
1860     {
1861       *earliest = jump;
1862
1863       if (reverse)
1864         cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
1865                                GET_MODE (cond), tmp, XEXP (cond, 1));
1866       return cond;
1867     }
1868
1869   /* Otherwise, fall back on canonicalize_condition to do the dirty
1870      work of manipulating MODE_CC values and COMPARE rtx codes.  */
1871   return canonicalize_condition (jump, cond, reverse, earliest,
1872                                  NULL_RTX, false, true);
1873 }
1874
1875 /* Return true if OP is ok for if-then-else processing.  */
1876
1877 static int
1878 noce_operand_ok (rtx op)
1879 {
1880   /* We special-case memories, so handle any of them with
1881      no address side effects.  */
1882   if (MEM_P (op))
1883     return ! side_effects_p (XEXP (op, 0));
1884
1885   if (side_effects_p (op))
1886     return FALSE;
1887
1888   return ! may_trap_p (op);
1889 }
1890
1891 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
1892    without using conditional execution.  Return TRUE if we were
1893    successful at converting the block.  */
1894
1895 static int
1896 noce_process_if_block (struct ce_if_block * ce_info)
1897 {
1898   basic_block test_bb = ce_info->test_bb;       /* test block */
1899   basic_block then_bb = ce_info->then_bb;       /* THEN */
1900   basic_block else_bb = ce_info->else_bb;       /* ELSE or NULL */
1901   struct noce_if_info if_info;
1902   rtx insn_a, insn_b;
1903   rtx set_a, set_b;
1904   rtx orig_x, x, a, b;
1905   rtx jump, cond;
1906
1907   /* We're looking for patterns of the form
1908
1909      (1) if (...) x = a; else x = b;
1910      (2) x = b; if (...) x = a;
1911      (3) if (...) x = a;   // as if with an initial x = x.
1912
1913      The later patterns require jumps to be more expensive.
1914
1915      ??? For future expansion, look for multiple X in such patterns.  */
1916
1917   /* If test is comprised of && or || elements, don't handle it unless it is
1918      the special case of && elements without an ELSE block.  */
1919   if (ce_info->num_multiple_test_blocks)
1920     {
1921       if (else_bb || ! ce_info->and_and_p)
1922         return FALSE;
1923
1924       ce_info->test_bb = test_bb = ce_info->last_test_bb;
1925       ce_info->num_multiple_test_blocks = 0;
1926       ce_info->num_and_and_blocks = 0;
1927       ce_info->num_or_or_blocks = 0;
1928     }
1929
1930   /* If this is not a standard conditional jump, we can't parse it.  */
1931   jump = BB_END (test_bb);
1932   cond = noce_get_condition (jump, &if_info.cond_earliest);
1933   if (! cond)
1934     return FALSE;
1935
1936   /* If the conditional jump is more than just a conditional
1937      jump, then we can not do if-conversion on this block.  */
1938   if (! onlyjump_p (jump))
1939     return FALSE;
1940
1941   /* We must be comparing objects whose modes imply the size.  */
1942   if (GET_MODE (XEXP (cond, 0)) == BLKmode)
1943     return FALSE;
1944
1945   /* Look for one of the potential sets.  */
1946   insn_a = first_active_insn (then_bb);
1947   if (! insn_a
1948       || insn_a != last_active_insn (then_bb, FALSE)
1949       || (set_a = single_set (insn_a)) == NULL_RTX)
1950     return FALSE;
1951
1952   x = SET_DEST (set_a);
1953   a = SET_SRC (set_a);
1954
1955   /* Look for the other potential set.  Make sure we've got equivalent
1956      destinations.  */
1957   /* ??? This is overconservative.  Storing to two different mems is
1958      as easy as conditionally computing the address.  Storing to a
1959      single mem merely requires a scratch memory to use as one of the
1960      destination addresses; often the memory immediately below the
1961      stack pointer is available for this.  */
1962   set_b = NULL_RTX;
1963   if (else_bb)
1964     {
1965       insn_b = first_active_insn (else_bb);
1966       if (! insn_b
1967           || insn_b != last_active_insn (else_bb, FALSE)
1968           || (set_b = single_set (insn_b)) == NULL_RTX
1969           || ! rtx_equal_p (x, SET_DEST (set_b)))
1970         return FALSE;
1971     }
1972   else
1973     {
1974       insn_b = prev_nonnote_insn (if_info.cond_earliest);
1975       /* We're going to be moving the evaluation of B down from above
1976          COND_EARLIEST to JUMP.  Make sure the relevant data is still
1977          intact.  */
1978       if (! insn_b
1979           || !NONJUMP_INSN_P (insn_b)
1980           || (set_b = single_set (insn_b)) == NULL_RTX
1981           || ! rtx_equal_p (x, SET_DEST (set_b))
1982           || reg_overlap_mentioned_p (x, SET_SRC (set_b))
1983           || modified_between_p (SET_SRC (set_b),
1984                                  PREV_INSN (if_info.cond_earliest), jump)
1985           /* Likewise with X.  In particular this can happen when
1986              noce_get_condition looks farther back in the instruction
1987              stream than one might expect.  */
1988           || reg_overlap_mentioned_p (x, cond)
1989           || reg_overlap_mentioned_p (x, a)
1990           || modified_between_p (x, PREV_INSN (if_info.cond_earliest), jump))
1991         insn_b = set_b = NULL_RTX;
1992     }
1993
1994   /* If x has side effects then only the if-then-else form is safe to
1995      convert.  But even in that case we would need to restore any notes
1996      (such as REG_INC) at then end.  That can be tricky if
1997      noce_emit_move_insn expands to more than one insn, so disable the
1998      optimization entirely for now if there are side effects.  */
1999   if (side_effects_p (x))
2000     return FALSE;
2001
2002   b = (set_b ? SET_SRC (set_b) : x);
2003
2004   /* Only operate on register destinations, and even then avoid extending
2005      the lifetime of hard registers on small register class machines.  */
2006   orig_x = x;
2007   if (!REG_P (x)
2008       || (SMALL_REGISTER_CLASSES
2009           && REGNO (x) < FIRST_PSEUDO_REGISTER))
2010     {
2011       if (no_new_pseudos || GET_MODE (x) == BLKmode)
2012         return FALSE;
2013       x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
2014                                  ? XEXP (x, 0) : x));
2015     }
2016
2017   /* Don't operate on sources that may trap or are volatile.  */
2018   if (! noce_operand_ok (a) || ! noce_operand_ok (b))
2019     return FALSE;
2020
2021   /* Set up the info block for our subroutines.  */
2022   if_info.test_bb = test_bb;
2023   if_info.cond = cond;
2024   if_info.jump = jump;
2025   if_info.insn_a = insn_a;
2026   if_info.insn_b = insn_b;
2027   if_info.x = x;
2028   if_info.a = a;
2029   if_info.b = b;
2030   if_info.b_unconditional = else_bb == 0;
2031
2032   /* Try optimizations in some approximation of a useful order.  */
2033   /* ??? Should first look to see if X is live incoming at all.  If it
2034      isn't, we don't need anything but an unconditional set.  */
2035
2036   /* Look and see if A and B are really the same.  Avoid creating silly
2037      cmove constructs that no one will fix up later.  */
2038   if (rtx_equal_p (a, b))
2039     {
2040       /* If we have an INSN_B, we don't have to create any new rtl.  Just
2041          move the instruction that we already have.  If we don't have an
2042          INSN_B, that means that A == X, and we've got a noop move.  In
2043          that case don't do anything and let the code below delete INSN_A.  */
2044       if (insn_b && else_bb)
2045         {
2046           rtx note;
2047
2048           if (else_bb && insn_b == BB_END (else_bb))
2049             BB_END (else_bb) = PREV_INSN (insn_b);
2050           reorder_insns (insn_b, insn_b, PREV_INSN (jump));
2051
2052           /* If there was a REG_EQUAL note, delete it since it may have been
2053              true due to this insn being after a jump.  */
2054           if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
2055             remove_note (insn_b, note);
2056
2057           insn_b = NULL_RTX;
2058         }
2059       /* If we have "x = b; if (...) x = a;", and x has side-effects, then
2060          x must be executed twice.  */
2061       else if (insn_b && side_effects_p (orig_x))
2062         return FALSE;
2063
2064       x = orig_x;
2065       goto success;
2066     }
2067
2068   /* Disallow the "if (...) x = a;" form (with an implicit "else x = x;")
2069      for most optimizations if writing to x may trap, i.e. it's a memory
2070      other than a static var or a stack slot.  */
2071   if (! set_b
2072       && MEM_P (orig_x)
2073       && ! MEM_NOTRAP_P (orig_x)
2074       && rtx_addr_can_trap_p (XEXP (orig_x, 0)))
2075     {
2076       if (HAVE_conditional_move)
2077         {
2078           if (noce_try_cmove (&if_info))
2079             goto success;
2080           if (! HAVE_conditional_execution
2081               && noce_try_cmove_arith (&if_info))
2082             goto success;
2083         }
2084       return FALSE;
2085     }
2086
2087   if (noce_try_move (&if_info))
2088     goto success;
2089   if (noce_try_store_flag (&if_info))
2090     goto success;
2091   if (noce_try_minmax (&if_info))
2092     goto success;
2093   if (noce_try_abs (&if_info))
2094     goto success;
2095   if (HAVE_conditional_move
2096       && noce_try_cmove (&if_info))
2097     goto success;
2098   if (! HAVE_conditional_execution)
2099     {
2100       if (noce_try_store_flag_constants (&if_info))
2101         goto success;
2102       if (noce_try_addcc (&if_info))
2103         goto success;
2104       if (noce_try_store_flag_mask (&if_info))
2105         goto success;
2106       if (HAVE_conditional_move
2107           && noce_try_cmove_arith (&if_info))
2108         goto success;
2109       if (noce_try_sign_mask (&if_info))
2110         goto success;
2111     }
2112
2113   return FALSE;
2114
2115  success:
2116   /* The original sets may now be killed.  */
2117   delete_insn (insn_a);
2118
2119   /* Several special cases here: First, we may have reused insn_b above,
2120      in which case insn_b is now NULL.  Second, we want to delete insn_b
2121      if it came from the ELSE block, because follows the now correct
2122      write that appears in the TEST block.  However, if we got insn_b from
2123      the TEST block, it may in fact be loading data needed for the comparison.
2124      We'll let life_analysis remove the insn if it's really dead.  */
2125   if (insn_b && else_bb)
2126     delete_insn (insn_b);
2127
2128   /* The new insns will have been inserted immediately before the jump.  We
2129      should be able to remove the jump with impunity, but the condition itself
2130      may have been modified by gcse to be shared across basic blocks.  */
2131   delete_insn (jump);
2132
2133   /* If we used a temporary, fix it up now.  */
2134   if (orig_x != x)
2135     {
2136       start_sequence ();
2137       noce_emit_move_insn (orig_x, x);
2138       insn_b = get_insns ();
2139       set_used_flags (orig_x);
2140       unshare_all_rtl_in_chain (insn_b);
2141       end_sequence ();
2142
2143       emit_insn_after_setloc (insn_b, BB_END (test_bb), INSN_LOCATOR (insn_a));
2144     }
2145
2146   /* Merge the blocks!  */
2147   merge_if_block (ce_info);
2148
2149   return TRUE;
2150 }
2151 \f
2152 /* Attempt to convert an IF-THEN or IF-THEN-ELSE block into
2153    straight line code.  Return true if successful.  */
2154
2155 static int
2156 process_if_block (struct ce_if_block * ce_info)
2157 {
2158   if (! reload_completed
2159       && noce_process_if_block (ce_info))
2160     return TRUE;
2161
2162   if (HAVE_conditional_execution && reload_completed)
2163     {
2164       /* If we have && and || tests, try to first handle combining the && and
2165          || tests into the conditional code, and if that fails, go back and
2166          handle it without the && and ||, which at present handles the && case
2167          if there was no ELSE block.  */
2168       if (cond_exec_process_if_block (ce_info, TRUE))
2169         return TRUE;
2170
2171       if (ce_info->num_multiple_test_blocks)
2172         {
2173           cancel_changes (0);
2174
2175           if (cond_exec_process_if_block (ce_info, FALSE))
2176             return TRUE;
2177         }
2178     }
2179
2180   return FALSE;
2181 }
2182
2183 /* Merge the blocks and mark for local life update.  */
2184
2185 static void
2186 merge_if_block (struct ce_if_block * ce_info)
2187 {
2188   basic_block test_bb = ce_info->test_bb;       /* last test block */
2189   basic_block then_bb = ce_info->then_bb;       /* THEN */
2190   basic_block else_bb = ce_info->else_bb;       /* ELSE or NULL */
2191   basic_block join_bb = ce_info->join_bb;       /* join block */
2192   basic_block combo_bb;
2193
2194   /* All block merging is done into the lower block numbers.  */
2195
2196   combo_bb = test_bb;
2197
2198   /* Merge any basic blocks to handle && and || subtests.  Each of
2199      the blocks are on the fallthru path from the predecessor block.  */
2200   if (ce_info->num_multiple_test_blocks > 0)
2201     {
2202       basic_block bb = test_bb;
2203       basic_block last_test_bb = ce_info->last_test_bb;
2204       basic_block fallthru = block_fallthru (bb);
2205
2206       do
2207         {
2208           bb = fallthru;
2209           fallthru = block_fallthru (bb);
2210           merge_blocks (combo_bb, bb);
2211           num_true_changes++;
2212         }
2213       while (bb != last_test_bb);
2214     }
2215
2216   /* Merge TEST block into THEN block.  Normally the THEN block won't have a
2217      label, but it might if there were || tests.  That label's count should be
2218      zero, and it normally should be removed.  */
2219
2220   if (then_bb)
2221     {
2222       if (combo_bb->global_live_at_end)
2223         COPY_REG_SET (combo_bb->global_live_at_end,
2224                       then_bb->global_live_at_end);
2225       merge_blocks (combo_bb, then_bb);
2226       num_true_changes++;
2227     }
2228
2229   /* The ELSE block, if it existed, had a label.  That label count
2230      will almost always be zero, but odd things can happen when labels
2231      get their addresses taken.  */
2232   if (else_bb)
2233     {
2234       merge_blocks (combo_bb, else_bb);
2235       num_true_changes++;
2236     }
2237
2238   /* If there was no join block reported, that means it was not adjacent
2239      to the others, and so we cannot merge them.  */
2240
2241   if (! join_bb)
2242     {
2243       rtx last = BB_END (combo_bb);
2244
2245       /* The outgoing edge for the current COMBO block should already
2246          be correct.  Verify this.  */
2247       if (EDGE_COUNT (combo_bb->succs) == 0)
2248         {
2249           if (find_reg_note (last, REG_NORETURN, NULL))
2250             ;
2251           else if (NONJUMP_INSN_P (last)
2252                    && GET_CODE (PATTERN (last)) == TRAP_IF
2253                    && TRAP_CONDITION (PATTERN (last)) == const_true_rtx)
2254             ;
2255           else
2256             abort ();
2257         }
2258
2259       /* There should still be something at the end of the THEN or ELSE
2260          blocks taking us to our final destination.  */
2261       else if (JUMP_P (last))
2262         ;
2263       else if (EDGE_SUCC (combo_bb, 0)->dest == EXIT_BLOCK_PTR
2264                && CALL_P (last)
2265                && SIBLING_CALL_P (last))
2266         ;
2267       else if ((EDGE_SUCC (combo_bb, 0)->flags & EDGE_EH)
2268                && can_throw_internal (last))
2269         ;
2270       else
2271         abort ();
2272     }
2273
2274   /* The JOIN block may have had quite a number of other predecessors too.
2275      Since we've already merged the TEST, THEN and ELSE blocks, we should
2276      have only one remaining edge from our if-then-else diamond.  If there
2277      is more than one remaining edge, it must come from elsewhere.  There
2278      may be zero incoming edges if the THEN block didn't actually join
2279      back up (as with a call to abort).  */
2280   else if (EDGE_COUNT (join_bb->preds) < 2
2281            && join_bb != EXIT_BLOCK_PTR)
2282     {
2283       /* We can merge the JOIN.  */
2284       if (combo_bb->global_live_at_end)
2285         COPY_REG_SET (combo_bb->global_live_at_end,
2286                       join_bb->global_live_at_end);
2287
2288       merge_blocks (combo_bb, join_bb);
2289       num_true_changes++;
2290     }
2291   else
2292     {
2293       /* We cannot merge the JOIN.  */
2294
2295       /* The outgoing edge for the current COMBO block should already
2296          be correct.  Verify this.  */
2297       if (EDGE_COUNT (combo_bb->succs) > 1
2298           || EDGE_SUCC (combo_bb, 0)->dest != join_bb)
2299         abort ();
2300
2301       /* Remove the jump and cruft from the end of the COMBO block.  */
2302       if (join_bb != EXIT_BLOCK_PTR)
2303         tidy_fallthru_edge (EDGE_SUCC (combo_bb, 0));
2304     }
2305
2306   num_updated_if_blocks++;
2307 }
2308 \f
2309 /* Find a block ending in a simple IF condition and try to transform it
2310    in some way.  When converting a multi-block condition, put the new code
2311    in the first such block and delete the rest.  Return a pointer to this
2312    first block if some transformation was done.  Return NULL otherwise.  */
2313
2314 static basic_block
2315 find_if_header (basic_block test_bb, int pass)
2316 {
2317   ce_if_block_t ce_info;
2318   edge then_edge;
2319   edge else_edge;
2320
2321   /* The kind of block we're looking for has exactly two successors.  */
2322   if (EDGE_COUNT (test_bb->succs) != 2)
2323     return NULL;
2324
2325   then_edge = EDGE_SUCC (test_bb, 0);
2326   else_edge = EDGE_SUCC (test_bb, 1);
2327
2328   /* Neither edge should be abnormal.  */
2329   if ((then_edge->flags & EDGE_COMPLEX)
2330       || (else_edge->flags & EDGE_COMPLEX))
2331     return NULL;
2332
2333   /* Nor exit the loop.  */
2334   if ((then_edge->flags & EDGE_LOOP_EXIT)
2335       || (else_edge->flags & EDGE_LOOP_EXIT))
2336     return NULL;
2337
2338   /* The THEN edge is canonically the one that falls through.  */
2339   if (then_edge->flags & EDGE_FALLTHRU)
2340     ;
2341   else if (else_edge->flags & EDGE_FALLTHRU)
2342     {
2343       edge e = else_edge;
2344       else_edge = then_edge;
2345       then_edge = e;
2346     }
2347   else
2348     /* Otherwise this must be a multiway branch of some sort.  */
2349     return NULL;
2350
2351   memset (&ce_info, '\0', sizeof (ce_info));
2352   ce_info.test_bb = test_bb;
2353   ce_info.then_bb = then_edge->dest;
2354   ce_info.else_bb = else_edge->dest;
2355   ce_info.pass = pass;
2356
2357 #ifdef IFCVT_INIT_EXTRA_FIELDS
2358   IFCVT_INIT_EXTRA_FIELDS (&ce_info);
2359 #endif
2360
2361   if (find_if_block (&ce_info))
2362     goto success;
2363
2364   if (HAVE_trap && HAVE_conditional_trap
2365       && find_cond_trap (test_bb, then_edge, else_edge))
2366     goto success;
2367
2368   if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY
2369       && (! HAVE_conditional_execution || reload_completed))
2370     {
2371       if (find_if_case_1 (test_bb, then_edge, else_edge))
2372         goto success;
2373       if (find_if_case_2 (test_bb, then_edge, else_edge))
2374         goto success;
2375     }
2376
2377   return NULL;
2378
2379  success:
2380   if (dump_file)
2381     fprintf (dump_file, "Conversion succeeded on pass %d.\n", pass);
2382   return ce_info.test_bb;
2383 }
2384
2385 /* Return true if a block has two edges, one of which falls through to the next
2386    block, and the other jumps to a specific block, so that we can tell if the
2387    block is part of an && test or an || test.  Returns either -1 or the number
2388    of non-note, non-jump, non-USE/CLOBBER insns in the block.  */
2389
2390 static int
2391 block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
2392 {
2393   edge cur_edge;
2394   int fallthru_p = FALSE;
2395   int jump_p = FALSE;
2396   rtx insn;
2397   rtx end;
2398   int n_insns = 0;
2399   edge_iterator ei;
2400
2401   if (!cur_bb || !target_bb)
2402     return -1;
2403
2404   /* If no edges, obviously it doesn't jump or fallthru.  */
2405   if (EDGE_COUNT (cur_bb->succs) == 0)
2406     return FALSE;
2407
2408   FOR_EACH_EDGE (cur_edge, ei, cur_bb->succs)
2409     {
2410       if (cur_edge->flags & EDGE_COMPLEX)
2411         /* Anything complex isn't what we want.  */
2412         return -1;
2413
2414       else if (cur_edge->flags & EDGE_FALLTHRU)
2415         fallthru_p = TRUE;
2416
2417       else if (cur_edge->dest == target_bb)
2418         jump_p = TRUE;
2419
2420       else
2421         return -1;
2422     }
2423
2424   if ((jump_p & fallthru_p) == 0)
2425     return -1;
2426
2427   /* Don't allow calls in the block, since this is used to group && and ||
2428      together for conditional execution support.  ??? we should support
2429      conditional execution support across calls for IA-64 some day, but
2430      for now it makes the code simpler.  */
2431   end = BB_END (cur_bb);
2432   insn = BB_HEAD (cur_bb);
2433
2434   while (insn != NULL_RTX)
2435     {
2436       if (CALL_P (insn))
2437         return -1;
2438
2439       if (INSN_P (insn)
2440           && !JUMP_P (insn)
2441           && GET_CODE (PATTERN (insn)) != USE
2442           && GET_CODE (PATTERN (insn)) != CLOBBER)
2443         n_insns++;
2444
2445       if (insn == end)
2446         break;
2447
2448       insn = NEXT_INSN (insn);
2449     }
2450
2451   return n_insns;
2452 }
2453
2454 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
2455    block.  If so, we'll try to convert the insns to not require the branch.
2456    Return TRUE if we were successful at converting the block.  */
2457
2458 static int
2459 find_if_block (struct ce_if_block * ce_info)
2460 {
2461   basic_block test_bb = ce_info->test_bb;
2462   basic_block then_bb = ce_info->then_bb;
2463   basic_block else_bb = ce_info->else_bb;
2464   basic_block join_bb = NULL_BLOCK;
2465   edge cur_edge;
2466   basic_block next;
2467   edge_iterator ei;
2468
2469   ce_info->last_test_bb = test_bb;
2470
2471   /* Discover if any fall through predecessors of the current test basic block
2472      were && tests (which jump to the else block) or || tests (which jump to
2473      the then block).  */
2474   if (HAVE_conditional_execution && reload_completed
2475       && EDGE_COUNT (test_bb->preds) == 1
2476       && EDGE_PRED (test_bb, 0)->flags == EDGE_FALLTHRU)
2477     {
2478       basic_block bb = EDGE_PRED (test_bb, 0)->src;
2479       basic_block target_bb;
2480       int max_insns = MAX_CONDITIONAL_EXECUTE;
2481       int n_insns;
2482
2483       /* Determine if the preceding block is an && or || block.  */
2484       if ((n_insns = block_jumps_and_fallthru_p (bb, else_bb)) >= 0)
2485         {
2486           ce_info->and_and_p = TRUE;
2487           target_bb = else_bb;
2488         }
2489       else if ((n_insns = block_jumps_and_fallthru_p (bb, then_bb)) >= 0)
2490         {
2491           ce_info->and_and_p = FALSE;
2492           target_bb = then_bb;
2493         }
2494       else
2495         target_bb = NULL_BLOCK;
2496
2497       if (target_bb && n_insns <= max_insns)
2498         {
2499           int total_insns = 0;
2500           int blocks = 0;
2501
2502           ce_info->last_test_bb = test_bb;
2503
2504           /* Found at least one && or || block, look for more.  */
2505           do
2506             {
2507               ce_info->test_bb = test_bb = bb;
2508               total_insns += n_insns;
2509               blocks++;
2510
2511               if (EDGE_COUNT (bb->preds) != 1)
2512                 break;
2513
2514               bb = EDGE_PRED (bb, 0)->src;
2515               n_insns = block_jumps_and_fallthru_p (bb, target_bb);
2516             }
2517           while (n_insns >= 0 && (total_insns + n_insns) <= max_insns);
2518
2519           ce_info->num_multiple_test_blocks = blocks;
2520           ce_info->num_multiple_test_insns = total_insns;
2521
2522           if (ce_info->and_and_p)
2523             ce_info->num_and_and_blocks = blocks;
2524           else
2525             ce_info->num_or_or_blocks = blocks;
2526         }
2527     }
2528
2529   /* The THEN block of an IF-THEN combo must have exactly one predecessor,
2530      other than any || blocks which jump to the THEN block.  */
2531   if ((EDGE_COUNT (then_bb->preds) - ce_info->num_or_or_blocks) != 1)
2532     return FALSE;
2533     
2534   /* The edges of the THEN and ELSE blocks cannot have complex edges.  */
2535   FOR_EACH_EDGE (cur_edge, ei, then_bb->preds)
2536     {
2537       if (cur_edge->flags & EDGE_COMPLEX)
2538         return FALSE;
2539     }
2540
2541   FOR_EACH_EDGE (cur_edge, ei, else_bb->preds)
2542     {
2543       if (cur_edge->flags & EDGE_COMPLEX)
2544         return FALSE;
2545     }
2546
2547   /* The THEN block of an IF-THEN combo must have zero or one successors.  */
2548   if (EDGE_COUNT (then_bb->succs) > 0
2549       && (EDGE_COUNT (then_bb->succs) > 1
2550           || (EDGE_SUCC (then_bb, 0)->flags & EDGE_COMPLEX)
2551           || (flow2_completed && tablejump_p (BB_END (then_bb), NULL, NULL))))
2552     return FALSE;
2553
2554   /* If the THEN block has no successors, conditional execution can still
2555      make a conditional call.  Don't do this unless the ELSE block has
2556      only one incoming edge -- the CFG manipulation is too ugly otherwise.
2557      Check for the last insn of the THEN block being an indirect jump, which
2558      is listed as not having any successors, but confuses the rest of the CE
2559      code processing.  ??? we should fix this in the future.  */
2560   if (EDGE_COUNT (then_bb->succs) == 0)
2561     {
2562       if (EDGE_COUNT (else_bb->preds) == 1)
2563         {
2564           rtx last_insn = BB_END (then_bb);
2565
2566           while (last_insn
2567                  && NOTE_P (last_insn)
2568                  && last_insn != BB_HEAD (then_bb))
2569             last_insn = PREV_INSN (last_insn);
2570
2571           if (last_insn
2572               && JUMP_P (last_insn)
2573               && ! simplejump_p (last_insn))
2574             return FALSE;
2575
2576           join_bb = else_bb;
2577           else_bb = NULL_BLOCK;
2578         }
2579       else
2580         return FALSE;
2581     }
2582
2583   /* If the THEN block's successor is the other edge out of the TEST block,
2584      then we have an IF-THEN combo without an ELSE.  */
2585   else if (EDGE_SUCC (then_bb, 0)->dest == else_bb)
2586     {
2587       join_bb = else_bb;
2588       else_bb = NULL_BLOCK;
2589     }
2590
2591   /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
2592      has exactly one predecessor and one successor, and the outgoing edge
2593      is not complex, then we have an IF-THEN-ELSE combo.  */
2594   else if (EDGE_COUNT (else_bb->succs) == 1
2595            && EDGE_SUCC (then_bb, 0)->dest == EDGE_SUCC (else_bb, 0)->dest
2596            && EDGE_COUNT (else_bb->preds) == 1
2597            && ! (EDGE_SUCC (else_bb, 0)->flags & EDGE_COMPLEX)
2598            && ! (flow2_completed && tablejump_p (BB_END (else_bb), NULL, NULL)))
2599     join_bb = EDGE_SUCC (else_bb, 0)->dest;
2600
2601   /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination.  */
2602   else
2603     return FALSE;
2604
2605   num_possible_if_blocks++;
2606
2607   if (dump_file)
2608     {
2609       fprintf (dump_file,
2610                "\nIF-THEN%s block found, pass %d, start block %d "
2611                "[insn %d], then %d [%d]",
2612                (else_bb) ? "-ELSE" : "",
2613                ce_info->pass,
2614                test_bb->index,
2615                BB_HEAD (test_bb) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
2616                then_bb->index,
2617                BB_HEAD (then_bb) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);
2618
2619       if (else_bb)
2620         fprintf (dump_file, ", else %d [%d]",
2621                  else_bb->index,
2622                  BB_HEAD (else_bb) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);
2623
2624       fprintf (dump_file, ", join %d [%d]",
2625                join_bb->index,
2626                BB_HEAD (join_bb) ? (int)INSN_UID (BB_HEAD (join_bb)) : -1);
2627
2628       if (ce_info->num_multiple_test_blocks > 0)
2629         fprintf (dump_file, ", %d %s block%s last test %d [%d]",
2630                  ce_info->num_multiple_test_blocks,
2631                  (ce_info->and_and_p) ? "&&" : "||",
2632                  (ce_info->num_multiple_test_blocks == 1) ? "" : "s",
2633                  ce_info->last_test_bb->index,
2634                  ((BB_HEAD (ce_info->last_test_bb))
2635                   ? (int)INSN_UID (BB_HEAD (ce_info->last_test_bb))
2636                   : -1));
2637
2638       fputc ('\n', dump_file);
2639     }
2640
2641   /* Make sure IF, THEN, and ELSE, blocks are adjacent.  Actually, we get the
2642      first condition for free, since we've already asserted that there's a
2643      fallthru edge from IF to THEN.  Likewise for the && and || blocks, since
2644      we checked the FALLTHRU flag, those are already adjacent to the last IF
2645      block.  */
2646   /* ??? As an enhancement, move the ELSE block.  Have to deal with
2647      BLOCK notes, if by no other means than aborting the merge if they
2648      exist.  Sticky enough I don't want to think about it now.  */
2649   next = then_bb;
2650   if (else_bb && (next = next->next_bb) != else_bb)
2651     return FALSE;
2652   if ((next = next->next_bb) != join_bb && join_bb != EXIT_BLOCK_PTR)
2653     {
2654       if (else_bb)
2655         join_bb = NULL;
2656       else
2657         return FALSE;
2658     }
2659
2660   /* Do the real work.  */
2661   ce_info->else_bb = else_bb;
2662   ce_info->join_bb = join_bb;
2663
2664   return process_if_block (ce_info);
2665 }
2666
2667 /* Convert a branch over a trap, or a branch
2668    to a trap, into a conditional trap.  */
2669
2670 static int
2671 find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
2672 {
2673   basic_block then_bb = then_edge->dest;
2674   basic_block else_bb = else_edge->dest;
2675   basic_block other_bb, trap_bb;
2676   rtx trap, jump, cond, cond_earliest, seq;
2677   enum rtx_code code;
2678
2679   /* Locate the block with the trap instruction.  */
2680   /* ??? While we look for no successors, we really ought to allow
2681      EH successors.  Need to fix merge_if_block for that to work.  */
2682   if ((trap = block_has_only_trap (then_bb)) != NULL)
2683     trap_bb = then_bb, other_bb = else_bb;
2684   else if ((trap = block_has_only_trap (else_bb)) != NULL)
2685     trap_bb = else_bb, other_bb = then_bb;
2686   else
2687     return FALSE;
2688
2689   if (dump_file)
2690     {
2691       fprintf (dump_file, "\nTRAP-IF block found, start %d, trap %d\n",
2692                test_bb->index, trap_bb->index);
2693     }
2694
2695   /* If this is not a standard conditional jump, we can't parse it.  */
2696   jump = BB_END (test_bb);
2697   cond = noce_get_condition (jump, &cond_earliest);
2698   if (! cond)
2699     return FALSE;
2700
2701   /* If the conditional jump is more than just a conditional jump, then
2702      we can not do if-conversion on this block.  */
2703   if (! onlyjump_p (jump))
2704     return FALSE;
2705
2706   /* We must be comparing objects whose modes imply the size.  */
2707   if (GET_MODE (XEXP (cond, 0)) == BLKmode)
2708     return FALSE;
2709
2710   /* Reverse the comparison code, if necessary.  */
2711   code = GET_CODE (cond);
2712   if (then_bb == trap_bb)
2713     {
2714       code = reversed_comparison_code (cond, jump);
2715       if (code == UNKNOWN)
2716         return FALSE;
2717     }
2718
2719   /* Attempt to generate the conditional trap.  */
2720   seq = gen_cond_trap (code, XEXP (cond, 0),
2721                        XEXP (cond, 1),
2722                        TRAP_CODE (PATTERN (trap)));
2723   if (seq == NULL)
2724     return FALSE;
2725
2726   num_true_changes++;
2727
2728   /* Emit the new insns before cond_earliest.  */
2729   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));
2730
2731   /* Delete the trap block if possible.  */
2732   remove_edge (trap_bb == then_bb ? then_edge : else_edge);
2733   if (EDGE_COUNT (trap_bb->preds) == 0)
2734     delete_basic_block (trap_bb);
2735
2736   /* If the non-trap block and the test are now adjacent, merge them.
2737      Otherwise we must insert a direct branch.  */
2738   if (test_bb->next_bb == other_bb)
2739     {
2740       struct ce_if_block new_ce_info;
2741       delete_insn (jump);
2742       memset (&new_ce_info, '\0', sizeof (new_ce_info));
2743       new_ce_info.test_bb = test_bb;
2744       new_ce_info.then_bb = NULL;
2745       new_ce_info.else_bb = NULL;
2746       new_ce_info.join_bb = other_bb;
2747       merge_if_block (&new_ce_info);
2748     }
2749   else
2750     {
2751       rtx lab, newjump;
2752
2753       lab = JUMP_LABEL (jump);
2754       newjump = emit_jump_insn_after (gen_jump (lab), jump);
2755       LABEL_NUSES (lab) += 1;
2756       JUMP_LABEL (newjump) = lab;
2757       emit_barrier_after (newjump);
2758
2759       delete_insn (jump);
2760     }
2761
2762   return TRUE;
2763 }
2764
2765 /* Subroutine of find_cond_trap: if BB contains only a trap insn,
2766    return it.  */
2767
2768 static rtx
2769 block_has_only_trap (basic_block bb)
2770 {
2771   rtx trap;
2772
2773   /* We're not the exit block.  */
2774   if (bb == EXIT_BLOCK_PTR)
2775     return NULL_RTX;
2776
2777   /* The block must have no successors.  */
2778   if (EDGE_COUNT (bb->succs) > 0)
2779     return NULL_RTX;
2780
2781   /* The only instruction in the THEN block must be the trap.  */
2782   trap = first_active_insn (bb);
2783   if (! (trap == BB_END (bb)
2784          && GET_CODE (PATTERN (trap)) == TRAP_IF
2785          && TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
2786     return NULL_RTX;
2787
2788   return trap;
2789 }
2790
2791 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
2792    transformable, but not necessarily the other.  There need be no
2793    JOIN block.
2794
2795    Return TRUE if we were successful at converting the block.
2796
2797    Cases we'd like to look at:
2798
2799    (1)
2800         if (test) goto over; // x not live
2801         x = a;
2802         goto label;
2803         over:
2804
2805    becomes
2806
2807         x = a;
2808         if (! test) goto label;
2809
2810    (2)
2811         if (test) goto E; // x not live
2812         x = big();
2813         goto L;
2814         E:
2815         x = b;
2816         goto M;
2817
2818    becomes
2819
2820         x = b;
2821         if (test) goto M;
2822         x = big();
2823         goto L;
2824
2825    (3) // This one's really only interesting for targets that can do
2826        // multiway branching, e.g. IA-64 BBB bundles.  For other targets
2827        // it results in multiple branches on a cache line, which often
2828        // does not sit well with predictors.
2829
2830         if (test1) goto E; // predicted not taken
2831         x = a;
2832         if (test2) goto F;
2833         ...
2834         E:
2835         x = b;
2836         J:
2837
2838    becomes
2839
2840         x = a;
2841         if (test1) goto E;
2842         if (test2) goto F;
2843
2844    Notes:
2845
2846    (A) Don't do (2) if the branch is predicted against the block we're
2847    eliminating.  Do it anyway if we can eliminate a branch; this requires
2848    that the sole successor of the eliminated block postdominate the other
2849    side of the if.
2850
2851    (B) With CE, on (3) we can steal from both sides of the if, creating
2852
2853         if (test1) x = a;
2854         if (!test1) x = b;
2855         if (test1) goto J;
2856         if (test2) goto F;
2857         ...
2858         J:
2859
2860    Again, this is most useful if J postdominates.
2861
2862    (C) CE substitutes for helpful life information.
2863
2864    (D) These heuristics need a lot of work.  */
2865
2866 /* Tests for case 1 above.  */
2867
2868 static int
2869 find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
2870 {
2871   basic_block then_bb = then_edge->dest;
2872   basic_block else_bb = else_edge->dest, new_bb;
2873   int then_bb_index;
2874
2875   /* If we are partitioning hot/cold basic blocks, we don't want to
2876      mess up unconditional or indirect jumps that cross between hot
2877      and cold sections.
2878   
2879      Basic block partitioning may result in some jumps that appear to
2880      be optimizable (or blocks that appear to be mergeable), but which really 
2881      must be left untouched (they are required to make it safely across 
2882      partition boundaries).  See  the comments at the top of 
2883      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
2884
2885   if (flag_reorder_blocks_and_partition
2886       && ((BB_END (then_bb) 
2887            && find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
2888           || (BB_END (else_bb)
2889               && find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP, 
2890                                 NULL_RTX))))
2891     return FALSE;
2892
2893   /* THEN has one successor.  */
2894   if (EDGE_COUNT (then_bb->succs) != 1)
2895     return FALSE;
2896
2897   /* THEN does not fall through, but is not strange either.  */
2898   if (EDGE_SUCC (then_bb, 0)->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
2899     return FALSE;
2900
2901   /* THEN has one predecessor.  */
2902   if (EDGE_COUNT (then_bb->preds) != 1)
2903     return FALSE;
2904
2905   /* THEN must do something.  */
2906   if (forwarder_block_p (then_bb))
2907     return FALSE;
2908
2909   num_possible_if_blocks++;
2910   if (dump_file)
2911     fprintf (dump_file,
2912              "\nIF-CASE-1 found, start %d, then %d\n",
2913              test_bb->index, then_bb->index);
2914
2915   /* THEN is small.  */
2916   if (! cheap_bb_rtx_cost_p (then_bb, COSTS_N_INSNS (BRANCH_COST)))
2917     return FALSE;
2918
2919   /* Registers set are dead, or are predicable.  */
2920   if (! dead_or_predicable (test_bb, then_bb, else_bb,
2921                             EDGE_SUCC (then_bb, 0)->dest, 1))
2922     return FALSE;
2923
2924   /* Conversion went ok, including moving the insns and fixing up the
2925      jump.  Adjust the CFG to match.  */
2926
2927   bitmap_ior (test_bb->global_live_at_end,
2928               else_bb->global_live_at_start,
2929               then_bb->global_live_at_end);
2930
2931
2932   /* We can avoid creating a new basic block if then_bb is immediately
2933      followed by else_bb, i.e. deleting then_bb allows test_bb to fall
2934      thru to else_bb.  */
2935
2936   if (then_bb->next_bb == else_bb
2937       && then_bb->prev_bb == test_bb
2938       && else_bb != EXIT_BLOCK_PTR)
2939     {
2940       redirect_edge_succ (FALLTHRU_EDGE (test_bb), else_bb);
2941       new_bb = 0;
2942     }
2943   else
2944     new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb),
2945                                              else_bb);
2946
2947   then_bb_index = then_bb->index;
2948   delete_basic_block (then_bb);
2949
2950   /* Make rest of code believe that the newly created block is the THEN_BB
2951      block we removed.  */
2952   if (new_bb)
2953     {
2954       new_bb->index = then_bb_index;
2955       BASIC_BLOCK (then_bb_index) = new_bb;
2956       /* Since the fallthru edge was redirected from test_bb to new_bb,
2957          we need to ensure that new_bb is in the same partition as
2958          test bb (you can not fall through across section boundaries).  */
2959       BB_COPY_PARTITION (new_bb, test_bb);
2960     }
2961   /* We've possibly created jump to next insn, cleanup_cfg will solve that
2962      later.  */
2963
2964   num_true_changes++;
2965   num_updated_if_blocks++;
2966
2967   return TRUE;
2968 }
2969
2970 /* Test for case 2 above.  */
2971
2972 static int
2973 find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
2974 {
2975   basic_block then_bb = then_edge->dest;
2976   basic_block else_bb = else_edge->dest;
2977   edge else_succ;
2978   rtx note;
2979
2980   /* If we are partitioning hot/cold basic blocks, we don't want to
2981      mess up unconditional or indirect jumps that cross between hot
2982      and cold sections.
2983   
2984      Basic block partitioning may result in some jumps that appear to
2985      be optimizable (or blocks that appear to be mergeable), but which really 
2986      must be left untouched (they are required to make it safely across 
2987      partition boundaries).  See  the comments at the top of 
2988      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
2989
2990   if (flag_reorder_blocks_and_partition
2991       && ((BB_END (then_bb)
2992            && find_reg_note (BB_END (then_bb), REG_CROSSING_JUMP, NULL_RTX))
2993           || (BB_END (else_bb) 
2994               && find_reg_note (BB_END (else_bb), REG_CROSSING_JUMP, 
2995                                 NULL_RTX))))
2996     return FALSE;
2997
2998   /* ELSE has one successor.  */
2999   if (EDGE_COUNT (else_bb->succs) != 1)
3000     return FALSE;
3001   else
3002     else_succ = EDGE_SUCC (else_bb, 0);
3003
3004   /* ELSE outgoing edge is not complex.  */
3005   if (else_succ->flags & EDGE_COMPLEX)
3006     return FALSE;
3007
3008   /* ELSE has one predecessor.  */
3009   if (EDGE_COUNT (else_bb->preds) != 1)
3010     return FALSE;
3011
3012   /* THEN is not EXIT.  */
3013   if (then_bb->index < 0)
3014     return FALSE;
3015
3016   /* ELSE is predicted or SUCC(ELSE) postdominates THEN.  */
3017   note = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
3018   if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
3019     ;
3020   else if (else_succ->dest->index < 0
3021            || dominated_by_p (CDI_POST_DOMINATORS, then_bb,
3022                               else_succ->dest))
3023     ;
3024   else
3025     return FALSE;
3026
3027   num_possible_if_blocks++;
3028   if (dump_file)
3029     fprintf (dump_file,
3030              "\nIF-CASE-2 found, start %d, else %d\n",
3031              test_bb->index, else_bb->index);
3032
3033   /* ELSE is small.  */
3034   if (! cheap_bb_rtx_cost_p (else_bb, COSTS_N_INSNS (BRANCH_COST)))
3035     return FALSE;
3036
3037   /* Registers set are dead, or are predicable.  */
3038   if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ->dest, 0))
3039     return FALSE;
3040
3041   /* Conversion went ok, including moving the insns and fixing up the
3042      jump.  Adjust the CFG to match.  */
3043
3044   bitmap_ior (test_bb->global_live_at_end,
3045               then_bb->global_live_at_start,
3046               else_bb->global_live_at_end);
3047
3048   delete_basic_block (else_bb);
3049
3050   num_true_changes++;
3051   num_updated_if_blocks++;
3052
3053   /* ??? We may now fallthru from one of THEN's successors into a join
3054      block.  Rerun cleanup_cfg?  Examine things manually?  Wait?  */
3055
3056   return TRUE;
3057 }
3058
3059 /* A subroutine of dead_or_predicable called through for_each_rtx.
3060    Return 1 if a memory is found.  */
3061
3062 static int
3063 find_memory (rtx *px, void *data ATTRIBUTE_UNUSED)
3064 {
3065   return MEM_P (*px);
3066 }
3067
3068 /* Used by the code above to perform the actual rtl transformations.
3069    Return TRUE if successful.
3070
3071    TEST_BB is the block containing the conditional branch.  MERGE_BB
3072    is the block containing the code to manipulate.  NEW_DEST is the
3073    label TEST_BB should be branching to after the conversion.
3074    REVERSEP is true if the sense of the branch should be reversed.  */
3075
3076 static int
3077 dead_or_predicable (basic_block test_bb, basic_block merge_bb,
3078                     basic_block other_bb, basic_block new_dest, int reversep)
3079 {
3080   rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
3081
3082   jump = BB_END (test_bb);
3083
3084   /* Find the extent of the real code in the merge block.  */
3085   head = BB_HEAD (merge_bb);
3086   end = BB_END (merge_bb);
3087
3088   if (LABEL_P (head))
3089     head = NEXT_INSN (head);
3090   if (NOTE_P (head))
3091     {
3092       if (head == end)
3093         {
3094           head = end = NULL_RTX;
3095           goto no_body;
3096         }
3097       head = NEXT_INSN (head);
3098     }
3099
3100   if (JUMP_P (end))
3101     {
3102       if (head == end)
3103         {
3104           head = end = NULL_RTX;
3105           goto no_body;
3106         }
3107       end = PREV_INSN (end);
3108     }
3109
3110   /* Disable handling dead code by conditional execution if the machine needs
3111      to do anything funny with the tests, etc.  */
3112 #ifndef IFCVT_MODIFY_TESTS
3113   if (HAVE_conditional_execution)
3114     {
3115       /* In the conditional execution case, we have things easy.  We know
3116          the condition is reversible.  We don't have to check life info
3117          because we're going to conditionally execute the code anyway.
3118          All that's left is making sure the insns involved can actually
3119          be predicated.  */
3120
3121       rtx cond, prob_val;
3122
3123       cond = cond_exec_get_condition (jump);
3124       if (! cond)
3125         return FALSE;
3126
3127       prob_val = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
3128       if (prob_val)
3129         prob_val = XEXP (prob_val, 0);
3130
3131       if (reversep)
3132         {
3133           enum rtx_code rev = reversed_comparison_code (cond, jump);
3134           if (rev == UNKNOWN)
3135             return FALSE;
3136           cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
3137                                  XEXP (cond, 1));
3138           if (prob_val)
3139             prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val));
3140         }
3141
3142       if (! cond_exec_process_insns ((ce_if_block_t *)0, head, end, cond,
3143                                      prob_val, 0))
3144         goto cancel;
3145
3146       earliest = jump;
3147     }
3148   else
3149 #endif
3150     {
3151       /* In the non-conditional execution case, we have to verify that there
3152          are no trapping operations, no calls, no references to memory, and
3153          that any registers modified are dead at the branch site.  */
3154
3155       rtx insn, cond, prev;
3156       regset merge_set, tmp, test_live, test_set;
3157       struct propagate_block_info *pbi;
3158       unsigned i, fail = 0;
3159       bitmap_iterator bi;
3160
3161       /* Check for no calls or trapping operations.  */
3162       for (insn = head; ; insn = NEXT_INSN (insn))
3163         {
3164           if (CALL_P (insn))
3165             return FALSE;
3166           if (INSN_P (insn))
3167             {
3168               if (may_trap_p (PATTERN (insn)))
3169                 return FALSE;
3170
3171               /* ??? Even non-trapping memories such as stack frame
3172                  references must be avoided.  For stores, we collect
3173                  no lifetime info; for reads, we'd have to assert
3174                  true_dependence false against every store in the
3175                  TEST range.  */
3176               if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
3177                 return FALSE;
3178             }
3179           if (insn == end)
3180             break;
3181         }
3182
3183       if (! any_condjump_p (jump))
3184         return FALSE;
3185
3186       /* Find the extent of the conditional.  */
3187       cond = noce_get_condition (jump, &earliest);
3188       if (! cond)
3189         return FALSE;
3190
3191       /* Collect:
3192            MERGE_SET = set of registers set in MERGE_BB
3193            TEST_LIVE = set of registers live at EARLIEST
3194            TEST_SET  = set of registers set between EARLIEST and the
3195                        end of the block.  */
3196
3197       tmp = ALLOC_REG_SET (&reg_obstack);
3198       merge_set = ALLOC_REG_SET (&reg_obstack);
3199       test_live = ALLOC_REG_SET (&reg_obstack);
3200       test_set = ALLOC_REG_SET (&reg_obstack);
3201
3202       /* ??? bb->local_set is only valid during calculate_global_regs_live,
3203          so we must recompute usage for MERGE_BB.  Not so bad, I suppose,
3204          since we've already asserted that MERGE_BB is small.  */
3205       propagate_block (merge_bb, tmp, merge_set, merge_set, 0);
3206
3207       /* For small register class machines, don't lengthen lifetimes of
3208          hard registers before reload.  */
3209       if (SMALL_REGISTER_CLASSES && ! reload_completed)
3210         {
3211           EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
3212             {
3213               if (i < FIRST_PSEUDO_REGISTER
3214                   && ! fixed_regs[i]
3215                   && ! global_regs[i])
3216                 fail = 1;
3217             }
3218         }
3219
3220       /* For TEST, we're interested in a range of insns, not a whole block.
3221          Moreover, we're interested in the insns live from OTHER_BB.  */
3222
3223       COPY_REG_SET (test_live, other_bb->global_live_at_start);
3224       pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set,
3225                                        0);
3226
3227       for (insn = jump; ; insn = prev)
3228         {
3229           prev = propagate_one_insn (pbi, insn);
3230           if (insn == earliest)
3231             break;
3232         }
3233
3234       free_propagate_block_info (pbi);
3235
3236       /* We can perform the transformation if
3237            MERGE_SET & (TEST_SET | TEST_LIVE)
3238          and
3239            TEST_SET & merge_bb->global_live_at_start
3240          are empty.  */
3241
3242       if (bitmap_intersect_p (test_set, merge_set)
3243           || bitmap_intersect_p (test_live, merge_set)
3244           || bitmap_intersect_p (test_set, merge_bb->global_live_at_start))
3245         fail = 1;
3246
3247       FREE_REG_SET (tmp);
3248       FREE_REG_SET (merge_set);
3249       FREE_REG_SET (test_live);
3250       FREE_REG_SET (test_set);
3251
3252       if (fail)
3253         return FALSE;
3254     }
3255
3256  no_body:
3257   /* We don't want to use normal invert_jump or redirect_jump because
3258      we don't want to delete_insn called.  Also, we want to do our own
3259      change group management.  */
3260
3261   old_dest = JUMP_LABEL (jump);
3262   if (other_bb != new_dest)
3263     {
3264       new_label = block_label (new_dest);
3265       if (reversep
3266           ? ! invert_jump_1 (jump, new_label)
3267           : ! redirect_jump_1 (jump, new_label))
3268         goto cancel;
3269     }
3270
3271   if (! apply_change_group ())
3272     return FALSE;
3273
3274   if (other_bb != new_dest)
3275     {
3276       if (old_dest)
3277         LABEL_NUSES (old_dest) -= 1;
3278       if (new_label)
3279         LABEL_NUSES (new_label) += 1;
3280       JUMP_LABEL (jump) = new_label;
3281       if (reversep)
3282         invert_br_probabilities (jump);
3283
3284       redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
3285       if (reversep)
3286         {
3287           gcov_type count, probability;
3288           count = BRANCH_EDGE (test_bb)->count;
3289           BRANCH_EDGE (test_bb)->count = FALLTHRU_EDGE (test_bb)->count;
3290           FALLTHRU_EDGE (test_bb)->count = count;
3291           probability = BRANCH_EDGE (test_bb)->probability;
3292           BRANCH_EDGE (test_bb)->probability
3293             = FALLTHRU_EDGE (test_bb)->probability;
3294           FALLTHRU_EDGE (test_bb)->probability = probability;
3295           update_br_prob_note (test_bb);
3296         }
3297     }
3298
3299   /* Move the insns out of MERGE_BB to before the branch.  */
3300   if (head != NULL)
3301     {
3302       if (end == BB_END (merge_bb))
3303         BB_END (merge_bb) = PREV_INSN (head);
3304
3305       if (squeeze_notes (&head, &end))
3306         return TRUE;
3307
3308       reorder_insns (head, end, PREV_INSN (earliest));
3309     }
3310
3311   /* Remove the jump and edge if we can.  */
3312   if (other_bb == new_dest)
3313     {
3314       delete_insn (jump);
3315       remove_edge (BRANCH_EDGE (test_bb));
3316       /* ??? Can't merge blocks here, as then_bb is still in use.
3317          At minimum, the merge will get done just before bb-reorder.  */
3318     }
3319
3320   return TRUE;
3321
3322  cancel:
3323   cancel_changes (0);
3324   return FALSE;
3325 }
3326 \f
3327 /* Main entry point for all if-conversion.  */
3328
3329 void
3330 if_convert (int x_life_data_ok)
3331 {
3332   basic_block bb;
3333   int pass;
3334
3335   num_possible_if_blocks = 0;
3336   num_updated_if_blocks = 0;
3337   num_true_changes = 0;
3338   life_data_ok = (x_life_data_ok != 0);
3339
3340   if ((! targetm.cannot_modify_jumps_p ())
3341       && (!flag_reorder_blocks_and_partition || !no_new_pseudos
3342           || !targetm.have_named_sections))
3343     mark_loop_exit_edges ();
3344
3345   /* Compute postdominators if we think we'll use them.  */
3346   if (HAVE_conditional_execution || life_data_ok)
3347     calculate_dominance_info (CDI_POST_DOMINATORS);
3348
3349   if (life_data_ok)
3350     clear_bb_flags ();
3351
3352   /* Go through each of the basic blocks looking for things to convert.  If we
3353      have conditional execution, we make multiple passes to allow us to handle
3354      IF-THEN{-ELSE} blocks within other IF-THEN{-ELSE} blocks.  */
3355   pass = 0;
3356   do
3357     {
3358       cond_exec_changed_p = FALSE;
3359       pass++;
3360
3361 #ifdef IFCVT_MULTIPLE_DUMPS
3362       if (dump_file && pass > 1)
3363         fprintf (dump_file, "\n\n========== Pass %d ==========\n", pass);
3364 #endif
3365
3366       FOR_EACH_BB (bb)
3367         {
3368           basic_block new_bb;
3369           while ((new_bb = find_if_header (bb, pass)))
3370             bb = new_bb;
3371         }
3372
3373 #ifdef IFCVT_MULTIPLE_DUMPS
3374       if (dump_file && cond_exec_changed_p)
3375         print_rtl_with_bb (dump_file, get_insns ());
3376 #endif
3377     }
3378   while (cond_exec_changed_p);
3379
3380 #ifdef IFCVT_MULTIPLE_DUMPS
3381   if (dump_file)
3382     fprintf (dump_file, "\n\n========== no more changes\n");
3383 #endif
3384
3385   free_dominance_info (CDI_POST_DOMINATORS);
3386
3387   if (dump_file)
3388     fflush (dump_file);
3389
3390   clear_aux_for_blocks ();
3391
3392   /* Rebuild life info for basic blocks that require it.  */
3393   if (num_true_changes && life_data_ok)
3394     {
3395       /* If we allocated new pseudos, we must resize the array for sched1.  */
3396       if (max_regno < max_reg_num ())
3397         {
3398           max_regno = max_reg_num ();
3399           allocate_reg_info (max_regno, FALSE, FALSE);
3400         }
3401       update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
3402                                         PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
3403                                         | PROP_KILL_DEAD_CODE);
3404     }
3405
3406   /* Write the final stats.  */
3407   if (dump_file && num_possible_if_blocks > 0)
3408     {
3409       fprintf (dump_file,
3410                "\n%d possible IF blocks searched.\n",
3411                num_possible_if_blocks);
3412       fprintf (dump_file,
3413                "%d IF blocks converted.\n",
3414                num_updated_if_blocks);
3415       fprintf (dump_file,
3416                "%d true changes made.\n\n\n",
3417                num_true_changes);
3418     }
3419
3420 #ifdef ENABLE_CHECKING
3421   verify_flow_info ();
3422 #endif
3423 }