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