2002-04-30 Mark Mitchell <mark@codesourcery.com>
[official-gcc.git] / gcc / jump.c
blobf32b831c6dfb1c22dca59559bd19f4c625e20762
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 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 /* This is the pathetic reminder of old fame of the jump-optimization pass
23 of the compiler. Now it contains basically set of utility function 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 delete_insn, redirect_jump, and invert_jump are used
35 from other passes as well. */
37 #include "config.h"
38 #include "system.h"
39 #include "rtl.h"
40 #include "tm_p.h"
41 #include "flags.h"
42 #include "hard-reg-set.h"
43 #include "regs.h"
44 #include "insn-config.h"
45 #include "insn-attr.h"
46 #include "recog.h"
47 #include "function.h"
48 #include "expr.h"
49 #include "real.h"
50 #include "except.h"
51 #include "toplev.h"
52 #include "reload.h"
53 #include "predict.h"
55 /* Optimize jump y; x: ... y: jumpif... x?
56 Don't know if it is worth bothering with. */
57 /* Optimize two cases of conditional jump to conditional jump?
58 This can never delete any instruction or make anything dead,
59 or even change what is live at any point.
60 So perhaps let combiner do it. */
62 static int init_label_info PARAMS ((rtx));
63 static void mark_all_labels PARAMS ((rtx));
64 static int duplicate_loop_exit_test PARAMS ((rtx));
65 static void delete_computation PARAMS ((rtx));
66 static void redirect_exp_1 PARAMS ((rtx *, rtx, rtx, rtx));
67 static int redirect_exp PARAMS ((rtx, rtx, rtx));
68 static void invert_exp_1 PARAMS ((rtx));
69 static int invert_exp PARAMS ((rtx));
70 static int returnjump_p_1 PARAMS ((rtx *, void *));
71 static void delete_prior_computation PARAMS ((rtx, rtx));
73 /* Alternate entry into the jump optimizer. This entry point only rebuilds
74 the JUMP_LABEL field in jumping insns and REG_LABEL notes in non-jumping
75 instructions. */
76 void
77 rebuild_jump_labels (f)
78 rtx f;
80 rtx insn;
81 int max_uid = 0;
83 max_uid = init_label_info (f) + 1;
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 (GET_CODE (XEXP (insn, 0)) == CODE_LABEL)
93 LABEL_NUSES (XEXP (insn, 0))++;
96 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
97 non-fallthru insn. This is not generally true, as multiple barriers
98 may have crept in, or the BARRIER may be separated from the last
99 real insn by one or more NOTEs.
101 This simple pass moves barriers and removes duplicates so that the
102 old code is happy.
104 void
105 cleanup_barriers ()
107 rtx insn, next, prev;
108 for (insn = get_insns (); insn; insn = next)
110 next = NEXT_INSN (insn);
111 if (GET_CODE (insn) == BARRIER)
113 prev = prev_nonnote_insn (insn);
114 if (GET_CODE (prev) == BARRIER)
115 delete_barrier (insn);
116 else if (prev != PREV_INSN (insn))
117 reorder_insns (insn, insn, prev);
122 void
123 copy_loop_headers (f)
124 rtx f;
126 rtx insn, next;
127 /* Now iterate optimizing jumps until nothing changes over one pass. */
128 for (insn = f; insn; insn = next)
130 rtx temp, temp1;
132 next = NEXT_INSN (insn);
134 /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional
135 jump. Try to optimize by duplicating the loop exit test if so.
136 This is only safe immediately after regscan, because it uses
137 the values of regno_first_uid and regno_last_uid. */
138 if (GET_CODE (insn) == NOTE
139 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
140 && (temp1 = next_nonnote_insn (insn)) != 0
141 && any_uncondjump_p (temp1) && onlyjump_p (temp1))
143 temp = PREV_INSN (insn);
144 if (duplicate_loop_exit_test (insn))
146 next = NEXT_INSN (temp);
152 void
153 purge_line_number_notes (f)
154 rtx f;
156 rtx last_note = 0;
157 rtx insn;
158 /* Delete extraneous line number notes.
159 Note that two consecutive notes for different lines are not really
160 extraneous. There should be some indication where that line belonged,
161 even if it became empty. */
163 for (insn = f; insn; insn = NEXT_INSN (insn))
164 if (GET_CODE (insn) == NOTE)
166 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
167 /* Any previous line note was for the prologue; gdb wants a new
168 note after the prologue even if it is for the same line. */
169 last_note = NULL_RTX;
170 else if (NOTE_LINE_NUMBER (insn) >= 0)
172 /* Delete this note if it is identical to previous note. */
173 if (last_note
174 && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
175 && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
177 delete_related_insns (insn);
178 continue;
181 last_note = insn;
186 /* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
187 notes whose labels don't occur in the insn any more. Returns the
188 largest INSN_UID found. */
189 static int
190 init_label_info (f)
191 rtx f;
193 int largest_uid = 0;
194 rtx insn;
196 for (insn = f; insn; insn = NEXT_INSN (insn))
198 if (GET_CODE (insn) == CODE_LABEL)
199 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
200 else if (GET_CODE (insn) == JUMP_INSN)
201 JUMP_LABEL (insn) = 0;
202 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
204 rtx note, next;
206 for (note = REG_NOTES (insn); note; note = next)
208 next = XEXP (note, 1);
209 if (REG_NOTE_KIND (note) == REG_LABEL
210 && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
211 remove_note (insn, note);
214 if (INSN_UID (insn) > largest_uid)
215 largest_uid = INSN_UID (insn);
218 return largest_uid;
221 /* Mark the label each jump jumps to.
222 Combine consecutive labels, and count uses of labels. */
224 static void
225 mark_all_labels (f)
226 rtx f;
228 rtx insn;
230 for (insn = f; insn; insn = NEXT_INSN (insn))
231 if (INSN_P (insn))
233 if (GET_CODE (insn) == CALL_INSN
234 && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
236 mark_all_labels (XEXP (PATTERN (insn), 0));
237 mark_all_labels (XEXP (PATTERN (insn), 1));
238 mark_all_labels (XEXP (PATTERN (insn), 2));
240 /* Canonicalize the tail recursion label attached to the
241 CALL_PLACEHOLDER insn. */
242 if (XEXP (PATTERN (insn), 3))
244 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
245 XEXP (PATTERN (insn), 3));
246 mark_jump_label (label_ref, insn, 0);
247 XEXP (PATTERN (insn), 3) = XEXP (label_ref, 0);
250 continue;
253 mark_jump_label (PATTERN (insn), insn, 0);
254 if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
256 /* When we know the LABEL_REF contained in a REG used in
257 an indirect jump, we'll have a REG_LABEL note so that
258 flow can tell where it's going. */
259 if (JUMP_LABEL (insn) == 0)
261 rtx label_note = find_reg_note (insn, REG_LABEL, NULL_RTX);
262 if (label_note)
264 /* But a LABEL_REF around the REG_LABEL note, so
265 that we can canonicalize it. */
266 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
267 XEXP (label_note, 0));
269 mark_jump_label (label_ref, insn, 0);
270 XEXP (label_note, 0) = XEXP (label_ref, 0);
271 JUMP_LABEL (insn) = XEXP (label_note, 0);
278 /* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional
279 jump. Assume that this unconditional jump is to the exit test code. If
280 the code is sufficiently simple, make a copy of it before INSN,
281 followed by a jump to the exit of the loop. Then delete the unconditional
282 jump after INSN.
284 Return 1 if we made the change, else 0.
286 This is only safe immediately after a regscan pass because it uses the
287 values of regno_first_uid and regno_last_uid. */
289 static int
290 duplicate_loop_exit_test (loop_start)
291 rtx loop_start;
293 rtx insn, set, reg, p, link;
294 rtx copy = 0, first_copy = 0;
295 int num_insns = 0;
296 rtx exitcode = NEXT_INSN (JUMP_LABEL (next_nonnote_insn (loop_start)));
297 rtx lastexit;
298 int max_reg = max_reg_num ();
299 rtx *reg_map = 0;
300 rtx loop_pre_header_label;
302 /* Scan the exit code. We do not perform this optimization if any insn:
304 is a CALL_INSN
305 is a CODE_LABEL
306 has a REG_RETVAL or REG_LIBCALL note (hard to adjust)
307 is a NOTE_INSN_LOOP_BEG because this means we have a nested loop
308 is a NOTE_INSN_BLOCK_{BEG,END} because duplicating these notes
309 is not valid.
311 We also do not do this if we find an insn with ASM_OPERANDS. While
312 this restriction should not be necessary, copying an insn with
313 ASM_OPERANDS can confuse asm_noperands in some cases.
315 Also, don't do this if the exit code is more than 20 insns. */
317 for (insn = exitcode;
318 insn
319 && ! (GET_CODE (insn) == NOTE
320 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
321 insn = NEXT_INSN (insn))
323 switch (GET_CODE (insn))
325 case CODE_LABEL:
326 case CALL_INSN:
327 return 0;
328 case NOTE:
329 /* We could be in front of the wrong NOTE_INSN_LOOP_END if there is
330 a jump immediately after the loop start that branches outside
331 the loop but within an outer loop, near the exit test.
332 If we copied this exit test and created a phony
333 NOTE_INSN_LOOP_VTOP, this could make instructions immediately
334 before the exit test look like these could be safely moved
335 out of the loop even if they actually may be never executed.
336 This can be avoided by checking here for NOTE_INSN_LOOP_CONT. */
338 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
339 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT)
340 return 0;
342 if (optimize < 2
343 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
344 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
345 /* If we were to duplicate this code, we would not move
346 the BLOCK notes, and so debugging the moved code would
347 be difficult. Thus, we only move the code with -O2 or
348 higher. */
349 return 0;
351 break;
352 case JUMP_INSN:
353 case INSN:
354 /* The code below would grossly mishandle REG_WAS_0 notes,
355 so get rid of them here. */
356 while ((p = find_reg_note (insn, REG_WAS_0, NULL_RTX)) != 0)
357 remove_note (insn, p);
358 if (++num_insns > 20
359 || find_reg_note (insn, REG_RETVAL, NULL_RTX)
360 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
361 return 0;
362 break;
363 default:
364 break;
368 /* Unless INSN is zero, we can do the optimization. */
369 if (insn == 0)
370 return 0;
372 lastexit = insn;
374 /* See if any insn sets a register only used in the loop exit code and
375 not a user variable. If so, replace it with a new register. */
376 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
377 if (GET_CODE (insn) == INSN
378 && (set = single_set (insn)) != 0
379 && ((reg = SET_DEST (set), GET_CODE (reg) == REG)
380 || (GET_CODE (reg) == SUBREG
381 && (reg = SUBREG_REG (reg), GET_CODE (reg) == REG)))
382 && REGNO (reg) >= FIRST_PSEUDO_REGISTER
383 && REGNO_FIRST_UID (REGNO (reg)) == INSN_UID (insn))
385 for (p = NEXT_INSN (insn); p != lastexit; p = NEXT_INSN (p))
386 if (REGNO_LAST_UID (REGNO (reg)) == INSN_UID (p))
387 break;
389 if (p != lastexit)
391 /* We can do the replacement. Allocate reg_map if this is the
392 first replacement we found. */
393 if (reg_map == 0)
394 reg_map = (rtx *) xcalloc (max_reg, sizeof (rtx));
396 REG_LOOP_TEST_P (reg) = 1;
398 reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg));
401 loop_pre_header_label = gen_label_rtx ();
403 /* Now copy each insn. */
404 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
406 switch (GET_CODE (insn))
408 case BARRIER:
409 copy = emit_barrier_before (loop_start);
410 break;
411 case NOTE:
412 /* Only copy line-number notes. */
413 if (NOTE_LINE_NUMBER (insn) >= 0)
415 copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
416 NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
418 break;
420 case INSN:
421 copy = emit_insn_before (copy_insn (PATTERN (insn)), loop_start);
422 if (reg_map)
423 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
425 mark_jump_label (PATTERN (copy), copy, 0);
427 /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
428 make them. */
429 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
430 if (REG_NOTE_KIND (link) != REG_LABEL)
432 if (GET_CODE (link) == EXPR_LIST)
433 REG_NOTES (copy)
434 = copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
435 XEXP (link, 0),
436 REG_NOTES (copy)));
437 else
438 REG_NOTES (copy)
439 = copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
440 XEXP (link, 0),
441 REG_NOTES (copy)));
444 if (reg_map && REG_NOTES (copy))
445 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
446 break;
448 case JUMP_INSN:
449 copy = emit_jump_insn_before (copy_insn (PATTERN (insn)),
450 loop_start);
451 if (reg_map)
452 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
453 mark_jump_label (PATTERN (copy), copy, 0);
454 if (REG_NOTES (insn))
456 REG_NOTES (copy) = copy_insn_1 (REG_NOTES (insn));
457 if (reg_map)
458 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
461 /* Predict conditional jump that do make loop looping as taken.
462 Other jumps are probably exit conditions, so predict
463 them as untaken. */
464 if (any_condjump_p (copy))
466 rtx label = JUMP_LABEL (copy);
467 if (label)
469 /* The jump_insn after loop_start should be followed
470 by barrier and loopback label. */
471 if (prev_nonnote_insn (label)
472 && (prev_nonnote_insn (prev_nonnote_insn (label))
473 == next_nonnote_insn (loop_start)))
475 predict_insn_def (copy, PRED_LOOP_HEADER, TAKEN);
476 /* To keep pre-header, we need to redirect all loop
477 entrances before the LOOP_BEG note. */
478 redirect_jump (copy, loop_pre_header_label, 0);
480 else
481 predict_insn_def (copy, PRED_LOOP_HEADER, NOT_TAKEN);
484 break;
486 default:
487 abort ();
490 /* Record the first insn we copied. We need it so that we can
491 scan the copied insns for new pseudo registers. */
492 if (! first_copy)
493 first_copy = copy;
496 /* Now clean up by emitting a jump to the end label and deleting the jump
497 at the start of the loop. */
498 if (! copy || GET_CODE (copy) != BARRIER)
500 copy = emit_jump_insn_before (gen_jump (get_label_after (insn)),
501 loop_start);
503 /* Record the first insn we copied. We need it so that we can
504 scan the copied insns for new pseudo registers. This may not
505 be strictly necessary since we should have copied at least one
506 insn above. But I am going to be safe. */
507 if (! first_copy)
508 first_copy = copy;
510 mark_jump_label (PATTERN (copy), copy, 0);
511 emit_barrier_before (loop_start);
514 emit_label_before (loop_pre_header_label, loop_start);
516 /* Now scan from the first insn we copied to the last insn we copied
517 (copy) for new pseudo registers. Do this after the code to jump to
518 the end label since that might create a new pseudo too. */
519 reg_scan_update (first_copy, copy, max_reg);
521 /* Mark the exit code as the virtual top of the converted loop. */
522 emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode);
524 delete_related_insns (next_nonnote_insn (loop_start));
526 /* Clean up. */
527 if (reg_map)
528 free (reg_map);
530 return 1;
533 /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
534 notes between START and END out before START. START and END may be such
535 notes. Returns the values of the new starting and ending insns, which
536 may be different if the original ones were such notes.
537 Return true if there were only such notes and no real instructions. */
539 bool
540 squeeze_notes (startp, endp)
541 rtx* startp;
542 rtx* endp;
544 rtx start = *startp;
545 rtx end = *endp;
547 rtx insn;
548 rtx next;
549 rtx last = NULL;
550 rtx past_end = NEXT_INSN (end);
552 for (insn = start; insn != past_end; insn = next)
554 next = NEXT_INSN (insn);
555 if (GET_CODE (insn) == NOTE
556 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
557 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
558 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
559 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
560 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
561 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
563 if (insn == start)
564 start = next;
565 else
567 rtx prev = PREV_INSN (insn);
568 PREV_INSN (insn) = PREV_INSN (start);
569 NEXT_INSN (insn) = start;
570 NEXT_INSN (PREV_INSN (insn)) = insn;
571 PREV_INSN (NEXT_INSN (insn)) = insn;
572 NEXT_INSN (prev) = next;
573 PREV_INSN (next) = prev;
576 else
577 last = insn;
580 /* There were no real instructions. */
581 if (start == past_end)
582 return true;
584 end = last;
586 *startp = start;
587 *endp = end;
588 return false;
591 /* Return the label before INSN, or put a new label there. */
594 get_label_before (insn)
595 rtx insn;
597 rtx label;
599 /* Find an existing label at this point
600 or make a new one if there is none. */
601 label = prev_nonnote_insn (insn);
603 if (label == 0 || GET_CODE (label) != CODE_LABEL)
605 rtx prev = PREV_INSN (insn);
607 label = gen_label_rtx ();
608 emit_label_after (label, prev);
609 LABEL_NUSES (label) = 0;
611 return label;
614 /* Return the label after INSN, or put a new label there. */
617 get_label_after (insn)
618 rtx insn;
620 rtx label;
622 /* Find an existing label at this point
623 or make a new one if there is none. */
624 label = next_nonnote_insn (insn);
626 if (label == 0 || GET_CODE (label) != CODE_LABEL)
628 label = gen_label_rtx ();
629 emit_label_after (label, insn);
630 LABEL_NUSES (label) = 0;
632 return label;
635 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
636 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
637 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
638 know whether it's source is floating point or integer comparison. Machine
639 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
640 to help this function avoid overhead in these cases. */
641 enum rtx_code
642 reversed_comparison_code_parts (code, arg0, arg1, insn)
643 rtx insn, arg0, arg1;
644 enum rtx_code code;
646 enum machine_mode mode;
648 /* If this is not actually a comparison, we can't reverse it. */
649 if (GET_RTX_CLASS (code) != '<')
650 return UNKNOWN;
652 mode = GET_MODE (arg0);
653 if (mode == VOIDmode)
654 mode = GET_MODE (arg1);
656 /* First see if machine description supply us way to reverse the comparison.
657 Give it priority over everything else to allow machine description to do
658 tricks. */
659 #ifdef REVERSIBLE_CC_MODE
660 if (GET_MODE_CLASS (mode) == MODE_CC
661 && REVERSIBLE_CC_MODE (mode))
663 #ifdef REVERSE_CONDITION
664 return REVERSE_CONDITION (code, mode);
665 #endif
666 return reverse_condition (code);
668 #endif
670 /* Try a few special cases based on the comparison code. */
671 switch (code)
673 case GEU:
674 case GTU:
675 case LEU:
676 case LTU:
677 case NE:
678 case EQ:
679 /* It is always safe to reverse EQ and NE, even for the floating
680 point. Similary the unsigned comparisons are never used for
681 floating point so we can reverse them in the default way. */
682 return reverse_condition (code);
683 case ORDERED:
684 case UNORDERED:
685 case LTGT:
686 case UNEQ:
687 /* In case we already see unordered comparison, we can be sure to
688 be dealing with floating point so we don't need any more tests. */
689 return reverse_condition_maybe_unordered (code);
690 case UNLT:
691 case UNLE:
692 case UNGT:
693 case UNGE:
694 /* We don't have safe way to reverse these yet. */
695 return UNKNOWN;
696 default:
697 break;
700 if (GET_MODE_CLASS (mode) == MODE_CC
701 #ifdef HAVE_cc0
702 || arg0 == cc0_rtx
703 #endif
706 rtx prev;
707 /* Try to search for the comparison to determine the real mode.
708 This code is expensive, but with sane machine description it
709 will be never used, since REVERSIBLE_CC_MODE will return true
710 in all cases. */
711 if (! insn)
712 return UNKNOWN;
714 for (prev = prev_nonnote_insn (insn);
715 prev != 0 && GET_CODE (prev) != CODE_LABEL;
716 prev = prev_nonnote_insn (prev))
718 rtx set = set_of (arg0, prev);
719 if (set && GET_CODE (set) == SET
720 && rtx_equal_p (SET_DEST (set), arg0))
722 rtx src = SET_SRC (set);
724 if (GET_CODE (src) == COMPARE)
726 rtx comparison = src;
727 arg0 = XEXP (src, 0);
728 mode = GET_MODE (arg0);
729 if (mode == VOIDmode)
730 mode = GET_MODE (XEXP (comparison, 1));
731 break;
733 /* We can get past reg-reg moves. This may be useful for model
734 of i387 comparisons that first move flag registers around. */
735 if (REG_P (src))
737 arg0 = src;
738 continue;
741 /* If register is clobbered in some ununderstandable way,
742 give up. */
743 if (set)
744 return UNKNOWN;
748 /* Test for an integer condition, or a floating-point comparison
749 in which NaNs can be ignored. */
750 if (GET_CODE (arg0) == CONST_INT
751 || (GET_MODE (arg0) != VOIDmode
752 && GET_MODE_CLASS (mode) != MODE_CC
753 && !HONOR_NANS (mode)))
754 return reverse_condition (code);
756 return UNKNOWN;
759 /* An wrapper around the previous function to take COMPARISON as rtx
760 expression. This simplifies many callers. */
761 enum rtx_code
762 reversed_comparison_code (comparison, insn)
763 rtx comparison, insn;
765 if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
766 return UNKNOWN;
767 return reversed_comparison_code_parts (GET_CODE (comparison),
768 XEXP (comparison, 0),
769 XEXP (comparison, 1), insn);
772 /* Given an rtx-code for a comparison, return the code for the negated
773 comparison. If no such code exists, return UNKNOWN.
775 WATCH OUT! reverse_condition is not safe to use on a jump that might
776 be acting on the results of an IEEE floating point comparison, because
777 of the special treatment of non-signaling nans in comparisons.
778 Use reversed_comparison_code instead. */
780 enum rtx_code
781 reverse_condition (code)
782 enum rtx_code code;
784 switch (code)
786 case EQ:
787 return NE;
788 case NE:
789 return EQ;
790 case GT:
791 return LE;
792 case GE:
793 return LT;
794 case LT:
795 return GE;
796 case LE:
797 return GT;
798 case GTU:
799 return LEU;
800 case GEU:
801 return LTU;
802 case LTU:
803 return GEU;
804 case LEU:
805 return GTU;
806 case UNORDERED:
807 return ORDERED;
808 case ORDERED:
809 return UNORDERED;
811 case UNLT:
812 case UNLE:
813 case UNGT:
814 case UNGE:
815 case UNEQ:
816 case LTGT:
817 return UNKNOWN;
819 default:
820 abort ();
824 /* Similar, but we're allowed to generate unordered comparisons, which
825 makes it safe for IEEE floating-point. Of course, we have to recognize
826 that the target will support them too... */
828 enum rtx_code
829 reverse_condition_maybe_unordered (code)
830 enum rtx_code code;
832 switch (code)
834 case EQ:
835 return NE;
836 case NE:
837 return EQ;
838 case GT:
839 return UNLE;
840 case GE:
841 return UNLT;
842 case LT:
843 return UNGE;
844 case LE:
845 return UNGT;
846 case LTGT:
847 return UNEQ;
848 case UNORDERED:
849 return ORDERED;
850 case ORDERED:
851 return UNORDERED;
852 case UNLT:
853 return GE;
854 case UNLE:
855 return GT;
856 case UNGT:
857 return LE;
858 case UNGE:
859 return LT;
860 case UNEQ:
861 return LTGT;
863 default:
864 abort ();
868 /* Similar, but return the code when two operands of a comparison are swapped.
869 This IS safe for IEEE floating-point. */
871 enum rtx_code
872 swap_condition (code)
873 enum rtx_code code;
875 switch (code)
877 case EQ:
878 case NE:
879 case UNORDERED:
880 case ORDERED:
881 case UNEQ:
882 case LTGT:
883 return code;
885 case GT:
886 return LT;
887 case GE:
888 return LE;
889 case LT:
890 return GT;
891 case LE:
892 return GE;
893 case GTU:
894 return LTU;
895 case GEU:
896 return LEU;
897 case LTU:
898 return GTU;
899 case LEU:
900 return GEU;
901 case UNLT:
902 return UNGT;
903 case UNLE:
904 return UNGE;
905 case UNGT:
906 return UNLT;
907 case UNGE:
908 return UNLE;
910 default:
911 abort ();
915 /* Given a comparison CODE, return the corresponding unsigned comparison.
916 If CODE is an equality comparison or already an unsigned comparison,
917 CODE is returned. */
919 enum rtx_code
920 unsigned_condition (code)
921 enum rtx_code code;
923 switch (code)
925 case EQ:
926 case NE:
927 case GTU:
928 case GEU:
929 case LTU:
930 case LEU:
931 return code;
933 case GT:
934 return GTU;
935 case GE:
936 return GEU;
937 case LT:
938 return LTU;
939 case LE:
940 return LEU;
942 default:
943 abort ();
947 /* Similarly, return the signed version of a comparison. */
949 enum rtx_code
950 signed_condition (code)
951 enum rtx_code code;
953 switch (code)
955 case EQ:
956 case NE:
957 case GT:
958 case GE:
959 case LT:
960 case LE:
961 return code;
963 case GTU:
964 return GT;
965 case GEU:
966 return GE;
967 case LTU:
968 return LT;
969 case LEU:
970 return LE;
972 default:
973 abort ();
977 /* Return non-zero if CODE1 is more strict than CODE2, i.e., if the
978 truth of CODE1 implies the truth of CODE2. */
981 comparison_dominates_p (code1, code2)
982 enum rtx_code code1, code2;
984 /* UNKNOWN comparison codes can happen as a result of trying to revert
985 comparison codes.
986 They can't match anything, so we have to reject them here. */
987 if (code1 == UNKNOWN || code2 == UNKNOWN)
988 return 0;
990 if (code1 == code2)
991 return 1;
993 switch (code1)
995 case UNEQ:
996 if (code2 == UNLE || code2 == UNGE)
997 return 1;
998 break;
1000 case EQ:
1001 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
1002 || code2 == ORDERED)
1003 return 1;
1004 break;
1006 case UNLT:
1007 if (code2 == UNLE || code2 == NE)
1008 return 1;
1009 break;
1011 case LT:
1012 if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
1013 return 1;
1014 break;
1016 case UNGT:
1017 if (code2 == UNGE || code2 == NE)
1018 return 1;
1019 break;
1021 case GT:
1022 if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
1023 return 1;
1024 break;
1026 case GE:
1027 case LE:
1028 if (code2 == ORDERED)
1029 return 1;
1030 break;
1032 case LTGT:
1033 if (code2 == NE || code2 == ORDERED)
1034 return 1;
1035 break;
1037 case LTU:
1038 if (code2 == LEU || code2 == NE)
1039 return 1;
1040 break;
1042 case GTU:
1043 if (code2 == GEU || code2 == NE)
1044 return 1;
1045 break;
1047 case UNORDERED:
1048 if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
1049 || code2 == UNGE || code2 == UNGT)
1050 return 1;
1051 break;
1053 default:
1054 break;
1057 return 0;
1060 /* Return 1 if INSN is an unconditional jump and nothing else. */
1063 simplejump_p (insn)
1064 rtx insn;
1066 return (GET_CODE (insn) == JUMP_INSN
1067 && GET_CODE (PATTERN (insn)) == SET
1068 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
1069 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
1072 /* Return nonzero if INSN is a (possibly) conditional jump
1073 and nothing more.
1075 Use this function is deprecated, since we need to support combined
1076 branch and compare insns. Use any_condjump_p instead whenever possible. */
1079 condjump_p (insn)
1080 rtx insn;
1082 rtx x = PATTERN (insn);
1084 if (GET_CODE (x) != SET
1085 || GET_CODE (SET_DEST (x)) != PC)
1086 return 0;
1088 x = SET_SRC (x);
1089 if (GET_CODE (x) == LABEL_REF)
1090 return 1;
1091 else
1092 return (GET_CODE (x) == IF_THEN_ELSE
1093 && ((GET_CODE (XEXP (x, 2)) == PC
1094 && (GET_CODE (XEXP (x, 1)) == LABEL_REF
1095 || GET_CODE (XEXP (x, 1)) == RETURN))
1096 || (GET_CODE (XEXP (x, 1)) == PC
1097 && (GET_CODE (XEXP (x, 2)) == LABEL_REF
1098 || GET_CODE (XEXP (x, 2)) == RETURN))));
1100 return 0;
1103 /* Return nonzero if INSN is a (possibly) conditional jump inside a
1104 PARALLEL.
1106 Use this function is deprecated, since we need to support combined
1107 branch and compare insns. Use any_condjump_p instead whenever possible. */
1110 condjump_in_parallel_p (insn)
1111 rtx insn;
1113 rtx x = PATTERN (insn);
1115 if (GET_CODE (x) != PARALLEL)
1116 return 0;
1117 else
1118 x = XVECEXP (x, 0, 0);
1120 if (GET_CODE (x) != SET)
1121 return 0;
1122 if (GET_CODE (SET_DEST (x)) != PC)
1123 return 0;
1124 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
1125 return 1;
1126 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
1127 return 0;
1128 if (XEXP (SET_SRC (x), 2) == pc_rtx
1129 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
1130 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
1131 return 1;
1132 if (XEXP (SET_SRC (x), 1) == pc_rtx
1133 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
1134 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
1135 return 1;
1136 return 0;
1139 /* Return set of PC, otherwise NULL. */
1142 pc_set (insn)
1143 rtx insn;
1145 rtx pat;
1146 if (GET_CODE (insn) != JUMP_INSN)
1147 return NULL_RTX;
1148 pat = PATTERN (insn);
1150 /* The set is allowed to appear either as the insn pattern or
1151 the first set in a PARALLEL. */
1152 if (GET_CODE (pat) == PARALLEL)
1153 pat = XVECEXP (pat, 0, 0);
1154 if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
1155 return pat;
1157 return NULL_RTX;
1160 /* Return true when insn is an unconditional direct jump,
1161 possibly bundled inside a PARALLEL. */
1164 any_uncondjump_p (insn)
1165 rtx insn;
1167 rtx x = pc_set (insn);
1168 if (!x)
1169 return 0;
1170 if (GET_CODE (SET_SRC (x)) != LABEL_REF)
1171 return 0;
1172 return 1;
1175 /* Return true when insn is a conditional jump. This function works for
1176 instructions containing PC sets in PARALLELs. The instruction may have
1177 various other effects so before removing the jump you must verify
1178 onlyjump_p.
1180 Note that unlike condjump_p it returns false for unconditional jumps. */
1183 any_condjump_p (insn)
1184 rtx insn;
1186 rtx x = pc_set (insn);
1187 enum rtx_code a, b;
1189 if (!x)
1190 return 0;
1191 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
1192 return 0;
1194 a = GET_CODE (XEXP (SET_SRC (x), 1));
1195 b = GET_CODE (XEXP (SET_SRC (x), 2));
1197 return ((b == PC && (a == LABEL_REF || a == RETURN))
1198 || (a == PC && (b == LABEL_REF || b == RETURN)));
1201 /* Return the label of a conditional jump. */
1204 condjump_label (insn)
1205 rtx insn;
1207 rtx x = pc_set (insn);
1209 if (!x)
1210 return NULL_RTX;
1211 x = SET_SRC (x);
1212 if (GET_CODE (x) == LABEL_REF)
1213 return x;
1214 if (GET_CODE (x) != IF_THEN_ELSE)
1215 return NULL_RTX;
1216 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
1217 return XEXP (x, 1);
1218 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
1219 return XEXP (x, 2);
1220 return NULL_RTX;
1223 /* Return true if INSN is a (possibly conditional) return insn. */
1225 static int
1226 returnjump_p_1 (loc, data)
1227 rtx *loc;
1228 void *data ATTRIBUTE_UNUSED;
1230 rtx x = *loc;
1232 return x && (GET_CODE (x) == RETURN
1233 || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
1237 returnjump_p (insn)
1238 rtx insn;
1240 if (GET_CODE (insn) != JUMP_INSN)
1241 return 0;
1242 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
1245 /* Return true if INSN is a jump that only transfers control and
1246 nothing more. */
1249 onlyjump_p (insn)
1250 rtx insn;
1252 rtx set;
1254 if (GET_CODE (insn) != JUMP_INSN)
1255 return 0;
1257 set = single_set (insn);
1258 if (set == NULL)
1259 return 0;
1260 if (GET_CODE (SET_DEST (set)) != PC)
1261 return 0;
1262 if (side_effects_p (SET_SRC (set)))
1263 return 0;
1265 return 1;
1268 #ifdef HAVE_cc0
1270 /* Return non-zero if X is an RTX that only sets the condition codes
1271 and has no side effects. */
1274 only_sets_cc0_p (x)
1275 rtx x;
1278 if (! x)
1279 return 0;
1281 if (INSN_P (x))
1282 x = PATTERN (x);
1284 return sets_cc0_p (x) == 1 && ! side_effects_p (x);
1287 /* Return 1 if X is an RTX that does nothing but set the condition codes
1288 and CLOBBER or USE registers.
1289 Return -1 if X does explicitly set the condition codes,
1290 but also does other things. */
1293 sets_cc0_p (x)
1294 rtx x;
1297 if (! x)
1298 return 0;
1300 if (INSN_P (x))
1301 x = PATTERN (x);
1303 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
1304 return 1;
1305 if (GET_CODE (x) == PARALLEL)
1307 int i;
1308 int sets_cc0 = 0;
1309 int other_things = 0;
1310 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1312 if (GET_CODE (XVECEXP (x, 0, i)) == SET
1313 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
1314 sets_cc0 = 1;
1315 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
1316 other_things = 1;
1318 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
1320 return 0;
1322 #endif
1324 /* Follow any unconditional jump at LABEL;
1325 return the ultimate label reached by any such chain of jumps.
1326 If LABEL is not followed by a jump, return LABEL.
1327 If the chain loops or we can't find end, return LABEL,
1328 since that tells caller to avoid changing the insn.
1330 If RELOAD_COMPLETED is 0, we do not chain across a NOTE_INSN_LOOP_BEG or
1331 a USE or CLOBBER. */
1334 follow_jumps (label)
1335 rtx label;
1337 rtx insn;
1338 rtx next;
1339 rtx value = label;
1340 int depth;
1342 for (depth = 0;
1343 (depth < 10
1344 && (insn = next_active_insn (value)) != 0
1345 && GET_CODE (insn) == JUMP_INSN
1346 && ((JUMP_LABEL (insn) != 0 && any_uncondjump_p (insn)
1347 && onlyjump_p (insn))
1348 || GET_CODE (PATTERN (insn)) == RETURN)
1349 && (next = NEXT_INSN (insn))
1350 && GET_CODE (next) == BARRIER);
1351 depth++)
1353 /* Don't chain through the insn that jumps into a loop
1354 from outside the loop,
1355 since that would create multiple loop entry jumps
1356 and prevent loop optimization. */
1357 rtx tem;
1358 if (!reload_completed)
1359 for (tem = value; tem != insn; tem = NEXT_INSN (tem))
1360 if (GET_CODE (tem) == NOTE
1361 && (NOTE_LINE_NUMBER (tem) == NOTE_INSN_LOOP_BEG
1362 /* ??? Optional. Disables some optimizations, but makes
1363 gcov output more accurate with -O. */
1364 || (flag_test_coverage && NOTE_LINE_NUMBER (tem) > 0)))
1365 return value;
1367 /* If we have found a cycle, make the insn jump to itself. */
1368 if (JUMP_LABEL (insn) == label)
1369 return label;
1371 tem = next_active_insn (JUMP_LABEL (insn));
1372 if (tem && (GET_CODE (PATTERN (tem)) == ADDR_VEC
1373 || GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
1374 break;
1376 value = JUMP_LABEL (insn);
1378 if (depth == 10)
1379 return label;
1380 return value;
1384 /* Find all CODE_LABELs referred to in X, and increment their use counts.
1385 If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced
1386 in INSN, then store one of them in JUMP_LABEL (INSN).
1387 If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL
1388 referenced in INSN, add a REG_LABEL note containing that label to INSN.
1389 Also, when there are consecutive labels, canonicalize on the last of them.
1391 Note that two labels separated by a loop-beginning note
1392 must be kept distinct if we have not yet done loop-optimization,
1393 because the gap between them is where loop-optimize
1394 will want to move invariant code to. CROSS_JUMP tells us
1395 that loop-optimization is done with. */
1397 void
1398 mark_jump_label (x, insn, in_mem)
1399 rtx x;
1400 rtx insn;
1401 int in_mem;
1403 RTX_CODE code = GET_CODE (x);
1404 int i;
1405 const char *fmt;
1407 switch (code)
1409 case PC:
1410 case CC0:
1411 case REG:
1412 case SUBREG:
1413 case CONST_INT:
1414 case CONST_DOUBLE:
1415 case CLOBBER:
1416 case CALL:
1417 return;
1419 case MEM:
1420 in_mem = 1;
1421 break;
1423 case SYMBOL_REF:
1424 if (!in_mem)
1425 return;
1427 /* If this is a constant-pool reference, see if it is a label. */
1428 if (CONSTANT_POOL_ADDRESS_P (x))
1429 mark_jump_label (get_pool_constant (x), insn, in_mem);
1430 break;
1432 case LABEL_REF:
1434 rtx label = XEXP (x, 0);
1436 /* Ignore remaining references to unreachable labels that
1437 have been deleted. */
1438 if (GET_CODE (label) == NOTE
1439 && NOTE_LINE_NUMBER (label) == NOTE_INSN_DELETED_LABEL)
1440 break;
1442 if (GET_CODE (label) != CODE_LABEL)
1443 abort ();
1445 /* Ignore references to labels of containing functions. */
1446 if (LABEL_REF_NONLOCAL_P (x))
1447 break;
1449 XEXP (x, 0) = label;
1450 if (! insn || ! INSN_DELETED_P (insn))
1451 ++LABEL_NUSES (label);
1453 if (insn)
1455 if (GET_CODE (insn) == JUMP_INSN)
1456 JUMP_LABEL (insn) = label;
1457 else
1459 /* Add a REG_LABEL note for LABEL unless there already
1460 is one. All uses of a label, except for labels
1461 that are the targets of jumps, must have a
1462 REG_LABEL note. */
1463 if (! find_reg_note (insn, REG_LABEL, label))
1464 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, label,
1465 REG_NOTES (insn));
1468 return;
1471 /* Do walk the labels in a vector, but not the first operand of an
1472 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1473 case ADDR_VEC:
1474 case ADDR_DIFF_VEC:
1475 if (! INSN_DELETED_P (insn))
1477 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
1479 for (i = 0; i < XVECLEN (x, eltnum); i++)
1480 mark_jump_label (XVECEXP (x, eltnum, i), NULL_RTX, in_mem);
1482 return;
1484 default:
1485 break;
1488 fmt = GET_RTX_FORMAT (code);
1489 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1491 if (fmt[i] == 'e')
1492 mark_jump_label (XEXP (x, i), insn, in_mem);
1493 else if (fmt[i] == 'E')
1495 int j;
1496 for (j = 0; j < XVECLEN (x, i); j++)
1497 mark_jump_label (XVECEXP (x, i, j), insn, in_mem);
1502 /* If all INSN does is set the pc, delete it,
1503 and delete the insn that set the condition codes for it
1504 if that's what the previous thing was. */
1506 void
1507 delete_jump (insn)
1508 rtx insn;
1510 rtx set = single_set (insn);
1512 if (set && GET_CODE (SET_DEST (set)) == PC)
1513 delete_computation (insn);
1516 /* Verify INSN is a BARRIER and delete it. */
1518 void
1519 delete_barrier (insn)
1520 rtx insn;
1522 if (GET_CODE (insn) != BARRIER)
1523 abort ();
1525 delete_insn (insn);
1528 /* Recursively delete prior insns that compute the value (used only by INSN
1529 which the caller is deleting) stored in the register mentioned by NOTE
1530 which is a REG_DEAD note associated with INSN. */
1532 static void
1533 delete_prior_computation (note, insn)
1534 rtx note;
1535 rtx insn;
1537 rtx our_prev;
1538 rtx reg = XEXP (note, 0);
1540 for (our_prev = prev_nonnote_insn (insn);
1541 our_prev && (GET_CODE (our_prev) == INSN
1542 || GET_CODE (our_prev) == CALL_INSN);
1543 our_prev = prev_nonnote_insn (our_prev))
1545 rtx pat = PATTERN (our_prev);
1547 /* If we reach a CALL which is not calling a const function
1548 or the callee pops the arguments, then give up. */
1549 if (GET_CODE (our_prev) == CALL_INSN
1550 && (! CONST_OR_PURE_CALL_P (our_prev)
1551 || GET_CODE (pat) != SET || GET_CODE (SET_SRC (pat)) != CALL))
1552 break;
1554 /* If we reach a SEQUENCE, it is too complex to try to
1555 do anything with it, so give up. */
1556 if (GET_CODE (pat) == SEQUENCE)
1557 break;
1559 if (GET_CODE (pat) == USE
1560 && GET_CODE (XEXP (pat, 0)) == INSN)
1561 /* reorg creates USEs that look like this. We leave them
1562 alone because reorg needs them for its own purposes. */
1563 break;
1565 if (reg_set_p (reg, pat))
1567 if (side_effects_p (pat) && GET_CODE (our_prev) != CALL_INSN)
1568 break;
1570 if (GET_CODE (pat) == PARALLEL)
1572 /* If we find a SET of something else, we can't
1573 delete the insn. */
1575 int i;
1577 for (i = 0; i < XVECLEN (pat, 0); i++)
1579 rtx part = XVECEXP (pat, 0, i);
1581 if (GET_CODE (part) == SET
1582 && SET_DEST (part) != reg)
1583 break;
1586 if (i == XVECLEN (pat, 0))
1587 delete_computation (our_prev);
1589 else if (GET_CODE (pat) == SET
1590 && GET_CODE (SET_DEST (pat)) == REG)
1592 int dest_regno = REGNO (SET_DEST (pat));
1593 int dest_endregno
1594 = (dest_regno
1595 + (dest_regno < FIRST_PSEUDO_REGISTER
1596 ? HARD_REGNO_NREGS (dest_regno,
1597 GET_MODE (SET_DEST (pat))) : 1));
1598 int regno = REGNO (reg);
1599 int endregno
1600 = (regno
1601 + (regno < FIRST_PSEUDO_REGISTER
1602 ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1));
1604 if (dest_regno >= regno
1605 && dest_endregno <= endregno)
1606 delete_computation (our_prev);
1608 /* We may have a multi-word hard register and some, but not
1609 all, of the words of the register are needed in subsequent
1610 insns. Write REG_UNUSED notes for those parts that were not
1611 needed. */
1612 else if (dest_regno <= regno
1613 && dest_endregno >= endregno)
1615 int i;
1617 REG_NOTES (our_prev)
1618 = gen_rtx_EXPR_LIST (REG_UNUSED, reg,
1619 REG_NOTES (our_prev));
1621 for (i = dest_regno; i < dest_endregno; i++)
1622 if (! find_regno_note (our_prev, REG_UNUSED, i))
1623 break;
1625 if (i == dest_endregno)
1626 delete_computation (our_prev);
1630 break;
1633 /* If PAT references the register that dies here, it is an
1634 additional use. Hence any prior SET isn't dead. However, this
1635 insn becomes the new place for the REG_DEAD note. */
1636 if (reg_overlap_mentioned_p (reg, pat))
1638 XEXP (note, 1) = REG_NOTES (our_prev);
1639 REG_NOTES (our_prev) = note;
1640 break;
1645 /* Delete INSN and recursively delete insns that compute values used only
1646 by INSN. This uses the REG_DEAD notes computed during flow analysis.
1647 If we are running before flow.c, we need do nothing since flow.c will
1648 delete dead code. We also can't know if the registers being used are
1649 dead or not at this point.
1651 Otherwise, look at all our REG_DEAD notes. If a previous insn does
1652 nothing other than set a register that dies in this insn, we can delete
1653 that insn as well.
1655 On machines with CC0, if CC0 is used in this insn, we may be able to
1656 delete the insn that set it. */
1658 static void
1659 delete_computation (insn)
1660 rtx insn;
1662 rtx note, next;
1664 #ifdef HAVE_cc0
1665 if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
1667 rtx prev = prev_nonnote_insn (insn);
1668 /* We assume that at this stage
1669 CC's are always set explicitly
1670 and always immediately before the jump that
1671 will use them. So if the previous insn
1672 exists to set the CC's, delete it
1673 (unless it performs auto-increments, etc.). */
1674 if (prev && GET_CODE (prev) == INSN
1675 && sets_cc0_p (PATTERN (prev)))
1677 if (sets_cc0_p (PATTERN (prev)) > 0
1678 && ! side_effects_p (PATTERN (prev)))
1679 delete_computation (prev);
1680 else
1681 /* Otherwise, show that cc0 won't be used. */
1682 REG_NOTES (prev) = gen_rtx_EXPR_LIST (REG_UNUSED,
1683 cc0_rtx, REG_NOTES (prev));
1686 #endif
1688 for (note = REG_NOTES (insn); note; note = next)
1690 next = XEXP (note, 1);
1692 if (REG_NOTE_KIND (note) != REG_DEAD
1693 /* Verify that the REG_NOTE is legitimate. */
1694 || GET_CODE (XEXP (note, 0)) != REG)
1695 continue;
1697 delete_prior_computation (note, insn);
1700 delete_related_insns (insn);
1703 /* Delete insn INSN from the chain of insns and update label ref counts
1704 and delete insns now unreachable.
1706 Returns the first insn after INSN that was not deleted.
1708 Usage of this instruction is deprecated. Use delete_insn instead and
1709 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1712 delete_related_insns (insn)
1713 rtx insn;
1715 int was_code_label = (GET_CODE (insn) == CODE_LABEL);
1716 rtx note;
1717 rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
1719 while (next && INSN_DELETED_P (next))
1720 next = NEXT_INSN (next);
1722 /* This insn is already deleted => return first following nondeleted. */
1723 if (INSN_DELETED_P (insn))
1724 return next;
1726 delete_insn (insn);
1728 /* If instruction is followed by a barrier,
1729 delete the barrier too. */
1731 if (next != 0 && GET_CODE (next) == BARRIER)
1732 delete_insn (next);
1734 /* If deleting a jump, decrement the count of the label,
1735 and delete the label if it is now unused. */
1737 if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
1739 rtx lab = JUMP_LABEL (insn), lab_next;
1741 if (LABEL_NUSES (lab) == 0)
1743 /* This can delete NEXT or PREV,
1744 either directly if NEXT is JUMP_LABEL (INSN),
1745 or indirectly through more levels of jumps. */
1746 delete_related_insns (lab);
1748 /* I feel a little doubtful about this loop,
1749 but I see no clean and sure alternative way
1750 to find the first insn after INSN that is not now deleted.
1751 I hope this works. */
1752 while (next && INSN_DELETED_P (next))
1753 next = NEXT_INSN (next);
1754 return next;
1756 else if ((lab_next = next_nonnote_insn (lab)) != NULL
1757 && GET_CODE (lab_next) == JUMP_INSN
1758 && (GET_CODE (PATTERN (lab_next)) == ADDR_VEC
1759 || GET_CODE (PATTERN (lab_next)) == ADDR_DIFF_VEC))
1761 /* If we're deleting the tablejump, delete the dispatch table.
1762 We may not be able to kill the label immediately preceding
1763 just yet, as it might be referenced in code leading up to
1764 the tablejump. */
1765 delete_related_insns (lab_next);
1769 /* Likewise if we're deleting a dispatch table. */
1771 if (GET_CODE (insn) == JUMP_INSN
1772 && (GET_CODE (PATTERN (insn)) == ADDR_VEC
1773 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
1775 rtx pat = PATTERN (insn);
1776 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1777 int len = XVECLEN (pat, diff_vec_p);
1779 for (i = 0; i < len; i++)
1780 if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1781 delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
1782 while (next && INSN_DELETED_P (next))
1783 next = NEXT_INSN (next);
1784 return next;
1787 /* Likewise for an ordinary INSN / CALL_INSN with a REG_LABEL note. */
1788 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
1789 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1790 if (REG_NOTE_KIND (note) == REG_LABEL
1791 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1792 && GET_CODE (XEXP (note, 0)) == CODE_LABEL)
1793 if (LABEL_NUSES (XEXP (note, 0)) == 0)
1794 delete_related_insns (XEXP (note, 0));
1796 while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
1797 prev = PREV_INSN (prev);
1799 /* If INSN was a label and a dispatch table follows it,
1800 delete the dispatch table. The tablejump must have gone already.
1801 It isn't useful to fall through into a table. */
1803 if (was_code_label
1804 && NEXT_INSN (insn) != 0
1805 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
1806 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
1807 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
1808 next = delete_related_insns (NEXT_INSN (insn));
1810 /* If INSN was a label, delete insns following it if now unreachable. */
1812 if (was_code_label && prev && GET_CODE (prev) == BARRIER)
1814 RTX_CODE code;
1815 while (next != 0
1816 && (GET_RTX_CLASS (code = GET_CODE (next)) == 'i'
1817 || code == NOTE || code == BARRIER
1818 || (code == CODE_LABEL && INSN_DELETED_P (next))))
1820 if (code == NOTE
1821 && NOTE_LINE_NUMBER (next) != NOTE_INSN_FUNCTION_END)
1822 next = NEXT_INSN (next);
1823 /* Keep going past other deleted labels to delete what follows. */
1824 else if (code == CODE_LABEL && INSN_DELETED_P (next))
1825 next = NEXT_INSN (next);
1826 else
1827 /* Note: if this deletes a jump, it can cause more
1828 deletion of unreachable code, after a different label.
1829 As long as the value from this recursive call is correct,
1830 this invocation functions correctly. */
1831 next = delete_related_insns (next);
1835 return next;
1838 /* Advance from INSN till reaching something not deleted
1839 then return that. May return INSN itself. */
1842 next_nondeleted_insn (insn)
1843 rtx insn;
1845 while (INSN_DELETED_P (insn))
1846 insn = NEXT_INSN (insn);
1847 return insn;
1850 /* Delete a range of insns from FROM to TO, inclusive.
1851 This is for the sake of peephole optimization, so assume
1852 that whatever these insns do will still be done by a new
1853 peephole insn that will replace them. */
1855 void
1856 delete_for_peephole (from, to)
1857 rtx from, to;
1859 rtx insn = from;
1861 while (1)
1863 rtx next = NEXT_INSN (insn);
1864 rtx prev = PREV_INSN (insn);
1866 if (GET_CODE (insn) != NOTE)
1868 INSN_DELETED_P (insn) = 1;
1870 /* Patch this insn out of the chain. */
1871 /* We don't do this all at once, because we
1872 must preserve all NOTEs. */
1873 if (prev)
1874 NEXT_INSN (prev) = next;
1876 if (next)
1877 PREV_INSN (next) = prev;
1880 if (insn == to)
1881 break;
1882 insn = next;
1885 /* Note that if TO is an unconditional jump
1886 we *do not* delete the BARRIER that follows,
1887 since the peephole that replaces this sequence
1888 is also an unconditional jump in that case. */
1891 /* We have determined that INSN is never reached, and are about to
1892 delete it. Print a warning if the user asked for one.
1894 To try to make this warning more useful, this should only be called
1895 once per basic block not reached, and it only warns when the basic
1896 block contains more than one line from the current function, and
1897 contains at least one operation. CSE and inlining can duplicate insns,
1898 so it's possible to get spurious warnings from this. */
1900 void
1901 never_reached_warning (avoided_insn, finish)
1902 rtx avoided_insn, finish;
1904 rtx insn;
1905 rtx a_line_note = NULL;
1906 int two_avoided_lines = 0, contains_insn = 0, reached_end = 0;
1908 if (! warn_notreached)
1909 return;
1911 /* Scan forwards, looking at LINE_NUMBER notes, until
1912 we hit a LABEL or we run out of insns. */
1914 for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
1916 if (finish == NULL && GET_CODE (insn) == CODE_LABEL)
1917 break;
1919 if (GET_CODE (insn) == NOTE /* A line number note? */
1920 && NOTE_LINE_NUMBER (insn) >= 0)
1922 if (a_line_note == NULL)
1923 a_line_note = insn;
1924 else
1925 two_avoided_lines |= (NOTE_LINE_NUMBER (a_line_note)
1926 != NOTE_LINE_NUMBER (insn));
1928 else if (INSN_P (insn))
1930 if (reached_end)
1931 break;
1932 contains_insn = 1;
1935 if (insn == finish)
1936 reached_end = 1;
1938 if (two_avoided_lines && contains_insn)
1939 warning_with_file_and_line (NOTE_SOURCE_FILE (a_line_note),
1940 NOTE_LINE_NUMBER (a_line_note),
1941 "will never be executed");
1944 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1945 NLABEL as a return. Accrue modifications into the change group. */
1947 static void
1948 redirect_exp_1 (loc, olabel, nlabel, insn)
1949 rtx *loc;
1950 rtx olabel, nlabel;
1951 rtx insn;
1953 rtx x = *loc;
1954 RTX_CODE code = GET_CODE (x);
1955 int i;
1956 const char *fmt;
1958 if (code == LABEL_REF)
1960 if (XEXP (x, 0) == olabel)
1962 rtx n;
1963 if (nlabel)
1964 n = gen_rtx_LABEL_REF (VOIDmode, nlabel);
1965 else
1966 n = gen_rtx_RETURN (VOIDmode);
1968 validate_change (insn, loc, n, 1);
1969 return;
1972 else if (code == RETURN && olabel == 0)
1974 x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
1975 if (loc == &PATTERN (insn))
1976 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1977 validate_change (insn, loc, x, 1);
1978 return;
1981 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1982 && GET_CODE (SET_SRC (x)) == LABEL_REF
1983 && XEXP (SET_SRC (x), 0) == olabel)
1985 validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1986 return;
1989 fmt = GET_RTX_FORMAT (code);
1990 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1992 if (fmt[i] == 'e')
1993 redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1994 else if (fmt[i] == 'E')
1996 int j;
1997 for (j = 0; j < XVECLEN (x, i); j++)
1998 redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
2003 /* Similar, but apply the change group and report success or failure. */
2005 static int
2006 redirect_exp (olabel, nlabel, insn)
2007 rtx olabel, nlabel;
2008 rtx insn;
2010 rtx *loc;
2012 if (GET_CODE (PATTERN (insn)) == PARALLEL)
2013 loc = &XVECEXP (PATTERN (insn), 0, 0);
2014 else
2015 loc = &PATTERN (insn);
2017 redirect_exp_1 (loc, olabel, nlabel, insn);
2018 if (num_validated_changes () == 0)
2019 return 0;
2021 return apply_change_group ();
2024 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
2025 the modifications into the change group. Return false if we did
2026 not see how to do that. */
2029 redirect_jump_1 (jump, nlabel)
2030 rtx jump, nlabel;
2032 int ochanges = num_validated_changes ();
2033 rtx *loc;
2035 if (GET_CODE (PATTERN (jump)) == PARALLEL)
2036 loc = &XVECEXP (PATTERN (jump), 0, 0);
2037 else
2038 loc = &PATTERN (jump);
2040 redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
2041 return num_validated_changes () > ochanges;
2044 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
2045 jump target label is unused as a result, it and the code following
2046 it may be deleted.
2048 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
2049 RETURN insn.
2051 The return value will be 1 if the change was made, 0 if it wasn't
2052 (this can only occur for NLABEL == 0). */
2055 redirect_jump (jump, nlabel, delete_unused)
2056 rtx jump, nlabel;
2057 int delete_unused;
2059 rtx olabel = JUMP_LABEL (jump);
2061 if (nlabel == olabel)
2062 return 1;
2064 if (! redirect_exp (olabel, nlabel, jump))
2065 return 0;
2067 JUMP_LABEL (jump) = nlabel;
2068 if (nlabel)
2069 ++LABEL_NUSES (nlabel);
2071 /* If we're eliding the jump over exception cleanups at the end of a
2072 function, move the function end note so that -Wreturn-type works. */
2073 if (olabel && nlabel
2074 && NEXT_INSN (olabel)
2075 && GET_CODE (NEXT_INSN (olabel)) == NOTE
2076 && NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END)
2077 emit_note_after (NOTE_INSN_FUNCTION_END, nlabel);
2079 if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused
2080 /* Undefined labels will remain outside the insn stream. */
2081 && INSN_UID (olabel))
2082 delete_related_insns (olabel);
2084 return 1;
2087 /* Invert the jump condition of rtx X contained in jump insn, INSN.
2088 Accrue the modifications into the change group. */
2090 static void
2091 invert_exp_1 (insn)
2092 rtx insn;
2094 RTX_CODE code;
2095 rtx x = pc_set (insn);
2097 if (!x)
2098 abort ();
2099 x = SET_SRC (x);
2101 code = GET_CODE (x);
2103 if (code == IF_THEN_ELSE)
2105 rtx comp = XEXP (x, 0);
2106 rtx tem;
2107 enum rtx_code reversed_code;
2109 /* We can do this in two ways: The preferable way, which can only
2110 be done if this is not an integer comparison, is to reverse
2111 the comparison code. Otherwise, swap the THEN-part and ELSE-part
2112 of the IF_THEN_ELSE. If we can't do either, fail. */
2114 reversed_code = reversed_comparison_code (comp, insn);
2116 if (reversed_code != UNKNOWN)
2118 validate_change (insn, &XEXP (x, 0),
2119 gen_rtx_fmt_ee (reversed_code,
2120 GET_MODE (comp), XEXP (comp, 0),
2121 XEXP (comp, 1)),
2123 return;
2126 tem = XEXP (x, 1);
2127 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
2128 validate_change (insn, &XEXP (x, 2), tem, 1);
2130 else
2131 abort ();
2134 /* Invert the jump condition of conditional jump insn, INSN.
2136 Return 1 if we can do so, 0 if we cannot find a way to do so that
2137 matches a pattern. */
2139 static int
2140 invert_exp (insn)
2141 rtx insn;
2143 invert_exp_1 (insn);
2144 if (num_validated_changes () == 0)
2145 return 0;
2147 return apply_change_group ();
2150 /* Invert the condition of the jump JUMP, and make it jump to label
2151 NLABEL instead of where it jumps now. Accrue changes into the
2152 change group. Return false if we didn't see how to perform the
2153 inversion and redirection. */
2156 invert_jump_1 (jump, nlabel)
2157 rtx jump, nlabel;
2159 int ochanges;
2161 ochanges = num_validated_changes ();
2162 invert_exp_1 (jump);
2163 if (num_validated_changes () == ochanges)
2164 return 0;
2166 return redirect_jump_1 (jump, nlabel);
2169 /* Invert the condition of the jump JUMP, and make it jump to label
2170 NLABEL instead of where it jumps now. Return true if successful. */
2173 invert_jump (jump, nlabel, delete_unused)
2174 rtx jump, nlabel;
2175 int delete_unused;
2177 /* We have to either invert the condition and change the label or
2178 do neither. Either operation could fail. We first try to invert
2179 the jump. If that succeeds, we try changing the label. If that fails,
2180 we invert the jump back to what it was. */
2182 if (! invert_exp (jump))
2183 return 0;
2185 if (redirect_jump (jump, nlabel, delete_unused))
2187 invert_br_probabilities (jump);
2189 return 1;
2192 if (! invert_exp (jump))
2193 /* This should just be putting it back the way it was. */
2194 abort ();
2196 return 0;
2200 /* Like rtx_equal_p except that it considers two REGs as equal
2201 if they renumber to the same value and considers two commutative
2202 operations to be the same if the order of the operands has been
2203 reversed.
2205 ??? Addition is not commutative on the PA due to the weird implicit
2206 space register selection rules for memory addresses. Therefore, we
2207 don't consider a + b == b + a.
2209 We could/should make this test a little tighter. Possibly only
2210 disabling it on the PA via some backend macro or only disabling this
2211 case when the PLUS is inside a MEM. */
2214 rtx_renumbered_equal_p (x, y)
2215 rtx x, y;
2217 int i;
2218 RTX_CODE code = GET_CODE (x);
2219 const char *fmt;
2221 if (x == y)
2222 return 1;
2224 if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
2225 && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
2226 && GET_CODE (SUBREG_REG (y)) == REG)))
2228 int reg_x = -1, reg_y = -1;
2229 int byte_x = 0, byte_y = 0;
2231 if (GET_MODE (x) != GET_MODE (y))
2232 return 0;
2234 /* If we haven't done any renumbering, don't
2235 make any assumptions. */
2236 if (reg_renumber == 0)
2237 return rtx_equal_p (x, y);
2239 if (code == SUBREG)
2241 reg_x = REGNO (SUBREG_REG (x));
2242 byte_x = SUBREG_BYTE (x);
2244 if (reg_renumber[reg_x] >= 0)
2246 reg_x = subreg_regno_offset (reg_renumber[reg_x],
2247 GET_MODE (SUBREG_REG (x)),
2248 byte_x,
2249 GET_MODE (x));
2250 byte_x = 0;
2253 else
2255 reg_x = REGNO (x);
2256 if (reg_renumber[reg_x] >= 0)
2257 reg_x = reg_renumber[reg_x];
2260 if (GET_CODE (y) == SUBREG)
2262 reg_y = REGNO (SUBREG_REG (y));
2263 byte_y = SUBREG_BYTE (y);
2265 if (reg_renumber[reg_y] >= 0)
2267 reg_y = subreg_regno_offset (reg_renumber[reg_y],
2268 GET_MODE (SUBREG_REG (y)),
2269 byte_y,
2270 GET_MODE (y));
2271 byte_y = 0;
2274 else
2276 reg_y = REGNO (y);
2277 if (reg_renumber[reg_y] >= 0)
2278 reg_y = reg_renumber[reg_y];
2281 return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
2284 /* Now we have disposed of all the cases
2285 in which different rtx codes can match. */
2286 if (code != GET_CODE (y))
2287 return 0;
2289 switch (code)
2291 case PC:
2292 case CC0:
2293 case ADDR_VEC:
2294 case ADDR_DIFF_VEC:
2295 return 0;
2297 case CONST_INT:
2298 return INTVAL (x) == INTVAL (y);
2300 case LABEL_REF:
2301 /* We can't assume nonlocal labels have their following insns yet. */
2302 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
2303 return XEXP (x, 0) == XEXP (y, 0);
2305 /* Two label-refs are equivalent if they point at labels
2306 in the same position in the instruction stream. */
2307 return (next_real_insn (XEXP (x, 0))
2308 == next_real_insn (XEXP (y, 0)));
2310 case SYMBOL_REF:
2311 return XSTR (x, 0) == XSTR (y, 0);
2313 case CODE_LABEL:
2314 /* If we didn't match EQ equality above, they aren't the same. */
2315 return 0;
2317 default:
2318 break;
2321 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
2323 if (GET_MODE (x) != GET_MODE (y))
2324 return 0;
2326 /* For commutative operations, the RTX match if the operand match in any
2327 order. Also handle the simple binary and unary cases without a loop.
2329 ??? Don't consider PLUS a commutative operator; see comments above. */
2330 if ((code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
2331 && code != PLUS)
2332 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
2333 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
2334 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
2335 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
2336 else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
2337 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
2338 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
2339 else if (GET_RTX_CLASS (code) == '1')
2340 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
2342 /* Compare the elements. If any pair of corresponding elements
2343 fail to match, return 0 for the whole things. */
2345 fmt = GET_RTX_FORMAT (code);
2346 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2348 int j;
2349 switch (fmt[i])
2351 case 'w':
2352 if (XWINT (x, i) != XWINT (y, i))
2353 return 0;
2354 break;
2356 case 'i':
2357 if (XINT (x, i) != XINT (y, i))
2358 return 0;
2359 break;
2361 case 't':
2362 if (XTREE (x, i) != XTREE (y, i))
2363 return 0;
2364 break;
2366 case 's':
2367 if (strcmp (XSTR (x, i), XSTR (y, i)))
2368 return 0;
2369 break;
2371 case 'e':
2372 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
2373 return 0;
2374 break;
2376 case 'u':
2377 if (XEXP (x, i) != XEXP (y, i))
2378 return 0;
2379 /* fall through. */
2380 case '0':
2381 break;
2383 case 'E':
2384 if (XVECLEN (x, i) != XVECLEN (y, i))
2385 return 0;
2386 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2387 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
2388 return 0;
2389 break;
2391 default:
2392 abort ();
2395 return 1;
2398 /* If X is a hard register or equivalent to one or a subregister of one,
2399 return the hard register number. If X is a pseudo register that was not
2400 assigned a hard register, return the pseudo register number. Otherwise,
2401 return -1. Any rtx is valid for X. */
2404 true_regnum (x)
2405 rtx x;
2407 if (GET_CODE (x) == REG)
2409 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
2410 return reg_renumber[REGNO (x)];
2411 return REGNO (x);
2413 if (GET_CODE (x) == SUBREG)
2415 int base = true_regnum (SUBREG_REG (x));
2416 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
2417 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
2418 GET_MODE (SUBREG_REG (x)),
2419 SUBREG_BYTE (x), GET_MODE (x));
2421 return -1;