1 /* If-conversion support.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GCC.
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)
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.
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
28 #include "insn-config.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
40 #ifndef HAVE_conditional_execution
41 #define HAVE_conditional_execution 0
43 #ifndef HAVE_conditional_move
44 #define HAVE_conditional_move 0
55 #ifndef HAVE_conditional_trap
56 #define HAVE_conditional_trap 0
59 #ifndef MAX_CONDITIONAL_EXECUTE
60 #define MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1)
63 #define NULL_EDGE ((struct edge_def *)NULL)
64 #define NULL_BLOCK ((struct basic_block_def *)NULL)
66 /* # of IF-THEN or IF-THEN-ELSE blocks we looked at */
67 static int num_possible_if_blocks
;
69 /* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
71 static int num_updated_if_blocks
;
73 /* # of basic blocks that were removed. */
74 static int num_removed_blocks
;
76 /* True if life data ok at present. */
77 static bool life_data_ok
;
79 /* The post-dominator relation on the original block numbers. */
80 static sbitmap
*post_dominators
;
82 /* Forward references. */
83 static int count_bb_insns
PARAMS ((basic_block
));
84 static rtx first_active_insn
PARAMS ((basic_block
));
85 static int last_active_insn_p
PARAMS ((basic_block
, rtx
));
86 static int seq_contains_jump
PARAMS ((rtx
));
88 static int cond_exec_process_insns
PARAMS ((rtx
, rtx
, rtx
, rtx
, int));
89 static rtx cond_exec_get_condition
PARAMS ((rtx
));
90 static int cond_exec_process_if_block
PARAMS ((basic_block
, basic_block
,
91 basic_block
, basic_block
));
93 static rtx noce_get_condition
PARAMS ((rtx
, rtx
*));
94 static int noce_operand_ok
PARAMS ((rtx
));
95 static int noce_process_if_block
PARAMS ((basic_block
, basic_block
,
96 basic_block
, basic_block
));
98 static int process_if_block
PARAMS ((basic_block
, basic_block
,
99 basic_block
, basic_block
));
100 static void merge_if_block
PARAMS ((basic_block
, basic_block
,
101 basic_block
, basic_block
));
103 static int find_if_header
PARAMS ((basic_block
));
104 static int find_if_block
PARAMS ((basic_block
, edge
, edge
));
105 static int find_if_case_1
PARAMS ((basic_block
, edge
, edge
));
106 static int find_if_case_2
PARAMS ((basic_block
, edge
, edge
));
107 static int find_cond_trap
PARAMS ((basic_block
, edge
, edge
));
108 static rtx block_has_only_trap
PARAMS ((basic_block
));
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
));
114 /* Abuse the basic_block AUX field to store the original block index,
115 as well as a flag indicating that the block should be rescaned for
118 #define SET_ORIG_INDEX(BB,I) ((BB)->aux = (void *)((size_t)(I) << 1))
119 #define ORIG_INDEX(BB) ((size_t)(BB)->aux >> 1)
120 #define SET_UPDATE_LIFE(BB) ((BB)->aux = (void *)((size_t)(BB)->aux | 1))
121 #define UPDATE_LIFE(BB) ((size_t)(BB)->aux & 1)
124 /* Count the number of non-jump active insns in BB. */
135 if (GET_CODE (insn
) == CALL_INSN
|| GET_CODE (insn
) == INSN
)
140 insn
= NEXT_INSN (insn
);
146 /* Return the first non-jump active insn in the basic block. */
149 first_active_insn (bb
)
154 if (GET_CODE (insn
) == CODE_LABEL
)
158 insn
= NEXT_INSN (insn
);
161 while (GET_CODE (insn
) == NOTE
)
165 insn
= NEXT_INSN (insn
);
168 if (GET_CODE (insn
) == JUMP_INSN
)
174 /* Return true if INSN is the last active non-jump insn in BB. */
177 last_active_insn_p (bb
, insn
)
185 insn
= NEXT_INSN (insn
);
187 while (GET_CODE (insn
) == NOTE
);
189 return GET_CODE (insn
) == JUMP_INSN
;
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. */
198 seq_contains_jump (insn
)
203 if (GET_CODE (insn
) == JUMP_INSN
)
205 insn
= NEXT_INSN (insn
);
210 /* Go through a bunch of insns, converting them to conditional
211 execution format if possible. Return TRUE if all of the non-note
212 insns were processed. */
215 cond_exec_process_insns (start
, end
, test
, prob_val
, mod_ok
)
216 rtx start
; /* first insn to look at */
217 rtx end
; /* last insn to look at */
218 rtx test
; /* conditional execution test */
219 rtx prob_val
; /* probability of branch taken. */
220 int mod_ok
; /* true if modifications ok last insn. */
222 int must_be_last
= FALSE
;
226 for (insn
= start
; ; insn
= NEXT_INSN (insn
))
228 if (GET_CODE (insn
) == NOTE
)
231 if (GET_CODE (insn
) != INSN
&& GET_CODE (insn
) != CALL_INSN
)
234 /* Remove USE insns that get in the way. */
235 if (reload_completed
&& GET_CODE (PATTERN (insn
)) == USE
)
237 /* ??? Ug. Actually unlinking the thing is problematic,
238 given what we'd have to coordinate with our callers. */
239 PUT_CODE (insn
, NOTE
);
240 NOTE_LINE_NUMBER (insn
) = NOTE_INSN_DELETED
;
241 NOTE_SOURCE_FILE (insn
) = 0;
245 /* Last insn wasn't last? */
249 if (modified_in_p (test
, insn
))
256 /* Now build the conditional form of the instruction. */
257 pattern
= PATTERN (insn
);
259 /* If the machine needs to modify the insn being conditionally executed,
260 say for example to force a constant integer operand into a temp
261 register, do so here. */
262 #ifdef IFCVT_MODIFY_INSN
263 IFCVT_MODIFY_INSN (pattern
, insn
);
268 validate_change (insn
, &PATTERN (insn
),
269 gen_rtx_COND_EXEC (VOIDmode
, copy_rtx (test
),
272 if (GET_CODE (insn
) == CALL_INSN
&& prob_val
)
273 validate_change (insn
, ®_NOTES (insn
),
274 alloc_EXPR_LIST (REG_BR_PROB
, prob_val
,
275 REG_NOTES (insn
)), 1);
285 /* Return the condition for a jump. Do not do any special processing. */
288 cond_exec_get_condition (jump
)
293 if (any_condjump_p (jump
))
294 test_if
= SET_SRC (pc_set (jump
));
297 cond
= XEXP (test_if
, 0);
299 /* If this branches to JUMP_LABEL when the condition is false,
300 reverse the condition. */
301 if (GET_CODE (XEXP (test_if
, 2)) == LABEL_REF
302 && XEXP (XEXP (test_if
, 2), 0) == JUMP_LABEL (jump
))
304 enum rtx_code rev
= reversed_comparison_code (cond
, jump
);
308 cond
= gen_rtx_fmt_ee (rev
, GET_MODE (cond
), XEXP (cond
, 0),
315 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
316 to conditional execution. Return TRUE if we were successful at
317 converting the the block. */
320 cond_exec_process_if_block (test_bb
, then_bb
, else_bb
, join_bb
)
321 basic_block test_bb
; /* Basic block test is in */
322 basic_block then_bb
; /* Basic block for THEN block */
323 basic_block else_bb
; /* Basic block for ELSE block */
324 basic_block join_bb
; /* Basic block the join label is in */
326 rtx test_expr
; /* expression in IF_THEN_ELSE that is tested */
327 rtx then_start
; /* first insn in THEN block */
328 rtx then_end
; /* last insn + 1 in THEN block */
329 rtx else_start
= NULL_RTX
; /* first insn in ELSE block or NULL */
330 rtx else_end
= NULL_RTX
; /* last insn + 1 in ELSE block */
331 int max
; /* max # of insns to convert. */
332 int then_mod_ok
; /* whether conditional mods are ok in THEN */
333 rtx true_expr
; /* test for else block insns */
334 rtx false_expr
; /* test for then block insns */
335 rtx true_prob_val
; /* probability of else block */
336 rtx false_prob_val
; /* probability of then block */
338 enum rtx_code false_code
;
340 /* Find the conditional jump to the ELSE or JOIN part, and isolate
342 test_expr
= cond_exec_get_condition (test_bb
->end
);
346 /* If the conditional jump is more than just a conditional jump,
347 then we can not do conditional execution conversion on this block. */
348 if (!onlyjump_p (test_bb
->end
))
351 /* Collect the bounds of where we're to search. */
353 then_start
= then_bb
->head
;
354 then_end
= then_bb
->end
;
356 /* Skip a label heading THEN block. */
357 if (GET_CODE (then_start
) == CODE_LABEL
)
358 then_start
= NEXT_INSN (then_start
);
360 /* Skip a (use (const_int 0)) or branch as the final insn. */
361 if (GET_CODE (then_end
) == INSN
362 && GET_CODE (PATTERN (then_end
)) == USE
363 && GET_CODE (XEXP (PATTERN (then_end
), 0)) == CONST_INT
)
364 then_end
= PREV_INSN (then_end
);
365 else if (GET_CODE (then_end
) == JUMP_INSN
)
366 then_end
= PREV_INSN (then_end
);
370 /* Skip the ELSE block's label. */
371 else_start
= NEXT_INSN (else_bb
->head
);
372 else_end
= else_bb
->end
;
374 /* Skip a (use (const_int 0)) or branch as the final insn. */
375 if (GET_CODE (else_end
) == INSN
376 && GET_CODE (PATTERN (else_end
)) == USE
377 && GET_CODE (XEXP (PATTERN (else_end
), 0)) == CONST_INT
)
378 else_end
= PREV_INSN (else_end
);
379 else if (GET_CODE (else_end
) == JUMP_INSN
)
380 else_end
= PREV_INSN (else_end
);
383 /* How many instructions should we convert in total? */
387 max
= 2 * MAX_CONDITIONAL_EXECUTE
;
388 n_insns
= count_bb_insns (else_bb
);
391 max
= MAX_CONDITIONAL_EXECUTE
;
392 n_insns
+= count_bb_insns (then_bb
);
396 /* Map test_expr/test_jump into the appropriate MD tests to use on
397 the conditionally executed code. */
399 true_expr
= test_expr
;
401 false_code
= reversed_comparison_code (true_expr
, test_bb
->end
);
402 if (false_code
!= UNKNOWN
)
403 false_expr
= gen_rtx_fmt_ee (false_code
, GET_MODE (true_expr
),
404 XEXP (true_expr
, 0), XEXP (true_expr
, 1));
406 false_expr
= NULL_RTX
;
408 #ifdef IFCVT_MODIFY_TESTS
409 /* If the machine description needs to modify the tests, such as setting a
410 conditional execution register from a comparison, it can do so here. */
411 IFCVT_MODIFY_TESTS (true_expr
, false_expr
, test_bb
, then_bb
, else_bb
,
414 /* See if the conversion failed */
415 if (!true_expr
|| !false_expr
)
419 true_prob_val
= find_reg_note (test_bb
->end
, REG_BR_PROB
, NULL_RTX
);
422 true_prob_val
= XEXP (true_prob_val
, 0);
423 false_prob_val
= GEN_INT (REG_BR_PROB_BASE
- INTVAL (true_prob_val
));
426 false_prob_val
= NULL_RTX
;
428 /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
429 on then THEN block. */
430 then_mod_ok
= (else_bb
== NULL_BLOCK
);
432 /* Go through the THEN and ELSE blocks converting the insns if possible
433 to conditional execution. */
437 || ! cond_exec_process_insns (then_start
, then_end
, false_expr
,
438 false_prob_val
, then_mod_ok
)))
442 && ! cond_exec_process_insns (else_start
, else_end
,
443 true_expr
, true_prob_val
, TRUE
))
446 if (! apply_change_group ())
449 #ifdef IFCVT_MODIFY_FINAL
450 /* Do any machine dependent final modifications */
451 IFCVT_MODIFY_FINAL (test_bb
, then_bb
, else_bb
, join_bb
);
454 /* Conversion succeeded. */
456 fprintf (rtl_dump_file
, "%d insn%s converted to conditional execution.\n",
457 n_insns
, (n_insns
== 1) ? " was" : "s were");
459 /* Merge the blocks! */
460 merge_if_block (test_bb
, then_bb
, else_bb
, join_bb
);
464 #ifdef IFCVT_MODIFY_CANCEL
465 /* Cancel any machine dependent changes. */
466 IFCVT_MODIFY_CANCEL (test_bb
, then_bb
, else_bb
, join_bb
);
473 /* Used by noce_process_if_block to communicate with its subroutines.
475 The subroutines know that A and B may be evaluated freely. They
476 know that X is a register. They should insert new instructions
477 before cond_earliest. */
484 rtx jump
, cond
, cond_earliest
;
487 static rtx noce_emit_store_flag
PARAMS ((struct noce_if_info
*,
489 static int noce_try_store_flag
PARAMS ((struct noce_if_info
*));
490 static int noce_try_store_flag_inc
PARAMS ((struct noce_if_info
*));
491 static int noce_try_store_flag_constants
PARAMS ((struct noce_if_info
*));
492 static int noce_try_store_flag_mask
PARAMS ((struct noce_if_info
*));
493 static rtx noce_emit_cmove
PARAMS ((struct noce_if_info
*,
494 rtx
, enum rtx_code
, rtx
,
496 static int noce_try_cmove
PARAMS ((struct noce_if_info
*));
497 static int noce_try_cmove_arith
PARAMS ((struct noce_if_info
*));
498 static rtx noce_get_alt_condition
PARAMS ((struct noce_if_info
*,
500 static int noce_try_minmax
PARAMS ((struct noce_if_info
*));
501 static int noce_try_abs
PARAMS ((struct noce_if_info
*));
503 /* Helper function for noce_try_store_flag*. */
506 noce_emit_store_flag (if_info
, x
, reversep
, normalize
)
507 struct noce_if_info
*if_info
;
509 int reversep
, normalize
;
511 rtx cond
= if_info
->cond
;
515 cond_complex
= (! general_operand (XEXP (cond
, 0), VOIDmode
)
516 || ! general_operand (XEXP (cond
, 1), VOIDmode
));
518 /* If earliest == jump, or when the condition is complex, try to
519 build the store_flag insn directly. */
522 cond
= XEXP (SET_SRC (pc_set (if_info
->jump
)), 0);
525 code
= reversed_comparison_code (cond
, if_info
->jump
);
527 code
= GET_CODE (cond
);
529 if ((if_info
->cond_earliest
== if_info
->jump
|| cond_complex
)
530 && (normalize
== 0 || STORE_FLAG_VALUE
== normalize
))
534 tmp
= gen_rtx_fmt_ee (code
, GET_MODE (x
), XEXP (cond
, 0),
536 tmp
= gen_rtx_SET (VOIDmode
, x
, tmp
);
539 tmp
= emit_insn (tmp
);
541 if (recog_memoized (tmp
) >= 0)
547 if_info
->cond_earliest
= if_info
->jump
;
555 /* Don't even try if the comparison operands are weird. */
559 return emit_store_flag (x
, code
, XEXP (cond
, 0),
560 XEXP (cond
, 1), VOIDmode
,
561 (code
== LTU
|| code
== LEU
562 || code
== GEU
|| code
== GTU
), normalize
);
565 /* Emit instruction to move an rtx into STRICT_LOW_PART. */
567 noce_emit_move_insn (x
, y
)
570 enum machine_mode outmode
, inmode
;
574 if (GET_CODE (x
) != STRICT_LOW_PART
)
576 emit_move_insn (x
, y
);
581 inner
= XEXP (outer
, 0);
582 outmode
= GET_MODE (outer
);
583 inmode
= GET_MODE (inner
);
584 bitpos
= SUBREG_BYTE (outer
) * BITS_PER_UNIT
;
585 store_bit_field (inner
, GET_MODE_BITSIZE (outmode
), bitpos
, outmode
, y
,
586 GET_MODE_BITSIZE (inmode
));
589 /* Convert "if (test) x = 1; else x = 0".
591 Only try 0 and STORE_FLAG_VALUE here. Other combinations will be
592 tried in noce_try_store_flag_constants after noce_try_cmove has had
593 a go at the conversion. */
596 noce_try_store_flag (if_info
)
597 struct noce_if_info
*if_info
;
602 if (GET_CODE (if_info
->b
) == CONST_INT
603 && INTVAL (if_info
->b
) == STORE_FLAG_VALUE
604 && if_info
->a
== const0_rtx
)
606 else if (if_info
->b
== const0_rtx
607 && GET_CODE (if_info
->a
) == CONST_INT
608 && INTVAL (if_info
->a
) == STORE_FLAG_VALUE
609 && (reversed_comparison_code (if_info
->cond
, if_info
->jump
)
617 target
= noce_emit_store_flag (if_info
, if_info
->x
, reversep
, 0);
620 if (target
!= if_info
->x
)
621 noce_emit_move_insn (if_info
->x
, target
);
625 emit_insns_before (seq
, if_info
->jump
);
636 /* Convert "if (test) x = a; else x = b", for A and B constant. */
639 noce_try_store_flag_constants (if_info
)
640 struct noce_if_info
*if_info
;
644 HOST_WIDE_INT itrue
, ifalse
, diff
, tmp
;
645 int normalize
, can_reverse
;
646 enum machine_mode mode
;
649 && GET_CODE (if_info
->a
) == CONST_INT
650 && GET_CODE (if_info
->b
) == CONST_INT
)
652 mode
= GET_MODE (if_info
->x
);
653 ifalse
= INTVAL (if_info
->a
);
654 itrue
= INTVAL (if_info
->b
);
656 /* Make sure we can represent the difference between the two values. */
657 if ((itrue
- ifalse
> 0)
658 != ((ifalse
< 0) != (itrue
< 0) ? ifalse
< 0 : ifalse
< itrue
))
661 diff
= trunc_int_for_mode (itrue
- ifalse
, mode
);
663 can_reverse
= (reversed_comparison_code (if_info
->cond
, if_info
->jump
)
667 if (diff
== STORE_FLAG_VALUE
|| diff
== -STORE_FLAG_VALUE
)
669 else if (ifalse
== 0 && exact_log2 (itrue
) >= 0
670 && (STORE_FLAG_VALUE
== 1
671 || BRANCH_COST
>= 2))
673 else if (itrue
== 0 && exact_log2 (ifalse
) >= 0 && can_reverse
674 && (STORE_FLAG_VALUE
== 1 || BRANCH_COST
>= 2))
675 normalize
= 1, reversep
= 1;
677 && (STORE_FLAG_VALUE
== -1
678 || BRANCH_COST
>= 2))
680 else if (ifalse
== -1 && can_reverse
681 && (STORE_FLAG_VALUE
== -1 || BRANCH_COST
>= 2))
682 normalize
= -1, reversep
= 1;
683 else if ((BRANCH_COST
>= 2 && STORE_FLAG_VALUE
== -1)
691 tmp
= itrue
; itrue
= ifalse
; ifalse
= tmp
;
692 diff
= trunc_int_for_mode (-diff
, mode
);
696 target
= noce_emit_store_flag (if_info
, if_info
->x
, reversep
, normalize
);
703 /* if (test) x = 3; else x = 4;
704 => x = 3 + (test == 0); */
705 if (diff
== STORE_FLAG_VALUE
|| diff
== -STORE_FLAG_VALUE
)
707 target
= expand_simple_binop (mode
,
708 (diff
== STORE_FLAG_VALUE
710 GEN_INT (ifalse
), target
, if_info
->x
, 0,
714 /* if (test) x = 8; else x = 0;
715 => x = (test != 0) << 3; */
716 else if (ifalse
== 0 && (tmp
= exact_log2 (itrue
)) >= 0)
718 target
= expand_simple_binop (mode
, ASHIFT
,
719 target
, GEN_INT (tmp
), if_info
->x
, 0,
723 /* if (test) x = -1; else x = b;
724 => x = -(test != 0) | b; */
725 else if (itrue
== -1)
727 target
= expand_simple_binop (mode
, IOR
,
728 target
, GEN_INT (ifalse
), if_info
->x
, 0,
732 /* if (test) x = a; else x = b;
733 => x = (-(test != 0) & (b - a)) + a; */
736 target
= expand_simple_binop (mode
, AND
,
737 target
, GEN_INT (diff
), if_info
->x
, 0,
740 target
= expand_simple_binop (mode
, PLUS
,
741 target
, GEN_INT (ifalse
),
742 if_info
->x
, 0, OPTAB_WIDEN
);
751 if (target
!= if_info
->x
)
752 noce_emit_move_insn (if_info
->x
, target
);
757 if (seq_contains_jump (seq
))
760 emit_insns_before (seq
, if_info
->jump
);
768 /* Convert "if (test) foo++" into "foo += (test != 0)", and
769 similarly for "foo--". */
772 noce_try_store_flag_inc (if_info
)
773 struct noce_if_info
*if_info
;
776 int subtract
, normalize
;
782 /* Should be no `else' case to worry about. */
783 && if_info
->b
== if_info
->x
784 && GET_CODE (if_info
->a
) == PLUS
785 && (XEXP (if_info
->a
, 1) == const1_rtx
786 || XEXP (if_info
->a
, 1) == constm1_rtx
)
787 && rtx_equal_p (XEXP (if_info
->a
, 0), if_info
->x
)
788 && (reversed_comparison_code (if_info
->cond
, if_info
->jump
)
791 if (STORE_FLAG_VALUE
== INTVAL (XEXP (if_info
->a
, 1)))
792 subtract
= 0, normalize
= 0;
793 else if (-STORE_FLAG_VALUE
== INTVAL (XEXP (if_info
->a
, 1)))
794 subtract
= 1, normalize
= 0;
796 subtract
= 0, normalize
= INTVAL (XEXP (if_info
->a
, 1));
800 target
= noce_emit_store_flag (if_info
,
801 gen_reg_rtx (GET_MODE (if_info
->x
)),
805 target
= expand_simple_binop (GET_MODE (if_info
->x
),
806 subtract
? MINUS
: PLUS
,
807 if_info
->x
, target
, if_info
->x
,
811 if (target
!= if_info
->x
)
812 noce_emit_move_insn (if_info
->x
, target
);
817 if (seq_contains_jump (seq
))
820 emit_insns_before (seq
, if_info
->jump
);
831 /* Convert "if (test) x = 0;" to "x &= -(test == 0);" */
834 noce_try_store_flag_mask (if_info
)
835 struct noce_if_info
*if_info
;
843 || STORE_FLAG_VALUE
== -1)
844 && ((if_info
->a
== const0_rtx
845 && rtx_equal_p (if_info
->b
, if_info
->x
))
846 || ((reversep
= (reversed_comparison_code (if_info
->cond
,
849 && if_info
->b
== const0_rtx
850 && rtx_equal_p (if_info
->a
, if_info
->x
))))
853 target
= noce_emit_store_flag (if_info
,
854 gen_reg_rtx (GET_MODE (if_info
->x
)),
857 target
= expand_simple_binop (GET_MODE (if_info
->x
), AND
,
858 if_info
->x
, target
, if_info
->x
, 0,
863 if (target
!= if_info
->x
)
864 noce_emit_move_insn (if_info
->x
, target
);
869 if (seq_contains_jump (seq
))
872 emit_insns_before (seq
, if_info
->jump
);
883 /* Helper function for noce_try_cmove and noce_try_cmove_arith. */
886 noce_emit_cmove (if_info
, x
, code
, cmp_a
, cmp_b
, vfalse
, vtrue
)
887 struct noce_if_info
*if_info
;
888 rtx x
, cmp_a
, cmp_b
, vfalse
, vtrue
;
891 /* If earliest == jump, try to build the cmove insn directly.
892 This is helpful when combine has created some complex condition
893 (like for alpha's cmovlbs) that we can't hope to regenerate
894 through the normal interface. */
896 if (if_info
->cond_earliest
== if_info
->jump
)
900 tmp
= gen_rtx_fmt_ee (code
, GET_MODE (if_info
->cond
), cmp_a
, cmp_b
);
901 tmp
= gen_rtx_IF_THEN_ELSE (GET_MODE (x
), tmp
, vtrue
, vfalse
);
902 tmp
= gen_rtx_SET (VOIDmode
, x
, tmp
);
905 tmp
= emit_insn (tmp
);
907 if (recog_memoized (tmp
) >= 0)
919 /* Don't even try if the comparison operands are weird. */
920 if (! general_operand (cmp_a
, GET_MODE (cmp_a
))
921 || ! general_operand (cmp_b
, GET_MODE (cmp_b
)))
924 #if HAVE_conditional_move
925 return emit_conditional_move (x
, code
, cmp_a
, cmp_b
, VOIDmode
,
926 vtrue
, vfalse
, GET_MODE (x
),
927 (code
== LTU
|| code
== GEU
928 || code
== LEU
|| code
== GTU
));
930 /* We'll never get here, as noce_process_if_block doesn't call the
931 functions involved. Ifdef code, however, should be discouraged
932 because it leads to typos in the code not selected. However,
933 emit_conditional_move won't exist either. */
938 /* Try only simple constants and registers here. More complex cases
939 are handled in noce_try_cmove_arith after noce_try_store_flag_arith
940 has had a go at it. */
943 noce_try_cmove (if_info
)
944 struct noce_if_info
*if_info
;
949 if ((CONSTANT_P (if_info
->a
) || register_operand (if_info
->a
, VOIDmode
))
950 && (CONSTANT_P (if_info
->b
) || register_operand (if_info
->b
, VOIDmode
)))
954 code
= GET_CODE (if_info
->cond
);
955 target
= noce_emit_cmove (if_info
, if_info
->x
, code
,
956 XEXP (if_info
->cond
, 0),
957 XEXP (if_info
->cond
, 1),
958 if_info
->a
, if_info
->b
);
962 if (target
!= if_info
->x
)
963 noce_emit_move_insn (if_info
->x
, target
);
967 emit_insns_before (seq
, if_info
->jump
);
980 /* Try more complex cases involving conditional_move. */
983 noce_try_cmove_arith (if_info
)
984 struct noce_if_info
*if_info
;
994 /* A conditional move from two memory sources is equivalent to a
995 conditional on their addresses followed by a load. Don't do this
996 early because it'll screw alias analysis. Note that we've
997 already checked for no side effects. */
998 if (! no_new_pseudos
&& cse_not_expected
999 && GET_CODE (a
) == MEM
&& GET_CODE (b
) == MEM
1000 && BRANCH_COST
>= 5)
1004 x
= gen_reg_rtx (Pmode
);
1008 /* ??? We could handle this if we knew that a load from A or B could
1009 not fault. This is also true if we've already loaded
1010 from the address along the path from ENTRY. */
1011 else if (may_trap_p (a
) || may_trap_p (b
))
1014 /* if (test) x = a + b; else x = c - d;
1021 code
= GET_CODE (if_info
->cond
);
1022 insn_a
= if_info
->insn_a
;
1023 insn_b
= if_info
->insn_b
;
1025 /* Possibly rearrange operands to make things come out more natural. */
1026 if (reversed_comparison_code (if_info
->cond
, if_info
->jump
) != UNKNOWN
)
1029 if (rtx_equal_p (b
, x
))
1031 else if (general_operand (b
, GET_MODE (b
)))
1036 code
= reversed_comparison_code (if_info
->cond
, if_info
->jump
);
1037 tmp
= a
, a
= b
, b
= tmp
;
1038 tmp
= insn_a
, insn_a
= insn_b
, insn_b
= tmp
;
1044 /* If either operand is complex, load it into a register first.
1045 The best way to do this is to copy the original insn. In this
1046 way we preserve any clobbers etc that the insn may have had.
1047 This is of course not possible in the IS_MEM case. */
1048 if (! general_operand (a
, GET_MODE (a
)))
1053 goto end_seq_and_fail
;
1057 tmp
= gen_reg_rtx (GET_MODE (a
));
1058 tmp
= emit_insn (gen_rtx_SET (VOIDmode
, tmp
, a
));
1061 goto end_seq_and_fail
;
1064 a
= gen_reg_rtx (GET_MODE (a
));
1065 tmp
= copy_rtx (insn_a
);
1066 set
= single_set (tmp
);
1068 tmp
= emit_insn (PATTERN (tmp
));
1070 if (recog_memoized (tmp
) < 0)
1071 goto end_seq_and_fail
;
1073 if (! general_operand (b
, GET_MODE (b
)))
1078 goto end_seq_and_fail
;
1082 tmp
= gen_reg_rtx (GET_MODE (b
));
1083 tmp
= emit_insn (gen_rtx_SET (VOIDmode
, tmp
, b
));
1086 goto end_seq_and_fail
;
1089 b
= gen_reg_rtx (GET_MODE (b
));
1090 tmp
= copy_rtx (insn_b
);
1091 set
= single_set (tmp
);
1093 tmp
= emit_insn (PATTERN (tmp
));
1095 if (recog_memoized (tmp
) < 0)
1096 goto end_seq_and_fail
;
1099 target
= noce_emit_cmove (if_info
, x
, code
, XEXP (if_info
->cond
, 0),
1100 XEXP (if_info
->cond
, 1), a
, b
);
1103 goto end_seq_and_fail
;
1105 /* If we're handling a memory for above, emit the load now. */
1108 tmp
= gen_rtx_MEM (GET_MODE (if_info
->x
), target
);
1110 /* Copy over flags as appropriate. */
1111 if (MEM_VOLATILE_P (if_info
->a
) || MEM_VOLATILE_P (if_info
->b
))
1112 MEM_VOLATILE_P (tmp
) = 1;
1113 if (MEM_IN_STRUCT_P (if_info
->a
) && MEM_IN_STRUCT_P (if_info
->b
))
1114 MEM_IN_STRUCT_P (tmp
) = 1;
1115 if (MEM_SCALAR_P (if_info
->a
) && MEM_SCALAR_P (if_info
->b
))
1116 MEM_SCALAR_P (tmp
) = 1;
1117 if (MEM_ALIAS_SET (if_info
->a
) == MEM_ALIAS_SET (if_info
->b
))
1118 set_mem_alias_set (tmp
, MEM_ALIAS_SET (if_info
->a
));
1120 MIN (MEM_ALIGN (if_info
->a
), MEM_ALIGN (if_info
->b
)));
1122 noce_emit_move_insn (if_info
->x
, tmp
);
1124 else if (target
!= x
)
1125 noce_emit_move_insn (x
, target
);
1129 emit_insns_before (tmp
, if_info
->jump
);
1137 /* For most cases, the simplified condition we found is the best
1138 choice, but this is not the case for the min/max/abs transforms.
1139 For these we wish to know that it is A or B in the condition. */
1142 noce_get_alt_condition (if_info
, target
, earliest
)
1143 struct noce_if_info
*if_info
;
1147 rtx cond
, set
, insn
;
1150 /* If target is already mentioned in the known condition, return it. */
1151 if (reg_mentioned_p (target
, if_info
->cond
))
1153 *earliest
= if_info
->cond_earliest
;
1154 return if_info
->cond
;
1157 set
= pc_set (if_info
->jump
);
1158 cond
= XEXP (SET_SRC (set
), 0);
1160 = GET_CODE (XEXP (SET_SRC (set
), 2)) == LABEL_REF
1161 && XEXP (XEXP (SET_SRC (set
), 2), 0) == JUMP_LABEL (if_info
->jump
);
1163 /* If we're looking for a constant, try to make the conditional
1164 have that constant in it. There are two reasons why it may
1165 not have the constant we want:
1167 1. GCC may have needed to put the constant in a register, because
1168 the target can't compare directly against that constant. For
1169 this case, we look for a SET immediately before the comparison
1170 that puts a constant in that register.
1172 2. GCC may have canonicalized the conditional, for example
1173 replacing "if x < 4" with "if x <= 3". We can undo that (or
1174 make equivalent types of changes) to get the constants we need
1175 if they're off by one in the right direction. */
1177 if (GET_CODE (target
) == CONST_INT
)
1179 enum rtx_code code
= GET_CODE (if_info
->cond
);
1180 rtx op_a
= XEXP (if_info
->cond
, 0);
1181 rtx op_b
= XEXP (if_info
->cond
, 1);
1184 /* First, look to see if we put a constant in a register. */
1185 prev_insn
= PREV_INSN (if_info
->cond_earliest
);
1187 && INSN_P (prev_insn
)
1188 && GET_CODE (PATTERN (prev_insn
)) == SET
)
1190 rtx src
= find_reg_equal_equiv_note (prev_insn
);
1192 src
= SET_SRC (PATTERN (prev_insn
));
1193 if (GET_CODE (src
) == CONST_INT
)
1195 if (rtx_equal_p (op_a
, SET_DEST (PATTERN (prev_insn
))))
1197 else if (rtx_equal_p (op_b
, SET_DEST (PATTERN (prev_insn
))))
1200 if (GET_CODE (op_a
) == CONST_INT
)
1205 code
= swap_condition (code
);
1210 /* Now, look to see if we can get the right constant by
1211 adjusting the conditional. */
1212 if (GET_CODE (op_b
) == CONST_INT
)
1214 HOST_WIDE_INT desired_val
= INTVAL (target
);
1215 HOST_WIDE_INT actual_val
= INTVAL (op_b
);
1220 if (actual_val
== desired_val
+ 1)
1223 op_b
= GEN_INT (desired_val
);
1227 if (actual_val
== desired_val
- 1)
1230 op_b
= GEN_INT (desired_val
);
1234 if (actual_val
== desired_val
- 1)
1237 op_b
= GEN_INT (desired_val
);
1241 if (actual_val
== desired_val
+ 1)
1244 op_b
= GEN_INT (desired_val
);
1252 /* If we made any changes, generate a new conditional that is
1253 equivalent to what we started with, but has the right
1255 if (code
!= GET_CODE (if_info
->cond
)
1256 || op_a
!= XEXP (if_info
->cond
, 0)
1257 || op_b
!= XEXP (if_info
->cond
, 1))
1259 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
), op_a
, op_b
);
1260 *earliest
= if_info
->cond_earliest
;
1265 cond
= canonicalize_condition (if_info
->jump
, cond
, reverse
,
1267 if (! cond
|| ! reg_mentioned_p (target
, cond
))
1270 /* We almost certainly searched back to a different place.
1271 Need to re-verify correct lifetimes. */
1273 /* X may not be mentioned in the range (cond_earliest, jump]. */
1274 for (insn
= if_info
->jump
; insn
!= *earliest
; insn
= PREV_INSN (insn
))
1275 if (INSN_P (insn
) && reg_mentioned_p (if_info
->x
, insn
))
1278 /* A and B may not be modified in the range [cond_earliest, jump). */
1279 for (insn
= *earliest
; insn
!= if_info
->jump
; insn
= NEXT_INSN (insn
))
1281 && (modified_in_p (if_info
->a
, insn
)
1282 || modified_in_p (if_info
->b
, insn
)))
1288 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc. */
1291 noce_try_minmax (if_info
)
1292 struct noce_if_info
*if_info
;
1294 rtx cond
, earliest
, target
, seq
;
1295 enum rtx_code code
, op
;
1298 /* ??? Can't guarantee that expand_binop won't create pseudos. */
1302 /* ??? Reject FP modes since we don't know how 0 vs -0 or NaNs
1303 will be resolved with an SMIN/SMAX. It wouldn't be too hard
1304 to get the target to tell us... */
1305 if (FLOAT_MODE_P (GET_MODE (if_info
->x
))
1306 && TARGET_FLOAT_FORMAT
== IEEE_FLOAT_FORMAT
1307 && ! flag_unsafe_math_optimizations
)
1310 cond
= noce_get_alt_condition (if_info
, if_info
->a
, &earliest
);
1314 /* Verify the condition is of the form we expect, and canonicalize
1315 the comparison code. */
1316 code
= GET_CODE (cond
);
1317 if (rtx_equal_p (XEXP (cond
, 0), if_info
->a
))
1319 if (! rtx_equal_p (XEXP (cond
, 1), if_info
->b
))
1322 else if (rtx_equal_p (XEXP (cond
, 1), if_info
->a
))
1324 if (! rtx_equal_p (XEXP (cond
, 0), if_info
->b
))
1326 code
= swap_condition (code
);
1331 /* Determine what sort of operation this is. Note that the code is for
1332 a taken branch, so the code->operation mapping appears backwards. */
1365 target
= expand_simple_binop (GET_MODE (if_info
->x
), op
,
1366 if_info
->a
, if_info
->b
,
1367 if_info
->x
, unsignedp
, OPTAB_WIDEN
);
1373 if (target
!= if_info
->x
)
1374 noce_emit_move_insn (if_info
->x
, target
);
1379 if (seq_contains_jump (seq
))
1382 emit_insns_before (seq
, if_info
->jump
);
1383 if_info
->cond
= cond
;
1384 if_info
->cond_earliest
= earliest
;
1389 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc. */
1392 noce_try_abs (if_info
)
1393 struct noce_if_info
*if_info
;
1395 rtx cond
, earliest
, target
, seq
, a
, b
, c
;
1398 /* ??? Can't guarantee that expand_binop won't create pseudos. */
1402 /* Recognize A and B as constituting an ABS or NABS. */
1405 if (GET_CODE (a
) == NEG
&& rtx_equal_p (XEXP (a
, 0), b
))
1407 else if (GET_CODE (b
) == NEG
&& rtx_equal_p (XEXP (b
, 0), a
))
1409 c
= a
; a
= b
; b
= c
;
1415 cond
= noce_get_alt_condition (if_info
, b
, &earliest
);
1419 /* Verify the condition is of the form we expect. */
1420 if (rtx_equal_p (XEXP (cond
, 0), b
))
1422 else if (rtx_equal_p (XEXP (cond
, 1), b
))
1427 /* Verify that C is zero. Search backward through the block for
1428 a REG_EQUAL note if necessary. */
1431 rtx insn
, note
= NULL
;
1432 for (insn
= earliest
;
1433 insn
!= if_info
->test_bb
->head
;
1434 insn
= PREV_INSN (insn
))
1436 && ((note
= find_reg_note (insn
, REG_EQUAL
, c
))
1437 || (note
= find_reg_note (insn
, REG_EQUIV
, c
))))
1443 if (GET_CODE (c
) == MEM
1444 && GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
1445 && CONSTANT_POOL_ADDRESS_P (XEXP (c
, 0)))
1446 c
= get_pool_constant (XEXP (c
, 0));
1448 /* Work around funny ideas get_condition has wrt canonicalization.
1449 Note that these rtx constants are known to be CONST_INT, and
1450 therefore imply integer comparisons. */
1451 if (c
== constm1_rtx
&& GET_CODE (cond
) == GT
)
1453 else if (c
== const1_rtx
&& GET_CODE (cond
) == LT
)
1455 else if (c
!= CONST0_RTX (GET_MODE (b
)))
1458 /* Determine what sort of operation this is. */
1459 switch (GET_CODE (cond
))
1478 target
= expand_simple_unop (GET_MODE (if_info
->x
), ABS
, b
, if_info
->x
, 0);
1480 /* ??? It's a quandry whether cmove would be better here, especially
1481 for integers. Perhaps combine will clean things up. */
1482 if (target
&& negate
)
1483 target
= expand_simple_unop (GET_MODE (target
), NEG
, target
, if_info
->x
, 0);
1491 if (target
!= if_info
->x
)
1492 noce_emit_move_insn (if_info
->x
, target
);
1497 if (seq_contains_jump (seq
))
1500 emit_insns_before (seq
, if_info
->jump
);
1501 if_info
->cond
= cond
;
1502 if_info
->cond_earliest
= earliest
;
1507 /* Similar to get_condition, only the resulting condition must be
1508 valid at JUMP, instead of at EARLIEST. */
1511 noce_get_condition (jump
, earliest
)
1515 rtx cond
, set
, tmp
, insn
;
1518 if (! any_condjump_p (jump
))
1521 set
= pc_set (jump
);
1523 /* If this branches to JUMP_LABEL when the condition is false,
1524 reverse the condition. */
1525 reverse
= (GET_CODE (XEXP (SET_SRC (set
), 2)) == LABEL_REF
1526 && XEXP (XEXP (SET_SRC (set
), 2), 0) == JUMP_LABEL (jump
));
1528 /* If the condition variable is a register and is MODE_INT, accept it. */
1530 cond
= XEXP (SET_SRC (set
), 0);
1531 tmp
= XEXP (cond
, 0);
1532 if (REG_P (tmp
) && GET_MODE_CLASS (GET_MODE (tmp
)) == MODE_INT
)
1537 cond
= gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond
)),
1538 GET_MODE (cond
), tmp
, XEXP (cond
, 1));
1542 /* Otherwise, fall back on canonicalize_condition to do the dirty
1543 work of manipulating MODE_CC values and COMPARE rtx codes. */
1545 tmp
= canonicalize_condition (jump
, cond
, reverse
, earliest
, NULL_RTX
);
1549 /* We are going to insert code before JUMP, not before EARLIEST.
1550 We must therefore be certain that the given condition is valid
1551 at JUMP by virtue of not having been modified since. */
1552 for (insn
= *earliest
; insn
!= jump
; insn
= NEXT_INSN (insn
))
1553 if (INSN_P (insn
) && modified_in_p (tmp
, insn
))
1558 /* The condition was modified. See if we can get a partial result
1559 that doesn't follow all the reversals. Perhaps combine can fold
1560 them together later. */
1561 tmp
= XEXP (tmp
, 0);
1562 if (!REG_P (tmp
) || GET_MODE_CLASS (GET_MODE (tmp
)) != MODE_INT
)
1564 tmp
= canonicalize_condition (jump
, cond
, reverse
, earliest
, tmp
);
1568 /* For sanity's sake, re-validate the new result. */
1569 for (insn
= *earliest
; insn
!= jump
; insn
= NEXT_INSN (insn
))
1570 if (INSN_P (insn
) && modified_in_p (tmp
, insn
))
1576 /* Return true if OP is ok for if-then-else processing. */
1579 noce_operand_ok (op
)
1582 /* We special-case memories, so handle any of them with
1583 no address side effects. */
1584 if (GET_CODE (op
) == MEM
)
1585 return ! side_effects_p (XEXP (op
, 0));
1587 if (side_effects_p (op
))
1590 /* ??? Unfortuantely may_trap_p can't look at flag_trapping_math, due to
1591 being linked into the genfoo programs. This is probably a mistake.
1592 With finite operands, most fp operations don't trap. */
1593 if (!flag_trapping_math
&& FLOAT_MODE_P (GET_MODE (op
)))
1594 switch (GET_CODE (op
))
1600 /* ??? This is kinda lame -- almost every target will have forced
1601 the constant into a register first. But given the expense of
1602 division, this is probably for the best. */
1603 return (CONSTANT_P (XEXP (op
, 1))
1604 && XEXP (op
, 1) != CONST0_RTX (GET_MODE (op
))
1605 && ! may_trap_p (XEXP (op
, 0)));
1608 switch (GET_RTX_CLASS (GET_CODE (op
)))
1611 return ! may_trap_p (XEXP (op
, 0));
1614 return ! may_trap_p (XEXP (op
, 0)) && ! may_trap_p (XEXP (op
, 1));
1619 return ! may_trap_p (op
);
1622 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
1623 without using conditional execution. Return TRUE if we were
1624 successful at converting the the block. */
1627 noce_process_if_block (test_bb
, then_bb
, else_bb
, join_bb
)
1628 basic_block test_bb
; /* Basic block test is in */
1629 basic_block then_bb
; /* Basic block for THEN block */
1630 basic_block else_bb
; /* Basic block for ELSE block */
1631 basic_block join_bb
; /* Basic block the join label is in */
1633 /* We're looking for patterns of the form
1635 (1) if (...) x = a; else x = b;
1636 (2) x = b; if (...) x = a;
1637 (3) if (...) x = a; // as if with an initial x = x.
1639 The later patterns require jumps to be more expensive.
1641 ??? For future expansion, look for multiple X in such patterns. */
1643 struct noce_if_info if_info
;
1646 rtx orig_x
, x
, a
, b
;
1647 rtx jump
, cond
, insn
;
1649 /* If this is not a standard conditional jump, we can't parse it. */
1650 jump
= test_bb
->end
;
1651 cond
= noce_get_condition (jump
, &if_info
.cond_earliest
);
1655 /* If the conditional jump is more than just a conditional jump,
1656 then we can not do if-conversion on this block. */
1657 if (! onlyjump_p (jump
))
1660 /* We must be comparing objects whose modes imply the size. */
1661 if (GET_MODE (XEXP (cond
, 0)) == BLKmode
)
1664 /* Look for one of the potential sets. */
1665 insn_a
= first_active_insn (then_bb
);
1667 || ! last_active_insn_p (then_bb
, insn_a
)
1668 || (set_a
= single_set (insn_a
)) == NULL_RTX
)
1671 x
= SET_DEST (set_a
);
1672 a
= SET_SRC (set_a
);
1674 /* Look for the other potential set. Make sure we've got equivalent
1676 /* ??? This is overconservative. Storing to two different mems is
1677 as easy as conditionally computing the address. Storing to a
1678 single mem merely requires a scratch memory to use as one of the
1679 destination addresses; often the memory immediately below the
1680 stack pointer is available for this. */
1684 insn_b
= first_active_insn (else_bb
);
1686 || ! last_active_insn_p (else_bb
, insn_b
)
1687 || (set_b
= single_set (insn_b
)) == NULL_RTX
1688 || ! rtx_equal_p (x
, SET_DEST (set_b
)))
1693 insn_b
= prev_nonnote_insn (if_info
.cond_earliest
);
1695 || GET_CODE (insn_b
) != INSN
1696 || (set_b
= single_set (insn_b
)) == NULL_RTX
1697 || ! rtx_equal_p (x
, SET_DEST (set_b
))
1698 || reg_mentioned_p (x
, cond
)
1699 || reg_mentioned_p (x
, a
)
1700 || reg_mentioned_p (x
, SET_SRC (set_b
)))
1701 insn_b
= set_b
= NULL_RTX
;
1703 b
= (set_b
? SET_SRC (set_b
) : x
);
1705 /* X may not be mentioned in the range (cond_earliest, jump]. */
1706 for (insn
= jump
; insn
!= if_info
.cond_earliest
; insn
= PREV_INSN (insn
))
1707 if (INSN_P (insn
) && reg_mentioned_p (x
, insn
))
1710 /* A and B may not be modified in the range [cond_earliest, jump). */
1711 for (insn
= if_info
.cond_earliest
; insn
!= jump
; insn
= NEXT_INSN (insn
))
1713 && (modified_in_p (a
, insn
) || modified_in_p (b
, insn
)))
1716 /* Only operate on register destinations, and even then avoid extending
1717 the lifetime of hard registers on small register class machines. */
1719 if (GET_CODE (x
) != REG
1720 || (SMALL_REGISTER_CLASSES
1721 && REGNO (x
) < FIRST_PSEUDO_REGISTER
))
1725 x
= gen_reg_rtx (GET_MODE (GET_CODE (x
) == STRICT_LOW_PART
1726 ? XEXP (x
, 0) : x
));
1729 /* Don't operate on sources that may trap or are volatile. */
1730 if (! noce_operand_ok (a
) || ! noce_operand_ok (b
))
1733 /* Set up the info block for our subroutines. */
1734 if_info
.test_bb
= test_bb
;
1735 if_info
.cond
= cond
;
1736 if_info
.jump
= jump
;
1737 if_info
.insn_a
= insn_a
;
1738 if_info
.insn_b
= insn_b
;
1743 /* Try optimizations in some approximation of a useful order. */
1744 /* ??? Should first look to see if X is live incoming at all. If it
1745 isn't, we don't need anything but an unconditional set. */
1747 /* Look and see if A and B are really the same. Avoid creating silly
1748 cmove constructs that no one will fix up later. */
1749 if (rtx_equal_p (a
, b
))
1751 /* If we have an INSN_B, we don't have to create any new rtl. Just
1752 move the instruction that we already have. If we don't have an
1753 INSN_B, that means that A == X, and we've got a noop move. In
1754 that case don't do anything and let the code below delete INSN_A. */
1755 if (insn_b
&& else_bb
)
1759 if (else_bb
&& insn_b
== else_bb
->end
)
1760 else_bb
->end
= PREV_INSN (insn_b
);
1761 reorder_insns (insn_b
, insn_b
, PREV_INSN (if_info
.cond_earliest
));
1763 /* If there was a REG_EQUAL note, delete it since it may have been
1764 true due to this insn being after a jump. */
1765 if ((note
= find_reg_note (insn_b
, REG_EQUAL
, NULL_RTX
)) != 0)
1766 remove_note (insn_b
, note
);
1770 /* If we have "x = b; if (...) x = a;", and x has side-effects, then
1771 x must be executed twice. */
1772 else if (insn_b
&& side_effects_p (orig_x
))
1779 if (noce_try_store_flag (&if_info
))
1781 if (noce_try_minmax (&if_info
))
1783 if (noce_try_abs (&if_info
))
1785 if (HAVE_conditional_move
1786 && noce_try_cmove (&if_info
))
1788 if (! HAVE_conditional_execution
)
1790 if (noce_try_store_flag_constants (&if_info
))
1792 if (noce_try_store_flag_inc (&if_info
))
1794 if (noce_try_store_flag_mask (&if_info
))
1796 if (HAVE_conditional_move
1797 && noce_try_cmove_arith (&if_info
))
1804 /* The original sets may now be killed. */
1805 delete_insn (insn_a
);
1807 /* Several special cases here: First, we may have reused insn_b above,
1808 in which case insn_b is now NULL. Second, we want to delete insn_b
1809 if it came from the ELSE block, because follows the now correct
1810 write that appears in the TEST block. However, if we got insn_b from
1811 the TEST block, it may in fact be loading data needed for the comparison.
1812 We'll let life_analysis remove the insn if it's really dead. */
1813 if (insn_b
&& else_bb
)
1814 delete_insn (insn_b
);
1816 /* The new insns will have been inserted just before the jump. We should
1817 be able to remove the jump with impunity, but the condition itself may
1818 have been modified by gcse to be shared across basic blocks. */
1821 /* If we used a temporary, fix it up now. */
1825 noce_emit_move_insn (copy_rtx (orig_x
), x
);
1826 insn_b
= gen_sequence ();
1829 emit_insn_after (insn_b
, test_bb
->end
);
1832 /* Merge the blocks! */
1833 merge_if_block (test_bb
, then_bb
, else_bb
, join_bb
);
1838 /* Attempt to convert an IF-THEN or IF-THEN-ELSE block into
1839 straight line code. Return true if successful. */
1842 process_if_block (test_bb
, then_bb
, else_bb
, join_bb
)
1843 basic_block test_bb
; /* Basic block test is in */
1844 basic_block then_bb
; /* Basic block for THEN block */
1845 basic_block else_bb
; /* Basic block for ELSE block */
1846 basic_block join_bb
; /* Basic block the join label is in */
1848 if (! reload_completed
1849 && noce_process_if_block (test_bb
, then_bb
, else_bb
, join_bb
))
1852 if (HAVE_conditional_execution
1854 && cond_exec_process_if_block (test_bb
, then_bb
, else_bb
, join_bb
))
1860 /* Merge the blocks and mark for local life update. */
1863 merge_if_block (test_bb
, then_bb
, else_bb
, join_bb
)
1864 basic_block test_bb
; /* Basic block test is in */
1865 basic_block then_bb
; /* Basic block for THEN block */
1866 basic_block else_bb
; /* Basic block for ELSE block */
1867 basic_block join_bb
; /* Basic block the join label is in */
1869 basic_block combo_bb
;
1871 /* All block merging is done into the lower block numbers. */
1875 /* First merge TEST block into THEN block. This is a no-brainer since
1876 the THEN block did not have a code label to begin with. */
1880 COPY_REG_SET (combo_bb
->global_live_at_end
,
1881 then_bb
->global_live_at_end
);
1882 merge_blocks_nomove (combo_bb
, then_bb
);
1883 num_removed_blocks
++;
1886 /* The ELSE block, if it existed, had a label. That label count
1887 will almost always be zero, but odd things can happen when labels
1888 get their addresses taken. */
1891 merge_blocks_nomove (combo_bb
, else_bb
);
1892 num_removed_blocks
++;
1895 /* If there was no join block reported, that means it was not adjacent
1896 to the others, and so we cannot merge them. */
1900 rtx last
= combo_bb
->end
;
1902 /* The outgoing edge for the current COMBO block should already
1903 be correct. Verify this. */
1904 if (combo_bb
->succ
== NULL_EDGE
)
1906 if (find_reg_note (last
, REG_NORETURN
, NULL
))
1908 else if (GET_CODE (last
) == INSN
1909 && GET_CODE (PATTERN (last
)) == TRAP_IF
1910 && TRAP_CONDITION (PATTERN (last
)) == const_true_rtx
)
1916 /* There should still be something at the end of the THEN or ELSE
1917 blocks taking us to our final destination. */
1918 else if (GET_CODE (last
) == JUMP_INSN
)
1920 else if (combo_bb
->succ
->dest
== EXIT_BLOCK_PTR
1921 && GET_CODE (last
) == CALL_INSN
1922 && SIBLING_CALL_P (last
))
1924 else if ((combo_bb
->succ
->flags
& EDGE_EH
)
1925 && can_throw_internal (last
))
1931 /* The JOIN block may have had quite a number of other predecessors too.
1932 Since we've already merged the TEST, THEN and ELSE blocks, we should
1933 have only one remaining edge from our if-then-else diamond. If there
1934 is more than one remaining edge, it must come from elsewhere. There
1935 may be zero incoming edges if the THEN block didn't actually join
1936 back up (as with a call to abort). */
1937 else if ((join_bb
->pred
== NULL
1938 || join_bb
->pred
->pred_next
== NULL
)
1939 && join_bb
!= EXIT_BLOCK_PTR
)
1941 /* We can merge the JOIN. */
1943 COPY_REG_SET (combo_bb
->global_live_at_end
,
1944 join_bb
->global_live_at_end
);
1945 merge_blocks_nomove (combo_bb
, join_bb
);
1946 num_removed_blocks
++;
1950 /* We cannot merge the JOIN. */
1952 /* The outgoing edge for the current COMBO block should already
1953 be correct. Verify this. */
1954 if (combo_bb
->succ
->succ_next
!= NULL_EDGE
1955 || combo_bb
->succ
->dest
!= join_bb
)
1958 /* Remove the jump and cruft from the end of the COMBO block. */
1959 if (join_bb
!= EXIT_BLOCK_PTR
)
1960 tidy_fallthru_edge (combo_bb
->succ
, combo_bb
, join_bb
);
1963 /* Make sure we update life info properly. */
1964 SET_UPDATE_LIFE (combo_bb
);
1966 num_updated_if_blocks
++;
1969 /* Find a block ending in a simple IF condition. Return TRUE if
1970 we were able to transform it in some way. */
1973 find_if_header (test_bb
)
1974 basic_block test_bb
;
1979 /* The kind of block we're looking for has exactly two successors. */
1980 if ((then_edge
= test_bb
->succ
) == NULL_EDGE
1981 || (else_edge
= then_edge
->succ_next
) == NULL_EDGE
1982 || else_edge
->succ_next
!= NULL_EDGE
)
1985 /* Neither edge should be abnormal. */
1986 if ((then_edge
->flags
& EDGE_COMPLEX
)
1987 || (else_edge
->flags
& EDGE_COMPLEX
))
1990 /* The THEN edge is canonically the one that falls through. */
1991 if (then_edge
->flags
& EDGE_FALLTHRU
)
1993 else if (else_edge
->flags
& EDGE_FALLTHRU
)
1996 else_edge
= then_edge
;
2000 /* Otherwise this must be a multiway branch of some sort. */
2003 if (find_if_block (test_bb
, then_edge
, else_edge
))
2005 if (HAVE_trap
&& HAVE_conditional_trap
2006 && find_cond_trap (test_bb
, then_edge
, else_edge
))
2009 && (! HAVE_conditional_execution
|| reload_completed
))
2011 if (find_if_case_1 (test_bb
, then_edge
, else_edge
))
2013 if (find_if_case_2 (test_bb
, then_edge
, else_edge
))
2021 fprintf (rtl_dump_file
, "Conversion succeeded.\n");
2025 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
2026 block. If so, we'll try to convert the insns to not require the branch.
2027 Return TRUE if we were successful at converting the the block. */
2030 find_if_block (test_bb
, then_edge
, else_edge
)
2031 basic_block test_bb
;
2032 edge then_edge
, else_edge
;
2034 basic_block then_bb
= then_edge
->dest
;
2035 basic_block else_bb
= else_edge
->dest
;
2036 basic_block join_bb
= NULL_BLOCK
;
2037 edge then_succ
= then_bb
->succ
;
2038 edge else_succ
= else_bb
->succ
;
2041 /* The THEN block of an IF-THEN combo must have exactly one predecessor. */
2042 if (then_bb
->pred
->pred_next
!= NULL_EDGE
)
2045 /* The THEN block of an IF-THEN combo must have zero or one successors. */
2046 if (then_succ
!= NULL_EDGE
2047 && (then_succ
->succ_next
!= NULL_EDGE
2048 || (then_succ
->flags
& EDGE_COMPLEX
)))
2051 /* If the THEN block has no successors, conditional execution can still
2052 make a conditional call. Don't do this unless the ELSE block has
2053 only one incoming edge -- the CFG manipulation is too ugly otherwise.
2054 Check for the last insn of the THEN block being an indirect jump, which
2055 is listed as not having any successors, but confuses the rest of the CE
2056 code processing. XXX we should fix this in the future. */
2057 if (then_succ
== NULL
)
2059 if (else_bb
->pred
->pred_next
== NULL_EDGE
)
2061 rtx last_insn
= then_bb
->end
;
2064 && GET_CODE (last_insn
) == NOTE
2065 && last_insn
!= then_bb
->head
)
2066 last_insn
= PREV_INSN (last_insn
);
2069 && GET_CODE (last_insn
) == JUMP_INSN
2070 && ! simplejump_p (last_insn
))
2074 else_bb
= NULL_BLOCK
;
2080 /* If the THEN block's successor is the other edge out of the TEST block,
2081 then we have an IF-THEN combo without an ELSE. */
2082 else if (then_succ
->dest
== else_bb
)
2085 else_bb
= NULL_BLOCK
;
2088 /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
2089 has exactly one predecessor and one successor, and the outgoing edge
2090 is not complex, then we have an IF-THEN-ELSE combo. */
2091 else if (else_succ
!= NULL_EDGE
2092 && then_succ
->dest
== else_succ
->dest
2093 && else_bb
->pred
->pred_next
== NULL_EDGE
2094 && else_succ
->succ_next
== NULL_EDGE
2095 && ! (else_succ
->flags
& EDGE_COMPLEX
))
2096 join_bb
= else_succ
->dest
;
2098 /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */
2102 num_possible_if_blocks
++;
2107 fprintf (rtl_dump_file
,
2108 "\nIF-THEN-ELSE block found, start %d, then %d, else %d, join %d\n",
2109 test_bb
->index
, then_bb
->index
, else_bb
->index
,
2112 fprintf (rtl_dump_file
,
2113 "\nIF-THEN block found, start %d, then %d, join %d\n",
2114 test_bb
->index
, then_bb
->index
, join_bb
->index
);
2117 /* Make sure IF, THEN, and ELSE, blocks are adjacent. Actually, we
2118 get the first condition for free, since we've already asserted that
2119 there's a fallthru edge from IF to THEN. */
2120 /* ??? As an enhancement, move the ELSE block. Have to deal with
2121 BLOCK notes, if by no other means than aborting the merge if they
2122 exist. Sticky enough I don't want to think about it now. */
2123 next_index
= then_bb
->index
;
2124 if (else_bb
&& ++next_index
!= else_bb
->index
)
2126 if (++next_index
!= join_bb
->index
&& join_bb
->index
!= EXIT_BLOCK
)
2134 /* Do the real work. */
2135 return process_if_block (test_bb
, then_bb
, else_bb
, join_bb
);
2138 /* Convert a branch over a trap, or a branch to a trap,
2139 into a conditional trap. */
2142 find_cond_trap (test_bb
, then_edge
, else_edge
)
2143 basic_block test_bb
;
2144 edge then_edge
, else_edge
;
2146 basic_block then_bb
, else_bb
, trap_bb
, other_bb
;
2147 rtx trap
, jump
, cond
, cond_earliest
, seq
;
2150 then_bb
= then_edge
->dest
;
2151 else_bb
= else_edge
->dest
;
2153 /* Locate the block with the trap instruction. */
2154 /* ??? While we look for no successors, we really ought to allow
2155 EH successors. Need to fix merge_if_block for that to work. */
2156 if ((trap
= block_has_only_trap (then_bb
)) != NULL
)
2157 trap_bb
= then_bb
, other_bb
= else_bb
;
2158 else if ((trap
= block_has_only_trap (else_bb
)) != NULL
)
2159 trap_bb
= else_bb
, other_bb
= then_bb
;
2165 fprintf (rtl_dump_file
, "\nTRAP-IF block found, start %d, trap %d\n",
2166 test_bb
->index
, trap_bb
->index
);
2169 /* If this is not a standard conditional jump, we can't parse it. */
2170 jump
= test_bb
->end
;
2171 cond
= noce_get_condition (jump
, &cond_earliest
);
2175 /* If the conditional jump is more than just a conditional jump,
2176 then we can not do if-conversion on this block. */
2177 if (! onlyjump_p (jump
))
2180 /* We must be comparing objects whose modes imply the size. */
2181 if (GET_MODE (XEXP (cond
, 0)) == BLKmode
)
2184 /* Reverse the comparison code, if necessary. */
2185 code
= GET_CODE (cond
);
2186 if (then_bb
== trap_bb
)
2188 code
= reversed_comparison_code (cond
, jump
);
2189 if (code
== UNKNOWN
)
2193 /* Attempt to generate the conditional trap. */
2194 seq
= gen_cond_trap (code
, XEXP (cond
, 0), XEXP (cond
, 1),
2195 TRAP_CODE (PATTERN (trap
)));
2199 /* Emit the new insns before cond_earliest. */
2200 emit_insn_before (seq
, cond_earliest
);
2202 /* Delete the trap block if possible. */
2203 remove_edge (trap_bb
== then_bb
? then_edge
: else_edge
);
2204 if (trap_bb
->pred
== NULL
)
2206 flow_delete_block (trap_bb
);
2207 num_removed_blocks
++;
2210 /* If the non-trap block and the test are now adjacent, merge them.
2211 Otherwise we must insert a direct branch. */
2212 if (test_bb
->index
+ 1 == other_bb
->index
)
2215 merge_if_block (test_bb
, NULL
, NULL
, other_bb
);
2221 lab
= JUMP_LABEL (jump
);
2222 newjump
= emit_jump_insn_after (gen_jump (lab
), jump
);
2223 LABEL_NUSES (lab
) += 1;
2224 JUMP_LABEL (newjump
) = lab
;
2225 emit_barrier_after (newjump
);
2233 /* Subroutine of find_cond_trap: if BB contains only a trap insn,
2237 block_has_only_trap (bb
)
2242 /* We're not the exit block. */
2243 if (bb
== EXIT_BLOCK_PTR
)
2246 /* The block must have no successors. */
2250 /* The only instruction in the THEN block must be the trap. */
2251 trap
= first_active_insn (bb
);
2252 if (! (trap
== bb
->end
2253 && GET_CODE (PATTERN (trap
)) == TRAP_IF
2254 && TRAP_CONDITION (PATTERN (trap
)) == const_true_rtx
))
2260 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
2261 transformable, but not necessarily the other. There need be no
2264 Return TRUE if we were successful at converting the the block.
2266 Cases we'd like to look at:
2269 if (test) goto over; // x not live
2277 if (! test) goto label;
2280 if (test) goto E; // x not live
2294 (3) // This one's really only interesting for targets that can do
2295 // multiway branching, e.g. IA-64 BBB bundles. For other targets
2296 // it results in multiple branches on a cache line, which often
2297 // does not sit well with predictors.
2299 if (test1) goto E; // predicted not taken
2315 (A) Don't do (2) if the branch is predicted against the block we're
2316 eliminating. Do it anyway if we can eliminate a branch; this requires
2317 that the sole successor of the eliminated block postdominate the other
2320 (B) With CE, on (3) we can steal from both sides of the if, creating
2329 Again, this is most useful if J postdominates.
2331 (C) CE substitutes for helpful life information.
2333 (D) These heuristics need a lot of work. */
2335 /* Tests for case 1 above. */
2338 find_if_case_1 (test_bb
, then_edge
, else_edge
)
2339 basic_block test_bb
;
2340 edge then_edge
, else_edge
;
2342 basic_block then_bb
= then_edge
->dest
;
2343 basic_block else_bb
= else_edge
->dest
, new_bb
;
2344 edge then_succ
= then_bb
->succ
;
2346 /* THEN has one successor. */
2347 if (!then_succ
|| then_succ
->succ_next
!= NULL
)
2350 /* THEN does not fall through, but is not strange either. */
2351 if (then_succ
->flags
& (EDGE_COMPLEX
| EDGE_FALLTHRU
))
2354 /* THEN has one predecessor. */
2355 if (then_bb
->pred
->pred_next
!= NULL
)
2358 /* THEN must do something. */
2359 if (forwarder_block_p (then_bb
))
2362 num_possible_if_blocks
++;
2364 fprintf (rtl_dump_file
,
2365 "\nIF-CASE-1 found, start %d, then %d\n",
2366 test_bb
->index
, then_bb
->index
);
2368 /* THEN is small. */
2369 if (count_bb_insns (then_bb
) > BRANCH_COST
)
2372 /* Registers set are dead, or are predicable. */
2373 if (! dead_or_predicable (test_bb
, then_bb
, else_bb
,
2374 then_bb
->succ
->dest
, 1))
2377 /* Conversion went ok, including moving the insns and fixing up the
2378 jump. Adjust the CFG to match. */
2380 SET_UPDATE_LIFE (test_bb
);
2381 bitmap_operation (test_bb
->global_live_at_end
,
2382 else_bb
->global_live_at_start
,
2383 then_bb
->global_live_at_end
, BITMAP_IOR
);
2385 new_bb
= redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb
), else_bb
);
2386 /* Make rest of code believe that the newly created block is the THEN_BB
2387 block we are going to remove. */
2390 new_bb
->aux
= then_bb
->aux
;
2391 SET_UPDATE_LIFE (then_bb
);
2393 flow_delete_block (then_bb
);
2394 /* We've possibly created jump to next insn, cleanup_cfg will solve that
2397 num_removed_blocks
++;
2398 num_updated_if_blocks
++;
2403 /* Test for case 2 above. */
2406 find_if_case_2 (test_bb
, then_edge
, else_edge
)
2407 basic_block test_bb
;
2408 edge then_edge
, else_edge
;
2410 basic_block then_bb
= then_edge
->dest
;
2411 basic_block else_bb
= else_edge
->dest
;
2412 edge else_succ
= else_bb
->succ
;
2415 /* ELSE has one successor. */
2416 if (!else_succ
|| else_succ
->succ_next
!= NULL
)
2419 /* ELSE outgoing edge is not complex. */
2420 if (else_succ
->flags
& EDGE_COMPLEX
)
2423 /* ELSE has one predecessor. */
2424 if (else_bb
->pred
->pred_next
!= NULL
)
2427 /* THEN is not EXIT. */
2428 if (then_bb
->index
< 0)
2431 /* ELSE is predicted or SUCC(ELSE) postdominates THEN. */
2432 note
= find_reg_note (test_bb
->end
, REG_BR_PROB
, NULL_RTX
);
2433 if (note
&& INTVAL (XEXP (note
, 0)) >= REG_BR_PROB_BASE
/ 2)
2435 else if (else_succ
->dest
->index
< 0
2436 || TEST_BIT (post_dominators
[ORIG_INDEX (then_bb
)],
2437 ORIG_INDEX (else_succ
->dest
)))
2442 num_possible_if_blocks
++;
2444 fprintf (rtl_dump_file
,
2445 "\nIF-CASE-2 found, start %d, else %d\n",
2446 test_bb
->index
, else_bb
->index
);
2448 /* ELSE is small. */
2449 if (count_bb_insns (then_bb
) > BRANCH_COST
)
2452 /* Registers set are dead, or are predicable. */
2453 if (! dead_or_predicable (test_bb
, else_bb
, then_bb
, else_succ
->dest
, 0))
2456 /* Conversion went ok, including moving the insns and fixing up the
2457 jump. Adjust the CFG to match. */
2459 SET_UPDATE_LIFE (test_bb
);
2460 bitmap_operation (test_bb
->global_live_at_end
,
2461 then_bb
->global_live_at_start
,
2462 else_bb
->global_live_at_end
, BITMAP_IOR
);
2464 flow_delete_block (else_bb
);
2466 num_removed_blocks
++;
2467 num_updated_if_blocks
++;
2469 /* ??? We may now fallthru from one of THEN's successors into a join
2470 block. Rerun cleanup_cfg? Examine things manually? Wait? */
2475 /* A subroutine of dead_or_predicable called through for_each_rtx.
2476 Return 1 if a memory is found. */
2479 find_memory (px
, data
)
2481 void *data ATTRIBUTE_UNUSED
;
2483 return GET_CODE (*px
) == MEM
;
2486 /* Used by the code above to perform the actual rtl transformations.
2487 Return TRUE if successful.
2489 TEST_BB is the block containing the conditional branch. MERGE_BB
2490 is the block containing the code to manipulate. NEW_DEST is the
2491 label TEST_BB should be branching to after the conversion.
2492 REVERSEP is true if the sense of the branch should be reversed. */
2495 dead_or_predicable (test_bb
, merge_bb
, other_bb
, new_dest
, reversep
)
2496 basic_block test_bb
, merge_bb
, other_bb
;
2497 basic_block new_dest
;
2500 rtx head
, end
, jump
, earliest
, old_dest
, new_label
= NULL_RTX
;
2502 jump
= test_bb
->end
;
2504 /* Find the extent of the real code in the merge block. */
2505 head
= merge_bb
->head
;
2506 end
= merge_bb
->end
;
2508 if (GET_CODE (head
) == CODE_LABEL
)
2509 head
= NEXT_INSN (head
);
2510 if (GET_CODE (head
) == NOTE
)
2514 head
= end
= NULL_RTX
;
2517 head
= NEXT_INSN (head
);
2520 if (GET_CODE (end
) == JUMP_INSN
)
2524 head
= end
= NULL_RTX
;
2527 end
= PREV_INSN (end
);
2530 /* Disable handling dead code by conditional execution if the machine needs
2531 to do anything funny with the tests, etc. */
2532 #ifndef IFCVT_MODIFY_TESTS
2533 if (HAVE_conditional_execution
)
2535 /* In the conditional execution case, we have things easy. We know
2536 the condition is reversable. We don't have to check life info,
2537 becase we're going to conditionally execute the code anyway.
2538 All that's left is making sure the insns involved can actually
2543 cond
= cond_exec_get_condition (jump
);
2547 prob_val
= find_reg_note (jump
, REG_BR_PROB
, NULL_RTX
);
2549 prob_val
= XEXP (prob_val
, 0);
2553 enum rtx_code rev
= reversed_comparison_code (cond
, jump
);
2556 cond
= gen_rtx_fmt_ee (rev
, GET_MODE (cond
), XEXP (cond
, 0),
2559 prob_val
= GEN_INT (REG_BR_PROB_BASE
- INTVAL (prob_val
));
2562 if (! cond_exec_process_insns (head
, end
, cond
, prob_val
, 0))
2570 /* In the non-conditional execution case, we have to verify that there
2571 are no trapping operations, no calls, no references to memory, and
2572 that any registers modified are dead at the branch site. */
2574 rtx insn
, cond
, prev
;
2575 regset_head merge_set_head
, tmp_head
, test_live_head
, test_set_head
;
2576 regset merge_set
, tmp
, test_live
, test_set
;
2577 struct propagate_block_info
*pbi
;
2580 /* Check for no calls or trapping operations. */
2581 for (insn
= head
; ; insn
= NEXT_INSN (insn
))
2583 if (GET_CODE (insn
) == CALL_INSN
)
2587 if (may_trap_p (PATTERN (insn
)))
2590 /* ??? Even non-trapping memories such as stack frame
2591 references must be avoided. For stores, we collect
2592 no lifetime info; for reads, we'd have to assert
2593 true_dependence false against every store in the
2595 if (for_each_rtx (&PATTERN (insn
), find_memory
, NULL
))
2602 if (! any_condjump_p (jump
))
2605 /* Find the extent of the conditional. */
2606 cond
= noce_get_condition (jump
, &earliest
);
2611 MERGE_SET = set of registers set in MERGE_BB
2612 TEST_LIVE = set of registers live at EARLIEST
2613 TEST_SET = set of registers set between EARLIEST and the
2614 end of the block. */
2616 tmp
= INITIALIZE_REG_SET (tmp_head
);
2617 merge_set
= INITIALIZE_REG_SET (merge_set_head
);
2618 test_live
= INITIALIZE_REG_SET (test_live_head
);
2619 test_set
= INITIALIZE_REG_SET (test_set_head
);
2621 /* ??? bb->local_set is only valid during calculate_global_regs_live,
2622 so we must recompute usage for MERGE_BB. Not so bad, I suppose,
2623 since we've already asserted that MERGE_BB is small. */
2624 propagate_block (merge_bb
, tmp
, merge_set
, merge_set
, 0);
2626 /* For small register class machines, don't lengthen lifetimes of
2627 hard registers before reload. */
2628 if (SMALL_REGISTER_CLASSES
&& ! reload_completed
)
2630 EXECUTE_IF_SET_IN_BITMAP
2633 if (i
< FIRST_PSEUDO_REGISTER
2635 && ! global_regs
[i
])
2640 /* For TEST, we're interested in a range of insns, not a whole block.
2641 Moreover, we're interested in the insns live from OTHER_BB. */
2643 COPY_REG_SET (test_live
, other_bb
->global_live_at_start
);
2644 pbi
= init_propagate_block_info (test_bb
, test_live
, test_set
, test_set
,
2647 for (insn
= jump
; ; insn
= prev
)
2649 prev
= propagate_one_insn (pbi
, insn
);
2650 if (insn
== earliest
)
2654 free_propagate_block_info (pbi
);
2656 /* We can perform the transformation if
2657 MERGE_SET & (TEST_SET | TEST_LIVE)
2659 TEST_SET & merge_bb->global_live_at_start
2662 bitmap_operation (tmp
, test_set
, test_live
, BITMAP_IOR
);
2663 bitmap_operation (tmp
, tmp
, merge_set
, BITMAP_AND
);
2664 EXECUTE_IF_SET_IN_BITMAP(tmp
, 0, i
, fail
= 1);
2666 bitmap_operation (tmp
, test_set
, merge_bb
->global_live_at_start
,
2668 EXECUTE_IF_SET_IN_BITMAP(tmp
, 0, i
, fail
= 1);
2671 FREE_REG_SET (merge_set
);
2672 FREE_REG_SET (test_live
);
2673 FREE_REG_SET (test_set
);
2680 /* We don't want to use normal invert_jump or redirect_jump because
2681 we don't want to delete_insn called. Also, we want to do our own
2682 change group management. */
2684 old_dest
= JUMP_LABEL (jump
);
2685 if (other_bb
!= new_dest
)
2687 new_label
= block_label (new_dest
);
2689 ? ! invert_jump_1 (jump
, new_label
)
2690 : ! redirect_jump_1 (jump
, new_label
))
2694 if (! apply_change_group ())
2697 if (other_bb
!= new_dest
)
2700 LABEL_NUSES (old_dest
) -= 1;
2702 LABEL_NUSES (new_label
) += 1;
2703 JUMP_LABEL (jump
) = new_label
;
2705 invert_br_probabilities (jump
);
2707 redirect_edge_succ (BRANCH_EDGE (test_bb
), new_dest
);
2710 gcov_type count
, probability
;
2711 count
= BRANCH_EDGE (test_bb
)->count
;
2712 BRANCH_EDGE (test_bb
)->count
= FALLTHRU_EDGE (test_bb
)->count
;
2713 FALLTHRU_EDGE (test_bb
)->count
= count
;
2714 probability
= BRANCH_EDGE (test_bb
)->probability
;
2715 BRANCH_EDGE (test_bb
)->probability
2716 = FALLTHRU_EDGE (test_bb
)->probability
;
2717 FALLTHRU_EDGE (test_bb
)->probability
= probability
;
2718 update_br_prob_note (test_bb
);
2722 /* Move the insns out of MERGE_BB to before the branch. */
2725 if (end
== merge_bb
->end
)
2726 merge_bb
->end
= PREV_INSN (head
);
2728 if (squeeze_notes (&head
, &end
))
2731 reorder_insns (head
, end
, PREV_INSN (earliest
));
2734 /* Remove the jump and edge if we can. */
2735 if (other_bb
== new_dest
)
2738 remove_edge (BRANCH_EDGE (test_bb
));
2739 /* ??? Can't merge blocks here, as then_bb is still in use.
2740 At minimum, the merge will get done just before bb-reorder. */
2750 /* Main entry point for all if-conversion. */
2753 if_convert (x_life_data_ok
)
2758 num_possible_if_blocks
= 0;
2759 num_updated_if_blocks
= 0;
2760 num_removed_blocks
= 0;
2761 life_data_ok
= (x_life_data_ok
!= 0);
2763 /* Free up basic_block_for_insn so that we don't have to keep it
2764 up to date, either here or in merge_blocks_nomove. */
2765 free_basic_block_vars (1);
2767 /* Compute postdominators if we think we'll use them. */
2768 post_dominators
= NULL
;
2769 if (HAVE_conditional_execution
|| life_data_ok
)
2771 post_dominators
= sbitmap_vector_alloc (n_basic_blocks
, n_basic_blocks
);
2772 calculate_dominance_info (NULL
, post_dominators
, CDI_POST_DOMINATORS
);
2775 /* Record initial block numbers. */
2776 for (block_num
= 0; block_num
< n_basic_blocks
; block_num
++)
2777 SET_ORIG_INDEX (BASIC_BLOCK (block_num
), block_num
);
2779 /* Go through each of the basic blocks looking for things to convert. */
2780 for (block_num
= 0; block_num
< n_basic_blocks
; )
2782 basic_block bb
= BASIC_BLOCK (block_num
);
2783 if (find_if_header (bb
))
2784 block_num
= bb
->index
;
2789 if (post_dominators
)
2790 sbitmap_vector_free (post_dominators
);
2793 fflush (rtl_dump_file
);
2795 /* Rebuild life info for basic blocks that require it. */
2796 if (num_removed_blocks
&& life_data_ok
)
2798 sbitmap update_life_blocks
= sbitmap_alloc (n_basic_blocks
);
2799 sbitmap_zero (update_life_blocks
);
2801 /* If we allocated new pseudos, we must resize the array for sched1. */
2802 if (max_regno
< max_reg_num ())
2804 max_regno
= max_reg_num ();
2805 allocate_reg_info (max_regno
, FALSE
, FALSE
);
2808 for (block_num
= 0; block_num
< n_basic_blocks
; block_num
++)
2809 if (UPDATE_LIFE (BASIC_BLOCK (block_num
)))
2810 SET_BIT (update_life_blocks
, block_num
);
2812 clear_aux_for_blocks ();
2813 count_or_remove_death_notes (update_life_blocks
, 1);
2814 /* ??? See about adding a mode that verifies that the initial
2815 set of blocks don't let registers come live. */
2816 update_life_info (update_life_blocks
, UPDATE_LIFE_GLOBAL
,
2817 PROP_DEATH_NOTES
| PROP_SCAN_DEAD_CODE
2818 | PROP_KILL_DEAD_CODE
);
2820 sbitmap_free (update_life_blocks
);
2823 clear_aux_for_blocks ();
2825 /* Write the final stats. */
2826 if (rtl_dump_file
&& num_possible_if_blocks
> 0)
2828 fprintf (rtl_dump_file
,
2829 "\n%d possible IF blocks searched.\n",
2830 num_possible_if_blocks
);
2831 fprintf (rtl_dump_file
,
2832 "%d IF blocks converted.\n",
2833 num_updated_if_blocks
);
2834 fprintf (rtl_dump_file
,
2835 "%d basic blocks deleted.\n\n\n",
2836 num_removed_blocks
);
2839 #ifdef ENABLE_CHECKING
2840 verify_flow_info ();