Merge -r 127928:132243 from trunk
[official-gcc.git] / gcc / jump.c
blob4564cd105ce2b90744048c1bc3546c5c4ce2169f
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
11 version.
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
16 for more details.
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
24 operate with jumps.
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
32 at by later passes.
34 The subroutines redirect_jump and invert_jump are used
35 from other passes as well. */
37 #include "config.h"
38 #include "system.h"
39 #include "coretypes.h"
40 #include "tm.h"
41 #include "rtl.h"
42 #include "tm_p.h"
43 #include "flags.h"
44 #include "hard-reg-set.h"
45 #include "regs.h"
46 #include "insn-config.h"
47 #include "insn-attr.h"
48 #include "recog.h"
49 #include "function.h"
50 #include "expr.h"
51 #include "real.h"
52 #include "except.h"
53 #include "diagnostic.h"
54 #include "toplev.h"
55 #include "reload.h"
56 #include "predict.h"
57 #include "timevar.h"
58 #include "tree-pass.h"
59 #include "target.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
78 (e.g. cbranchsi4). */
79 void
80 rebuild_jump_labels (rtx f)
82 rtx insn;
84 timevar_push (TV_REBUILD_JUMP);
85 init_label_info (f);
86 mark_all_labels (f);
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
104 old code is happy.
106 unsigned int
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))
117 delete_insn (insn);
118 else if (prev != PREV_INSN (insn))
119 reorder_insns (insn, insn, prev);
122 return 0;
125 struct tree_opt_pass pass_cleanup_barriers =
127 "barriers", /* name */
128 NULL, /* gate */
129 cleanup_barriers, /* execute */
130 NULL, /* sub */
131 NULL, /* next */
132 0, /* static_pass_number */
133 0, /* tv_id */
134 0, /* properties_required */
135 0, /* properties_provided */
136 0, /* properties_destroyed */
137 0, /* todo_flags_start */
138 TODO_dump_func, /* todo_flags_finish */
139 0 /* letter */
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. */
147 static void
148 init_label_info (rtx f)
150 rtx insn;
152 for (insn = f; insn; insn = NEXT_INSN (insn))
154 if (LABEL_P (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
165 allocation. */
167 if (INSN_P (insn))
169 rtx note, next;
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. */
185 static void
186 mark_all_labels (rtx f)
188 rtx insn;
189 rtx prev_nonjump_insn = NULL;
191 for (insn = f; insn; insn = NEXT_INSN (insn))
192 if (INSN_P (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)
205 && JUMP_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)
213 label_note
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);
219 rtx label_dest
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)
257 basic_block bb;
258 rtx insn;
259 FOR_EACH_BB (bb)
261 for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
262 if (INSN_P (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))
269 if (INSN_P (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. */
284 enum rtx_code
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)
293 return UNKNOWN;
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);
307 #endif
308 return reverse_condition (code);
311 /* Try a few special cases based on the comparison code. */
312 switch (code)
314 case GEU:
315 case GTU:
316 case LEU:
317 case LTU:
318 case NE:
319 case EQ:
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);
324 case ORDERED:
325 case UNORDERED:
326 case LTGT:
327 case UNEQ:
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);
331 case UNLT:
332 case UNLE:
333 case UNGT:
334 case UNGE:
335 /* We don't have safe way to reverse these yet. */
336 return UNKNOWN;
337 default:
338 break;
341 if (GET_MODE_CLASS (mode) == MODE_CC || CC0_P (arg0))
343 const_rtx prev;
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
347 in all cases. */
348 if (! insn)
349 return UNKNOWN;
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
353 variable. */
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));
371 break;
373 /* We can get past reg-reg moves. This may be useful for model
374 of i387 comparisons that first move flag registers around. */
375 if (REG_P (src))
377 arg0 = src;
378 continue;
381 /* If register is clobbered in some ununderstandable way,
382 give up. */
383 if (set)
384 return UNKNOWN;
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);
396 return UNKNOWN;
399 /* A wrapper around the previous function to take COMPARISON as rtx
400 expression. This simplifies many callers. */
401 enum rtx_code
402 reversed_comparison_code (const_rtx comparison, const_rtx insn)
404 if (!COMPARISON_P (comparison))
405 return UNKNOWN;
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)
418 return NULL_RTX;
419 else
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. */
433 enum rtx_code
434 reverse_condition (enum rtx_code code)
436 switch (code)
438 case EQ:
439 return NE;
440 case NE:
441 return EQ;
442 case GT:
443 return LE;
444 case GE:
445 return LT;
446 case LT:
447 return GE;
448 case LE:
449 return GT;
450 case GTU:
451 return LEU;
452 case GEU:
453 return LTU;
454 case LTU:
455 return GEU;
456 case LEU:
457 return GTU;
458 case UNORDERED:
459 return ORDERED;
460 case ORDERED:
461 return UNORDERED;
463 case UNLT:
464 case UNLE:
465 case UNGT:
466 case UNGE:
467 case UNEQ:
468 case LTGT:
469 return UNKNOWN;
471 default:
472 gcc_unreachable ();
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... */
480 enum rtx_code
481 reverse_condition_maybe_unordered (enum rtx_code code)
483 switch (code)
485 case EQ:
486 return NE;
487 case NE:
488 return EQ;
489 case GT:
490 return UNLE;
491 case GE:
492 return UNLT;
493 case LT:
494 return UNGE;
495 case LE:
496 return UNGT;
497 case LTGT:
498 return UNEQ;
499 case UNORDERED:
500 return ORDERED;
501 case ORDERED:
502 return UNORDERED;
503 case UNLT:
504 return GE;
505 case UNLE:
506 return GT;
507 case UNGT:
508 return LE;
509 case UNGE:
510 return LT;
511 case UNEQ:
512 return LTGT;
514 default:
515 gcc_unreachable ();
519 /* Similar, but return the code when two operands of a comparison are swapped.
520 This IS safe for IEEE floating-point. */
522 enum rtx_code
523 swap_condition (enum rtx_code code)
525 switch (code)
527 case EQ:
528 case NE:
529 case UNORDERED:
530 case ORDERED:
531 case UNEQ:
532 case LTGT:
533 return code;
535 case GT:
536 return LT;
537 case GE:
538 return LE;
539 case LT:
540 return GT;
541 case LE:
542 return GE;
543 case GTU:
544 return LTU;
545 case GEU:
546 return LEU;
547 case LTU:
548 return GTU;
549 case LEU:
550 return GEU;
551 case UNLT:
552 return UNGT;
553 case UNLE:
554 return UNGE;
555 case UNGT:
556 return UNLT;
557 case UNGE:
558 return UNLE;
560 default:
561 gcc_unreachable ();
565 /* Given a comparison CODE, return the corresponding unsigned comparison.
566 If CODE is an equality comparison or already an unsigned comparison,
567 CODE is returned. */
569 enum rtx_code
570 unsigned_condition (enum rtx_code code)
572 switch (code)
574 case EQ:
575 case NE:
576 case GTU:
577 case GEU:
578 case LTU:
579 case LEU:
580 return code;
582 case GT:
583 return GTU;
584 case GE:
585 return GEU;
586 case LT:
587 return LTU;
588 case LE:
589 return LEU;
591 default:
592 gcc_unreachable ();
596 /* Similarly, return the signed version of a comparison. */
598 enum rtx_code
599 signed_condition (enum rtx_code code)
601 switch (code)
603 case EQ:
604 case NE:
605 case GT:
606 case GE:
607 case LT:
608 case LE:
609 return code;
611 case GTU:
612 return GT;
613 case GEU:
614 return GE;
615 case LTU:
616 return LT;
617 case LEU:
618 return LE;
620 default:
621 gcc_unreachable ();
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
632 comparison codes.
633 They can't match anything, so we have to reject them here. */
634 if (code1 == UNKNOWN || code2 == UNKNOWN)
635 return 0;
637 if (code1 == code2)
638 return 1;
640 switch (code1)
642 case UNEQ:
643 if (code2 == UNLE || code2 == UNGE)
644 return 1;
645 break;
647 case EQ:
648 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
649 || code2 == ORDERED)
650 return 1;
651 break;
653 case UNLT:
654 if (code2 == UNLE || code2 == NE)
655 return 1;
656 break;
658 case LT:
659 if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
660 return 1;
661 break;
663 case UNGT:
664 if (code2 == UNGE || code2 == NE)
665 return 1;
666 break;
668 case GT:
669 if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
670 return 1;
671 break;
673 case GE:
674 case LE:
675 if (code2 == ORDERED)
676 return 1;
677 break;
679 case LTGT:
680 if (code2 == NE || code2 == ORDERED)
681 return 1;
682 break;
684 case LTU:
685 if (code2 == LEU || code2 == NE)
686 return 1;
687 break;
689 case GTU:
690 if (code2 == GEU || code2 == NE)
691 return 1;
692 break;
694 case UNORDERED:
695 if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
696 || code2 == UNGE || code2 == UNGT)
697 return 1;
698 break;
700 default:
701 break;
704 return 0;
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
719 and nothing more.
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)
731 return 0;
733 x = SET_SRC (x);
734 if (GET_CODE (x) == LABEL_REF)
735 return 1;
736 else
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
747 PARALLEL.
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)
758 return 0;
759 else
760 x = XVECEXP (x, 0, 0);
762 if (GET_CODE (x) != SET)
763 return 0;
764 if (GET_CODE (SET_DEST (x)) != PC)
765 return 0;
766 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
767 return 1;
768 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
769 return 0;
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))
773 return 1;
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))
777 return 1;
778 return 0;
781 /* Return set of PC, otherwise NULL. */
784 pc_set (const_rtx insn)
786 rtx pat;
787 if (!JUMP_P (insn))
788 return NULL_RTX;
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)
796 return pat;
798 return NULL_RTX;
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);
808 if (!x)
809 return 0;
810 if (GET_CODE (SET_SRC (x)) != LABEL_REF)
811 return 0;
812 if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
813 return 0;
814 return 1;
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
820 onlyjump_p.
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);
828 enum rtx_code a, b;
830 if (!x)
831 return 0;
832 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
833 return 0;
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);
849 if (!x)
850 return NULL_RTX;
851 x = SET_SRC (x);
852 if (GET_CODE (x) == LABEL_REF)
853 return x;
854 if (GET_CODE (x) != IF_THEN_ELSE)
855 return NULL_RTX;
856 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
857 return XEXP (x, 1);
858 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
859 return XEXP (x, 2);
860 return NULL_RTX;
863 /* Return true if INSN is a (possibly conditional) return insn. */
865 static int
866 returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
868 rtx x = *loc;
870 return x && (GET_CODE (x) == RETURN
871 || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
875 returnjump_p (rtx insn)
877 if (!JUMP_P (insn))
878 return 0;
879 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
882 /* Return true if INSN is a jump that only transfers control and
883 nothing more. */
886 onlyjump_p (const_rtx insn)
888 rtx set;
890 if (!JUMP_P (insn))
891 return 0;
893 set = single_set (insn);
894 if (set == NULL)
895 return 0;
896 if (GET_CODE (SET_DEST (set)) != PC)
897 return 0;
898 if (side_effects_p (SET_SRC (set)))
899 return 0;
901 return 1;
904 #ifdef HAVE_cc0
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)
912 if (! x)
913 return 0;
915 if (INSN_P (x))
916 x = PATTERN (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)
929 if (! x)
930 return 0;
932 if (INSN_P (x))
933 x = PATTERN (x);
935 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
936 return 1;
937 if (GET_CODE (x) == PARALLEL)
939 int i;
940 int sets_cc0 = 0;
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)
946 sets_cc0 = 1;
947 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
948 other_things = 1;
950 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
952 return 0;
954 #endif
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. */
971 void
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
982 note. */
984 static void
985 mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
987 RTX_CODE code = GET_CODE (x);
988 int i;
989 const char *fmt;
991 switch (code)
993 case PC:
994 case CC0:
995 case REG:
996 case CONST_INT:
997 case CONST_DOUBLE:
998 case CLOBBER:
999 case CALL:
1000 return;
1002 case MEM:
1003 in_mem = true;
1004 break;
1006 case SEQUENCE:
1007 for (i = 0; i < XVECLEN (x, 0); i++)
1008 mark_jump_label (PATTERN (XVECEXP (x, 0, i)),
1009 XVECEXP (x, 0, i), 0);
1010 return;
1012 case SYMBOL_REF:
1013 if (!in_mem)
1014 return;
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);
1019 break;
1021 /* Handle operands in the condition of an if-then-else as for a
1022 non-jump insn. */
1023 case IF_THEN_ELSE:
1024 if (!is_target)
1025 break;
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);
1029 return;
1031 case LABEL_REF:
1033 rtx label = XEXP (x, 0);
1035 /* Ignore remaining references to unreachable labels that
1036 have been deleted. */
1037 if (NOTE_P (label)
1038 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL)
1039 break;
1041 gcc_assert (LABEL_P (label));
1043 /* Ignore references to labels of containing functions. */
1044 if (LABEL_REF_NONLOCAL_P (x))
1045 break;
1047 XEXP (x, 0) = label;
1048 if (! insn || ! INSN_DELETED_P (insn))
1049 ++LABEL_NUSES (label);
1051 if (insn)
1053 if (is_target
1054 /* Do not change a previous setting of JUMP_LABEL. If the
1055 JUMP_LABEL slot is occupied by a different label,
1056 create a note for this label. */
1057 && (JUMP_LABEL (insn) == NULL || JUMP_LABEL (insn) == label))
1058 JUMP_LABEL (insn) = label;
1059 else
1061 enum reg_note kind
1062 = is_target ? REG_LABEL_TARGET : REG_LABEL_OPERAND;
1064 /* Add a REG_LABEL_OPERAND or REG_LABEL_TARGET note
1065 for LABEL unless there already is one. All uses of
1066 a label, except for the primary target of a jump,
1067 must have such a note. */
1068 if (! find_reg_note (insn, kind, label))
1069 REG_NOTES (insn)
1070 = gen_rtx_INSN_LIST (kind, label, REG_NOTES (insn));
1073 return;
1076 /* Do walk the labels in a vector, but not the first operand of an
1077 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1078 case ADDR_VEC:
1079 case ADDR_DIFF_VEC:
1080 if (! INSN_DELETED_P (insn))
1082 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
1084 for (i = 0; i < XVECLEN (x, eltnum); i++)
1085 mark_jump_label_1 (XVECEXP (x, eltnum, i), NULL_RTX, in_mem,
1086 is_target);
1088 return;
1090 default:
1091 break;
1094 fmt = GET_RTX_FORMAT (code);
1096 /* The primary target of a tablejump is the label of the ADDR_VEC,
1097 which is canonically mentioned *last* in the insn. To get it
1098 marked as JUMP_LABEL, we iterate over items in reverse order. */
1099 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1101 if (fmt[i] == 'e')
1102 mark_jump_label_1 (XEXP (x, i), insn, in_mem, is_target);
1103 else if (fmt[i] == 'E')
1105 int j;
1107 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1108 mark_jump_label_1 (XVECEXP (x, i, j), insn, in_mem,
1109 is_target);
1115 /* Delete insn INSN from the chain of insns and update label ref counts
1116 and delete insns now unreachable.
1118 Returns the first insn after INSN that was not deleted.
1120 Usage of this instruction is deprecated. Use delete_insn instead and
1121 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1124 delete_related_insns (rtx insn)
1126 int was_code_label = (LABEL_P (insn));
1127 rtx note;
1128 rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
1130 while (next && INSN_DELETED_P (next))
1131 next = NEXT_INSN (next);
1133 /* This insn is already deleted => return first following nondeleted. */
1134 if (INSN_DELETED_P (insn))
1135 return next;
1137 delete_insn (insn);
1139 /* If instruction is followed by a barrier,
1140 delete the barrier too. */
1142 if (next != 0 && BARRIER_P (next))
1143 delete_insn (next);
1145 /* If deleting a jump, decrement the count of the label,
1146 and delete the label if it is now unused. */
1148 if (JUMP_P (insn) && JUMP_LABEL (insn))
1150 rtx lab = JUMP_LABEL (insn), lab_next;
1152 if (LABEL_NUSES (lab) == 0)
1153 /* This can delete NEXT or PREV,
1154 either directly if NEXT is JUMP_LABEL (INSN),
1155 or indirectly through more levels of jumps. */
1156 delete_related_insns (lab);
1157 else if (tablejump_p (insn, NULL, &lab_next))
1159 /* If we're deleting the tablejump, delete the dispatch table.
1160 We may not be able to kill the label immediately preceding
1161 just yet, as it might be referenced in code leading up to
1162 the tablejump. */
1163 delete_related_insns (lab_next);
1167 /* Likewise if we're deleting a dispatch table. */
1169 if (JUMP_P (insn)
1170 && (GET_CODE (PATTERN (insn)) == ADDR_VEC
1171 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
1173 rtx pat = PATTERN (insn);
1174 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1175 int len = XVECLEN (pat, diff_vec_p);
1177 for (i = 0; i < len; i++)
1178 if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1179 delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
1180 while (next && INSN_DELETED_P (next))
1181 next = NEXT_INSN (next);
1182 return next;
1185 /* Likewise for any JUMP_P / INSN / CALL_INSN with a
1186 REG_LABEL_OPERAND or REG_LABEL_TARGET note. */
1187 if (INSN_P (insn))
1188 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1189 if ((REG_NOTE_KIND (note) == REG_LABEL_OPERAND
1190 || REG_NOTE_KIND (note) == REG_LABEL_TARGET)
1191 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1192 && LABEL_P (XEXP (note, 0)))
1193 if (LABEL_NUSES (XEXP (note, 0)) == 0)
1194 delete_related_insns (XEXP (note, 0));
1196 while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
1197 prev = PREV_INSN (prev);
1199 /* If INSN was a label and a dispatch table follows it,
1200 delete the dispatch table. The tablejump must have gone already.
1201 It isn't useful to fall through into a table. */
1203 if (was_code_label
1204 && NEXT_INSN (insn) != 0
1205 && JUMP_P (NEXT_INSN (insn))
1206 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
1207 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
1208 next = delete_related_insns (NEXT_INSN (insn));
1210 /* If INSN was a label, delete insns following it if now unreachable. */
1212 if (was_code_label && prev && BARRIER_P (prev))
1214 enum rtx_code code;
1215 while (next)
1217 code = GET_CODE (next);
1218 if (code == NOTE)
1219 next = NEXT_INSN (next);
1220 /* Keep going past other deleted labels to delete what follows. */
1221 else if (code == CODE_LABEL && INSN_DELETED_P (next))
1222 next = NEXT_INSN (next);
1223 else if (code == BARRIER || INSN_P (next))
1224 /* Note: if this deletes a jump, it can cause more
1225 deletion of unreachable code, after a different label.
1226 As long as the value from this recursive call is correct,
1227 this invocation functions correctly. */
1228 next = delete_related_insns (next);
1229 else
1230 break;
1234 /* I feel a little doubtful about this loop,
1235 but I see no clean and sure alternative way
1236 to find the first insn after INSN that is not now deleted.
1237 I hope this works. */
1238 while (next && INSN_DELETED_P (next))
1239 next = NEXT_INSN (next);
1240 return next;
1243 /* Delete a range of insns from FROM to TO, inclusive.
1244 This is for the sake of peephole optimization, so assume
1245 that whatever these insns do will still be done by a new
1246 peephole insn that will replace them. */
1248 void
1249 delete_for_peephole (rtx from, rtx to)
1251 rtx insn = from;
1253 while (1)
1255 rtx next = NEXT_INSN (insn);
1256 rtx prev = PREV_INSN (insn);
1258 if (!NOTE_P (insn))
1260 INSN_DELETED_P (insn) = 1;
1262 /* Patch this insn out of the chain. */
1263 /* We don't do this all at once, because we
1264 must preserve all NOTEs. */
1265 if (prev)
1266 NEXT_INSN (prev) = next;
1268 if (next)
1269 PREV_INSN (next) = prev;
1272 if (insn == to)
1273 break;
1274 insn = next;
1277 /* Note that if TO is an unconditional jump
1278 we *do not* delete the BARRIER that follows,
1279 since the peephole that replaces this sequence
1280 is also an unconditional jump in that case. */
1283 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1284 NLABEL as a return. Accrue modifications into the change group. */
1286 static void
1287 redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
1289 rtx x = *loc;
1290 RTX_CODE code = GET_CODE (x);
1291 int i;
1292 const char *fmt;
1294 if (code == LABEL_REF)
1296 if (XEXP (x, 0) == olabel)
1298 rtx n;
1299 if (nlabel)
1300 n = gen_rtx_LABEL_REF (Pmode, nlabel);
1301 else
1302 n = gen_rtx_RETURN (VOIDmode);
1304 validate_change (insn, loc, n, 1);
1305 return;
1308 else if (code == RETURN && olabel == 0)
1310 if (nlabel)
1311 x = gen_rtx_LABEL_REF (Pmode, nlabel);
1312 else
1313 x = gen_rtx_RETURN (VOIDmode);
1314 if (loc == &PATTERN (insn))
1315 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1316 validate_change (insn, loc, x, 1);
1317 return;
1320 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1321 && GET_CODE (SET_SRC (x)) == LABEL_REF
1322 && XEXP (SET_SRC (x), 0) == olabel)
1324 validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1325 return;
1328 fmt = GET_RTX_FORMAT (code);
1329 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1331 if (fmt[i] == 'e')
1332 redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1333 else if (fmt[i] == 'E')
1335 int j;
1336 for (j = 0; j < XVECLEN (x, i); j++)
1337 redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
1342 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
1343 the modifications into the change group. Return false if we did
1344 not see how to do that. */
1347 redirect_jump_1 (rtx jump, rtx nlabel)
1349 int ochanges = num_validated_changes ();
1350 rtx *loc;
1352 if (GET_CODE (PATTERN (jump)) == PARALLEL)
1353 loc = &XVECEXP (PATTERN (jump), 0, 0);
1354 else
1355 loc = &PATTERN (jump);
1357 redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
1358 return num_validated_changes () > ochanges;
1361 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
1362 jump target label is unused as a result, it and the code following
1363 it may be deleted.
1365 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
1366 RETURN insn.
1368 The return value will be 1 if the change was made, 0 if it wasn't
1369 (this can only occur for NLABEL == 0). */
1372 redirect_jump (rtx jump, rtx nlabel, int delete_unused)
1374 rtx olabel = JUMP_LABEL (jump);
1376 if (nlabel == olabel)
1377 return 1;
1379 if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
1380 return 0;
1382 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
1383 return 1;
1386 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1387 NLABEL in JUMP.
1388 If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1389 count has dropped to zero. */
1390 void
1391 redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
1392 int invert)
1394 rtx note;
1396 gcc_assert (JUMP_LABEL (jump) == olabel);
1398 /* Negative DELETE_UNUSED used to be used to signalize behavior on
1399 moving FUNCTION_END note. Just sanity check that no user still worry
1400 about this. */
1401 gcc_assert (delete_unused >= 0);
1402 JUMP_LABEL (jump) = nlabel;
1403 if (nlabel)
1404 ++LABEL_NUSES (nlabel);
1406 /* Update labels in any REG_EQUAL note. */
1407 if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
1409 if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
1410 remove_note (jump, note);
1411 else
1413 redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
1414 confirm_change_group ();
1418 if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
1419 /* Undefined labels will remain outside the insn stream. */
1420 && INSN_UID (olabel))
1421 delete_related_insns (olabel);
1422 if (invert)
1423 invert_br_probabilities (jump);
1426 /* Invert the jump condition X contained in jump insn INSN. Accrue the
1427 modifications into the change group. Return nonzero for success. */
1428 static int
1429 invert_exp_1 (rtx x, rtx insn)
1431 RTX_CODE code = GET_CODE (x);
1433 if (code == IF_THEN_ELSE)
1435 rtx comp = XEXP (x, 0);
1436 rtx tem;
1437 enum rtx_code reversed_code;
1439 /* We can do this in two ways: The preferable way, which can only
1440 be done if this is not an integer comparison, is to reverse
1441 the comparison code. Otherwise, swap the THEN-part and ELSE-part
1442 of the IF_THEN_ELSE. If we can't do either, fail. */
1444 reversed_code = reversed_comparison_code (comp, insn);
1446 if (reversed_code != UNKNOWN)
1448 validate_change (insn, &XEXP (x, 0),
1449 gen_rtx_fmt_ee (reversed_code,
1450 GET_MODE (comp), XEXP (comp, 0),
1451 XEXP (comp, 1)),
1453 return 1;
1456 tem = XEXP (x, 1);
1457 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
1458 validate_change (insn, &XEXP (x, 2), tem, 1);
1459 return 1;
1461 else
1462 return 0;
1465 /* Invert the condition of the jump JUMP, and make it jump to label
1466 NLABEL instead of where it jumps now. Accrue changes into the
1467 change group. Return false if we didn't see how to perform the
1468 inversion and redirection. */
1471 invert_jump_1 (rtx jump, rtx nlabel)
1473 rtx x = pc_set (jump);
1474 int ochanges;
1475 int ok;
1477 ochanges = num_validated_changes ();
1478 gcc_assert (x);
1479 ok = invert_exp_1 (SET_SRC (x), jump);
1480 gcc_assert (ok);
1482 if (num_validated_changes () == ochanges)
1483 return 0;
1485 /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1486 in Pmode, so checking this is not merely an optimization. */
1487 return nlabel == JUMP_LABEL (jump) || redirect_jump_1 (jump, nlabel);
1490 /* Invert the condition of the jump JUMP, and make it jump to label
1491 NLABEL instead of where it jumps now. Return true if successful. */
1494 invert_jump (rtx jump, rtx nlabel, int delete_unused)
1496 rtx olabel = JUMP_LABEL (jump);
1498 if (invert_jump_1 (jump, nlabel) && apply_change_group ())
1500 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
1501 return 1;
1503 cancel_changes (0);
1504 return 0;
1508 /* Like rtx_equal_p except that it considers two REGs as equal
1509 if they renumber to the same value and considers two commutative
1510 operations to be the same if the order of the operands has been
1511 reversed. */
1514 rtx_renumbered_equal_p (const_rtx x, const_rtx y)
1516 int i;
1517 const enum rtx_code code = GET_CODE (x);
1518 const char *fmt;
1520 if (x == y)
1521 return 1;
1523 if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
1524 && (REG_P (y) || (GET_CODE (y) == SUBREG
1525 && REG_P (SUBREG_REG (y)))))
1527 int reg_x = -1, reg_y = -1;
1528 int byte_x = 0, byte_y = 0;
1530 if (GET_MODE (x) != GET_MODE (y))
1531 return 0;
1533 /* If we haven't done any renumbering, don't
1534 make any assumptions. */
1535 if (reg_renumber == 0)
1536 return rtx_equal_p (x, y);
1538 if (code == SUBREG)
1540 reg_x = REGNO (SUBREG_REG (x));
1541 byte_x = SUBREG_BYTE (x);
1543 if (reg_renumber[reg_x] >= 0)
1545 reg_x = subreg_regno_offset (reg_renumber[reg_x],
1546 GET_MODE (SUBREG_REG (x)),
1547 byte_x,
1548 GET_MODE (x));
1549 byte_x = 0;
1552 else
1554 reg_x = REGNO (x);
1555 if (reg_renumber[reg_x] >= 0)
1556 reg_x = reg_renumber[reg_x];
1559 if (GET_CODE (y) == SUBREG)
1561 reg_y = REGNO (SUBREG_REG (y));
1562 byte_y = SUBREG_BYTE (y);
1564 if (reg_renumber[reg_y] >= 0)
1566 reg_y = subreg_regno_offset (reg_renumber[reg_y],
1567 GET_MODE (SUBREG_REG (y)),
1568 byte_y,
1569 GET_MODE (y));
1570 byte_y = 0;
1573 else
1575 reg_y = REGNO (y);
1576 if (reg_renumber[reg_y] >= 0)
1577 reg_y = reg_renumber[reg_y];
1580 return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
1583 /* Now we have disposed of all the cases
1584 in which different rtx codes can match. */
1585 if (code != GET_CODE (y))
1586 return 0;
1588 switch (code)
1590 case PC:
1591 case CC0:
1592 case ADDR_VEC:
1593 case ADDR_DIFF_VEC:
1594 case CONST_INT:
1595 case CONST_DOUBLE:
1596 return 0;
1598 case LABEL_REF:
1599 /* We can't assume nonlocal labels have their following insns yet. */
1600 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
1601 return XEXP (x, 0) == XEXP (y, 0);
1603 /* Two label-refs are equivalent if they point at labels
1604 in the same position in the instruction stream. */
1605 return (next_real_insn (XEXP (x, 0))
1606 == next_real_insn (XEXP (y, 0)));
1608 case SYMBOL_REF:
1609 return XSTR (x, 0) == XSTR (y, 0);
1611 case CODE_LABEL:
1612 /* If we didn't match EQ equality above, they aren't the same. */
1613 return 0;
1615 default:
1616 break;
1619 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
1621 if (GET_MODE (x) != GET_MODE (y))
1622 return 0;
1624 /* For commutative operations, the RTX match if the operand match in any
1625 order. Also handle the simple binary and unary cases without a loop. */
1626 if (targetm.commutative_p (x, UNKNOWN))
1627 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1628 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
1629 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
1630 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
1631 else if (NON_COMMUTATIVE_P (x))
1632 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1633 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
1634 else if (UNARY_P (x))
1635 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
1637 /* Compare the elements. If any pair of corresponding elements
1638 fail to match, return 0 for the whole things. */
1640 fmt = GET_RTX_FORMAT (code);
1641 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1643 int j;
1644 switch (fmt[i])
1646 case 'w':
1647 if (XWINT (x, i) != XWINT (y, i))
1648 return 0;
1649 break;
1651 case 'i':
1652 if (XINT (x, i) != XINT (y, i))
1653 return 0;
1654 break;
1656 case 't':
1657 if (XTREE (x, i) != XTREE (y, i))
1658 return 0;
1659 break;
1661 case 's':
1662 if (strcmp (XSTR (x, i), XSTR (y, i)))
1663 return 0;
1664 break;
1666 case 'e':
1667 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
1668 return 0;
1669 break;
1671 case 'u':
1672 if (XEXP (x, i) != XEXP (y, i))
1673 return 0;
1674 /* Fall through. */
1675 case '0':
1676 break;
1678 case 'E':
1679 if (XVECLEN (x, i) != XVECLEN (y, i))
1680 return 0;
1681 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1682 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
1683 return 0;
1684 break;
1686 default:
1687 gcc_unreachable ();
1690 return 1;
1693 /* If X is a hard register or equivalent to one or a subregister of one,
1694 return the hard register number. If X is a pseudo register that was not
1695 assigned a hard register, return the pseudo register number. Otherwise,
1696 return -1. Any rtx is valid for X. */
1699 true_regnum (const_rtx x)
1701 if (REG_P (x))
1703 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
1704 return reg_renumber[REGNO (x)];
1705 return REGNO (x);
1707 if (GET_CODE (x) == SUBREG)
1709 int base = true_regnum (SUBREG_REG (x));
1710 if (base >= 0
1711 && base < FIRST_PSEUDO_REGISTER
1712 && subreg_offset_representable_p (REGNO (SUBREG_REG (x)),
1713 GET_MODE (SUBREG_REG (x)),
1714 SUBREG_BYTE (x), GET_MODE (x)))
1715 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
1716 GET_MODE (SUBREG_REG (x)),
1717 SUBREG_BYTE (x), GET_MODE (x));
1719 return -1;
1722 /* Return regno of the register REG and handle subregs too. */
1723 unsigned int
1724 reg_or_subregno (const_rtx reg)
1726 if (GET_CODE (reg) == SUBREG)
1727 reg = SUBREG_REG (reg);
1728 gcc_assert (REG_P (reg));
1729 return REGNO (reg);