include cstring as well
[official-gcc.git] / gcc / jump.c
blobe61e2fba9d7d53b6f1da21dbbedc8bfd811a4255
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
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 2, 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 COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 /* This is the pathetic reminder of old fame of the jump-optimization pass
24 of the compiler. Now it contains basically a set of utility functions to
25 operate with jumps.
27 Each CODE_LABEL has a count of the times it is used
28 stored in the LABEL_NUSES internal field, and each JUMP_INSN
29 has one label that it refers to stored in the
30 JUMP_LABEL internal field. With this we can detect labels that
31 become unused because of the deletion of all the jumps that
32 formerly used them. The JUMP_LABEL info is sometimes looked
33 at by later passes.
35 The subroutines redirect_jump and invert_jump are used
36 from other passes as well. */
38 #include "config.h"
39 #include "system.h"
40 #include "coretypes.h"
41 #include "tm.h"
42 #include "rtl.h"
43 #include "tm_p.h"
44 #include "flags.h"
45 #include "hard-reg-set.h"
46 #include "regs.h"
47 #include "insn-config.h"
48 #include "insn-attr.h"
49 #include "recog.h"
50 #include "function.h"
51 #include "expr.h"
52 #include "real.h"
53 #include "except.h"
54 #include "diagnostic.h"
55 #include "toplev.h"
56 #include "reload.h"
57 #include "predict.h"
58 #include "timevar.h"
59 #include "tree-pass.h"
60 #include "target.h"
62 /* Optimize jump y; x: ... y: jumpif... x?
63 Don't know if it is worth bothering with. */
64 /* Optimize two cases of conditional jump to conditional jump?
65 This can never delete any instruction or make anything dead,
66 or even change what is live at any point.
67 So perhaps let combiner do it. */
69 static void init_label_info (rtx);
70 static void mark_all_labels (rtx);
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 /* Alternate entry into the jump optimizer. This entry point only rebuilds
76 the JUMP_LABEL field in jumping insns and REG_LABEL notes in non-jumping
77 instructions. */
78 void
79 rebuild_jump_labels (rtx f)
81 rtx insn;
83 timevar_push (TV_REBUILD_JUMP);
84 init_label_info (f);
85 mark_all_labels (f);
87 /* Keep track of labels used from static data; we don't track them
88 closely enough to delete them here, so make sure their reference
89 count doesn't drop to zero. */
91 for (insn = forced_labels; insn; insn = XEXP (insn, 1))
92 if (LABEL_P (XEXP (insn, 0)))
93 LABEL_NUSES (XEXP (insn, 0))++;
94 timevar_pop (TV_REBUILD_JUMP);
97 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
98 non-fallthru insn. This is not generally true, as multiple barriers
99 may have crept in, or the BARRIER may be separated from the last
100 real insn by one or more NOTEs.
102 This simple pass moves barriers and removes duplicates so that the
103 old code is happy.
105 unsigned int
106 cleanup_barriers (void)
108 rtx insn, next, prev;
109 for (insn = get_insns (); insn; insn = next)
111 next = NEXT_INSN (insn);
112 if (BARRIER_P (insn))
114 prev = prev_nonnote_insn (insn);
115 if (BARRIER_P (prev))
116 delete_insn (insn);
117 else if (prev != PREV_INSN (insn))
118 reorder_insns (insn, insn, prev);
121 return 0;
124 struct tree_opt_pass pass_cleanup_barriers =
126 "barriers", /* name */
127 NULL, /* gate */
128 cleanup_barriers, /* execute */
129 NULL, /* sub */
130 NULL, /* next */
131 0, /* static_pass_number */
132 0, /* tv_id */
133 0, /* properties_required */
134 0, /* properties_provided */
135 0, /* properties_destroyed */
136 0, /* todo_flags_start */
137 TODO_dump_func, /* todo_flags_finish */
138 0 /* letter */
142 /* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
143 notes whose labels don't occur in the insn any more. Returns the
144 largest INSN_UID found. */
145 static void
146 init_label_info (rtx f)
148 rtx insn;
150 for (insn = f; insn; insn = NEXT_INSN (insn))
151 if (LABEL_P (insn))
152 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
153 else if (JUMP_P (insn))
154 JUMP_LABEL (insn) = 0;
155 else if (NONJUMP_INSN_P (insn) || CALL_P (insn))
157 rtx note, next;
159 for (note = REG_NOTES (insn); note; note = next)
161 next = XEXP (note, 1);
162 if (REG_NOTE_KIND (note) == REG_LABEL
163 && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
164 remove_note (insn, note);
169 /* Mark the label each jump jumps to.
170 Combine consecutive labels, and count uses of labels. */
172 static void
173 mark_all_labels (rtx f)
175 rtx insn;
177 for (insn = f; insn; insn = NEXT_INSN (insn))
178 if (INSN_P (insn))
180 mark_jump_label (PATTERN (insn), insn, 0);
181 if (! INSN_DELETED_P (insn) && JUMP_P (insn))
183 /* When we know the LABEL_REF contained in a REG used in
184 an indirect jump, we'll have a REG_LABEL note so that
185 flow can tell where it's going. */
186 if (JUMP_LABEL (insn) == 0)
188 rtx label_note = find_reg_note (insn, REG_LABEL, NULL_RTX);
189 if (label_note)
191 /* But a LABEL_REF around the REG_LABEL note, so
192 that we can canonicalize it. */
193 rtx label_ref = gen_rtx_LABEL_REF (Pmode,
194 XEXP (label_note, 0));
196 mark_jump_label (label_ref, insn, 0);
197 XEXP (label_note, 0) = XEXP (label_ref, 0);
198 JUMP_LABEL (insn) = XEXP (label_note, 0);
204 /* If we are in cfglayout mode, there may be non-insns between the
205 basic blocks. If those non-insns represent tablejump data, they
206 contain label references that we must record. */
207 if (current_ir_type () == IR_RTL_CFGLAYOUT)
209 basic_block bb;
210 rtx insn;
211 FOR_EACH_BB (bb)
213 for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
214 if (INSN_P (insn))
216 gcc_assert (JUMP_TABLE_DATA_P (insn));
217 mark_jump_label (PATTERN (insn), insn, 0);
220 for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
221 if (INSN_P (insn))
223 gcc_assert (JUMP_TABLE_DATA_P (insn));
224 mark_jump_label (PATTERN (insn), insn, 0);
230 /* Move all block-beg, block-end and loop-beg notes between START and END out
231 before START. START and END may be such notes. Returns the values of the
232 new starting and ending insns, which may be different if the original ones
233 were such notes. Return true if there were only such notes and no real
234 instructions. */
236 bool
237 squeeze_notes (rtx* startp, rtx* endp)
239 rtx start = *startp;
240 rtx end = *endp;
242 rtx insn;
243 rtx next;
244 rtx last = NULL;
245 rtx past_end = NEXT_INSN (end);
247 for (insn = start; insn != past_end; insn = next)
249 next = NEXT_INSN (insn);
250 if (NOTE_P (insn)
251 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
252 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG))
254 /* BLOCK_BEG or BLOCK_END notes only exist in the `final' pass. */
255 gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_BEG
256 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END);
258 if (insn == start)
259 start = next;
260 else
262 rtx prev = PREV_INSN (insn);
263 PREV_INSN (insn) = PREV_INSN (start);
264 NEXT_INSN (insn) = start;
265 NEXT_INSN (PREV_INSN (insn)) = insn;
266 PREV_INSN (NEXT_INSN (insn)) = insn;
267 NEXT_INSN (prev) = next;
268 PREV_INSN (next) = prev;
271 else
272 last = insn;
275 /* There were no real instructions. */
276 if (start == past_end)
277 return true;
279 end = last;
281 *startp = start;
282 *endp = end;
283 return false;
286 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
287 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
288 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
289 know whether it's source is floating point or integer comparison. Machine
290 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
291 to help this function avoid overhead in these cases. */
292 enum rtx_code
293 reversed_comparison_code_parts (enum rtx_code code, rtx arg0, rtx arg1, rtx insn)
295 enum machine_mode mode;
297 /* If this is not actually a comparison, we can't reverse it. */
298 if (GET_RTX_CLASS (code) != RTX_COMPARE
299 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
300 return UNKNOWN;
302 mode = GET_MODE (arg0);
303 if (mode == VOIDmode)
304 mode = GET_MODE (arg1);
306 /* First see if machine description supplies us way to reverse the
307 comparison. Give it priority over everything else to allow
308 machine description to do tricks. */
309 if (GET_MODE_CLASS (mode) == MODE_CC
310 && REVERSIBLE_CC_MODE (mode))
312 #ifdef REVERSE_CONDITION
313 return REVERSE_CONDITION (code, mode);
314 #endif
315 return reverse_condition (code);
318 /* Try a few special cases based on the comparison code. */
319 switch (code)
321 case GEU:
322 case GTU:
323 case LEU:
324 case LTU:
325 case NE:
326 case EQ:
327 /* It is always safe to reverse EQ and NE, even for the floating
328 point. Similarly the unsigned comparisons are never used for
329 floating point so we can reverse them in the default way. */
330 return reverse_condition (code);
331 case ORDERED:
332 case UNORDERED:
333 case LTGT:
334 case UNEQ:
335 /* In case we already see unordered comparison, we can be sure to
336 be dealing with floating point so we don't need any more tests. */
337 return reverse_condition_maybe_unordered (code);
338 case UNLT:
339 case UNLE:
340 case UNGT:
341 case UNGE:
342 /* We don't have safe way to reverse these yet. */
343 return UNKNOWN;
344 default:
345 break;
348 if (GET_MODE_CLASS (mode) == MODE_CC || CC0_P (arg0))
350 rtx prev;
351 /* Try to search for the comparison to determine the real mode.
352 This code is expensive, but with sane machine description it
353 will be never used, since REVERSIBLE_CC_MODE will return true
354 in all cases. */
355 if (! insn)
356 return UNKNOWN;
358 for (prev = prev_nonnote_insn (insn);
359 prev != 0 && !LABEL_P (prev);
360 prev = prev_nonnote_insn (prev))
362 rtx set = set_of (arg0, prev);
363 if (set && GET_CODE (set) == SET
364 && rtx_equal_p (SET_DEST (set), arg0))
366 rtx src = SET_SRC (set);
368 if (GET_CODE (src) == COMPARE)
370 rtx comparison = src;
371 arg0 = XEXP (src, 0);
372 mode = GET_MODE (arg0);
373 if (mode == VOIDmode)
374 mode = GET_MODE (XEXP (comparison, 1));
375 break;
377 /* We can get past reg-reg moves. This may be useful for model
378 of i387 comparisons that first move flag registers around. */
379 if (REG_P (src))
381 arg0 = src;
382 continue;
385 /* If register is clobbered in some ununderstandable way,
386 give up. */
387 if (set)
388 return UNKNOWN;
392 /* Test for an integer condition, or a floating-point comparison
393 in which NaNs can be ignored. */
394 if (GET_CODE (arg0) == CONST_INT
395 || (GET_MODE (arg0) != VOIDmode
396 && GET_MODE_CLASS (mode) != MODE_CC
397 && !HONOR_NANS (mode)))
398 return reverse_condition (code);
400 return UNKNOWN;
403 /* A wrapper around the previous function to take COMPARISON as rtx
404 expression. This simplifies many callers. */
405 enum rtx_code
406 reversed_comparison_code (rtx comparison, rtx insn)
408 if (!COMPARISON_P (comparison))
409 return UNKNOWN;
410 return reversed_comparison_code_parts (GET_CODE (comparison),
411 XEXP (comparison, 0),
412 XEXP (comparison, 1), insn);
415 /* Return comparison with reversed code of EXP.
416 Return NULL_RTX in case we fail to do the reversal. */
418 reversed_comparison (rtx exp, enum machine_mode mode)
420 enum rtx_code reversed_code = reversed_comparison_code (exp, NULL_RTX);
421 if (reversed_code == UNKNOWN)
422 return NULL_RTX;
423 else
424 return simplify_gen_relational (reversed_code, mode, VOIDmode,
425 XEXP (exp, 0), XEXP (exp, 1));
429 /* Given an rtx-code for a comparison, return the code for the negated
430 comparison. If no such code exists, return UNKNOWN.
432 WATCH OUT! reverse_condition is not safe to use on a jump that might
433 be acting on the results of an IEEE floating point comparison, because
434 of the special treatment of non-signaling nans in comparisons.
435 Use reversed_comparison_code instead. */
437 enum rtx_code
438 reverse_condition (enum rtx_code code)
440 switch (code)
442 case EQ:
443 return NE;
444 case NE:
445 return EQ;
446 case GT:
447 return LE;
448 case GE:
449 return LT;
450 case LT:
451 return GE;
452 case LE:
453 return GT;
454 case GTU:
455 return LEU;
456 case GEU:
457 return LTU;
458 case LTU:
459 return GEU;
460 case LEU:
461 return GTU;
462 case UNORDERED:
463 return ORDERED;
464 case ORDERED:
465 return UNORDERED;
467 case UNLT:
468 case UNLE:
469 case UNGT:
470 case UNGE:
471 case UNEQ:
472 case LTGT:
473 return UNKNOWN;
475 default:
476 gcc_unreachable ();
480 /* Similar, but we're allowed to generate unordered comparisons, which
481 makes it safe for IEEE floating-point. Of course, we have to recognize
482 that the target will support them too... */
484 enum rtx_code
485 reverse_condition_maybe_unordered (enum rtx_code code)
487 switch (code)
489 case EQ:
490 return NE;
491 case NE:
492 return EQ;
493 case GT:
494 return UNLE;
495 case GE:
496 return UNLT;
497 case LT:
498 return UNGE;
499 case LE:
500 return UNGT;
501 case LTGT:
502 return UNEQ;
503 case UNORDERED:
504 return ORDERED;
505 case ORDERED:
506 return UNORDERED;
507 case UNLT:
508 return GE;
509 case UNLE:
510 return GT;
511 case UNGT:
512 return LE;
513 case UNGE:
514 return LT;
515 case UNEQ:
516 return LTGT;
518 default:
519 gcc_unreachable ();
523 /* Similar, but return the code when two operands of a comparison are swapped.
524 This IS safe for IEEE floating-point. */
526 enum rtx_code
527 swap_condition (enum rtx_code code)
529 switch (code)
531 case EQ:
532 case NE:
533 case UNORDERED:
534 case ORDERED:
535 case UNEQ:
536 case LTGT:
537 return code;
539 case GT:
540 return LT;
541 case GE:
542 return LE;
543 case LT:
544 return GT;
545 case LE:
546 return GE;
547 case GTU:
548 return LTU;
549 case GEU:
550 return LEU;
551 case LTU:
552 return GTU;
553 case LEU:
554 return GEU;
555 case UNLT:
556 return UNGT;
557 case UNLE:
558 return UNGE;
559 case UNGT:
560 return UNLT;
561 case UNGE:
562 return UNLE;
564 default:
565 gcc_unreachable ();
569 /* Given a comparison CODE, return the corresponding unsigned comparison.
570 If CODE is an equality comparison or already an unsigned comparison,
571 CODE is returned. */
573 enum rtx_code
574 unsigned_condition (enum rtx_code code)
576 switch (code)
578 case EQ:
579 case NE:
580 case GTU:
581 case GEU:
582 case LTU:
583 case LEU:
584 return code;
586 case GT:
587 return GTU;
588 case GE:
589 return GEU;
590 case LT:
591 return LTU;
592 case LE:
593 return LEU;
595 default:
596 gcc_unreachable ();
600 /* Similarly, return the signed version of a comparison. */
602 enum rtx_code
603 signed_condition (enum rtx_code code)
605 switch (code)
607 case EQ:
608 case NE:
609 case GT:
610 case GE:
611 case LT:
612 case LE:
613 return code;
615 case GTU:
616 return GT;
617 case GEU:
618 return GE;
619 case LTU:
620 return LT;
621 case LEU:
622 return LE;
624 default:
625 gcc_unreachable ();
629 /* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
630 truth of CODE1 implies the truth of CODE2. */
633 comparison_dominates_p (enum rtx_code code1, enum rtx_code code2)
635 /* UNKNOWN comparison codes can happen as a result of trying to revert
636 comparison codes.
637 They can't match anything, so we have to reject them here. */
638 if (code1 == UNKNOWN || code2 == UNKNOWN)
639 return 0;
641 if (code1 == code2)
642 return 1;
644 switch (code1)
646 case UNEQ:
647 if (code2 == UNLE || code2 == UNGE)
648 return 1;
649 break;
651 case EQ:
652 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
653 || code2 == ORDERED)
654 return 1;
655 break;
657 case UNLT:
658 if (code2 == UNLE || code2 == NE)
659 return 1;
660 break;
662 case LT:
663 if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
664 return 1;
665 break;
667 case UNGT:
668 if (code2 == UNGE || code2 == NE)
669 return 1;
670 break;
672 case GT:
673 if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
674 return 1;
675 break;
677 case GE:
678 case LE:
679 if (code2 == ORDERED)
680 return 1;
681 break;
683 case LTGT:
684 if (code2 == NE || code2 == ORDERED)
685 return 1;
686 break;
688 case LTU:
689 if (code2 == LEU || code2 == NE)
690 return 1;
691 break;
693 case GTU:
694 if (code2 == GEU || code2 == NE)
695 return 1;
696 break;
698 case UNORDERED:
699 if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
700 || code2 == UNGE || code2 == UNGT)
701 return 1;
702 break;
704 default:
705 break;
708 return 0;
711 /* Return 1 if INSN is an unconditional jump and nothing else. */
714 simplejump_p (rtx insn)
716 return (JUMP_P (insn)
717 && GET_CODE (PATTERN (insn)) == SET
718 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
719 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
722 /* Return nonzero if INSN is a (possibly) conditional jump
723 and nothing more.
725 Use of this function is deprecated, since we need to support combined
726 branch and compare insns. Use any_condjump_p instead whenever possible. */
729 condjump_p (rtx insn)
731 rtx x = PATTERN (insn);
733 if (GET_CODE (x) != SET
734 || GET_CODE (SET_DEST (x)) != PC)
735 return 0;
737 x = SET_SRC (x);
738 if (GET_CODE (x) == LABEL_REF)
739 return 1;
740 else
741 return (GET_CODE (x) == IF_THEN_ELSE
742 && ((GET_CODE (XEXP (x, 2)) == PC
743 && (GET_CODE (XEXP (x, 1)) == LABEL_REF
744 || GET_CODE (XEXP (x, 1)) == RETURN))
745 || (GET_CODE (XEXP (x, 1)) == PC
746 && (GET_CODE (XEXP (x, 2)) == LABEL_REF
747 || GET_CODE (XEXP (x, 2)) == RETURN))));
750 /* Return nonzero if INSN is a (possibly) conditional jump inside a
751 PARALLEL.
753 Use this function is deprecated, since we need to support combined
754 branch and compare insns. Use any_condjump_p instead whenever possible. */
757 condjump_in_parallel_p (rtx insn)
759 rtx x = PATTERN (insn);
761 if (GET_CODE (x) != PARALLEL)
762 return 0;
763 else
764 x = XVECEXP (x, 0, 0);
766 if (GET_CODE (x) != SET)
767 return 0;
768 if (GET_CODE (SET_DEST (x)) != PC)
769 return 0;
770 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
771 return 1;
772 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
773 return 0;
774 if (XEXP (SET_SRC (x), 2) == pc_rtx
775 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
776 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
777 return 1;
778 if (XEXP (SET_SRC (x), 1) == pc_rtx
779 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
780 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
781 return 1;
782 return 0;
785 /* Return set of PC, otherwise NULL. */
788 pc_set (rtx insn)
790 rtx pat;
791 if (!JUMP_P (insn))
792 return NULL_RTX;
793 pat = PATTERN (insn);
795 /* The set is allowed to appear either as the insn pattern or
796 the first set in a PARALLEL. */
797 if (GET_CODE (pat) == PARALLEL)
798 pat = XVECEXP (pat, 0, 0);
799 if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
800 return pat;
802 return NULL_RTX;
805 /* Return true when insn is an unconditional direct jump,
806 possibly bundled inside a PARALLEL. */
809 any_uncondjump_p (rtx insn)
811 rtx x = pc_set (insn);
812 if (!x)
813 return 0;
814 if (GET_CODE (SET_SRC (x)) != LABEL_REF)
815 return 0;
816 if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
817 return 0;
818 return 1;
821 /* Return true when insn is a conditional jump. This function works for
822 instructions containing PC sets in PARALLELs. The instruction may have
823 various other effects so before removing the jump you must verify
824 onlyjump_p.
826 Note that unlike condjump_p it returns false for unconditional jumps. */
829 any_condjump_p (rtx insn)
831 rtx x = pc_set (insn);
832 enum rtx_code a, b;
834 if (!x)
835 return 0;
836 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
837 return 0;
839 a = GET_CODE (XEXP (SET_SRC (x), 1));
840 b = GET_CODE (XEXP (SET_SRC (x), 2));
842 return ((b == PC && (a == LABEL_REF || a == RETURN))
843 || (a == PC && (b == LABEL_REF || b == RETURN)));
846 /* Return the label of a conditional jump. */
849 condjump_label (rtx insn)
851 rtx x = pc_set (insn);
853 if (!x)
854 return NULL_RTX;
855 x = SET_SRC (x);
856 if (GET_CODE (x) == LABEL_REF)
857 return x;
858 if (GET_CODE (x) != IF_THEN_ELSE)
859 return NULL_RTX;
860 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
861 return XEXP (x, 1);
862 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
863 return XEXP (x, 2);
864 return NULL_RTX;
867 /* Return true if INSN is a (possibly conditional) return insn. */
869 static int
870 returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
872 rtx x = *loc;
874 return x && (GET_CODE (x) == RETURN
875 || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
879 returnjump_p (rtx insn)
881 if (!JUMP_P (insn))
882 return 0;
883 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
886 /* Return true if INSN is a jump that only transfers control and
887 nothing more. */
890 onlyjump_p (rtx insn)
892 rtx set;
894 if (!JUMP_P (insn))
895 return 0;
897 set = single_set (insn);
898 if (set == NULL)
899 return 0;
900 if (GET_CODE (SET_DEST (set)) != PC)
901 return 0;
902 if (side_effects_p (SET_SRC (set)))
903 return 0;
905 return 1;
908 #ifdef HAVE_cc0
910 /* Return nonzero if X is an RTX that only sets the condition codes
911 and has no side effects. */
914 only_sets_cc0_p (rtx x)
916 if (! x)
917 return 0;
919 if (INSN_P (x))
920 x = PATTERN (x);
922 return sets_cc0_p (x) == 1 && ! side_effects_p (x);
925 /* Return 1 if X is an RTX that does nothing but set the condition codes
926 and CLOBBER or USE registers.
927 Return -1 if X does explicitly set the condition codes,
928 but also does other things. */
931 sets_cc0_p (rtx x)
933 if (! x)
934 return 0;
936 if (INSN_P (x))
937 x = PATTERN (x);
939 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
940 return 1;
941 if (GET_CODE (x) == PARALLEL)
943 int i;
944 int sets_cc0 = 0;
945 int other_things = 0;
946 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
948 if (GET_CODE (XVECEXP (x, 0, i)) == SET
949 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
950 sets_cc0 = 1;
951 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
952 other_things = 1;
954 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
956 return 0;
958 #endif
960 /* Find all CODE_LABELs referred to in X, and increment their use counts.
961 If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced
962 in INSN, then store one of them in JUMP_LABEL (INSN).
963 If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL
964 referenced in INSN, add a REG_LABEL note containing that label to INSN.
965 Also, when there are consecutive labels, canonicalize on the last of them.
967 Note that two labels separated by a loop-beginning note
968 must be kept distinct if we have not yet done loop-optimization,
969 because the gap between them is where loop-optimize
970 will want to move invariant code to. CROSS_JUMP tells us
971 that loop-optimization is done with. */
973 void
974 mark_jump_label (rtx x, rtx insn, int in_mem)
976 RTX_CODE code = GET_CODE (x);
977 int i;
978 const char *fmt;
980 switch (code)
982 case PC:
983 case CC0:
984 case REG:
985 case CONST_INT:
986 case CONST_DOUBLE:
987 case CLOBBER:
988 case CALL:
989 return;
991 case MEM:
992 in_mem = 1;
993 break;
995 case SEQUENCE:
996 for (i = 0; i < XVECLEN (x, 0); i++)
997 mark_jump_label (PATTERN (XVECEXP (x, 0, i)),
998 XVECEXP (x, 0, i), 0);
999 return;
1001 case SYMBOL_REF:
1002 if (!in_mem)
1003 return;
1005 /* If this is a constant-pool reference, see if it is a label. */
1006 if (CONSTANT_POOL_ADDRESS_P (x))
1007 mark_jump_label (get_pool_constant (x), insn, in_mem);
1008 break;
1010 case LABEL_REF:
1012 rtx label = XEXP (x, 0);
1014 /* Ignore remaining references to unreachable labels that
1015 have been deleted. */
1016 if (NOTE_P (label)
1017 && NOTE_LINE_NUMBER (label) == NOTE_INSN_DELETED_LABEL)
1018 break;
1020 gcc_assert (LABEL_P (label));
1022 /* Ignore references to labels of containing functions. */
1023 if (LABEL_REF_NONLOCAL_P (x))
1024 break;
1026 XEXP (x, 0) = label;
1027 if (! insn || ! INSN_DELETED_P (insn))
1028 ++LABEL_NUSES (label);
1030 if (insn)
1032 if (JUMP_P (insn))
1033 JUMP_LABEL (insn) = label;
1034 else
1036 /* Add a REG_LABEL note for LABEL unless there already
1037 is one. All uses of a label, except for labels
1038 that are the targets of jumps, must have a
1039 REG_LABEL note. */
1040 if (! find_reg_note (insn, REG_LABEL, label))
1041 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, label,
1042 REG_NOTES (insn));
1045 return;
1048 /* Do walk the labels in a vector, but not the first operand of an
1049 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1050 case ADDR_VEC:
1051 case ADDR_DIFF_VEC:
1052 if (! INSN_DELETED_P (insn))
1054 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
1056 for (i = 0; i < XVECLEN (x, eltnum); i++)
1057 mark_jump_label (XVECEXP (x, eltnum, i), NULL_RTX, in_mem);
1059 return;
1061 default:
1062 break;
1065 fmt = GET_RTX_FORMAT (code);
1066 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1068 if (fmt[i] == 'e')
1069 mark_jump_label (XEXP (x, i), insn, in_mem);
1070 else if (fmt[i] == 'E')
1072 int j;
1073 for (j = 0; j < XVECLEN (x, i); j++)
1074 mark_jump_label (XVECEXP (x, i, j), insn, in_mem);
1080 /* Delete insn INSN from the chain of insns and update label ref counts
1081 and delete insns now unreachable.
1083 Returns the first insn after INSN that was not deleted.
1085 Usage of this instruction is deprecated. Use delete_insn instead and
1086 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1089 delete_related_insns (rtx insn)
1091 int was_code_label = (LABEL_P (insn));
1092 rtx note;
1093 rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
1095 while (next && INSN_DELETED_P (next))
1096 next = NEXT_INSN (next);
1098 /* This insn is already deleted => return first following nondeleted. */
1099 if (INSN_DELETED_P (insn))
1100 return next;
1102 delete_insn (insn);
1104 /* If instruction is followed by a barrier,
1105 delete the barrier too. */
1107 if (next != 0 && BARRIER_P (next))
1108 delete_insn (next);
1110 /* If deleting a jump, decrement the count of the label,
1111 and delete the label if it is now unused. */
1113 if (JUMP_P (insn) && JUMP_LABEL (insn))
1115 rtx lab = JUMP_LABEL (insn), lab_next;
1117 if (LABEL_NUSES (lab) == 0)
1119 /* This can delete NEXT or PREV,
1120 either directly if NEXT is JUMP_LABEL (INSN),
1121 or indirectly through more levels of jumps. */
1122 delete_related_insns (lab);
1124 /* I feel a little doubtful about this loop,
1125 but I see no clean and sure alternative way
1126 to find the first insn after INSN that is not now deleted.
1127 I hope this works. */
1128 while (next && INSN_DELETED_P (next))
1129 next = NEXT_INSN (next);
1130 return next;
1132 else if (tablejump_p (insn, NULL, &lab_next))
1134 /* If we're deleting the tablejump, delete the dispatch table.
1135 We may not be able to kill the label immediately preceding
1136 just yet, as it might be referenced in code leading up to
1137 the tablejump. */
1138 delete_related_insns (lab_next);
1142 /* Likewise if we're deleting a dispatch table. */
1144 if (JUMP_P (insn)
1145 && (GET_CODE (PATTERN (insn)) == ADDR_VEC
1146 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
1148 rtx pat = PATTERN (insn);
1149 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1150 int len = XVECLEN (pat, diff_vec_p);
1152 for (i = 0; i < len; i++)
1153 if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1154 delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
1155 while (next && INSN_DELETED_P (next))
1156 next = NEXT_INSN (next);
1157 return next;
1160 /* Likewise for an ordinary INSN / CALL_INSN with a REG_LABEL note. */
1161 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
1162 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1163 if (REG_NOTE_KIND (note) == REG_LABEL
1164 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1165 && LABEL_P (XEXP (note, 0)))
1166 if (LABEL_NUSES (XEXP (note, 0)) == 0)
1167 delete_related_insns (XEXP (note, 0));
1169 while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
1170 prev = PREV_INSN (prev);
1172 /* If INSN was a label and a dispatch table follows it,
1173 delete the dispatch table. The tablejump must have gone already.
1174 It isn't useful to fall through into a table. */
1176 if (was_code_label
1177 && NEXT_INSN (insn) != 0
1178 && JUMP_P (NEXT_INSN (insn))
1179 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
1180 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
1181 next = delete_related_insns (NEXT_INSN (insn));
1183 /* If INSN was a label, delete insns following it if now unreachable. */
1185 if (was_code_label && prev && BARRIER_P (prev))
1187 enum rtx_code code;
1188 while (next)
1190 code = GET_CODE (next);
1191 if (code == NOTE)
1192 next = NEXT_INSN (next);
1193 /* Keep going past other deleted labels to delete what follows. */
1194 else if (code == CODE_LABEL && INSN_DELETED_P (next))
1195 next = NEXT_INSN (next);
1196 else if (code == BARRIER || INSN_P (next))
1197 /* Note: if this deletes a jump, it can cause more
1198 deletion of unreachable code, after a different label.
1199 As long as the value from this recursive call is correct,
1200 this invocation functions correctly. */
1201 next = delete_related_insns (next);
1202 else
1203 break;
1207 return next;
1210 /* Delete a range of insns from FROM to TO, inclusive.
1211 This is for the sake of peephole optimization, so assume
1212 that whatever these insns do will still be done by a new
1213 peephole insn that will replace them. */
1215 void
1216 delete_for_peephole (rtx from, rtx to)
1218 rtx insn = from;
1220 while (1)
1222 rtx next = NEXT_INSN (insn);
1223 rtx prev = PREV_INSN (insn);
1225 if (!NOTE_P (insn))
1227 INSN_DELETED_P (insn) = 1;
1229 /* Patch this insn out of the chain. */
1230 /* We don't do this all at once, because we
1231 must preserve all NOTEs. */
1232 if (prev)
1233 NEXT_INSN (prev) = next;
1235 if (next)
1236 PREV_INSN (next) = prev;
1239 if (insn == to)
1240 break;
1241 insn = next;
1244 /* Note that if TO is an unconditional jump
1245 we *do not* delete the BARRIER that follows,
1246 since the peephole that replaces this sequence
1247 is also an unconditional jump in that case. */
1250 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1251 NLABEL as a return. Accrue modifications into the change group. */
1253 static void
1254 redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
1256 rtx x = *loc;
1257 RTX_CODE code = GET_CODE (x);
1258 int i;
1259 const char *fmt;
1261 if (code == LABEL_REF)
1263 if (XEXP (x, 0) == olabel)
1265 rtx n;
1266 if (nlabel)
1267 n = gen_rtx_LABEL_REF (Pmode, nlabel);
1268 else
1269 n = gen_rtx_RETURN (VOIDmode);
1271 validate_change (insn, loc, n, 1);
1272 return;
1275 else if (code == RETURN && olabel == 0)
1277 if (nlabel)
1278 x = gen_rtx_LABEL_REF (Pmode, nlabel);
1279 else
1280 x = gen_rtx_RETURN (VOIDmode);
1281 if (loc == &PATTERN (insn))
1282 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1283 validate_change (insn, loc, x, 1);
1284 return;
1287 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1288 && GET_CODE (SET_SRC (x)) == LABEL_REF
1289 && XEXP (SET_SRC (x), 0) == olabel)
1291 validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1292 return;
1295 fmt = GET_RTX_FORMAT (code);
1296 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1298 if (fmt[i] == 'e')
1299 redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1300 else if (fmt[i] == 'E')
1302 int j;
1303 for (j = 0; j < XVECLEN (x, i); j++)
1304 redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
1309 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
1310 the modifications into the change group. Return false if we did
1311 not see how to do that. */
1314 redirect_jump_1 (rtx jump, rtx nlabel)
1316 int ochanges = num_validated_changes ();
1317 rtx *loc;
1319 if (GET_CODE (PATTERN (jump)) == PARALLEL)
1320 loc = &XVECEXP (PATTERN (jump), 0, 0);
1321 else
1322 loc = &PATTERN (jump);
1324 redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
1325 return num_validated_changes () > ochanges;
1328 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
1329 jump target label is unused as a result, it and the code following
1330 it may be deleted.
1332 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
1333 RETURN insn.
1335 The return value will be 1 if the change was made, 0 if it wasn't
1336 (this can only occur for NLABEL == 0). */
1339 redirect_jump (rtx jump, rtx nlabel, int delete_unused)
1341 rtx olabel = JUMP_LABEL (jump);
1343 if (nlabel == olabel)
1344 return 1;
1346 if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
1347 return 0;
1349 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
1350 return 1;
1353 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1354 NLABEL in JUMP.
1355 If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1356 count has dropped to zero. */
1357 void
1358 redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
1359 int invert)
1361 rtx note;
1363 /* Negative DELETE_UNUSED used to be used to signalize behavior on
1364 moving FUNCTION_END note. Just sanity check that no user still worry
1365 about this. */
1366 gcc_assert (delete_unused >= 0);
1367 JUMP_LABEL (jump) = nlabel;
1368 if (nlabel)
1369 ++LABEL_NUSES (nlabel);
1371 /* Update labels in any REG_EQUAL note. */
1372 if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
1374 if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
1375 remove_note (jump, note);
1376 else
1378 redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
1379 confirm_change_group ();
1383 if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
1384 /* Undefined labels will remain outside the insn stream. */
1385 && INSN_UID (olabel))
1386 delete_related_insns (olabel);
1387 if (invert)
1388 invert_br_probabilities (jump);
1391 /* Invert the jump condition X contained in jump insn INSN. Accrue the
1392 modifications into the change group. Return nonzero for success. */
1393 static int
1394 invert_exp_1 (rtx x, rtx insn)
1396 RTX_CODE code = GET_CODE (x);
1398 if (code == IF_THEN_ELSE)
1400 rtx comp = XEXP (x, 0);
1401 rtx tem;
1402 enum rtx_code reversed_code;
1404 /* We can do this in two ways: The preferable way, which can only
1405 be done if this is not an integer comparison, is to reverse
1406 the comparison code. Otherwise, swap the THEN-part and ELSE-part
1407 of the IF_THEN_ELSE. If we can't do either, fail. */
1409 reversed_code = reversed_comparison_code (comp, insn);
1411 if (reversed_code != UNKNOWN)
1413 validate_change (insn, &XEXP (x, 0),
1414 gen_rtx_fmt_ee (reversed_code,
1415 GET_MODE (comp), XEXP (comp, 0),
1416 XEXP (comp, 1)),
1418 return 1;
1421 tem = XEXP (x, 1);
1422 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
1423 validate_change (insn, &XEXP (x, 2), tem, 1);
1424 return 1;
1426 else
1427 return 0;
1430 /* Invert the condition of the jump JUMP, and make it jump to label
1431 NLABEL instead of where it jumps now. Accrue changes into the
1432 change group. Return false if we didn't see how to perform the
1433 inversion and redirection. */
1436 invert_jump_1 (rtx jump, rtx nlabel)
1438 rtx x = pc_set (jump);
1439 int ochanges;
1440 int ok;
1442 ochanges = num_validated_changes ();
1443 gcc_assert (x);
1444 ok = invert_exp_1 (SET_SRC (x), jump);
1445 gcc_assert (ok);
1447 if (num_validated_changes () == ochanges)
1448 return 0;
1450 /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1451 in Pmode, so checking this is not merely an optimization. */
1452 return nlabel == JUMP_LABEL (jump) || redirect_jump_1 (jump, nlabel);
1455 /* Invert the condition of the jump JUMP, and make it jump to label
1456 NLABEL instead of where it jumps now. Return true if successful. */
1459 invert_jump (rtx jump, rtx nlabel, int delete_unused)
1461 rtx olabel = JUMP_LABEL (jump);
1463 if (invert_jump_1 (jump, nlabel) && apply_change_group ())
1465 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
1466 return 1;
1468 cancel_changes (0);
1469 return 0;
1473 /* Like rtx_equal_p except that it considers two REGs as equal
1474 if they renumber to the same value and considers two commutative
1475 operations to be the same if the order of the operands has been
1476 reversed. */
1479 rtx_renumbered_equal_p (rtx x, rtx y)
1481 int i;
1482 enum rtx_code code = GET_CODE (x);
1483 const char *fmt;
1485 if (x == y)
1486 return 1;
1488 if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
1489 && (REG_P (y) || (GET_CODE (y) == SUBREG
1490 && REG_P (SUBREG_REG (y)))))
1492 int reg_x = -1, reg_y = -1;
1493 int byte_x = 0, byte_y = 0;
1495 if (GET_MODE (x) != GET_MODE (y))
1496 return 0;
1498 /* If we haven't done any renumbering, don't
1499 make any assumptions. */
1500 if (reg_renumber == 0)
1501 return rtx_equal_p (x, y);
1503 if (code == SUBREG)
1505 reg_x = REGNO (SUBREG_REG (x));
1506 byte_x = SUBREG_BYTE (x);
1508 if (reg_renumber[reg_x] >= 0)
1510 reg_x = subreg_regno_offset (reg_renumber[reg_x],
1511 GET_MODE (SUBREG_REG (x)),
1512 byte_x,
1513 GET_MODE (x));
1514 byte_x = 0;
1517 else
1519 reg_x = REGNO (x);
1520 if (reg_renumber[reg_x] >= 0)
1521 reg_x = reg_renumber[reg_x];
1524 if (GET_CODE (y) == SUBREG)
1526 reg_y = REGNO (SUBREG_REG (y));
1527 byte_y = SUBREG_BYTE (y);
1529 if (reg_renumber[reg_y] >= 0)
1531 reg_y = subreg_regno_offset (reg_renumber[reg_y],
1532 GET_MODE (SUBREG_REG (y)),
1533 byte_y,
1534 GET_MODE (y));
1535 byte_y = 0;
1538 else
1540 reg_y = REGNO (y);
1541 if (reg_renumber[reg_y] >= 0)
1542 reg_y = reg_renumber[reg_y];
1545 return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
1548 /* Now we have disposed of all the cases
1549 in which different rtx codes can match. */
1550 if (code != GET_CODE (y))
1551 return 0;
1553 switch (code)
1555 case PC:
1556 case CC0:
1557 case ADDR_VEC:
1558 case ADDR_DIFF_VEC:
1559 case CONST_INT:
1560 case CONST_DOUBLE:
1561 return 0;
1563 case LABEL_REF:
1564 /* We can't assume nonlocal labels have their following insns yet. */
1565 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
1566 return XEXP (x, 0) == XEXP (y, 0);
1568 /* Two label-refs are equivalent if they point at labels
1569 in the same position in the instruction stream. */
1570 return (next_real_insn (XEXP (x, 0))
1571 == next_real_insn (XEXP (y, 0)));
1573 case SYMBOL_REF:
1574 return XSTR (x, 0) == XSTR (y, 0);
1576 case CODE_LABEL:
1577 /* If we didn't match EQ equality above, they aren't the same. */
1578 return 0;
1580 default:
1581 break;
1584 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
1586 if (GET_MODE (x) != GET_MODE (y))
1587 return 0;
1589 /* For commutative operations, the RTX match if the operand match in any
1590 order. Also handle the simple binary and unary cases without a loop. */
1591 if (targetm.commutative_p (x, UNKNOWN))
1592 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1593 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
1594 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
1595 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
1596 else if (NON_COMMUTATIVE_P (x))
1597 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1598 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
1599 else if (UNARY_P (x))
1600 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
1602 /* Compare the elements. If any pair of corresponding elements
1603 fail to match, return 0 for the whole things. */
1605 fmt = GET_RTX_FORMAT (code);
1606 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1608 int j;
1609 switch (fmt[i])
1611 case 'w':
1612 if (XWINT (x, i) != XWINT (y, i))
1613 return 0;
1614 break;
1616 case 'i':
1617 if (XINT (x, i) != XINT (y, i))
1618 return 0;
1619 break;
1621 case 't':
1622 if (XTREE (x, i) != XTREE (y, i))
1623 return 0;
1624 break;
1626 case 's':
1627 if (strcmp (XSTR (x, i), XSTR (y, i)))
1628 return 0;
1629 break;
1631 case 'e':
1632 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
1633 return 0;
1634 break;
1636 case 'u':
1637 if (XEXP (x, i) != XEXP (y, i))
1638 return 0;
1639 /* Fall through. */
1640 case '0':
1641 break;
1643 case 'E':
1644 if (XVECLEN (x, i) != XVECLEN (y, i))
1645 return 0;
1646 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1647 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
1648 return 0;
1649 break;
1651 default:
1652 gcc_unreachable ();
1655 return 1;
1658 /* If X is a hard register or equivalent to one or a subregister of one,
1659 return the hard register number. If X is a pseudo register that was not
1660 assigned a hard register, return the pseudo register number. Otherwise,
1661 return -1. Any rtx is valid for X. */
1664 true_regnum (rtx x)
1666 if (REG_P (x))
1668 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
1669 return reg_renumber[REGNO (x)];
1670 return REGNO (x);
1672 if (GET_CODE (x) == SUBREG)
1674 int base = true_regnum (SUBREG_REG (x));
1675 if (base >= 0
1676 && base < FIRST_PSEUDO_REGISTER
1677 && subreg_offset_representable_p (REGNO (SUBREG_REG (x)),
1678 GET_MODE (SUBREG_REG (x)),
1679 SUBREG_BYTE (x), GET_MODE (x)))
1680 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
1681 GET_MODE (SUBREG_REG (x)),
1682 SUBREG_BYTE (x), GET_MODE (x));
1684 return -1;
1687 /* Return regno of the register REG and handle subregs too. */
1688 unsigned int
1689 reg_or_subregno (rtx reg)
1691 if (GET_CODE (reg) == SUBREG)
1692 reg = SUBREG_REG (reg);
1693 gcc_assert (REG_P (reg));
1694 return REGNO (reg);