1 /* Optimize jump instructions, for GNU compiler.
2 Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This is the pathetic reminder of old fame of the jump-optimization pass
23 of the compiler. Now it contains basically a set of utility functions to
26 Each CODE_LABEL has a count of the times it is used
27 stored in the LABEL_NUSES internal field, and each JUMP_INSN
28 has one label that it refers to stored in the
29 JUMP_LABEL internal field. With this we can detect labels that
30 become unused because of the deletion of all the jumps that
31 formerly used them. The JUMP_LABEL info is sometimes looked
34 The subroutines redirect_jump and invert_jump are used
35 from other passes as well. */
39 #include "coretypes.h"
44 #include "hard-reg-set.h"
46 #include "insn-config.h"
47 #include "insn-attr.h"
53 #include "diagnostic.h"
58 #include "tree-pass.h"
61 /* Optimize jump y; x: ... y: jumpif... x?
62 Don't know if it is worth bothering with. */
63 /* Optimize two cases of conditional jump to conditional jump?
64 This can never delete any instruction or make anything dead,
65 or even change what is live at any point.
66 So perhaps let combiner do it. */
68 static void init_label_info (rtx
);
69 static void mark_all_labels (rtx
);
70 static void mark_jump_label_1 (rtx
, rtx
, bool, bool);
71 static void redirect_exp_1 (rtx
*, rtx
, rtx
, rtx
);
72 static int invert_exp_1 (rtx
, rtx
);
73 static int returnjump_p_1 (rtx
*, void *);
75 /* This function rebuilds the JUMP_LABEL field and REG_LABEL_TARGET
76 notes in jumping insns and REG_LABEL_OPERAND notes in non-jumping
77 instructions and jumping insns that have labels as operands
80 rebuild_jump_labels (rtx f
)
84 timevar_push (TV_REBUILD_JUMP
);
88 /* Keep track of labels used from static data; we don't track them
89 closely enough to delete them here, so make sure their reference
90 count doesn't drop to zero. */
92 for (insn
= forced_labels
; insn
; insn
= XEXP (insn
, 1))
93 if (LABEL_P (XEXP (insn
, 0)))
94 LABEL_NUSES (XEXP (insn
, 0))++;
95 timevar_pop (TV_REBUILD_JUMP
);
98 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
99 non-fallthru insn. This is not generally true, as multiple barriers
100 may have crept in, or the BARRIER may be separated from the last
101 real insn by one or more NOTEs.
103 This simple pass moves barriers and removes duplicates so that the
107 cleanup_barriers (void)
109 rtx insn
, next
, prev
;
110 for (insn
= get_insns (); insn
; insn
= next
)
112 next
= NEXT_INSN (insn
);
113 if (BARRIER_P (insn
))
115 prev
= prev_nonnote_insn (insn
);
116 if (BARRIER_P (prev
))
118 else if (prev
!= PREV_INSN (insn
))
119 reorder_insns (insn
, insn
, prev
);
125 struct tree_opt_pass pass_cleanup_barriers
=
127 "barriers", /* name */
129 cleanup_barriers
, /* execute */
132 0, /* static_pass_number */
134 0, /* properties_required */
135 0, /* properties_provided */
136 0, /* properties_destroyed */
137 0, /* todo_flags_start */
138 TODO_dump_func
, /* todo_flags_finish */
143 /* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
144 for remaining targets for JUMP_P. Delete any REG_LABEL_OPERAND
145 notes whose labels don't occur in the insn any more. */
148 init_label_info (rtx f
)
152 for (insn
= f
; insn
; insn
= NEXT_INSN (insn
))
155 LABEL_NUSES (insn
) = (LABEL_PRESERVE_P (insn
) != 0);
157 /* REG_LABEL_TARGET notes (including the JUMP_LABEL field) are
158 sticky and not reset here; that way we won't lose association
159 with a label when e.g. the source for a target register
160 disappears out of reach for targets that may use jump-target
161 registers. Jump transformations are supposed to transform
162 any REG_LABEL_TARGET notes. The target label reference in a
163 branch may disappear from the branch (and from the
164 instruction before it) for other reasons, like register
171 for (note
= REG_NOTES (insn
); note
; note
= next
)
173 next
= XEXP (note
, 1);
174 if (REG_NOTE_KIND (note
) == REG_LABEL_OPERAND
175 && ! reg_mentioned_p (XEXP (note
, 0), PATTERN (insn
)))
176 remove_note (insn
, note
);
182 /* Mark the label each jump jumps to.
183 Combine consecutive labels, and count uses of labels. */
186 mark_all_labels (rtx f
)
189 rtx prev_nonjump_insn
= NULL
;
191 for (insn
= f
; insn
; insn
= NEXT_INSN (insn
))
194 mark_jump_label (PATTERN (insn
), insn
, 0);
196 /* If the previous non-jump insn sets something to a label,
197 something that this jump insn uses, make that label the primary
198 target of this insn if we don't yet have any. That previous
199 insn must be a single_set and not refer to more than one label.
200 The jump insn must not refer to other labels as jump targets
201 and must be a plain (set (pc) ...), maybe in a parallel, and
202 may refer to the item being set only directly or as one of the
203 arms in an IF_THEN_ELSE. */
204 if (! INSN_DELETED_P (insn
)
206 && JUMP_LABEL (insn
) == NULL
)
208 rtx label_note
= NULL
;
209 rtx pc
= pc_set (insn
);
210 rtx pc_src
= pc
!= NULL
? SET_SRC (pc
) : NULL
;
212 if (prev_nonjump_insn
!= NULL
)
214 = find_reg_note (prev_nonjump_insn
, REG_LABEL_OPERAND
, NULL
);
216 if (label_note
!= NULL
&& pc_src
!= NULL
)
218 rtx label_set
= single_set (prev_nonjump_insn
);
220 = label_set
!= NULL
? SET_DEST (label_set
) : NULL
;
222 if (label_set
!= NULL
223 /* The source must be the direct LABEL_REF, not a
224 PLUS, UNSPEC, IF_THEN_ELSE etc. */
225 && GET_CODE (SET_SRC (label_set
)) == LABEL_REF
226 && (rtx_equal_p (label_dest
, pc_src
)
227 || (GET_CODE (pc_src
) == IF_THEN_ELSE
228 && (rtx_equal_p (label_dest
, XEXP (pc_src
, 1))
229 || rtx_equal_p (label_dest
,
230 XEXP (pc_src
, 2))))))
233 /* The CODE_LABEL referred to in the note must be the
234 CODE_LABEL in the LABEL_REF of the "set". We can
235 conveniently use it for the marker function, which
236 requires a LABEL_REF wrapping. */
237 gcc_assert (XEXP (label_note
, 0)
238 == XEXP (SET_SRC (label_set
), 0));
240 mark_jump_label_1 (label_set
, insn
, false, true);
241 gcc_assert (JUMP_LABEL (insn
)
242 == XEXP (SET_SRC (label_set
), 0));
246 else if (! INSN_DELETED_P (insn
))
247 prev_nonjump_insn
= insn
;
249 else if (LABEL_P (insn
))
250 prev_nonjump_insn
= NULL
;
252 /* If we are in cfglayout mode, there may be non-insns between the
253 basic blocks. If those non-insns represent tablejump data, they
254 contain label references that we must record. */
255 if (current_ir_type () == IR_RTL_CFGLAYOUT
)
261 for (insn
= bb
->il
.rtl
->header
; insn
; insn
= NEXT_INSN (insn
))
264 gcc_assert (JUMP_TABLE_DATA_P (insn
));
265 mark_jump_label (PATTERN (insn
), insn
, 0);
268 for (insn
= bb
->il
.rtl
->footer
; insn
; insn
= NEXT_INSN (insn
))
271 gcc_assert (JUMP_TABLE_DATA_P (insn
));
272 mark_jump_label (PATTERN (insn
), insn
, 0);
278 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
279 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
280 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
281 know whether it's source is floating point or integer comparison. Machine
282 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
283 to help this function avoid overhead in these cases. */
285 reversed_comparison_code_parts (enum rtx_code code
, const_rtx arg0
,
286 const_rtx arg1
, const_rtx insn
)
288 enum machine_mode mode
;
290 /* If this is not actually a comparison, we can't reverse it. */
291 if (GET_RTX_CLASS (code
) != RTX_COMPARE
292 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
)
295 mode
= GET_MODE (arg0
);
296 if (mode
== VOIDmode
)
297 mode
= GET_MODE (arg1
);
299 /* First see if machine description supplies us way to reverse the
300 comparison. Give it priority over everything else to allow
301 machine description to do tricks. */
302 if (GET_MODE_CLASS (mode
) == MODE_CC
303 && REVERSIBLE_CC_MODE (mode
))
305 #ifdef REVERSE_CONDITION
306 return REVERSE_CONDITION (code
, mode
);
308 return reverse_condition (code
);
311 /* Try a few special cases based on the comparison code. */
320 /* It is always safe to reverse EQ and NE, even for the floating
321 point. Similarly the unsigned comparisons are never used for
322 floating point so we can reverse them in the default way. */
323 return reverse_condition (code
);
328 /* In case we already see unordered comparison, we can be sure to
329 be dealing with floating point so we don't need any more tests. */
330 return reverse_condition_maybe_unordered (code
);
335 /* We don't have safe way to reverse these yet. */
341 if (GET_MODE_CLASS (mode
) == MODE_CC
|| CC0_P (arg0
))
344 /* Try to search for the comparison to determine the real mode.
345 This code is expensive, but with sane machine description it
346 will be never used, since REVERSIBLE_CC_MODE will return true
351 /* These CONST_CAST's are okay because prev_nonnote_insn just
352 returns it's argument and we assign it to a const_rtx
354 for (prev
= prev_nonnote_insn (CONST_CAST_RTX(insn
));
355 prev
!= 0 && !LABEL_P (prev
);
356 prev
= prev_nonnote_insn (CONST_CAST_RTX(prev
)))
358 const_rtx set
= set_of (arg0
, prev
);
359 if (set
&& GET_CODE (set
) == SET
360 && rtx_equal_p (SET_DEST (set
), arg0
))
362 rtx src
= SET_SRC (set
);
364 if (GET_CODE (src
) == COMPARE
)
366 rtx comparison
= src
;
367 arg0
= XEXP (src
, 0);
368 mode
= GET_MODE (arg0
);
369 if (mode
== VOIDmode
)
370 mode
= GET_MODE (XEXP (comparison
, 1));
373 /* We can get past reg-reg moves. This may be useful for model
374 of i387 comparisons that first move flag registers around. */
381 /* If register is clobbered in some ununderstandable way,
388 /* Test for an integer condition, or a floating-point comparison
389 in which NaNs can be ignored. */
390 if (GET_CODE (arg0
) == CONST_INT
391 || (GET_MODE (arg0
) != VOIDmode
392 && GET_MODE_CLASS (mode
) != MODE_CC
393 && !HONOR_NANS (mode
)))
394 return reverse_condition (code
);
399 /* A wrapper around the previous function to take COMPARISON as rtx
400 expression. This simplifies many callers. */
402 reversed_comparison_code (const_rtx comparison
, const_rtx insn
)
404 if (!COMPARISON_P (comparison
))
406 return reversed_comparison_code_parts (GET_CODE (comparison
),
407 XEXP (comparison
, 0),
408 XEXP (comparison
, 1), insn
);
411 /* Return comparison with reversed code of EXP.
412 Return NULL_RTX in case we fail to do the reversal. */
414 reversed_comparison (const_rtx exp
, enum machine_mode mode
)
416 enum rtx_code reversed_code
= reversed_comparison_code (exp
, NULL_RTX
);
417 if (reversed_code
== UNKNOWN
)
420 return simplify_gen_relational (reversed_code
, mode
, VOIDmode
,
421 XEXP (exp
, 0), XEXP (exp
, 1));
425 /* Given an rtx-code for a comparison, return the code for the negated
426 comparison. If no such code exists, return UNKNOWN.
428 WATCH OUT! reverse_condition is not safe to use on a jump that might
429 be acting on the results of an IEEE floating point comparison, because
430 of the special treatment of non-signaling nans in comparisons.
431 Use reversed_comparison_code instead. */
434 reverse_condition (enum rtx_code code
)
476 /* Similar, but we're allowed to generate unordered comparisons, which
477 makes it safe for IEEE floating-point. Of course, we have to recognize
478 that the target will support them too... */
481 reverse_condition_maybe_unordered (enum rtx_code code
)
519 /* Similar, but return the code when two operands of a comparison are swapped.
520 This IS safe for IEEE floating-point. */
523 swap_condition (enum rtx_code code
)
565 /* Given a comparison CODE, return the corresponding unsigned comparison.
566 If CODE is an equality comparison or already an unsigned comparison,
570 unsigned_condition (enum rtx_code code
)
596 /* Similarly, return the signed version of a comparison. */
599 signed_condition (enum rtx_code code
)
625 /* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
626 truth of CODE1 implies the truth of CODE2. */
629 comparison_dominates_p (enum rtx_code code1
, enum rtx_code code2
)
631 /* UNKNOWN comparison codes can happen as a result of trying to revert
633 They can't match anything, so we have to reject them here. */
634 if (code1
== UNKNOWN
|| code2
== UNKNOWN
)
643 if (code2
== UNLE
|| code2
== UNGE
)
648 if (code2
== LE
|| code2
== LEU
|| code2
== GE
|| code2
== GEU
654 if (code2
== UNLE
|| code2
== NE
)
659 if (code2
== LE
|| code2
== NE
|| code2
== ORDERED
|| code2
== LTGT
)
664 if (code2
== UNGE
|| code2
== NE
)
669 if (code2
== GE
|| code2
== NE
|| code2
== ORDERED
|| code2
== LTGT
)
675 if (code2
== ORDERED
)
680 if (code2
== NE
|| code2
== ORDERED
)
685 if (code2
== LEU
|| code2
== NE
)
690 if (code2
== GEU
|| code2
== NE
)
695 if (code2
== NE
|| code2
== UNEQ
|| code2
== UNLE
|| code2
== UNLT
696 || code2
== UNGE
|| code2
== UNGT
)
707 /* Return 1 if INSN is an unconditional jump and nothing else. */
710 simplejump_p (const_rtx insn
)
712 return (JUMP_P (insn
)
713 && GET_CODE (PATTERN (insn
)) == SET
714 && GET_CODE (SET_DEST (PATTERN (insn
))) == PC
715 && GET_CODE (SET_SRC (PATTERN (insn
))) == LABEL_REF
);
718 /* Return nonzero if INSN is a (possibly) conditional jump
721 Use of this function is deprecated, since we need to support combined
722 branch and compare insns. Use any_condjump_p instead whenever possible. */
725 condjump_p (const_rtx insn
)
727 const_rtx x
= PATTERN (insn
);
729 if (GET_CODE (x
) != SET
730 || GET_CODE (SET_DEST (x
)) != PC
)
734 if (GET_CODE (x
) == LABEL_REF
)
737 return (GET_CODE (x
) == IF_THEN_ELSE
738 && ((GET_CODE (XEXP (x
, 2)) == PC
739 && (GET_CODE (XEXP (x
, 1)) == LABEL_REF
740 || GET_CODE (XEXP (x
, 1)) == RETURN
))
741 || (GET_CODE (XEXP (x
, 1)) == PC
742 && (GET_CODE (XEXP (x
, 2)) == LABEL_REF
743 || GET_CODE (XEXP (x
, 2)) == RETURN
))));
746 /* Return nonzero if INSN is a (possibly) conditional jump inside a
749 Use this function is deprecated, since we need to support combined
750 branch and compare insns. Use any_condjump_p instead whenever possible. */
753 condjump_in_parallel_p (const_rtx insn
)
755 const_rtx x
= PATTERN (insn
);
757 if (GET_CODE (x
) != PARALLEL
)
760 x
= XVECEXP (x
, 0, 0);
762 if (GET_CODE (x
) != SET
)
764 if (GET_CODE (SET_DEST (x
)) != PC
)
766 if (GET_CODE (SET_SRC (x
)) == LABEL_REF
)
768 if (GET_CODE (SET_SRC (x
)) != IF_THEN_ELSE
)
770 if (XEXP (SET_SRC (x
), 2) == pc_rtx
771 && (GET_CODE (XEXP (SET_SRC (x
), 1)) == LABEL_REF
772 || GET_CODE (XEXP (SET_SRC (x
), 1)) == RETURN
))
774 if (XEXP (SET_SRC (x
), 1) == pc_rtx
775 && (GET_CODE (XEXP (SET_SRC (x
), 2)) == LABEL_REF
776 || GET_CODE (XEXP (SET_SRC (x
), 2)) == RETURN
))
781 /* Return set of PC, otherwise NULL. */
784 pc_set (const_rtx insn
)
789 pat
= PATTERN (insn
);
791 /* The set is allowed to appear either as the insn pattern or
792 the first set in a PARALLEL. */
793 if (GET_CODE (pat
) == PARALLEL
)
794 pat
= XVECEXP (pat
, 0, 0);
795 if (GET_CODE (pat
) == SET
&& GET_CODE (SET_DEST (pat
)) == PC
)
801 /* Return true when insn is an unconditional direct jump,
802 possibly bundled inside a PARALLEL. */
805 any_uncondjump_p (const_rtx insn
)
807 const_rtx x
= pc_set (insn
);
810 if (GET_CODE (SET_SRC (x
)) != LABEL_REF
)
812 if (find_reg_note (insn
, REG_NON_LOCAL_GOTO
, NULL_RTX
))
817 /* Return true when insn is a conditional jump. This function works for
818 instructions containing PC sets in PARALLELs. The instruction may have
819 various other effects so before removing the jump you must verify
822 Note that unlike condjump_p it returns false for unconditional jumps. */
825 any_condjump_p (const_rtx insn
)
827 const_rtx x
= pc_set (insn
);
832 if (GET_CODE (SET_SRC (x
)) != IF_THEN_ELSE
)
835 a
= GET_CODE (XEXP (SET_SRC (x
), 1));
836 b
= GET_CODE (XEXP (SET_SRC (x
), 2));
838 return ((b
== PC
&& (a
== LABEL_REF
|| a
== RETURN
))
839 || (a
== PC
&& (b
== LABEL_REF
|| b
== RETURN
)));
842 /* Return the label of a conditional jump. */
845 condjump_label (const_rtx insn
)
847 rtx x
= pc_set (insn
);
852 if (GET_CODE (x
) == LABEL_REF
)
854 if (GET_CODE (x
) != IF_THEN_ELSE
)
856 if (XEXP (x
, 2) == pc_rtx
&& GET_CODE (XEXP (x
, 1)) == LABEL_REF
)
858 if (XEXP (x
, 1) == pc_rtx
&& GET_CODE (XEXP (x
, 2)) == LABEL_REF
)
863 /* Return true if INSN is a (possibly conditional) return insn. */
866 returnjump_p_1 (rtx
*loc
, void *data ATTRIBUTE_UNUSED
)
870 return x
&& (GET_CODE (x
) == RETURN
871 || (GET_CODE (x
) == SET
&& SET_IS_RETURN_P (x
)));
875 returnjump_p (rtx insn
)
879 return for_each_rtx (&PATTERN (insn
), returnjump_p_1
, NULL
);
882 /* Return true if INSN is a jump that only transfers control and
886 onlyjump_p (const_rtx insn
)
893 set
= single_set (insn
);
896 if (GET_CODE (SET_DEST (set
)) != PC
)
898 if (side_effects_p (SET_SRC (set
)))
906 /* Return nonzero if X is an RTX that only sets the condition codes
907 and has no side effects. */
910 only_sets_cc0_p (const_rtx x
)
918 return sets_cc0_p (x
) == 1 && ! side_effects_p (x
);
921 /* Return 1 if X is an RTX that does nothing but set the condition codes
922 and CLOBBER or USE registers.
923 Return -1 if X does explicitly set the condition codes,
924 but also does other things. */
927 sets_cc0_p (const_rtx x
)
935 if (GET_CODE (x
) == SET
&& SET_DEST (x
) == cc0_rtx
)
937 if (GET_CODE (x
) == PARALLEL
)
941 int other_things
= 0;
942 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
944 if (GET_CODE (XVECEXP (x
, 0, i
)) == SET
945 && SET_DEST (XVECEXP (x
, 0, i
)) == cc0_rtx
)
947 else if (GET_CODE (XVECEXP (x
, 0, i
)) == SET
)
950 return ! sets_cc0
? 0 : other_things
? -1 : 1;
956 /* Find all CODE_LABELs referred to in X, and increment their use
957 counts. If INSN is a JUMP_INSN and there is at least one
958 CODE_LABEL referenced in INSN as a jump target, then store the last
959 one in JUMP_LABEL (INSN). For a tablejump, this must be the label
960 for the ADDR_VEC. Store any other jump targets as REG_LABEL_TARGET
961 notes. If INSN is an INSN or a CALL_INSN or non-target operands of
962 a JUMP_INSN, and there is at least one CODE_LABEL referenced in
963 INSN, add a REG_LABEL_OPERAND note containing that label to INSN.
965 Note that two labels separated by a loop-beginning note
966 must be kept distinct if we have not yet done loop-optimization,
967 because the gap between them is where loop-optimize
968 will want to move invariant code to. CROSS_JUMP tells us
969 that loop-optimization is done with. */
972 mark_jump_label (rtx x
, rtx insn
, int in_mem
)
974 mark_jump_label_1 (x
, insn
, in_mem
!= 0,
975 (insn
!= NULL
&& x
== PATTERN (insn
) && JUMP_P (insn
)));
978 /* Worker function for mark_jump_label. IN_MEM is TRUE when X occurs
979 within a (MEM ...). IS_TARGET is TRUE when X is to be treated as a
980 jump-target; when the JUMP_LABEL field of INSN should be set or a
981 REG_LABEL_TARGET note should be added, not a REG_LABEL_OPERAND
985 mark_jump_label_1 (rtx x
, rtx insn
, bool in_mem
, bool is_target
)
987 RTX_CODE code
= GET_CODE (x
);
1007 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
1008 mark_jump_label (PATTERN (XVECEXP (x
, 0, i
)),
1009 XVECEXP (x
, 0, i
), 0);
1016 /* If this is a constant-pool reference, see if it is a label. */
1017 if (CONSTANT_POOL_ADDRESS_P (x
))
1018 mark_jump_label_1 (get_pool_constant (x
), insn
, in_mem
, is_target
);
1021 /* Handle operands in the condition of an if-then-else as for a
1026 mark_jump_label_1 (XEXP (x
, 0), insn
, in_mem
, false);
1027 mark_jump_label_1 (XEXP (x
, 1), insn
, in_mem
, true);
1028 mark_jump_label_1 (XEXP (x
, 2), insn
, in_mem
, true);
1033 rtx label
= XEXP (x
, 0);
1035 /* Ignore remaining references to unreachable labels that
1036 have been deleted. */
1038 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
)
1041 gcc_assert (LABEL_P (label
));
1043 /* Ignore references to labels of containing functions. */
1044 if (LABEL_REF_NONLOCAL_P (x
))
1047 XEXP (x
, 0) = label
;
1048 if (! insn
|| ! INSN_DELETED_P (insn
))
1049 ++LABEL_NUSES (label
);
1054 && (JUMP_LABEL (insn
) == NULL
|| JUMP_LABEL (insn
) == label
))
1055 JUMP_LABEL (insn
) = label
;
1059 = is_target
? REG_LABEL_TARGET
: REG_LABEL_OPERAND
;
1061 /* Add a REG_LABEL_OPERAND or REG_LABEL_TARGET note
1062 for LABEL unless there already is one. All uses of
1063 a label, except for the primary target of a jump,
1064 must have such a note. */
1065 if (! find_reg_note (insn
, kind
, label
))
1067 = gen_rtx_INSN_LIST (kind
, label
, REG_NOTES (insn
));
1073 /* Do walk the labels in a vector, but not the first operand of an
1074 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1077 if (! INSN_DELETED_P (insn
))
1079 int eltnum
= code
== ADDR_DIFF_VEC
? 1 : 0;
1081 for (i
= 0; i
< XVECLEN (x
, eltnum
); i
++)
1082 mark_jump_label_1 (XVECEXP (x
, eltnum
, i
), NULL_RTX
, in_mem
,
1091 fmt
= GET_RTX_FORMAT (code
);
1093 /* The primary target of a tablejump is the label of the ADDR_VEC,
1094 which is canonically mentioned *last* in the insn. To get it
1095 marked as JUMP_LABEL, we iterate over items in reverse order. */
1096 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1099 mark_jump_label_1 (XEXP (x
, i
), insn
, in_mem
, is_target
);
1100 else if (fmt
[i
] == 'E')
1104 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
1105 mark_jump_label_1 (XVECEXP (x
, i
, j
), insn
, in_mem
,
1112 /* Delete insn INSN from the chain of insns and update label ref counts
1113 and delete insns now unreachable.
1115 Returns the first insn after INSN that was not deleted.
1117 Usage of this instruction is deprecated. Use delete_insn instead and
1118 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1121 delete_related_insns (rtx insn
)
1123 int was_code_label
= (LABEL_P (insn
));
1125 rtx next
= NEXT_INSN (insn
), prev
= PREV_INSN (insn
);
1127 while (next
&& INSN_DELETED_P (next
))
1128 next
= NEXT_INSN (next
);
1130 /* This insn is already deleted => return first following nondeleted. */
1131 if (INSN_DELETED_P (insn
))
1136 /* If instruction is followed by a barrier,
1137 delete the barrier too. */
1139 if (next
!= 0 && BARRIER_P (next
))
1142 /* If deleting a jump, decrement the count of the label,
1143 and delete the label if it is now unused. */
1145 if (JUMP_P (insn
) && JUMP_LABEL (insn
))
1147 rtx lab
= JUMP_LABEL (insn
), lab_next
;
1149 if (LABEL_NUSES (lab
) == 0)
1150 /* This can delete NEXT or PREV,
1151 either directly if NEXT is JUMP_LABEL (INSN),
1152 or indirectly through more levels of jumps. */
1153 delete_related_insns (lab
);
1154 else if (tablejump_p (insn
, NULL
, &lab_next
))
1156 /* If we're deleting the tablejump, delete the dispatch table.
1157 We may not be able to kill the label immediately preceding
1158 just yet, as it might be referenced in code leading up to
1160 delete_related_insns (lab_next
);
1164 /* Likewise if we're deleting a dispatch table. */
1167 && (GET_CODE (PATTERN (insn
)) == ADDR_VEC
1168 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
))
1170 rtx pat
= PATTERN (insn
);
1171 int i
, diff_vec_p
= GET_CODE (pat
) == ADDR_DIFF_VEC
;
1172 int len
= XVECLEN (pat
, diff_vec_p
);
1174 for (i
= 0; i
< len
; i
++)
1175 if (LABEL_NUSES (XEXP (XVECEXP (pat
, diff_vec_p
, i
), 0)) == 0)
1176 delete_related_insns (XEXP (XVECEXP (pat
, diff_vec_p
, i
), 0));
1177 while (next
&& INSN_DELETED_P (next
))
1178 next
= NEXT_INSN (next
);
1182 /* Likewise for any JUMP_P / INSN / CALL_INSN with a
1183 REG_LABEL_OPERAND or REG_LABEL_TARGET note. */
1185 for (note
= REG_NOTES (insn
); note
; note
= XEXP (note
, 1))
1186 if ((REG_NOTE_KIND (note
) == REG_LABEL_OPERAND
1187 || REG_NOTE_KIND (note
) == REG_LABEL_TARGET
)
1188 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1189 && LABEL_P (XEXP (note
, 0)))
1190 if (LABEL_NUSES (XEXP (note
, 0)) == 0)
1191 delete_related_insns (XEXP (note
, 0));
1193 while (prev
&& (INSN_DELETED_P (prev
) || NOTE_P (prev
)))
1194 prev
= PREV_INSN (prev
);
1196 /* If INSN was a label and a dispatch table follows it,
1197 delete the dispatch table. The tablejump must have gone already.
1198 It isn't useful to fall through into a table. */
1201 && NEXT_INSN (insn
) != 0
1202 && JUMP_P (NEXT_INSN (insn
))
1203 && (GET_CODE (PATTERN (NEXT_INSN (insn
))) == ADDR_VEC
1204 || GET_CODE (PATTERN (NEXT_INSN (insn
))) == ADDR_DIFF_VEC
))
1205 next
= delete_related_insns (NEXT_INSN (insn
));
1207 /* If INSN was a label, delete insns following it if now unreachable. */
1209 if (was_code_label
&& prev
&& BARRIER_P (prev
))
1214 code
= GET_CODE (next
);
1216 next
= NEXT_INSN (next
);
1217 /* Keep going past other deleted labels to delete what follows. */
1218 else if (code
== CODE_LABEL
&& INSN_DELETED_P (next
))
1219 next
= NEXT_INSN (next
);
1220 else if (code
== BARRIER
|| INSN_P (next
))
1221 /* Note: if this deletes a jump, it can cause more
1222 deletion of unreachable code, after a different label.
1223 As long as the value from this recursive call is correct,
1224 this invocation functions correctly. */
1225 next
= delete_related_insns (next
);
1231 /* I feel a little doubtful about this loop,
1232 but I see no clean and sure alternative way
1233 to find the first insn after INSN that is not now deleted.
1234 I hope this works. */
1235 while (next
&& INSN_DELETED_P (next
))
1236 next
= NEXT_INSN (next
);
1240 /* Delete a range of insns from FROM to TO, inclusive.
1241 This is for the sake of peephole optimization, so assume
1242 that whatever these insns do will still be done by a new
1243 peephole insn that will replace them. */
1246 delete_for_peephole (rtx from
, rtx to
)
1252 rtx next
= NEXT_INSN (insn
);
1253 rtx prev
= PREV_INSN (insn
);
1257 INSN_DELETED_P (insn
) = 1;
1259 /* Patch this insn out of the chain. */
1260 /* We don't do this all at once, because we
1261 must preserve all NOTEs. */
1263 NEXT_INSN (prev
) = next
;
1266 PREV_INSN (next
) = prev
;
1274 /* Note that if TO is an unconditional jump
1275 we *do not* delete the BARRIER that follows,
1276 since the peephole that replaces this sequence
1277 is also an unconditional jump in that case. */
1280 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1281 NLABEL as a return. Accrue modifications into the change group. */
1284 redirect_exp_1 (rtx
*loc
, rtx olabel
, rtx nlabel
, rtx insn
)
1287 RTX_CODE code
= GET_CODE (x
);
1291 if (code
== LABEL_REF
)
1293 if (XEXP (x
, 0) == olabel
)
1297 n
= gen_rtx_LABEL_REF (Pmode
, nlabel
);
1299 n
= gen_rtx_RETURN (VOIDmode
);
1301 validate_change (insn
, loc
, n
, 1);
1305 else if (code
== RETURN
&& olabel
== 0)
1308 x
= gen_rtx_LABEL_REF (Pmode
, nlabel
);
1310 x
= gen_rtx_RETURN (VOIDmode
);
1311 if (loc
== &PATTERN (insn
))
1312 x
= gen_rtx_SET (VOIDmode
, pc_rtx
, x
);
1313 validate_change (insn
, loc
, x
, 1);
1317 if (code
== SET
&& nlabel
== 0 && SET_DEST (x
) == pc_rtx
1318 && GET_CODE (SET_SRC (x
)) == LABEL_REF
1319 && XEXP (SET_SRC (x
), 0) == olabel
)
1321 validate_change (insn
, loc
, gen_rtx_RETURN (VOIDmode
), 1);
1325 fmt
= GET_RTX_FORMAT (code
);
1326 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1329 redirect_exp_1 (&XEXP (x
, i
), olabel
, nlabel
, insn
);
1330 else if (fmt
[i
] == 'E')
1333 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1334 redirect_exp_1 (&XVECEXP (x
, i
, j
), olabel
, nlabel
, insn
);
1339 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
1340 the modifications into the change group. Return false if we did
1341 not see how to do that. */
1344 redirect_jump_1 (rtx jump
, rtx nlabel
)
1346 int ochanges
= num_validated_changes ();
1349 if (GET_CODE (PATTERN (jump
)) == PARALLEL
)
1350 loc
= &XVECEXP (PATTERN (jump
), 0, 0);
1352 loc
= &PATTERN (jump
);
1354 redirect_exp_1 (loc
, JUMP_LABEL (jump
), nlabel
, jump
);
1355 return num_validated_changes () > ochanges
;
1358 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
1359 jump target label is unused as a result, it and the code following
1362 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
1365 The return value will be 1 if the change was made, 0 if it wasn't
1366 (this can only occur for NLABEL == 0). */
1369 redirect_jump (rtx jump
, rtx nlabel
, int delete_unused
)
1371 rtx olabel
= JUMP_LABEL (jump
);
1373 if (nlabel
== olabel
)
1376 if (! redirect_jump_1 (jump
, nlabel
) || ! apply_change_group ())
1379 redirect_jump_2 (jump
, olabel
, nlabel
, delete_unused
, 0);
1383 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1385 If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1386 count has dropped to zero. */
1388 redirect_jump_2 (rtx jump
, rtx olabel
, rtx nlabel
, int delete_unused
,
1393 gcc_assert (JUMP_LABEL (jump
) == olabel
);
1395 /* Negative DELETE_UNUSED used to be used to signalize behavior on
1396 moving FUNCTION_END note. Just sanity check that no user still worry
1398 gcc_assert (delete_unused
>= 0);
1399 JUMP_LABEL (jump
) = nlabel
;
1401 ++LABEL_NUSES (nlabel
);
1403 /* Update labels in any REG_EQUAL note. */
1404 if ((note
= find_reg_note (jump
, REG_EQUAL
, NULL_RTX
)) != NULL_RTX
)
1406 if (!nlabel
|| (invert
&& !invert_exp_1 (XEXP (note
, 0), jump
)))
1407 remove_note (jump
, note
);
1410 redirect_exp_1 (&XEXP (note
, 0), olabel
, nlabel
, jump
);
1411 confirm_change_group ();
1415 if (olabel
&& --LABEL_NUSES (olabel
) == 0 && delete_unused
> 0
1416 /* Undefined labels will remain outside the insn stream. */
1417 && INSN_UID (olabel
))
1418 delete_related_insns (olabel
);
1420 invert_br_probabilities (jump
);
1423 /* Invert the jump condition X contained in jump insn INSN. Accrue the
1424 modifications into the change group. Return nonzero for success. */
1426 invert_exp_1 (rtx x
, rtx insn
)
1428 RTX_CODE code
= GET_CODE (x
);
1430 if (code
== IF_THEN_ELSE
)
1432 rtx comp
= XEXP (x
, 0);
1434 enum rtx_code reversed_code
;
1436 /* We can do this in two ways: The preferable way, which can only
1437 be done if this is not an integer comparison, is to reverse
1438 the comparison code. Otherwise, swap the THEN-part and ELSE-part
1439 of the IF_THEN_ELSE. If we can't do either, fail. */
1441 reversed_code
= reversed_comparison_code (comp
, insn
);
1443 if (reversed_code
!= UNKNOWN
)
1445 validate_change (insn
, &XEXP (x
, 0),
1446 gen_rtx_fmt_ee (reversed_code
,
1447 GET_MODE (comp
), XEXP (comp
, 0),
1454 validate_change (insn
, &XEXP (x
, 1), XEXP (x
, 2), 1);
1455 validate_change (insn
, &XEXP (x
, 2), tem
, 1);
1462 /* Invert the condition of the jump JUMP, and make it jump to label
1463 NLABEL instead of where it jumps now. Accrue changes into the
1464 change group. Return false if we didn't see how to perform the
1465 inversion and redirection. */
1468 invert_jump_1 (rtx jump
, rtx nlabel
)
1470 rtx x
= pc_set (jump
);
1474 ochanges
= num_validated_changes ();
1476 ok
= invert_exp_1 (SET_SRC (x
), jump
);
1479 if (num_validated_changes () == ochanges
)
1482 /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1483 in Pmode, so checking this is not merely an optimization. */
1484 return nlabel
== JUMP_LABEL (jump
) || redirect_jump_1 (jump
, nlabel
);
1487 /* Invert the condition of the jump JUMP, and make it jump to label
1488 NLABEL instead of where it jumps now. Return true if successful. */
1491 invert_jump (rtx jump
, rtx nlabel
, int delete_unused
)
1493 rtx olabel
= JUMP_LABEL (jump
);
1495 if (invert_jump_1 (jump
, nlabel
) && apply_change_group ())
1497 redirect_jump_2 (jump
, olabel
, nlabel
, delete_unused
, 1);
1505 /* Like rtx_equal_p except that it considers two REGs as equal
1506 if they renumber to the same value and considers two commutative
1507 operations to be the same if the order of the operands has been
1511 rtx_renumbered_equal_p (const_rtx x
, const_rtx y
)
1514 const enum rtx_code code
= GET_CODE (x
);
1520 if ((code
== REG
|| (code
== SUBREG
&& REG_P (SUBREG_REG (x
))))
1521 && (REG_P (y
) || (GET_CODE (y
) == SUBREG
1522 && REG_P (SUBREG_REG (y
)))))
1524 int reg_x
= -1, reg_y
= -1;
1525 int byte_x
= 0, byte_y
= 0;
1527 if (GET_MODE (x
) != GET_MODE (y
))
1530 /* If we haven't done any renumbering, don't
1531 make any assumptions. */
1532 if (reg_renumber
== 0)
1533 return rtx_equal_p (x
, y
);
1537 reg_x
= REGNO (SUBREG_REG (x
));
1538 byte_x
= SUBREG_BYTE (x
);
1540 if (reg_renumber
[reg_x
] >= 0)
1542 reg_x
= subreg_regno_offset (reg_renumber
[reg_x
],
1543 GET_MODE (SUBREG_REG (x
)),
1552 if (reg_renumber
[reg_x
] >= 0)
1553 reg_x
= reg_renumber
[reg_x
];
1556 if (GET_CODE (y
) == SUBREG
)
1558 reg_y
= REGNO (SUBREG_REG (y
));
1559 byte_y
= SUBREG_BYTE (y
);
1561 if (reg_renumber
[reg_y
] >= 0)
1563 reg_y
= subreg_regno_offset (reg_renumber
[reg_y
],
1564 GET_MODE (SUBREG_REG (y
)),
1573 if (reg_renumber
[reg_y
] >= 0)
1574 reg_y
= reg_renumber
[reg_y
];
1577 return reg_x
>= 0 && reg_x
== reg_y
&& byte_x
== byte_y
;
1580 /* Now we have disposed of all the cases
1581 in which different rtx codes can match. */
1582 if (code
!= GET_CODE (y
))
1596 /* We can't assume nonlocal labels have their following insns yet. */
1597 if (LABEL_REF_NONLOCAL_P (x
) || LABEL_REF_NONLOCAL_P (y
))
1598 return XEXP (x
, 0) == XEXP (y
, 0);
1600 /* Two label-refs are equivalent if they point at labels
1601 in the same position in the instruction stream. */
1602 return (next_real_insn (XEXP (x
, 0))
1603 == next_real_insn (XEXP (y
, 0)));
1606 return XSTR (x
, 0) == XSTR (y
, 0);
1609 /* If we didn't match EQ equality above, they aren't the same. */
1616 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
1618 if (GET_MODE (x
) != GET_MODE (y
))
1621 /* For commutative operations, the RTX match if the operand match in any
1622 order. Also handle the simple binary and unary cases without a loop. */
1623 if (targetm
.commutative_p (x
, UNKNOWN
))
1624 return ((rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0))
1625 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 1)))
1626 || (rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 1))
1627 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 0))));
1628 else if (NON_COMMUTATIVE_P (x
))
1629 return (rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0))
1630 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 1)));
1631 else if (UNARY_P (x
))
1632 return rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0));
1634 /* Compare the elements. If any pair of corresponding elements
1635 fail to match, return 0 for the whole things. */
1637 fmt
= GET_RTX_FORMAT (code
);
1638 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1644 if (XWINT (x
, i
) != XWINT (y
, i
))
1649 if (XINT (x
, i
) != XINT (y
, i
))
1654 if (XTREE (x
, i
) != XTREE (y
, i
))
1659 if (strcmp (XSTR (x
, i
), XSTR (y
, i
)))
1664 if (! rtx_renumbered_equal_p (XEXP (x
, i
), XEXP (y
, i
)))
1669 if (XEXP (x
, i
) != XEXP (y
, i
))
1676 if (XVECLEN (x
, i
) != XVECLEN (y
, i
))
1678 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
1679 if (!rtx_renumbered_equal_p (XVECEXP (x
, i
, j
), XVECEXP (y
, i
, j
)))
1690 /* If X is a hard register or equivalent to one or a subregister of one,
1691 return the hard register number. If X is a pseudo register that was not
1692 assigned a hard register, return the pseudo register number. Otherwise,
1693 return -1. Any rtx is valid for X. */
1696 true_regnum (const_rtx x
)
1700 if (REGNO (x
) >= FIRST_PSEUDO_REGISTER
&& reg_renumber
[REGNO (x
)] >= 0)
1701 return reg_renumber
[REGNO (x
)];
1704 if (GET_CODE (x
) == SUBREG
)
1706 int base
= true_regnum (SUBREG_REG (x
));
1708 && base
< FIRST_PSEUDO_REGISTER
1709 && subreg_offset_representable_p (REGNO (SUBREG_REG (x
)),
1710 GET_MODE (SUBREG_REG (x
)),
1711 SUBREG_BYTE (x
), GET_MODE (x
)))
1712 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
1713 GET_MODE (SUBREG_REG (x
)),
1714 SUBREG_BYTE (x
), GET_MODE (x
));
1719 /* Return regno of the register REG and handle subregs too. */
1721 reg_or_subregno (const_rtx reg
)
1723 if (GET_CODE (reg
) == SUBREG
)
1724 reg
= SUBREG_REG (reg
);
1725 gcc_assert (REG_P (reg
));