-dA enhancement
[official-gcc.git] / gcc / jump.c
blob39fc2340c31085561a3bb3b0323bb028076d40fc
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, 2008, 2009, 2010
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 "basic-block.h"
51 #include "expr.h"
52 #include "except.h"
53 #include "diagnostic-core.h"
54 #include "reload.h"
55 #include "predict.h"
56 #include "timevar.h"
57 #include "tree-pass.h"
58 #include "target.h"
60 /* Optimize jump y; x: ... y: jumpif... x?
61 Don't know if it is worth bothering with. */
62 /* Optimize two cases of conditional jump to conditional jump?
63 This can never delete any instruction or make anything dead,
64 or even change what is live at any point.
65 So perhaps let combiner do it. */
67 static void init_label_info (rtx);
68 static void mark_all_labels (rtx);
69 static void mark_jump_label_1 (rtx, rtx, bool, bool);
70 static void mark_jump_label_asm (rtx, 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 /* Worker for rebuild_jump_labels and rebuild_jump_labels_chain. */
76 static void
77 rebuild_jump_labels_1 (rtx f, bool count_forced)
79 rtx insn;
81 timevar_push (TV_REBUILD_JUMP);
82 init_label_info (f);
83 mark_all_labels (f);
85 /* Keep track of labels used from static data; we don't track them
86 closely enough to delete them here, so make sure their reference
87 count doesn't drop to zero. */
89 if (count_forced)
90 for (insn = forced_labels; insn; insn = XEXP (insn, 1))
91 if (LABEL_P (XEXP (insn, 0)))
92 LABEL_NUSES (XEXP (insn, 0))++;
93 timevar_pop (TV_REBUILD_JUMP);
96 /* This function rebuilds the JUMP_LABEL field and REG_LABEL_TARGET
97 notes in jumping insns and REG_LABEL_OPERAND notes in non-jumping
98 instructions and jumping insns that have labels as operands
99 (e.g. cbranchsi4). */
100 void
101 rebuild_jump_labels (rtx f)
103 rebuild_jump_labels_1 (f, true);
106 /* This function is like rebuild_jump_labels, but doesn't run over
107 forced_labels. It can be used on insn chains that aren't the
108 main function chain. */
109 void
110 rebuild_jump_labels_chain (rtx chain)
112 rebuild_jump_labels_1 (chain, false);
115 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
116 non-fallthru insn. This is not generally true, as multiple barriers
117 may have crept in, or the BARRIER may be separated from the last
118 real insn by one or more NOTEs.
120 This simple pass moves barriers and removes duplicates so that the
121 old code is happy.
123 unsigned int
124 cleanup_barriers (void)
126 rtx insn, next, prev;
127 for (insn = get_insns (); insn; insn = next)
129 next = NEXT_INSN (insn);
130 if (BARRIER_P (insn))
132 prev = prev_nonnote_insn (insn);
133 if (!prev)
134 continue;
135 if (BARRIER_P (prev))
136 delete_insn (insn);
137 else if (prev != PREV_INSN (insn))
138 reorder_insns (insn, insn, prev);
141 return 0;
144 struct rtl_opt_pass pass_cleanup_barriers =
147 RTL_PASS,
148 "barriers", /* name */
149 NULL, /* gate */
150 cleanup_barriers, /* execute */
151 NULL, /* sub */
152 NULL, /* next */
153 0, /* static_pass_number */
154 TV_NONE, /* tv_id */
155 0, /* properties_required */
156 0, /* properties_provided */
157 0, /* properties_destroyed */
158 0, /* todo_flags_start */
159 TODO_dump_func /* todo_flags_finish */
164 /* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
165 for remaining targets for JUMP_P. Delete any REG_LABEL_OPERAND
166 notes whose labels don't occur in the insn any more. */
168 static void
169 init_label_info (rtx f)
171 rtx insn;
173 for (insn = f; insn; insn = NEXT_INSN (insn))
175 if (LABEL_P (insn))
176 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
178 /* REG_LABEL_TARGET notes (including the JUMP_LABEL field) are
179 sticky and not reset here; that way we won't lose association
180 with a label when e.g. the source for a target register
181 disappears out of reach for targets that may use jump-target
182 registers. Jump transformations are supposed to transform
183 any REG_LABEL_TARGET notes. The target label reference in a
184 branch may disappear from the branch (and from the
185 instruction before it) for other reasons, like register
186 allocation. */
188 if (INSN_P (insn))
190 rtx note, next;
192 for (note = REG_NOTES (insn); note; note = next)
194 next = XEXP (note, 1);
195 if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND
196 && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
197 remove_note (insn, note);
203 /* Mark the label each jump jumps to.
204 Combine consecutive labels, and count uses of labels. */
206 static void
207 mark_all_labels (rtx f)
209 rtx insn;
210 rtx prev_nonjump_insn = NULL;
212 for (insn = f; insn; insn = NEXT_INSN (insn))
213 if (NONDEBUG_INSN_P (insn))
215 mark_jump_label (PATTERN (insn), insn, 0);
217 /* If the previous non-jump insn sets something to a label,
218 something that this jump insn uses, make that label the primary
219 target of this insn if we don't yet have any. That previous
220 insn must be a single_set and not refer to more than one label.
221 The jump insn must not refer to other labels as jump targets
222 and must be a plain (set (pc) ...), maybe in a parallel, and
223 may refer to the item being set only directly or as one of the
224 arms in an IF_THEN_ELSE. */
225 if (! INSN_DELETED_P (insn)
226 && JUMP_P (insn)
227 && JUMP_LABEL (insn) == NULL)
229 rtx label_note = NULL;
230 rtx pc = pc_set (insn);
231 rtx pc_src = pc != NULL ? SET_SRC (pc) : NULL;
233 if (prev_nonjump_insn != NULL)
234 label_note
235 = find_reg_note (prev_nonjump_insn, REG_LABEL_OPERAND, NULL);
237 if (label_note != NULL && pc_src != NULL)
239 rtx label_set = single_set (prev_nonjump_insn);
240 rtx label_dest
241 = label_set != NULL ? SET_DEST (label_set) : NULL;
243 if (label_set != NULL
244 /* The source must be the direct LABEL_REF, not a
245 PLUS, UNSPEC, IF_THEN_ELSE etc. */
246 && GET_CODE (SET_SRC (label_set)) == LABEL_REF
247 && (rtx_equal_p (label_dest, pc_src)
248 || (GET_CODE (pc_src) == IF_THEN_ELSE
249 && (rtx_equal_p (label_dest, XEXP (pc_src, 1))
250 || rtx_equal_p (label_dest,
251 XEXP (pc_src, 2))))))
254 /* The CODE_LABEL referred to in the note must be the
255 CODE_LABEL in the LABEL_REF of the "set". We can
256 conveniently use it for the marker function, which
257 requires a LABEL_REF wrapping. */
258 gcc_assert (XEXP (label_note, 0)
259 == XEXP (SET_SRC (label_set), 0));
261 mark_jump_label_1 (label_set, insn, false, true);
262 gcc_assert (JUMP_LABEL (insn)
263 == XEXP (SET_SRC (label_set), 0));
267 else if (! INSN_DELETED_P (insn))
268 prev_nonjump_insn = insn;
270 else if (LABEL_P (insn))
271 prev_nonjump_insn = NULL;
273 /* If we are in cfglayout mode, there may be non-insns between the
274 basic blocks. If those non-insns represent tablejump data, they
275 contain label references that we must record. */
276 if (current_ir_type () == IR_RTL_CFGLAYOUT)
278 basic_block bb;
279 rtx insn;
280 FOR_EACH_BB (bb)
282 for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
283 if (INSN_P (insn))
285 gcc_assert (JUMP_TABLE_DATA_P (insn));
286 mark_jump_label (PATTERN (insn), insn, 0);
289 for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
290 if (INSN_P (insn))
292 gcc_assert (JUMP_TABLE_DATA_P (insn));
293 mark_jump_label (PATTERN (insn), insn, 0);
299 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
300 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
301 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
302 know whether it's source is floating point or integer comparison. Machine
303 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
304 to help this function avoid overhead in these cases. */
305 enum rtx_code
306 reversed_comparison_code_parts (enum rtx_code code, const_rtx arg0,
307 const_rtx arg1, const_rtx insn)
309 enum machine_mode mode;
311 /* If this is not actually a comparison, we can't reverse it. */
312 if (GET_RTX_CLASS (code) != RTX_COMPARE
313 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
314 return UNKNOWN;
316 mode = GET_MODE (arg0);
317 if (mode == VOIDmode)
318 mode = GET_MODE (arg1);
320 /* First see if machine description supplies us way to reverse the
321 comparison. Give it priority over everything else to allow
322 machine description to do tricks. */
323 if (GET_MODE_CLASS (mode) == MODE_CC
324 && REVERSIBLE_CC_MODE (mode))
326 #ifdef REVERSE_CONDITION
327 return REVERSE_CONDITION (code, mode);
328 #else
329 return reverse_condition (code);
330 #endif
333 /* Try a few special cases based on the comparison code. */
334 switch (code)
336 case GEU:
337 case GTU:
338 case LEU:
339 case LTU:
340 case NE:
341 case EQ:
342 /* It is always safe to reverse EQ and NE, even for the floating
343 point. Similarly the unsigned comparisons are never used for
344 floating point so we can reverse them in the default way. */
345 return reverse_condition (code);
346 case ORDERED:
347 case UNORDERED:
348 case LTGT:
349 case UNEQ:
350 /* In case we already see unordered comparison, we can be sure to
351 be dealing with floating point so we don't need any more tests. */
352 return reverse_condition_maybe_unordered (code);
353 case UNLT:
354 case UNLE:
355 case UNGT:
356 case UNGE:
357 /* We don't have safe way to reverse these yet. */
358 return UNKNOWN;
359 default:
360 break;
363 if (GET_MODE_CLASS (mode) == MODE_CC || CC0_P (arg0))
365 const_rtx prev;
366 /* Try to search for the comparison to determine the real mode.
367 This code is expensive, but with sane machine description it
368 will be never used, since REVERSIBLE_CC_MODE will return true
369 in all cases. */
370 if (! insn)
371 return UNKNOWN;
373 /* These CONST_CAST's are okay because prev_nonnote_insn just
374 returns its argument and we assign it to a const_rtx
375 variable. */
376 for (prev = prev_nonnote_insn (CONST_CAST_RTX(insn));
377 prev != 0 && !LABEL_P (prev);
378 prev = prev_nonnote_insn (CONST_CAST_RTX(prev)))
380 const_rtx set = set_of (arg0, prev);
381 if (set && GET_CODE (set) == SET
382 && rtx_equal_p (SET_DEST (set), arg0))
384 rtx src = SET_SRC (set);
386 if (GET_CODE (src) == COMPARE)
388 rtx comparison = src;
389 arg0 = XEXP (src, 0);
390 mode = GET_MODE (arg0);
391 if (mode == VOIDmode)
392 mode = GET_MODE (XEXP (comparison, 1));
393 break;
395 /* We can get past reg-reg moves. This may be useful for model
396 of i387 comparisons that first move flag registers around. */
397 if (REG_P (src))
399 arg0 = src;
400 continue;
403 /* If register is clobbered in some ununderstandable way,
404 give up. */
405 if (set)
406 return UNKNOWN;
410 /* Test for an integer condition, or a floating-point comparison
411 in which NaNs can be ignored. */
412 if (CONST_INT_P (arg0)
413 || (GET_MODE (arg0) != VOIDmode
414 && GET_MODE_CLASS (mode) != MODE_CC
415 && !HONOR_NANS (mode)))
416 return reverse_condition (code);
418 return UNKNOWN;
421 /* A wrapper around the previous function to take COMPARISON as rtx
422 expression. This simplifies many callers. */
423 enum rtx_code
424 reversed_comparison_code (const_rtx comparison, const_rtx insn)
426 if (!COMPARISON_P (comparison))
427 return UNKNOWN;
428 return reversed_comparison_code_parts (GET_CODE (comparison),
429 XEXP (comparison, 0),
430 XEXP (comparison, 1), insn);
433 /* Return comparison with reversed code of EXP.
434 Return NULL_RTX in case we fail to do the reversal. */
436 reversed_comparison (const_rtx exp, enum machine_mode mode)
438 enum rtx_code reversed_code = reversed_comparison_code (exp, NULL_RTX);
439 if (reversed_code == UNKNOWN)
440 return NULL_RTX;
441 else
442 return simplify_gen_relational (reversed_code, mode, VOIDmode,
443 XEXP (exp, 0), XEXP (exp, 1));
447 /* Given an rtx-code for a comparison, return the code for the negated
448 comparison. If no such code exists, return UNKNOWN.
450 WATCH OUT! reverse_condition is not safe to use on a jump that might
451 be acting on the results of an IEEE floating point comparison, because
452 of the special treatment of non-signaling nans in comparisons.
453 Use reversed_comparison_code instead. */
455 enum rtx_code
456 reverse_condition (enum rtx_code code)
458 switch (code)
460 case EQ:
461 return NE;
462 case NE:
463 return EQ;
464 case GT:
465 return LE;
466 case GE:
467 return LT;
468 case LT:
469 return GE;
470 case LE:
471 return GT;
472 case GTU:
473 return LEU;
474 case GEU:
475 return LTU;
476 case LTU:
477 return GEU;
478 case LEU:
479 return GTU;
480 case UNORDERED:
481 return ORDERED;
482 case ORDERED:
483 return UNORDERED;
485 case UNLT:
486 case UNLE:
487 case UNGT:
488 case UNGE:
489 case UNEQ:
490 case LTGT:
491 return UNKNOWN;
493 default:
494 gcc_unreachable ();
498 /* Similar, but we're allowed to generate unordered comparisons, which
499 makes it safe for IEEE floating-point. Of course, we have to recognize
500 that the target will support them too... */
502 enum rtx_code
503 reverse_condition_maybe_unordered (enum rtx_code code)
505 switch (code)
507 case EQ:
508 return NE;
509 case NE:
510 return EQ;
511 case GT:
512 return UNLE;
513 case GE:
514 return UNLT;
515 case LT:
516 return UNGE;
517 case LE:
518 return UNGT;
519 case LTGT:
520 return UNEQ;
521 case UNORDERED:
522 return ORDERED;
523 case ORDERED:
524 return UNORDERED;
525 case UNLT:
526 return GE;
527 case UNLE:
528 return GT;
529 case UNGT:
530 return LE;
531 case UNGE:
532 return LT;
533 case UNEQ:
534 return LTGT;
536 default:
537 gcc_unreachable ();
541 /* Similar, but return the code when two operands of a comparison are swapped.
542 This IS safe for IEEE floating-point. */
544 enum rtx_code
545 swap_condition (enum rtx_code code)
547 switch (code)
549 case EQ:
550 case NE:
551 case UNORDERED:
552 case ORDERED:
553 case UNEQ:
554 case LTGT:
555 return code;
557 case GT:
558 return LT;
559 case GE:
560 return LE;
561 case LT:
562 return GT;
563 case LE:
564 return GE;
565 case GTU:
566 return LTU;
567 case GEU:
568 return LEU;
569 case LTU:
570 return GTU;
571 case LEU:
572 return GEU;
573 case UNLT:
574 return UNGT;
575 case UNLE:
576 return UNGE;
577 case UNGT:
578 return UNLT;
579 case UNGE:
580 return UNLE;
582 default:
583 gcc_unreachable ();
587 /* Given a comparison CODE, return the corresponding unsigned comparison.
588 If CODE is an equality comparison or already an unsigned comparison,
589 CODE is returned. */
591 enum rtx_code
592 unsigned_condition (enum rtx_code code)
594 switch (code)
596 case EQ:
597 case NE:
598 case GTU:
599 case GEU:
600 case LTU:
601 case LEU:
602 return code;
604 case GT:
605 return GTU;
606 case GE:
607 return GEU;
608 case LT:
609 return LTU;
610 case LE:
611 return LEU;
613 default:
614 gcc_unreachable ();
618 /* Similarly, return the signed version of a comparison. */
620 enum rtx_code
621 signed_condition (enum rtx_code code)
623 switch (code)
625 case EQ:
626 case NE:
627 case GT:
628 case GE:
629 case LT:
630 case LE:
631 return code;
633 case GTU:
634 return GT;
635 case GEU:
636 return GE;
637 case LTU:
638 return LT;
639 case LEU:
640 return LE;
642 default:
643 gcc_unreachable ();
647 /* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
648 truth of CODE1 implies the truth of CODE2. */
651 comparison_dominates_p (enum rtx_code code1, enum rtx_code code2)
653 /* UNKNOWN comparison codes can happen as a result of trying to revert
654 comparison codes.
655 They can't match anything, so we have to reject them here. */
656 if (code1 == UNKNOWN || code2 == UNKNOWN)
657 return 0;
659 if (code1 == code2)
660 return 1;
662 switch (code1)
664 case UNEQ:
665 if (code2 == UNLE || code2 == UNGE)
666 return 1;
667 break;
669 case EQ:
670 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
671 || code2 == ORDERED)
672 return 1;
673 break;
675 case UNLT:
676 if (code2 == UNLE || code2 == NE)
677 return 1;
678 break;
680 case LT:
681 if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
682 return 1;
683 break;
685 case UNGT:
686 if (code2 == UNGE || code2 == NE)
687 return 1;
688 break;
690 case GT:
691 if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
692 return 1;
693 break;
695 case GE:
696 case LE:
697 if (code2 == ORDERED)
698 return 1;
699 break;
701 case LTGT:
702 if (code2 == NE || code2 == ORDERED)
703 return 1;
704 break;
706 case LTU:
707 if (code2 == LEU || code2 == NE)
708 return 1;
709 break;
711 case GTU:
712 if (code2 == GEU || code2 == NE)
713 return 1;
714 break;
716 case UNORDERED:
717 if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
718 || code2 == UNGE || code2 == UNGT)
719 return 1;
720 break;
722 default:
723 break;
726 return 0;
729 /* Return 1 if INSN is an unconditional jump and nothing else. */
732 simplejump_p (const_rtx insn)
734 return (JUMP_P (insn)
735 && GET_CODE (PATTERN (insn)) == SET
736 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
737 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
740 /* Return nonzero if INSN is a (possibly) conditional jump
741 and nothing more.
743 Use of this function is deprecated, since we need to support combined
744 branch and compare insns. Use any_condjump_p instead whenever possible. */
747 condjump_p (const_rtx insn)
749 const_rtx x = PATTERN (insn);
751 if (GET_CODE (x) != SET
752 || GET_CODE (SET_DEST (x)) != PC)
753 return 0;
755 x = SET_SRC (x);
756 if (GET_CODE (x) == LABEL_REF)
757 return 1;
758 else
759 return (GET_CODE (x) == IF_THEN_ELSE
760 && ((GET_CODE (XEXP (x, 2)) == PC
761 && (GET_CODE (XEXP (x, 1)) == LABEL_REF
762 || GET_CODE (XEXP (x, 1)) == RETURN))
763 || (GET_CODE (XEXP (x, 1)) == PC
764 && (GET_CODE (XEXP (x, 2)) == LABEL_REF
765 || GET_CODE (XEXP (x, 2)) == RETURN))));
768 /* Return nonzero if INSN is a (possibly) conditional jump inside a
769 PARALLEL.
771 Use this function is deprecated, since we need to support combined
772 branch and compare insns. Use any_condjump_p instead whenever possible. */
775 condjump_in_parallel_p (const_rtx insn)
777 const_rtx x = PATTERN (insn);
779 if (GET_CODE (x) != PARALLEL)
780 return 0;
781 else
782 x = XVECEXP (x, 0, 0);
784 if (GET_CODE (x) != SET)
785 return 0;
786 if (GET_CODE (SET_DEST (x)) != PC)
787 return 0;
788 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
789 return 1;
790 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
791 return 0;
792 if (XEXP (SET_SRC (x), 2) == pc_rtx
793 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
794 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
795 return 1;
796 if (XEXP (SET_SRC (x), 1) == pc_rtx
797 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
798 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
799 return 1;
800 return 0;
803 /* Return set of PC, otherwise NULL. */
806 pc_set (const_rtx insn)
808 rtx pat;
809 if (!JUMP_P (insn))
810 return NULL_RTX;
811 pat = PATTERN (insn);
813 /* The set is allowed to appear either as the insn pattern or
814 the first set in a PARALLEL. */
815 if (GET_CODE (pat) == PARALLEL)
816 pat = XVECEXP (pat, 0, 0);
817 if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
818 return pat;
820 return NULL_RTX;
823 /* Return true when insn is an unconditional direct jump,
824 possibly bundled inside a PARALLEL. */
827 any_uncondjump_p (const_rtx insn)
829 const_rtx x = pc_set (insn);
830 if (!x)
831 return 0;
832 if (GET_CODE (SET_SRC (x)) != LABEL_REF)
833 return 0;
834 if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
835 return 0;
836 return 1;
839 /* Return true when insn is a conditional jump. This function works for
840 instructions containing PC sets in PARALLELs. The instruction may have
841 various other effects so before removing the jump you must verify
842 onlyjump_p.
844 Note that unlike condjump_p it returns false for unconditional jumps. */
847 any_condjump_p (const_rtx insn)
849 const_rtx x = pc_set (insn);
850 enum rtx_code a, b;
852 if (!x)
853 return 0;
854 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
855 return 0;
857 a = GET_CODE (XEXP (SET_SRC (x), 1));
858 b = GET_CODE (XEXP (SET_SRC (x), 2));
860 return ((b == PC && (a == LABEL_REF || a == RETURN))
861 || (a == PC && (b == LABEL_REF || b == RETURN)));
864 /* Return the label of a conditional jump. */
867 condjump_label (const_rtx insn)
869 rtx x = pc_set (insn);
871 if (!x)
872 return NULL_RTX;
873 x = SET_SRC (x);
874 if (GET_CODE (x) == LABEL_REF)
875 return x;
876 if (GET_CODE (x) != IF_THEN_ELSE)
877 return NULL_RTX;
878 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
879 return XEXP (x, 1);
880 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
881 return XEXP (x, 2);
882 return NULL_RTX;
885 /* Return true if INSN is a (possibly conditional) return insn. */
887 static int
888 returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
890 rtx x = *loc;
892 if (x == NULL)
893 return false;
895 switch (GET_CODE (x))
897 case RETURN:
898 case EH_RETURN:
899 return true;
901 case SET:
902 return SET_IS_RETURN_P (x);
904 default:
905 return false;
909 /* Return TRUE if INSN is a return jump. */
912 returnjump_p (rtx insn)
914 if (!JUMP_P (insn))
915 return 0;
916 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
919 /* Return true if INSN is a (possibly conditional) return insn. */
921 static int
922 eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
924 return *loc && GET_CODE (*loc) == EH_RETURN;
928 eh_returnjump_p (rtx insn)
930 if (!JUMP_P (insn))
931 return 0;
932 return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL);
935 /* Return true if INSN is a jump that only transfers control and
936 nothing more. */
939 onlyjump_p (const_rtx insn)
941 rtx set;
943 if (!JUMP_P (insn))
944 return 0;
946 set = single_set (insn);
947 if (set == NULL)
948 return 0;
949 if (GET_CODE (SET_DEST (set)) != PC)
950 return 0;
951 if (side_effects_p (SET_SRC (set)))
952 return 0;
954 return 1;
957 #ifdef HAVE_cc0
959 /* Return nonzero if X is an RTX that only sets the condition codes
960 and has no side effects. */
963 only_sets_cc0_p (const_rtx x)
965 if (! x)
966 return 0;
968 if (INSN_P (x))
969 x = PATTERN (x);
971 return sets_cc0_p (x) == 1 && ! side_effects_p (x);
974 /* Return 1 if X is an RTX that does nothing but set the condition codes
975 and CLOBBER or USE registers.
976 Return -1 if X does explicitly set the condition codes,
977 but also does other things. */
980 sets_cc0_p (const_rtx x)
982 if (! x)
983 return 0;
985 if (INSN_P (x))
986 x = PATTERN (x);
988 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
989 return 1;
990 if (GET_CODE (x) == PARALLEL)
992 int i;
993 int sets_cc0 = 0;
994 int other_things = 0;
995 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
997 if (GET_CODE (XVECEXP (x, 0, i)) == SET
998 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
999 sets_cc0 = 1;
1000 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
1001 other_things = 1;
1003 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
1005 return 0;
1007 #endif
1009 /* Find all CODE_LABELs referred to in X, and increment their use
1010 counts. If INSN is a JUMP_INSN and there is at least one
1011 CODE_LABEL referenced in INSN as a jump target, then store the last
1012 one in JUMP_LABEL (INSN). For a tablejump, this must be the label
1013 for the ADDR_VEC. Store any other jump targets as REG_LABEL_TARGET
1014 notes. If INSN is an INSN or a CALL_INSN or non-target operands of
1015 a JUMP_INSN, and there is at least one CODE_LABEL referenced in
1016 INSN, add a REG_LABEL_OPERAND note containing that label to INSN.
1018 Note that two labels separated by a loop-beginning note
1019 must be kept distinct if we have not yet done loop-optimization,
1020 because the gap between them is where loop-optimize
1021 will want to move invariant code to. CROSS_JUMP tells us
1022 that loop-optimization is done with. */
1024 void
1025 mark_jump_label (rtx x, rtx insn, int in_mem)
1027 rtx asmop = extract_asm_operands (x);
1028 if (asmop)
1029 mark_jump_label_asm (asmop, insn);
1030 else
1031 mark_jump_label_1 (x, insn, in_mem != 0,
1032 (insn != NULL && x == PATTERN (insn) && JUMP_P (insn)));
1035 /* Worker function for mark_jump_label. IN_MEM is TRUE when X occurs
1036 within a (MEM ...). IS_TARGET is TRUE when X is to be treated as a
1037 jump-target; when the JUMP_LABEL field of INSN should be set or a
1038 REG_LABEL_TARGET note should be added, not a REG_LABEL_OPERAND
1039 note. */
1041 static void
1042 mark_jump_label_1 (rtx x, rtx insn, bool in_mem, bool is_target)
1044 RTX_CODE code = GET_CODE (x);
1045 int i;
1046 const char *fmt;
1048 switch (code)
1050 case PC:
1051 case CC0:
1052 case REG:
1053 case CONST_INT:
1054 case CONST_DOUBLE:
1055 case CLOBBER:
1056 case CALL:
1057 return;
1059 case MEM:
1060 in_mem = true;
1061 break;
1063 case SEQUENCE:
1064 for (i = 0; i < XVECLEN (x, 0); i++)
1065 mark_jump_label (PATTERN (XVECEXP (x, 0, i)),
1066 XVECEXP (x, 0, i), 0);
1067 return;
1069 case SYMBOL_REF:
1070 if (!in_mem)
1071 return;
1073 /* If this is a constant-pool reference, see if it is a label. */
1074 if (CONSTANT_POOL_ADDRESS_P (x))
1075 mark_jump_label_1 (get_pool_constant (x), insn, in_mem, is_target);
1076 break;
1078 /* Handle operands in the condition of an if-then-else as for a
1079 non-jump insn. */
1080 case IF_THEN_ELSE:
1081 if (!is_target)
1082 break;
1083 mark_jump_label_1 (XEXP (x, 0), insn, in_mem, false);
1084 mark_jump_label_1 (XEXP (x, 1), insn, in_mem, true);
1085 mark_jump_label_1 (XEXP (x, 2), insn, in_mem, true);
1086 return;
1088 case LABEL_REF:
1090 rtx label = XEXP (x, 0);
1092 /* Ignore remaining references to unreachable labels that
1093 have been deleted. */
1094 if (NOTE_P (label)
1095 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL)
1096 break;
1098 gcc_assert (LABEL_P (label));
1100 /* Ignore references to labels of containing functions. */
1101 if (LABEL_REF_NONLOCAL_P (x))
1102 break;
1104 XEXP (x, 0) = label;
1105 if (! insn || ! INSN_DELETED_P (insn))
1106 ++LABEL_NUSES (label);
1108 if (insn)
1110 if (is_target
1111 /* Do not change a previous setting of JUMP_LABEL. If the
1112 JUMP_LABEL slot is occupied by a different label,
1113 create a note for this label. */
1114 && (JUMP_LABEL (insn) == NULL || JUMP_LABEL (insn) == label))
1115 JUMP_LABEL (insn) = label;
1116 else
1118 enum reg_note kind
1119 = is_target ? REG_LABEL_TARGET : REG_LABEL_OPERAND;
1121 /* Add a REG_LABEL_OPERAND or REG_LABEL_TARGET note
1122 for LABEL unless there already is one. All uses of
1123 a label, except for the primary target of a jump,
1124 must have such a note. */
1125 if (! find_reg_note (insn, kind, label))
1126 add_reg_note (insn, kind, label);
1129 return;
1132 /* Do walk the labels in a vector, but not the first operand of an
1133 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1134 case ADDR_VEC:
1135 case ADDR_DIFF_VEC:
1136 if (! INSN_DELETED_P (insn))
1138 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
1140 for (i = 0; i < XVECLEN (x, eltnum); i++)
1141 mark_jump_label_1 (XVECEXP (x, eltnum, i), NULL_RTX, in_mem,
1142 is_target);
1144 return;
1146 default:
1147 break;
1150 fmt = GET_RTX_FORMAT (code);
1152 /* The primary target of a tablejump is the label of the ADDR_VEC,
1153 which is canonically mentioned *last* in the insn. To get it
1154 marked as JUMP_LABEL, we iterate over items in reverse order. */
1155 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1157 if (fmt[i] == 'e')
1158 mark_jump_label_1 (XEXP (x, i), insn, in_mem, is_target);
1159 else if (fmt[i] == 'E')
1161 int j;
1163 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1164 mark_jump_label_1 (XVECEXP (x, i, j), insn, in_mem,
1165 is_target);
1170 /* Worker function for mark_jump_label. Handle asm insns specially.
1171 In particular, output operands need not be considered so we can
1172 avoid re-scanning the replicated asm_operand. Also, the asm_labels
1173 need to be considered targets. */
1175 static void
1176 mark_jump_label_asm (rtx asmop, rtx insn)
1178 int i;
1180 for (i = ASM_OPERANDS_INPUT_LENGTH (asmop) - 1; i >= 0; --i)
1181 mark_jump_label_1 (ASM_OPERANDS_INPUT (asmop, i), insn, false, false);
1183 for (i = ASM_OPERANDS_LABEL_LENGTH (asmop) - 1; i >= 0; --i)
1184 mark_jump_label_1 (ASM_OPERANDS_LABEL (asmop, i), insn, false, true);
1187 /* Delete insn INSN from the chain of insns and update label ref counts
1188 and delete insns now unreachable.
1190 Returns the first insn after INSN that was not deleted.
1192 Usage of this instruction is deprecated. Use delete_insn instead and
1193 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1196 delete_related_insns (rtx insn)
1198 int was_code_label = (LABEL_P (insn));
1199 rtx note;
1200 rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
1202 while (next && INSN_DELETED_P (next))
1203 next = NEXT_INSN (next);
1205 /* This insn is already deleted => return first following nondeleted. */
1206 if (INSN_DELETED_P (insn))
1207 return next;
1209 delete_insn (insn);
1211 /* If instruction is followed by a barrier,
1212 delete the barrier too. */
1214 if (next != 0 && BARRIER_P (next))
1215 delete_insn (next);
1217 /* If deleting a jump, decrement the count of the label,
1218 and delete the label if it is now unused. */
1220 if (JUMP_P (insn) && JUMP_LABEL (insn))
1222 rtx lab = JUMP_LABEL (insn), lab_next;
1224 if (LABEL_NUSES (lab) == 0)
1225 /* This can delete NEXT or PREV,
1226 either directly if NEXT is JUMP_LABEL (INSN),
1227 or indirectly through more levels of jumps. */
1228 delete_related_insns (lab);
1229 else if (tablejump_p (insn, NULL, &lab_next))
1231 /* If we're deleting the tablejump, delete the dispatch table.
1232 We may not be able to kill the label immediately preceding
1233 just yet, as it might be referenced in code leading up to
1234 the tablejump. */
1235 delete_related_insns (lab_next);
1239 /* Likewise if we're deleting a dispatch table. */
1241 if (JUMP_TABLE_DATA_P (insn))
1243 rtx pat = PATTERN (insn);
1244 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1245 int len = XVECLEN (pat, diff_vec_p);
1247 for (i = 0; i < len; i++)
1248 if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1249 delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
1250 while (next && INSN_DELETED_P (next))
1251 next = NEXT_INSN (next);
1252 return next;
1255 /* Likewise for any JUMP_P / INSN / CALL_INSN with a
1256 REG_LABEL_OPERAND or REG_LABEL_TARGET note. */
1257 if (INSN_P (insn))
1258 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1259 if ((REG_NOTE_KIND (note) == REG_LABEL_OPERAND
1260 || REG_NOTE_KIND (note) == REG_LABEL_TARGET)
1261 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1262 && LABEL_P (XEXP (note, 0)))
1263 if (LABEL_NUSES (XEXP (note, 0)) == 0)
1264 delete_related_insns (XEXP (note, 0));
1266 while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
1267 prev = PREV_INSN (prev);
1269 /* If INSN was a label and a dispatch table follows it,
1270 delete the dispatch table. The tablejump must have gone already.
1271 It isn't useful to fall through into a table. */
1273 if (was_code_label
1274 && NEXT_INSN (insn) != 0
1275 && JUMP_TABLE_DATA_P (NEXT_INSN (insn)))
1276 next = delete_related_insns (NEXT_INSN (insn));
1278 /* If INSN was a label, delete insns following it if now unreachable. */
1280 if (was_code_label && prev && BARRIER_P (prev))
1282 enum rtx_code code;
1283 while (next)
1285 code = GET_CODE (next);
1286 if (code == NOTE)
1287 next = NEXT_INSN (next);
1288 /* Keep going past other deleted labels to delete what follows. */
1289 else if (code == CODE_LABEL && INSN_DELETED_P (next))
1290 next = NEXT_INSN (next);
1291 else if (code == BARRIER || INSN_P (next))
1292 /* Note: if this deletes a jump, it can cause more
1293 deletion of unreachable code, after a different label.
1294 As long as the value from this recursive call is correct,
1295 this invocation functions correctly. */
1296 next = delete_related_insns (next);
1297 else
1298 break;
1302 /* I feel a little doubtful about this loop,
1303 but I see no clean and sure alternative way
1304 to find the first insn after INSN that is not now deleted.
1305 I hope this works. */
1306 while (next && INSN_DELETED_P (next))
1307 next = NEXT_INSN (next);
1308 return next;
1311 /* Delete a range of insns from FROM to TO, inclusive.
1312 This is for the sake of peephole optimization, so assume
1313 that whatever these insns do will still be done by a new
1314 peephole insn that will replace them. */
1316 void
1317 delete_for_peephole (rtx from, rtx to)
1319 rtx insn = from;
1321 while (1)
1323 rtx next = NEXT_INSN (insn);
1324 rtx prev = PREV_INSN (insn);
1326 if (!NOTE_P (insn))
1328 INSN_DELETED_P (insn) = 1;
1330 /* Patch this insn out of the chain. */
1331 /* We don't do this all at once, because we
1332 must preserve all NOTEs. */
1333 if (prev)
1334 NEXT_INSN (prev) = next;
1336 if (next)
1337 PREV_INSN (next) = prev;
1340 if (insn == to)
1341 break;
1342 insn = next;
1345 /* Note that if TO is an unconditional jump
1346 we *do not* delete the BARRIER that follows,
1347 since the peephole that replaces this sequence
1348 is also an unconditional jump in that case. */
1351 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1352 NLABEL as a return. Accrue modifications into the change group. */
1354 static void
1355 redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
1357 rtx x = *loc;
1358 RTX_CODE code = GET_CODE (x);
1359 int i;
1360 const char *fmt;
1362 if (code == LABEL_REF)
1364 if (XEXP (x, 0) == olabel)
1366 rtx n;
1367 if (nlabel)
1368 n = gen_rtx_LABEL_REF (Pmode, nlabel);
1369 else
1370 n = gen_rtx_RETURN (VOIDmode);
1372 validate_change (insn, loc, n, 1);
1373 return;
1376 else if (code == RETURN && olabel == 0)
1378 if (nlabel)
1379 x = gen_rtx_LABEL_REF (Pmode, nlabel);
1380 else
1381 x = gen_rtx_RETURN (VOIDmode);
1382 if (loc == &PATTERN (insn))
1383 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1384 validate_change (insn, loc, x, 1);
1385 return;
1388 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1389 && GET_CODE (SET_SRC (x)) == LABEL_REF
1390 && XEXP (SET_SRC (x), 0) == olabel)
1392 validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1393 return;
1396 if (code == IF_THEN_ELSE)
1398 /* Skip the condition of an IF_THEN_ELSE. We only want to
1399 change jump destinations, not eventual label comparisons. */
1400 redirect_exp_1 (&XEXP (x, 1), olabel, nlabel, insn);
1401 redirect_exp_1 (&XEXP (x, 2), olabel, nlabel, insn);
1402 return;
1405 fmt = GET_RTX_FORMAT (code);
1406 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1408 if (fmt[i] == 'e')
1409 redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1410 else if (fmt[i] == 'E')
1412 int j;
1413 for (j = 0; j < XVECLEN (x, i); j++)
1414 redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
1419 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
1420 the modifications into the change group. Return false if we did
1421 not see how to do that. */
1424 redirect_jump_1 (rtx jump, rtx nlabel)
1426 int ochanges = num_validated_changes ();
1427 rtx *loc, asmop;
1429 asmop = extract_asm_operands (PATTERN (jump));
1430 if (asmop)
1432 if (nlabel == NULL)
1433 return 0;
1434 gcc_assert (ASM_OPERANDS_LABEL_LENGTH (asmop) == 1);
1435 loc = &ASM_OPERANDS_LABEL (asmop, 0);
1437 else if (GET_CODE (PATTERN (jump)) == PARALLEL)
1438 loc = &XVECEXP (PATTERN (jump), 0, 0);
1439 else
1440 loc = &PATTERN (jump);
1442 redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
1443 return num_validated_changes () > ochanges;
1446 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
1447 jump target label is unused as a result, it and the code following
1448 it may be deleted.
1450 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
1451 RETURN insn.
1453 The return value will be 1 if the change was made, 0 if it wasn't
1454 (this can only occur for NLABEL == 0). */
1457 redirect_jump (rtx jump, rtx nlabel, int delete_unused)
1459 rtx olabel = JUMP_LABEL (jump);
1461 if (nlabel == olabel)
1462 return 1;
1464 if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
1465 return 0;
1467 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
1468 return 1;
1471 /* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
1472 NLABEL in JUMP.
1473 If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1474 count has dropped to zero. */
1475 void
1476 redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
1477 int invert)
1479 rtx note;
1481 gcc_assert (JUMP_LABEL (jump) == olabel);
1483 /* Negative DELETE_UNUSED used to be used to signalize behavior on
1484 moving FUNCTION_END note. Just sanity check that no user still worry
1485 about this. */
1486 gcc_assert (delete_unused >= 0);
1487 JUMP_LABEL (jump) = nlabel;
1488 if (nlabel)
1489 ++LABEL_NUSES (nlabel);
1491 /* Update labels in any REG_EQUAL note. */
1492 if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
1494 if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
1495 remove_note (jump, note);
1496 else
1498 redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
1499 confirm_change_group ();
1503 if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
1504 /* Undefined labels will remain outside the insn stream. */
1505 && INSN_UID (olabel))
1506 delete_related_insns (olabel);
1507 if (invert)
1508 invert_br_probabilities (jump);
1511 /* Invert the jump condition X contained in jump insn INSN. Accrue the
1512 modifications into the change group. Return nonzero for success. */
1513 static int
1514 invert_exp_1 (rtx x, rtx insn)
1516 RTX_CODE code = GET_CODE (x);
1518 if (code == IF_THEN_ELSE)
1520 rtx comp = XEXP (x, 0);
1521 rtx tem;
1522 enum rtx_code reversed_code;
1524 /* We can do this in two ways: The preferable way, which can only
1525 be done if this is not an integer comparison, is to reverse
1526 the comparison code. Otherwise, swap the THEN-part and ELSE-part
1527 of the IF_THEN_ELSE. If we can't do either, fail. */
1529 reversed_code = reversed_comparison_code (comp, insn);
1531 if (reversed_code != UNKNOWN)
1533 validate_change (insn, &XEXP (x, 0),
1534 gen_rtx_fmt_ee (reversed_code,
1535 GET_MODE (comp), XEXP (comp, 0),
1536 XEXP (comp, 1)),
1538 return 1;
1541 tem = XEXP (x, 1);
1542 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
1543 validate_change (insn, &XEXP (x, 2), tem, 1);
1544 return 1;
1546 else
1547 return 0;
1550 /* Invert the condition of the jump JUMP, and make it jump to label
1551 NLABEL instead of where it jumps now. Accrue changes into the
1552 change group. Return false if we didn't see how to perform the
1553 inversion and redirection. */
1556 invert_jump_1 (rtx jump, rtx nlabel)
1558 rtx x = pc_set (jump);
1559 int ochanges;
1560 int ok;
1562 ochanges = num_validated_changes ();
1563 if (x == NULL)
1564 return 0;
1565 ok = invert_exp_1 (SET_SRC (x), jump);
1566 gcc_assert (ok);
1568 if (num_validated_changes () == ochanges)
1569 return 0;
1571 /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1572 in Pmode, so checking this is not merely an optimization. */
1573 return nlabel == JUMP_LABEL (jump) || redirect_jump_1 (jump, nlabel);
1576 /* Invert the condition of the jump JUMP, and make it jump to label
1577 NLABEL instead of where it jumps now. Return true if successful. */
1580 invert_jump (rtx jump, rtx nlabel, int delete_unused)
1582 rtx olabel = JUMP_LABEL (jump);
1584 if (invert_jump_1 (jump, nlabel) && apply_change_group ())
1586 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
1587 return 1;
1589 cancel_changes (0);
1590 return 0;
1594 /* Like rtx_equal_p except that it considers two REGs as equal
1595 if they renumber to the same value and considers two commutative
1596 operations to be the same if the order of the operands has been
1597 reversed. */
1600 rtx_renumbered_equal_p (const_rtx x, const_rtx y)
1602 int i;
1603 const enum rtx_code code = GET_CODE (x);
1604 const char *fmt;
1606 if (x == y)
1607 return 1;
1609 if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
1610 && (REG_P (y) || (GET_CODE (y) == SUBREG
1611 && REG_P (SUBREG_REG (y)))))
1613 int reg_x = -1, reg_y = -1;
1614 int byte_x = 0, byte_y = 0;
1615 struct subreg_info info;
1617 if (GET_MODE (x) != GET_MODE (y))
1618 return 0;
1620 /* If we haven't done any renumbering, don't
1621 make any assumptions. */
1622 if (reg_renumber == 0)
1623 return rtx_equal_p (x, y);
1625 if (code == SUBREG)
1627 reg_x = REGNO (SUBREG_REG (x));
1628 byte_x = SUBREG_BYTE (x);
1630 if (reg_renumber[reg_x] >= 0)
1632 subreg_get_info (reg_renumber[reg_x],
1633 GET_MODE (SUBREG_REG (x)), byte_x,
1634 GET_MODE (x), &info);
1635 if (!info.representable_p)
1636 return 0;
1637 reg_x = info.offset;
1638 byte_x = 0;
1641 else
1643 reg_x = REGNO (x);
1644 if (reg_renumber[reg_x] >= 0)
1645 reg_x = reg_renumber[reg_x];
1648 if (GET_CODE (y) == SUBREG)
1650 reg_y = REGNO (SUBREG_REG (y));
1651 byte_y = SUBREG_BYTE (y);
1653 if (reg_renumber[reg_y] >= 0)
1655 subreg_get_info (reg_renumber[reg_y],
1656 GET_MODE (SUBREG_REG (y)), byte_y,
1657 GET_MODE (y), &info);
1658 if (!info.representable_p)
1659 return 0;
1660 reg_y = info.offset;
1661 byte_y = 0;
1664 else
1666 reg_y = REGNO (y);
1667 if (reg_renumber[reg_y] >= 0)
1668 reg_y = reg_renumber[reg_y];
1671 return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
1674 /* Now we have disposed of all the cases
1675 in which different rtx codes can match. */
1676 if (code != GET_CODE (y))
1677 return 0;
1679 switch (code)
1681 case PC:
1682 case CC0:
1683 case ADDR_VEC:
1684 case ADDR_DIFF_VEC:
1685 case CONST_INT:
1686 case CONST_DOUBLE:
1687 return 0;
1689 case LABEL_REF:
1690 /* We can't assume nonlocal labels have their following insns yet. */
1691 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
1692 return XEXP (x, 0) == XEXP (y, 0);
1694 /* Two label-refs are equivalent if they point at labels
1695 in the same position in the instruction stream. */
1696 return (next_real_insn (XEXP (x, 0))
1697 == next_real_insn (XEXP (y, 0)));
1699 case SYMBOL_REF:
1700 return XSTR (x, 0) == XSTR (y, 0);
1702 case CODE_LABEL:
1703 /* If we didn't match EQ equality above, they aren't the same. */
1704 return 0;
1706 default:
1707 break;
1710 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
1712 if (GET_MODE (x) != GET_MODE (y))
1713 return 0;
1715 /* MEMs refering to different address space are not equivalent. */
1716 if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
1717 return 0;
1719 /* For commutative operations, the RTX match if the operand match in any
1720 order. Also handle the simple binary and unary cases without a loop. */
1721 if (targetm.commutative_p (x, UNKNOWN))
1722 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1723 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
1724 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
1725 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
1726 else if (NON_COMMUTATIVE_P (x))
1727 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1728 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
1729 else if (UNARY_P (x))
1730 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
1732 /* Compare the elements. If any pair of corresponding elements
1733 fail to match, return 0 for the whole things. */
1735 fmt = GET_RTX_FORMAT (code);
1736 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1738 int j;
1739 switch (fmt[i])
1741 case 'w':
1742 if (XWINT (x, i) != XWINT (y, i))
1743 return 0;
1744 break;
1746 case 'i':
1747 if (XINT (x, i) != XINT (y, i))
1749 if (((code == ASM_OPERANDS && i == 6)
1750 || (code == ASM_INPUT && i == 1))
1751 && locator_eq (XINT (x, i), XINT (y, i)))
1752 break;
1753 return 0;
1755 break;
1757 case 't':
1758 if (XTREE (x, i) != XTREE (y, i))
1759 return 0;
1760 break;
1762 case 's':
1763 if (strcmp (XSTR (x, i), XSTR (y, i)))
1764 return 0;
1765 break;
1767 case 'e':
1768 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
1769 return 0;
1770 break;
1772 case 'u':
1773 if (XEXP (x, i) != XEXP (y, i))
1774 return 0;
1775 /* Fall through. */
1776 case '0':
1777 break;
1779 case 'E':
1780 if (XVECLEN (x, i) != XVECLEN (y, i))
1781 return 0;
1782 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1783 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
1784 return 0;
1785 break;
1787 default:
1788 gcc_unreachable ();
1791 return 1;
1794 /* If X is a hard register or equivalent to one or a subregister of one,
1795 return the hard register number. If X is a pseudo register that was not
1796 assigned a hard register, return the pseudo register number. Otherwise,
1797 return -1. Any rtx is valid for X. */
1800 true_regnum (const_rtx x)
1802 if (REG_P (x))
1804 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
1805 return reg_renumber[REGNO (x)];
1806 return REGNO (x);
1808 if (GET_CODE (x) == SUBREG)
1810 int base = true_regnum (SUBREG_REG (x));
1811 if (base >= 0
1812 && base < FIRST_PSEUDO_REGISTER)
1814 struct subreg_info info;
1816 subreg_get_info (REGNO (SUBREG_REG (x)),
1817 GET_MODE (SUBREG_REG (x)),
1818 SUBREG_BYTE (x), GET_MODE (x), &info);
1820 if (info.representable_p)
1821 return base + info.offset;
1824 return -1;
1827 /* Return regno of the register REG and handle subregs too. */
1828 unsigned int
1829 reg_or_subregno (const_rtx reg)
1831 if (GET_CODE (reg) == SUBREG)
1832 reg = SUBREG_REG (reg);
1833 gcc_assert (REG_P (reg));
1834 return REGNO (reg);