1 /* Optimize jump instructions, for GNU compiler.
2 Copyright (C) 1987-2014 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 /* This is the pathetic reminder of old fame of the jump-optimization pass
21 of the compiler. Now it contains basically a set of utility functions to
24 Each CODE_LABEL has a count of the times it is used
25 stored in the LABEL_NUSES internal field, and each JUMP_INSN
26 has one label that it refers to stored in the
27 JUMP_LABEL internal field. With this we can detect labels that
28 become unused because of the deletion of all the jumps that
29 formerly used them. The JUMP_LABEL info is sometimes looked
30 at by later passes. For return insns, it contains either a
31 RETURN or a SIMPLE_RETURN rtx.
33 The subroutines redirect_jump and invert_jump are used
34 from other passes as well. */
38 #include "coretypes.h"
43 #include "hard-reg-set.h"
45 #include "insn-config.h"
46 #include "insn-attr.h"
49 #include "basic-block.h"
52 #include "diagnostic-core.h"
55 #include "tree-pass.h"
58 /* Optimize jump y; x: ... y: jumpif... x?
59 Don't know if it is worth bothering with. */
60 /* Optimize two cases of conditional jump to conditional jump?
61 This can never delete any instruction or make anything dead,
62 or even change what is live at any point.
63 So perhaps let combiner do it. */
65 static void init_label_info (rtx
);
66 static void mark_all_labels (rtx
);
67 static void mark_jump_label_1 (rtx
, rtx
, bool, bool);
68 static void mark_jump_label_asm (rtx
, rtx
);
69 static void redirect_exp_1 (rtx
*, rtx
, rtx
, rtx
);
70 static int invert_exp_1 (rtx
, rtx
);
71 static int returnjump_p_1 (rtx
*, void *);
73 /* Worker for rebuild_jump_labels and rebuild_jump_labels_chain. */
75 rebuild_jump_labels_1 (rtx f
, bool count_forced
)
79 timevar_push (TV_REBUILD_JUMP
);
83 /* Keep track of labels used from static data; we don't track them
84 closely enough to delete them here, so make sure their reference
85 count doesn't drop to zero. */
88 for (insn
= forced_labels
; insn
; insn
= XEXP (insn
, 1))
89 if (LABEL_P (XEXP (insn
, 0)))
90 LABEL_NUSES (XEXP (insn
, 0))++;
91 timevar_pop (TV_REBUILD_JUMP
);
94 /* This function rebuilds the JUMP_LABEL field and REG_LABEL_TARGET
95 notes in jumping insns and REG_LABEL_OPERAND notes in non-jumping
96 instructions and jumping insns that have labels as operands
99 rebuild_jump_labels (rtx f
)
101 rebuild_jump_labels_1 (f
, true);
104 /* This function is like rebuild_jump_labels, but doesn't run over
105 forced_labels. It can be used on insn chains that aren't the
106 main function chain. */
108 rebuild_jump_labels_chain (rtx chain
)
110 rebuild_jump_labels_1 (chain
, false);
113 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
114 non-fallthru insn. This is not generally true, as multiple barriers
115 may have crept in, or the BARRIER may be separated from the last
116 real insn by one or more NOTEs.
118 This simple pass moves barriers and removes duplicates so that the
122 cleanup_barriers (void)
124 rtx insn
, next
, prev
;
125 for (insn
= get_insns (); insn
; insn
= next
)
127 next
= NEXT_INSN (insn
);
128 if (BARRIER_P (insn
))
130 prev
= prev_nonnote_insn (insn
);
133 if (BARRIER_P (prev
))
135 else if (prev
!= PREV_INSN (insn
))
136 reorder_insns_nobb (insn
, insn
, prev
);
144 const pass_data pass_data_cleanup_barriers
=
147 "barriers", /* name */
148 OPTGROUP_NONE
, /* optinfo_flags */
149 true, /* has_execute */
151 0, /* properties_required */
152 0, /* properties_provided */
153 0, /* properties_destroyed */
154 0, /* todo_flags_start */
155 0, /* todo_flags_finish */
158 class pass_cleanup_barriers
: public rtl_opt_pass
161 pass_cleanup_barriers (gcc::context
*ctxt
)
162 : rtl_opt_pass (pass_data_cleanup_barriers
, ctxt
)
165 /* opt_pass methods: */
166 virtual unsigned int execute (function
*) { return cleanup_barriers (); }
168 }; // class pass_cleanup_barriers
173 make_pass_cleanup_barriers (gcc::context
*ctxt
)
175 return new pass_cleanup_barriers (ctxt
);
179 /* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
180 for remaining targets for JUMP_P. Delete any REG_LABEL_OPERAND
181 notes whose labels don't occur in the insn any more. */
184 init_label_info (rtx f
)
188 for (insn
= f
; insn
; insn
= NEXT_INSN (insn
))
191 LABEL_NUSES (insn
) = (LABEL_PRESERVE_P (insn
) != 0);
193 /* REG_LABEL_TARGET notes (including the JUMP_LABEL field) are
194 sticky and not reset here; that way we won't lose association
195 with a label when e.g. the source for a target register
196 disappears out of reach for targets that may use jump-target
197 registers. Jump transformations are supposed to transform
198 any REG_LABEL_TARGET notes. The target label reference in a
199 branch may disappear from the branch (and from the
200 instruction before it) for other reasons, like register
207 for (note
= REG_NOTES (insn
); note
; note
= next
)
209 next
= XEXP (note
, 1);
210 if (REG_NOTE_KIND (note
) == REG_LABEL_OPERAND
211 && ! reg_mentioned_p (XEXP (note
, 0), PATTERN (insn
)))
212 remove_note (insn
, note
);
218 /* A subroutine of mark_all_labels. Trivially propagate a simple label
219 load into a jump_insn that uses it. */
222 maybe_propagate_label_ref (rtx jump_insn
, rtx prev_nonjump_insn
)
224 rtx label_note
, pc
, pc_src
;
226 pc
= pc_set (jump_insn
);
227 pc_src
= pc
!= NULL
? SET_SRC (pc
) : NULL
;
228 label_note
= find_reg_note (prev_nonjump_insn
, REG_LABEL_OPERAND
, NULL
);
230 /* If the previous non-jump insn sets something to a label,
231 something that this jump insn uses, make that label the primary
232 target of this insn if we don't yet have any. That previous
233 insn must be a single_set and not refer to more than one label.
234 The jump insn must not refer to other labels as jump targets
235 and must be a plain (set (pc) ...), maybe in a parallel, and
236 may refer to the item being set only directly or as one of the
237 arms in an IF_THEN_ELSE. */
239 if (label_note
!= NULL
&& pc_src
!= NULL
)
241 rtx label_set
= single_set (prev_nonjump_insn
);
242 rtx label_dest
= label_set
!= NULL
? SET_DEST (label_set
) : NULL
;
244 if (label_set
!= NULL
245 /* The source must be the direct LABEL_REF, not a
246 PLUS, UNSPEC, IF_THEN_ELSE etc. */
247 && GET_CODE (SET_SRC (label_set
)) == LABEL_REF
248 && (rtx_equal_p (label_dest
, pc_src
)
249 || (GET_CODE (pc_src
) == IF_THEN_ELSE
250 && (rtx_equal_p (label_dest
, XEXP (pc_src
, 1))
251 || rtx_equal_p (label_dest
, XEXP (pc_src
, 2))))))
253 /* The CODE_LABEL referred to in the note must be the
254 CODE_LABEL in the LABEL_REF of the "set". We can
255 conveniently use it for the marker function, which
256 requires a LABEL_REF wrapping. */
257 gcc_assert (XEXP (label_note
, 0) == XEXP (SET_SRC (label_set
), 0));
259 mark_jump_label_1 (label_set
, jump_insn
, false, true);
261 gcc_assert (JUMP_LABEL (jump_insn
) == XEXP (label_note
, 0));
266 /* Mark the label each jump jumps to.
267 Combine consecutive labels, and count uses of labels. */
270 mark_all_labels (rtx f
)
274 if (current_ir_type () == IR_RTL_CFGLAYOUT
)
277 FOR_EACH_BB_FN (bb
, cfun
)
279 /* In cfglayout mode, we don't bother with trivial next-insn
280 propagation of LABEL_REFs into JUMP_LABEL. This will be
281 handled by other optimizers using better algorithms. */
282 FOR_BB_INSNS (bb
, insn
)
284 gcc_assert (! INSN_DELETED_P (insn
));
285 if (NONDEBUG_INSN_P (insn
))
286 mark_jump_label (PATTERN (insn
), insn
, 0);
289 /* In cfglayout mode, there may be non-insns between the
290 basic blocks. If those non-insns represent tablejump data,
291 they contain label references that we must record. */
292 for (insn
= BB_HEADER (bb
); insn
; insn
= NEXT_INSN (insn
))
293 if (JUMP_TABLE_DATA_P (insn
))
294 mark_jump_label (PATTERN (insn
), insn
, 0);
295 for (insn
= BB_FOOTER (bb
); insn
; insn
= NEXT_INSN (insn
))
296 if (JUMP_TABLE_DATA_P (insn
))
297 mark_jump_label (PATTERN (insn
), insn
, 0);
302 rtx prev_nonjump_insn
= NULL
;
303 for (insn
= f
; insn
; insn
= NEXT_INSN (insn
))
305 if (INSN_DELETED_P (insn
))
307 else if (LABEL_P (insn
))
308 prev_nonjump_insn
= NULL
;
309 else if (JUMP_TABLE_DATA_P (insn
))
310 mark_jump_label (PATTERN (insn
), insn
, 0);
311 else if (NONDEBUG_INSN_P (insn
))
313 mark_jump_label (PATTERN (insn
), insn
, 0);
316 if (JUMP_LABEL (insn
) == NULL
&& prev_nonjump_insn
!= NULL
)
317 maybe_propagate_label_ref (insn
, prev_nonjump_insn
);
320 prev_nonjump_insn
= insn
;
326 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
327 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
328 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
329 know whether it's source is floating point or integer comparison. Machine
330 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
331 to help this function avoid overhead in these cases. */
333 reversed_comparison_code_parts (enum rtx_code code
, const_rtx arg0
,
334 const_rtx arg1
, const_rtx insn
)
336 enum machine_mode mode
;
338 /* If this is not actually a comparison, we can't reverse it. */
339 if (GET_RTX_CLASS (code
) != RTX_COMPARE
340 && GET_RTX_CLASS (code
) != RTX_COMM_COMPARE
)
343 mode
= GET_MODE (arg0
);
344 if (mode
== VOIDmode
)
345 mode
= GET_MODE (arg1
);
347 /* First see if machine description supplies us way to reverse the
348 comparison. Give it priority over everything else to allow
349 machine description to do tricks. */
350 if (GET_MODE_CLASS (mode
) == MODE_CC
351 && REVERSIBLE_CC_MODE (mode
))
353 #ifdef REVERSE_CONDITION
354 return REVERSE_CONDITION (code
, mode
);
356 return reverse_condition (code
);
360 /* Try a few special cases based on the comparison code. */
369 /* It is always safe to reverse EQ and NE, even for the floating
370 point. Similarly the unsigned comparisons are never used for
371 floating point so we can reverse them in the default way. */
372 return reverse_condition (code
);
377 /* In case we already see unordered comparison, we can be sure to
378 be dealing with floating point so we don't need any more tests. */
379 return reverse_condition_maybe_unordered (code
);
384 /* We don't have safe way to reverse these yet. */
390 if (GET_MODE_CLASS (mode
) == MODE_CC
|| CC0_P (arg0
))
393 /* Try to search for the comparison to determine the real mode.
394 This code is expensive, but with sane machine description it
395 will be never used, since REVERSIBLE_CC_MODE will return true
400 /* These CONST_CAST's are okay because prev_nonnote_insn just
401 returns its argument and we assign it to a const_rtx
403 for (prev
= prev_nonnote_insn (CONST_CAST_RTX (insn
));
404 prev
!= 0 && !LABEL_P (prev
);
405 prev
= prev_nonnote_insn (CONST_CAST_RTX (prev
)))
407 const_rtx set
= set_of (arg0
, prev
);
408 if (set
&& GET_CODE (set
) == SET
409 && rtx_equal_p (SET_DEST (set
), arg0
))
411 rtx src
= SET_SRC (set
);
413 if (GET_CODE (src
) == COMPARE
)
415 rtx comparison
= src
;
416 arg0
= XEXP (src
, 0);
417 mode
= GET_MODE (arg0
);
418 if (mode
== VOIDmode
)
419 mode
= GET_MODE (XEXP (comparison
, 1));
422 /* We can get past reg-reg moves. This may be useful for model
423 of i387 comparisons that first move flag registers around. */
430 /* If register is clobbered in some ununderstandable way,
437 /* Test for an integer condition, or a floating-point comparison
438 in which NaNs can be ignored. */
439 if (CONST_INT_P (arg0
)
440 || (GET_MODE (arg0
) != VOIDmode
441 && GET_MODE_CLASS (mode
) != MODE_CC
442 && !HONOR_NANS (mode
)))
443 return reverse_condition (code
);
448 /* A wrapper around the previous function to take COMPARISON as rtx
449 expression. This simplifies many callers. */
451 reversed_comparison_code (const_rtx comparison
, const_rtx insn
)
453 if (!COMPARISON_P (comparison
))
455 return reversed_comparison_code_parts (GET_CODE (comparison
),
456 XEXP (comparison
, 0),
457 XEXP (comparison
, 1), insn
);
460 /* Return comparison with reversed code of EXP.
461 Return NULL_RTX in case we fail to do the reversal. */
463 reversed_comparison (const_rtx exp
, enum machine_mode mode
)
465 enum rtx_code reversed_code
= reversed_comparison_code (exp
, NULL_RTX
);
466 if (reversed_code
== UNKNOWN
)
469 return simplify_gen_relational (reversed_code
, mode
, VOIDmode
,
470 XEXP (exp
, 0), XEXP (exp
, 1));
474 /* Given an rtx-code for a comparison, return the code for the negated
475 comparison. If no such code exists, return UNKNOWN.
477 WATCH OUT! reverse_condition is not safe to use on a jump that might
478 be acting on the results of an IEEE floating point comparison, because
479 of the special treatment of non-signaling nans in comparisons.
480 Use reversed_comparison_code instead. */
483 reverse_condition (enum rtx_code code
)
525 /* Similar, but we're allowed to generate unordered comparisons, which
526 makes it safe for IEEE floating-point. Of course, we have to recognize
527 that the target will support them too... */
530 reverse_condition_maybe_unordered (enum rtx_code code
)
568 /* Similar, but return the code when two operands of a comparison are swapped.
569 This IS safe for IEEE floating-point. */
572 swap_condition (enum rtx_code code
)
614 /* Given a comparison CODE, return the corresponding unsigned comparison.
615 If CODE is an equality comparison or already an unsigned comparison,
619 unsigned_condition (enum rtx_code code
)
645 /* Similarly, return the signed version of a comparison. */
648 signed_condition (enum rtx_code code
)
674 /* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
675 truth of CODE1 implies the truth of CODE2. */
678 comparison_dominates_p (enum rtx_code code1
, enum rtx_code code2
)
680 /* UNKNOWN comparison codes can happen as a result of trying to revert
682 They can't match anything, so we have to reject them here. */
683 if (code1
== UNKNOWN
|| code2
== UNKNOWN
)
692 if (code2
== UNLE
|| code2
== UNGE
)
697 if (code2
== LE
|| code2
== LEU
|| code2
== GE
|| code2
== GEU
703 if (code2
== UNLE
|| code2
== NE
)
708 if (code2
== LE
|| code2
== NE
|| code2
== ORDERED
|| code2
== LTGT
)
713 if (code2
== UNGE
|| code2
== NE
)
718 if (code2
== GE
|| code2
== NE
|| code2
== ORDERED
|| code2
== LTGT
)
724 if (code2
== ORDERED
)
729 if (code2
== NE
|| code2
== ORDERED
)
734 if (code2
== LEU
|| code2
== NE
)
739 if (code2
== GEU
|| code2
== NE
)
744 if (code2
== NE
|| code2
== UNEQ
|| code2
== UNLE
|| code2
== UNLT
745 || code2
== UNGE
|| code2
== UNGT
)
756 /* Return 1 if INSN is an unconditional jump and nothing else. */
759 simplejump_p (const_rtx insn
)
761 return (JUMP_P (insn
)
762 && GET_CODE (PATTERN (insn
)) == SET
763 && GET_CODE (SET_DEST (PATTERN (insn
))) == PC
764 && GET_CODE (SET_SRC (PATTERN (insn
))) == LABEL_REF
);
767 /* Return nonzero if INSN is a (possibly) conditional jump
770 Use of this function is deprecated, since we need to support combined
771 branch and compare insns. Use any_condjump_p instead whenever possible. */
774 condjump_p (const_rtx insn
)
776 const_rtx x
= PATTERN (insn
);
778 if (GET_CODE (x
) != SET
779 || GET_CODE (SET_DEST (x
)) != PC
)
783 if (GET_CODE (x
) == LABEL_REF
)
786 return (GET_CODE (x
) == IF_THEN_ELSE
787 && ((GET_CODE (XEXP (x
, 2)) == PC
788 && (GET_CODE (XEXP (x
, 1)) == LABEL_REF
789 || ANY_RETURN_P (XEXP (x
, 1))))
790 || (GET_CODE (XEXP (x
, 1)) == PC
791 && (GET_CODE (XEXP (x
, 2)) == LABEL_REF
792 || ANY_RETURN_P (XEXP (x
, 2))))));
795 /* Return nonzero if INSN is a (possibly) conditional jump inside a
798 Use this function is deprecated, since we need to support combined
799 branch and compare insns. Use any_condjump_p instead whenever possible. */
802 condjump_in_parallel_p (const_rtx insn
)
804 const_rtx x
= PATTERN (insn
);
806 if (GET_CODE (x
) != PARALLEL
)
809 x
= XVECEXP (x
, 0, 0);
811 if (GET_CODE (x
) != SET
)
813 if (GET_CODE (SET_DEST (x
)) != PC
)
815 if (GET_CODE (SET_SRC (x
)) == LABEL_REF
)
817 if (GET_CODE (SET_SRC (x
)) != IF_THEN_ELSE
)
819 if (XEXP (SET_SRC (x
), 2) == pc_rtx
820 && (GET_CODE (XEXP (SET_SRC (x
), 1)) == LABEL_REF
821 || ANY_RETURN_P (XEXP (SET_SRC (x
), 1))))
823 if (XEXP (SET_SRC (x
), 1) == pc_rtx
824 && (GET_CODE (XEXP (SET_SRC (x
), 2)) == LABEL_REF
825 || ANY_RETURN_P (XEXP (SET_SRC (x
), 2))))
830 /* Return set of PC, otherwise NULL. */
833 pc_set (const_rtx insn
)
838 pat
= PATTERN (insn
);
840 /* The set is allowed to appear either as the insn pattern or
841 the first set in a PARALLEL. */
842 if (GET_CODE (pat
) == PARALLEL
)
843 pat
= XVECEXP (pat
, 0, 0);
844 if (GET_CODE (pat
) == SET
&& GET_CODE (SET_DEST (pat
)) == PC
)
850 /* Return true when insn is an unconditional direct jump,
851 possibly bundled inside a PARALLEL. */
854 any_uncondjump_p (const_rtx insn
)
856 const_rtx x
= pc_set (insn
);
859 if (GET_CODE (SET_SRC (x
)) != LABEL_REF
)
861 if (find_reg_note (insn
, REG_NON_LOCAL_GOTO
, NULL_RTX
))
866 /* Return true when insn is a conditional jump. This function works for
867 instructions containing PC sets in PARALLELs. The instruction may have
868 various other effects so before removing the jump you must verify
871 Note that unlike condjump_p it returns false for unconditional jumps. */
874 any_condjump_p (const_rtx insn
)
876 const_rtx x
= pc_set (insn
);
881 if (GET_CODE (SET_SRC (x
)) != IF_THEN_ELSE
)
884 a
= GET_CODE (XEXP (SET_SRC (x
), 1));
885 b
= GET_CODE (XEXP (SET_SRC (x
), 2));
887 return ((b
== PC
&& (a
== LABEL_REF
|| a
== RETURN
|| a
== SIMPLE_RETURN
))
889 && (b
== LABEL_REF
|| b
== RETURN
|| b
== SIMPLE_RETURN
)));
892 /* Return the label of a conditional jump. */
895 condjump_label (const_rtx insn
)
897 rtx x
= pc_set (insn
);
902 if (GET_CODE (x
) == LABEL_REF
)
904 if (GET_CODE (x
) != IF_THEN_ELSE
)
906 if (XEXP (x
, 2) == pc_rtx
&& GET_CODE (XEXP (x
, 1)) == LABEL_REF
)
908 if (XEXP (x
, 1) == pc_rtx
&& GET_CODE (XEXP (x
, 2)) == LABEL_REF
)
913 /* Return true if INSN is a (possibly conditional) return insn. */
916 returnjump_p_1 (rtx
*loc
, void *data ATTRIBUTE_UNUSED
)
923 switch (GET_CODE (x
))
931 return SET_IS_RETURN_P (x
);
938 /* Return TRUE if INSN is a return jump. */
941 returnjump_p (rtx insn
)
945 return for_each_rtx (&PATTERN (insn
), returnjump_p_1
, NULL
);
948 /* Return true if INSN is a (possibly conditional) return insn. */
951 eh_returnjump_p_1 (rtx
*loc
, void *data ATTRIBUTE_UNUSED
)
953 return *loc
&& GET_CODE (*loc
) == EH_RETURN
;
957 eh_returnjump_p (rtx insn
)
961 return for_each_rtx (&PATTERN (insn
), eh_returnjump_p_1
, NULL
);
964 /* Return true if INSN is a jump that only transfers control and
968 onlyjump_p (const_rtx insn
)
975 set
= single_set (insn
);
978 if (GET_CODE (SET_DEST (set
)) != PC
)
980 if (side_effects_p (SET_SRC (set
)))
986 /* Return true iff INSN is a jump and its JUMP_LABEL is a label, not
989 jump_to_label_p (rtx insn
)
991 return (JUMP_P (insn
)
992 && JUMP_LABEL (insn
) != NULL
&& !ANY_RETURN_P (JUMP_LABEL (insn
)));
997 /* Return nonzero if X is an RTX that only sets the condition codes
998 and has no side effects. */
1001 only_sets_cc0_p (const_rtx x
)
1009 return sets_cc0_p (x
) == 1 && ! side_effects_p (x
);
1012 /* Return 1 if X is an RTX that does nothing but set the condition codes
1013 and CLOBBER or USE registers.
1014 Return -1 if X does explicitly set the condition codes,
1015 but also does other things. */
1018 sets_cc0_p (const_rtx x
)
1026 if (GET_CODE (x
) == SET
&& SET_DEST (x
) == cc0_rtx
)
1028 if (GET_CODE (x
) == PARALLEL
)
1032 int other_things
= 0;
1033 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
1035 if (GET_CODE (XVECEXP (x
, 0, i
)) == SET
1036 && SET_DEST (XVECEXP (x
, 0, i
)) == cc0_rtx
)
1038 else if (GET_CODE (XVECEXP (x
, 0, i
)) == SET
)
1041 return ! sets_cc0
? 0 : other_things
? -1 : 1;
1047 /* Find all CODE_LABELs referred to in X, and increment their use
1048 counts. If INSN is a JUMP_INSN and there is at least one
1049 CODE_LABEL referenced in INSN as a jump target, then store the last
1050 one in JUMP_LABEL (INSN). For a tablejump, this must be the label
1051 for the ADDR_VEC. Store any other jump targets as REG_LABEL_TARGET
1052 notes. If INSN is an INSN or a CALL_INSN or non-target operands of
1053 a JUMP_INSN, and there is at least one CODE_LABEL referenced in
1054 INSN, add a REG_LABEL_OPERAND note containing that label to INSN.
1055 For returnjumps, the JUMP_LABEL will also be set as appropriate.
1057 Note that two labels separated by a loop-beginning note
1058 must be kept distinct if we have not yet done loop-optimization,
1059 because the gap between them is where loop-optimize
1060 will want to move invariant code to. CROSS_JUMP tells us
1061 that loop-optimization is done with. */
1064 mark_jump_label (rtx x
, rtx insn
, int in_mem
)
1066 rtx asmop
= extract_asm_operands (x
);
1068 mark_jump_label_asm (asmop
, insn
);
1070 mark_jump_label_1 (x
, insn
, in_mem
!= 0,
1071 (insn
!= NULL
&& x
== PATTERN (insn
) && JUMP_P (insn
)));
1074 /* Worker function for mark_jump_label. IN_MEM is TRUE when X occurs
1075 within a (MEM ...). IS_TARGET is TRUE when X is to be treated as a
1076 jump-target; when the JUMP_LABEL field of INSN should be set or a
1077 REG_LABEL_TARGET note should be added, not a REG_LABEL_OPERAND
1081 mark_jump_label_1 (rtx x
, rtx insn
, bool in_mem
, bool is_target
)
1083 RTX_CODE code
= GET_CODE (x
);
1100 gcc_assert (JUMP_LABEL (insn
) == NULL
|| JUMP_LABEL (insn
) == x
);
1101 JUMP_LABEL (insn
) = x
;
1110 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
1111 mark_jump_label (PATTERN (XVECEXP (x
, 0, i
)),
1112 XVECEXP (x
, 0, i
), 0);
1119 /* If this is a constant-pool reference, see if it is a label. */
1120 if (CONSTANT_POOL_ADDRESS_P (x
))
1121 mark_jump_label_1 (get_pool_constant (x
), insn
, in_mem
, is_target
);
1124 /* Handle operands in the condition of an if-then-else as for a
1129 mark_jump_label_1 (XEXP (x
, 0), insn
, in_mem
, false);
1130 mark_jump_label_1 (XEXP (x
, 1), insn
, in_mem
, true);
1131 mark_jump_label_1 (XEXP (x
, 2), insn
, in_mem
, true);
1136 rtx label
= XEXP (x
, 0);
1138 /* Ignore remaining references to unreachable labels that
1139 have been deleted. */
1141 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
)
1144 gcc_assert (LABEL_P (label
));
1146 /* Ignore references to labels of containing functions. */
1147 if (LABEL_REF_NONLOCAL_P (x
))
1150 XEXP (x
, 0) = label
;
1151 if (! insn
|| ! INSN_DELETED_P (insn
))
1152 ++LABEL_NUSES (label
);
1157 /* Do not change a previous setting of JUMP_LABEL. If the
1158 JUMP_LABEL slot is occupied by a different label,
1159 create a note for this label. */
1160 && (JUMP_LABEL (insn
) == NULL
|| JUMP_LABEL (insn
) == label
))
1161 JUMP_LABEL (insn
) = label
;
1165 = is_target
? REG_LABEL_TARGET
: REG_LABEL_OPERAND
;
1167 /* Add a REG_LABEL_OPERAND or REG_LABEL_TARGET note
1168 for LABEL unless there already is one. All uses of
1169 a label, except for the primary target of a jump,
1170 must have such a note. */
1171 if (! find_reg_note (insn
, kind
, label
))
1172 add_reg_note (insn
, kind
, label
);
1178 /* Do walk the labels in a vector, but not the first operand of an
1179 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1182 if (! INSN_DELETED_P (insn
))
1184 int eltnum
= code
== ADDR_DIFF_VEC
? 1 : 0;
1186 for (i
= 0; i
< XVECLEN (x
, eltnum
); i
++)
1187 mark_jump_label_1 (XVECEXP (x
, eltnum
, i
), NULL_RTX
, in_mem
,
1196 fmt
= GET_RTX_FORMAT (code
);
1198 /* The primary target of a tablejump is the label of the ADDR_VEC,
1199 which is canonically mentioned *last* in the insn. To get it
1200 marked as JUMP_LABEL, we iterate over items in reverse order. */
1201 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1204 mark_jump_label_1 (XEXP (x
, i
), insn
, in_mem
, is_target
);
1205 else if (fmt
[i
] == 'E')
1209 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
1210 mark_jump_label_1 (XVECEXP (x
, i
, j
), insn
, in_mem
,
1216 /* Worker function for mark_jump_label. Handle asm insns specially.
1217 In particular, output operands need not be considered so we can
1218 avoid re-scanning the replicated asm_operand. Also, the asm_labels
1219 need to be considered targets. */
1222 mark_jump_label_asm (rtx asmop
, rtx insn
)
1226 for (i
= ASM_OPERANDS_INPUT_LENGTH (asmop
) - 1; i
>= 0; --i
)
1227 mark_jump_label_1 (ASM_OPERANDS_INPUT (asmop
, i
), insn
, false, false);
1229 for (i
= ASM_OPERANDS_LABEL_LENGTH (asmop
) - 1; i
>= 0; --i
)
1230 mark_jump_label_1 (ASM_OPERANDS_LABEL (asmop
, i
), insn
, false, true);
1233 /* Delete insn INSN from the chain of insns and update label ref counts
1234 and delete insns now unreachable.
1236 Returns the first insn after INSN that was not deleted.
1238 Usage of this instruction is deprecated. Use delete_insn instead and
1239 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1242 delete_related_insns (rtx insn
)
1244 int was_code_label
= (LABEL_P (insn
));
1246 rtx next
= NEXT_INSN (insn
), prev
= PREV_INSN (insn
);
1248 while (next
&& INSN_DELETED_P (next
))
1249 next
= NEXT_INSN (next
);
1251 /* This insn is already deleted => return first following nondeleted. */
1252 if (INSN_DELETED_P (insn
))
1257 /* If instruction is followed by a barrier,
1258 delete the barrier too. */
1260 if (next
!= 0 && BARRIER_P (next
))
1263 /* If this is a call, then we have to remove the var tracking note
1264 for the call arguments. */
1267 || (NONJUMP_INSN_P (insn
)
1268 && GET_CODE (PATTERN (insn
)) == SEQUENCE
1269 && CALL_P (XVECEXP (PATTERN (insn
), 0, 0))))
1273 for (p
= next
&& INSN_DELETED_P (next
) ? NEXT_INSN (next
) : next
;
1276 if (NOTE_KIND (p
) == NOTE_INSN_CALL_ARG_LOCATION
)
1283 /* If deleting a jump, decrement the count of the label,
1284 and delete the label if it is now unused. */
1286 if (jump_to_label_p (insn
))
1288 rtx lab
= JUMP_LABEL (insn
), lab_next
;
1290 if (LABEL_NUSES (lab
) == 0)
1291 /* This can delete NEXT or PREV,
1292 either directly if NEXT is JUMP_LABEL (INSN),
1293 or indirectly through more levels of jumps. */
1294 delete_related_insns (lab
);
1295 else if (tablejump_p (insn
, NULL
, &lab_next
))
1297 /* If we're deleting the tablejump, delete the dispatch table.
1298 We may not be able to kill the label immediately preceding
1299 just yet, as it might be referenced in code leading up to
1301 delete_related_insns (lab_next
);
1305 /* Likewise if we're deleting a dispatch table. */
1307 if (JUMP_TABLE_DATA_P (insn
))
1309 rtx pat
= PATTERN (insn
);
1310 int i
, diff_vec_p
= GET_CODE (pat
) == ADDR_DIFF_VEC
;
1311 int len
= XVECLEN (pat
, diff_vec_p
);
1313 for (i
= 0; i
< len
; i
++)
1314 if (LABEL_NUSES (XEXP (XVECEXP (pat
, diff_vec_p
, i
), 0)) == 0)
1315 delete_related_insns (XEXP (XVECEXP (pat
, diff_vec_p
, i
), 0));
1316 while (next
&& INSN_DELETED_P (next
))
1317 next
= NEXT_INSN (next
);
1321 /* Likewise for any JUMP_P / INSN / CALL_INSN with a
1322 REG_LABEL_OPERAND or REG_LABEL_TARGET note. */
1324 for (note
= REG_NOTES (insn
); note
; note
= XEXP (note
, 1))
1325 if ((REG_NOTE_KIND (note
) == REG_LABEL_OPERAND
1326 || REG_NOTE_KIND (note
) == REG_LABEL_TARGET
)
1327 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1328 && LABEL_P (XEXP (note
, 0)))
1329 if (LABEL_NUSES (XEXP (note
, 0)) == 0)
1330 delete_related_insns (XEXP (note
, 0));
1332 while (prev
&& (INSN_DELETED_P (prev
) || NOTE_P (prev
)))
1333 prev
= PREV_INSN (prev
);
1335 /* If INSN was a label and a dispatch table follows it,
1336 delete the dispatch table. The tablejump must have gone already.
1337 It isn't useful to fall through into a table. */
1340 && NEXT_INSN (insn
) != 0
1341 && JUMP_TABLE_DATA_P (NEXT_INSN (insn
)))
1342 next
= delete_related_insns (NEXT_INSN (insn
));
1344 /* If INSN was a label, delete insns following it if now unreachable. */
1346 if (was_code_label
&& prev
&& BARRIER_P (prev
))
1351 code
= GET_CODE (next
);
1353 next
= NEXT_INSN (next
);
1354 /* Keep going past other deleted labels to delete what follows. */
1355 else if (code
== CODE_LABEL
&& INSN_DELETED_P (next
))
1356 next
= NEXT_INSN (next
);
1357 /* Keep the (use (insn))s created by dbr_schedule, which needs
1358 them in order to track liveness relative to a previous
1360 else if (INSN_P (next
)
1361 && GET_CODE (PATTERN (next
)) == USE
1362 && INSN_P (XEXP (PATTERN (next
), 0)))
1363 next
= NEXT_INSN (next
);
1364 else if (code
== BARRIER
|| INSN_P (next
))
1365 /* Note: if this deletes a jump, it can cause more
1366 deletion of unreachable code, after a different label.
1367 As long as the value from this recursive call is correct,
1368 this invocation functions correctly. */
1369 next
= delete_related_insns (next
);
1375 /* I feel a little doubtful about this loop,
1376 but I see no clean and sure alternative way
1377 to find the first insn after INSN that is not now deleted.
1378 I hope this works. */
1379 while (next
&& INSN_DELETED_P (next
))
1380 next
= NEXT_INSN (next
);
1384 /* Delete a range of insns from FROM to TO, inclusive.
1385 This is for the sake of peephole optimization, so assume
1386 that whatever these insns do will still be done by a new
1387 peephole insn that will replace them. */
1390 delete_for_peephole (rtx from
, rtx to
)
1396 rtx next
= NEXT_INSN (insn
);
1397 rtx prev
= PREV_INSN (insn
);
1401 INSN_DELETED_P (insn
) = 1;
1403 /* Patch this insn out of the chain. */
1404 /* We don't do this all at once, because we
1405 must preserve all NOTEs. */
1407 NEXT_INSN (prev
) = next
;
1410 PREV_INSN (next
) = prev
;
1418 /* Note that if TO is an unconditional jump
1419 we *do not* delete the BARRIER that follows,
1420 since the peephole that replaces this sequence
1421 is also an unconditional jump in that case. */
1424 /* A helper function for redirect_exp_1; examines its input X and returns
1425 either a LABEL_REF around a label, or a RETURN if X was NULL. */
1427 redirect_target (rtx x
)
1431 if (!ANY_RETURN_P (x
))
1432 return gen_rtx_LABEL_REF (Pmode
, x
);
1436 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1437 NLABEL as a return. Accrue modifications into the change group. */
1440 redirect_exp_1 (rtx
*loc
, rtx olabel
, rtx nlabel
, rtx insn
)
1443 RTX_CODE code
= GET_CODE (x
);
1447 if ((code
== LABEL_REF
&& XEXP (x
, 0) == olabel
)
1450 x
= redirect_target (nlabel
);
1451 if (GET_CODE (x
) == LABEL_REF
&& loc
== &PATTERN (insn
))
1452 x
= gen_rtx_SET (VOIDmode
, pc_rtx
, x
);
1453 validate_change (insn
, loc
, x
, 1);
1457 if (code
== SET
&& SET_DEST (x
) == pc_rtx
1458 && ANY_RETURN_P (nlabel
)
1459 && GET_CODE (SET_SRC (x
)) == LABEL_REF
1460 && XEXP (SET_SRC (x
), 0) == olabel
)
1462 validate_change (insn
, loc
, nlabel
, 1);
1466 if (code
== IF_THEN_ELSE
)
1468 /* Skip the condition of an IF_THEN_ELSE. We only want to
1469 change jump destinations, not eventual label comparisons. */
1470 redirect_exp_1 (&XEXP (x
, 1), olabel
, nlabel
, insn
);
1471 redirect_exp_1 (&XEXP (x
, 2), olabel
, nlabel
, insn
);
1475 fmt
= GET_RTX_FORMAT (code
);
1476 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1479 redirect_exp_1 (&XEXP (x
, i
), olabel
, nlabel
, insn
);
1480 else if (fmt
[i
] == 'E')
1483 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1484 redirect_exp_1 (&XVECEXP (x
, i
, j
), olabel
, nlabel
, insn
);
1489 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
1490 the modifications into the change group. Return false if we did
1491 not see how to do that. */
1494 redirect_jump_1 (rtx jump
, rtx nlabel
)
1496 int ochanges
= num_validated_changes ();
1499 gcc_assert (nlabel
!= NULL_RTX
);
1500 asmop
= extract_asm_operands (PATTERN (jump
));
1505 gcc_assert (ASM_OPERANDS_LABEL_LENGTH (asmop
) == 1);
1506 loc
= &ASM_OPERANDS_LABEL (asmop
, 0);
1508 else if (GET_CODE (PATTERN (jump
)) == PARALLEL
)
1509 loc
= &XVECEXP (PATTERN (jump
), 0, 0);
1511 loc
= &PATTERN (jump
);
1513 redirect_exp_1 (loc
, JUMP_LABEL (jump
), nlabel
, jump
);
1514 return num_validated_changes () > ochanges
;
1517 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
1518 jump target label is unused as a result, it and the code following
1521 Normally, NLABEL will be a label, but it may also be a RETURN rtx;
1522 in that case we are to turn the jump into a (possibly conditional)
1525 The return value will be 1 if the change was made, 0 if it wasn't
1526 (this can only occur when trying to produce return insns). */
1529 redirect_jump (rtx jump
, rtx nlabel
, int delete_unused
)
1531 rtx olabel
= JUMP_LABEL (jump
);
1535 /* If there is no label, we are asked to redirect to the EXIT block.
1536 When before the epilogue is emitted, return/simple_return cannot be
1537 created so we return 0 immediately. After the epilogue is emitted,
1538 we always expect a label, either a non-null label, or a
1539 return/simple_return RTX. */
1541 if (!epilogue_completed
)
1546 if (nlabel
== olabel
)
1549 if (! redirect_jump_1 (jump
, nlabel
) || ! apply_change_group ())
1552 redirect_jump_2 (jump
, olabel
, nlabel
, delete_unused
, 0);
1556 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1558 If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1559 count has dropped to zero. */
1561 redirect_jump_2 (rtx jump
, rtx olabel
, rtx nlabel
, int delete_unused
,
1566 gcc_assert (JUMP_LABEL (jump
) == olabel
);
1568 /* Negative DELETE_UNUSED used to be used to signalize behavior on
1569 moving FUNCTION_END note. Just sanity check that no user still worry
1571 gcc_assert (delete_unused
>= 0);
1572 JUMP_LABEL (jump
) = nlabel
;
1573 if (!ANY_RETURN_P (nlabel
))
1574 ++LABEL_NUSES (nlabel
);
1576 /* Update labels in any REG_EQUAL note. */
1577 if ((note
= find_reg_note (jump
, REG_EQUAL
, NULL_RTX
)) != NULL_RTX
)
1579 if (ANY_RETURN_P (nlabel
)
1580 || (invert
&& !invert_exp_1 (XEXP (note
, 0), jump
)))
1581 remove_note (jump
, note
);
1584 redirect_exp_1 (&XEXP (note
, 0), olabel
, nlabel
, jump
);
1585 confirm_change_group ();
1589 /* Handle the case where we had a conditional crossing jump to a return
1590 label and are now changing it into a direct conditional return.
1591 The jump is no longer crossing in that case. */
1592 if (ANY_RETURN_P (nlabel
))
1594 note
= find_reg_note (jump
, REG_CROSSING_JUMP
, NULL_RTX
);
1596 remove_note (jump
, note
);
1599 if (!ANY_RETURN_P (olabel
)
1600 && --LABEL_NUSES (olabel
) == 0 && delete_unused
> 0
1601 /* Undefined labels will remain outside the insn stream. */
1602 && INSN_UID (olabel
))
1603 delete_related_insns (olabel
);
1605 invert_br_probabilities (jump
);
1608 /* Invert the jump condition X contained in jump insn INSN. Accrue the
1609 modifications into the change group. Return nonzero for success. */
1611 invert_exp_1 (rtx x
, rtx insn
)
1613 RTX_CODE code
= GET_CODE (x
);
1615 if (code
== IF_THEN_ELSE
)
1617 rtx comp
= XEXP (x
, 0);
1619 enum rtx_code reversed_code
;
1621 /* We can do this in two ways: The preferable way, which can only
1622 be done if this is not an integer comparison, is to reverse
1623 the comparison code. Otherwise, swap the THEN-part and ELSE-part
1624 of the IF_THEN_ELSE. If we can't do either, fail. */
1626 reversed_code
= reversed_comparison_code (comp
, insn
);
1628 if (reversed_code
!= UNKNOWN
)
1630 validate_change (insn
, &XEXP (x
, 0),
1631 gen_rtx_fmt_ee (reversed_code
,
1632 GET_MODE (comp
), XEXP (comp
, 0),
1639 validate_change (insn
, &XEXP (x
, 1), XEXP (x
, 2), 1);
1640 validate_change (insn
, &XEXP (x
, 2), tem
, 1);
1647 /* Invert the condition of the jump JUMP, and make it jump to label
1648 NLABEL instead of where it jumps now. Accrue changes into the
1649 change group. Return false if we didn't see how to perform the
1650 inversion and redirection. */
1653 invert_jump_1 (rtx jump
, rtx nlabel
)
1655 rtx x
= pc_set (jump
);
1659 ochanges
= num_validated_changes ();
1662 ok
= invert_exp_1 (SET_SRC (x
), jump
);
1665 if (num_validated_changes () == ochanges
)
1668 /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1669 in Pmode, so checking this is not merely an optimization. */
1670 return nlabel
== JUMP_LABEL (jump
) || redirect_jump_1 (jump
, nlabel
);
1673 /* Invert the condition of the jump JUMP, and make it jump to label
1674 NLABEL instead of where it jumps now. Return true if successful. */
1677 invert_jump (rtx jump
, rtx nlabel
, int delete_unused
)
1679 rtx olabel
= JUMP_LABEL (jump
);
1681 if (invert_jump_1 (jump
, nlabel
) && apply_change_group ())
1683 redirect_jump_2 (jump
, olabel
, nlabel
, delete_unused
, 1);
1691 /* Like rtx_equal_p except that it considers two REGs as equal
1692 if they renumber to the same value and considers two commutative
1693 operations to be the same if the order of the operands has been
1697 rtx_renumbered_equal_p (const_rtx x
, const_rtx y
)
1700 const enum rtx_code code
= GET_CODE (x
);
1706 if ((code
== REG
|| (code
== SUBREG
&& REG_P (SUBREG_REG (x
))))
1707 && (REG_P (y
) || (GET_CODE (y
) == SUBREG
1708 && REG_P (SUBREG_REG (y
)))))
1710 int reg_x
= -1, reg_y
= -1;
1711 int byte_x
= 0, byte_y
= 0;
1712 struct subreg_info info
;
1714 if (GET_MODE (x
) != GET_MODE (y
))
1717 /* If we haven't done any renumbering, don't
1718 make any assumptions. */
1719 if (reg_renumber
== 0)
1720 return rtx_equal_p (x
, y
);
1724 reg_x
= REGNO (SUBREG_REG (x
));
1725 byte_x
= SUBREG_BYTE (x
);
1727 if (reg_renumber
[reg_x
] >= 0)
1729 subreg_get_info (reg_renumber
[reg_x
],
1730 GET_MODE (SUBREG_REG (x
)), byte_x
,
1731 GET_MODE (x
), &info
);
1732 if (!info
.representable_p
)
1734 reg_x
= info
.offset
;
1741 if (reg_renumber
[reg_x
] >= 0)
1742 reg_x
= reg_renumber
[reg_x
];
1745 if (GET_CODE (y
) == SUBREG
)
1747 reg_y
= REGNO (SUBREG_REG (y
));
1748 byte_y
= SUBREG_BYTE (y
);
1750 if (reg_renumber
[reg_y
] >= 0)
1752 subreg_get_info (reg_renumber
[reg_y
],
1753 GET_MODE (SUBREG_REG (y
)), byte_y
,
1754 GET_MODE (y
), &info
);
1755 if (!info
.representable_p
)
1757 reg_y
= info
.offset
;
1764 if (reg_renumber
[reg_y
] >= 0)
1765 reg_y
= reg_renumber
[reg_y
];
1768 return reg_x
>= 0 && reg_x
== reg_y
&& byte_x
== byte_y
;
1771 /* Now we have disposed of all the cases
1772 in which different rtx codes can match. */
1773 if (code
!= GET_CODE (y
))
1786 /* We can't assume nonlocal labels have their following insns yet. */
1787 if (LABEL_REF_NONLOCAL_P (x
) || LABEL_REF_NONLOCAL_P (y
))
1788 return XEXP (x
, 0) == XEXP (y
, 0);
1790 /* Two label-refs are equivalent if they point at labels
1791 in the same position in the instruction stream. */
1792 return (next_real_insn (XEXP (x
, 0))
1793 == next_real_insn (XEXP (y
, 0)));
1796 return XSTR (x
, 0) == XSTR (y
, 0);
1799 /* If we didn't match EQ equality above, they aren't the same. */
1806 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
1808 if (GET_MODE (x
) != GET_MODE (y
))
1811 /* MEMs referring to different address space are not equivalent. */
1812 if (code
== MEM
&& MEM_ADDR_SPACE (x
) != MEM_ADDR_SPACE (y
))
1815 /* For commutative operations, the RTX match if the operand match in any
1816 order. Also handle the simple binary and unary cases without a loop. */
1817 if (targetm
.commutative_p (x
, UNKNOWN
))
1818 return ((rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0))
1819 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 1)))
1820 || (rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 1))
1821 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 0))));
1822 else if (NON_COMMUTATIVE_P (x
))
1823 return (rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0))
1824 && rtx_renumbered_equal_p (XEXP (x
, 1), XEXP (y
, 1)));
1825 else if (UNARY_P (x
))
1826 return rtx_renumbered_equal_p (XEXP (x
, 0), XEXP (y
, 0));
1828 /* Compare the elements. If any pair of corresponding elements
1829 fail to match, return 0 for the whole things. */
1831 fmt
= GET_RTX_FORMAT (code
);
1832 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1838 if (XWINT (x
, i
) != XWINT (y
, i
))
1843 if (XINT (x
, i
) != XINT (y
, i
))
1845 if (((code
== ASM_OPERANDS
&& i
== 6)
1846 || (code
== ASM_INPUT
&& i
== 1)))
1853 if (XTREE (x
, i
) != XTREE (y
, i
))
1858 if (strcmp (XSTR (x
, i
), XSTR (y
, i
)))
1863 if (! rtx_renumbered_equal_p (XEXP (x
, i
), XEXP (y
, i
)))
1868 if (XEXP (x
, i
) != XEXP (y
, i
))
1875 if (XVECLEN (x
, i
) != XVECLEN (y
, i
))
1877 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
1878 if (!rtx_renumbered_equal_p (XVECEXP (x
, i
, j
), XVECEXP (y
, i
, j
)))
1889 /* If X is a hard register or equivalent to one or a subregister of one,
1890 return the hard register number. If X is a pseudo register that was not
1891 assigned a hard register, return the pseudo register number. Otherwise,
1892 return -1. Any rtx is valid for X. */
1895 true_regnum (const_rtx x
)
1899 if (REGNO (x
) >= FIRST_PSEUDO_REGISTER
1900 && (lra_in_progress
|| reg_renumber
[REGNO (x
)] >= 0))
1901 return reg_renumber
[REGNO (x
)];
1904 if (GET_CODE (x
) == SUBREG
)
1906 int base
= true_regnum (SUBREG_REG (x
));
1908 && base
< FIRST_PSEUDO_REGISTER
)
1910 struct subreg_info info
;
1912 subreg_get_info (lra_in_progress
1913 ? (unsigned) base
: REGNO (SUBREG_REG (x
)),
1914 GET_MODE (SUBREG_REG (x
)),
1915 SUBREG_BYTE (x
), GET_MODE (x
), &info
);
1917 if (info
.representable_p
)
1918 return base
+ info
.offset
;
1924 /* Return regno of the register REG and handle subregs too. */
1926 reg_or_subregno (const_rtx reg
)
1928 if (GET_CODE (reg
) == SUBREG
)
1929 reg
= SUBREG_REG (reg
);
1930 gcc_assert (REG_P (reg
));