* loop.c (check_dbra_loop): Fix last change: examine both
[official-gcc.git] / gcc / jump.c
blobfcb3c61800bbfc8433ab9eba25f020048902d32f
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 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))++;
95 /* Keep track of labels used for marking handlers for exception
96 regions; they cannot usually be deleted. */
98 for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
99 if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL)
100 LABEL_NUSES (XEXP (insn, 0))++;
103 /* Some old code expects exactly one BARRIER as the NEXT_INSN of a
104 non-fallthru insn. This is not generally true, as multiple barriers
105 may have crept in, or the BARRIER may be separated from the last
106 real insn by one or more NOTEs.
108 This simple pass moves barriers and removes duplicates so that the
109 old code is happy.
111 void
112 cleanup_barriers ()
114 rtx insn, next, prev;
115 for (insn = get_insns (); insn; insn = next)
117 next = NEXT_INSN (insn);
118 if (GET_CODE (insn) == BARRIER)
120 prev = prev_nonnote_insn (insn);
121 if (GET_CODE (prev) == BARRIER)
122 delete_barrier (insn);
123 else if (prev != PREV_INSN (insn))
124 reorder_insns (insn, insn, prev);
129 void
130 copy_loop_headers (f)
131 rtx f;
133 rtx insn, next;
134 /* Now iterate optimizing jumps until nothing changes over one pass. */
135 for (insn = f; insn; insn = next)
137 rtx temp, temp1;
139 next = NEXT_INSN (insn);
141 /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional
142 jump. Try to optimize by duplicating the loop exit test if so.
143 This is only safe immediately after regscan, because it uses
144 the values of regno_first_uid and regno_last_uid. */
145 if (GET_CODE (insn) == NOTE
146 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
147 && (temp1 = next_nonnote_insn (insn)) != 0
148 && any_uncondjump_p (temp1) && onlyjump_p (temp1))
150 temp = PREV_INSN (insn);
151 if (duplicate_loop_exit_test (insn))
153 next = NEXT_INSN (temp);
159 void
160 purge_line_number_notes (f)
161 rtx f;
163 rtx last_note = 0;
164 rtx insn;
165 /* Delete extraneous line number notes.
166 Note that two consecutive notes for different lines are not really
167 extraneous. There should be some indication where that line belonged,
168 even if it became empty. */
170 for (insn = f; insn; insn = NEXT_INSN (insn))
171 if (GET_CODE (insn) == NOTE)
173 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
174 /* Any previous line note was for the prologue; gdb wants a new
175 note after the prologue even if it is for the same line. */
176 last_note = NULL_RTX;
177 else if (NOTE_LINE_NUMBER (insn) >= 0)
179 /* Delete this note if it is identical to previous note. */
180 if (last_note
181 && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
182 && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
184 delete_related_insns (insn);
185 continue;
188 last_note = insn;
193 /* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
194 notes whose labels don't occur in the insn any more. Returns the
195 largest INSN_UID found. */
196 static int
197 init_label_info (f)
198 rtx f;
200 int largest_uid = 0;
201 rtx insn;
203 for (insn = f; insn; insn = NEXT_INSN (insn))
205 if (GET_CODE (insn) == CODE_LABEL)
206 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
207 else if (GET_CODE (insn) == JUMP_INSN)
208 JUMP_LABEL (insn) = 0;
209 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
211 rtx note, next;
213 for (note = REG_NOTES (insn); note; note = next)
215 next = XEXP (note, 1);
216 if (REG_NOTE_KIND (note) == REG_LABEL
217 && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
218 remove_note (insn, note);
221 if (INSN_UID (insn) > largest_uid)
222 largest_uid = INSN_UID (insn);
225 return largest_uid;
228 /* Mark the label each jump jumps to.
229 Combine consecutive labels, and count uses of labels. */
231 static void
232 mark_all_labels (f)
233 rtx f;
235 rtx insn;
237 for (insn = f; insn; insn = NEXT_INSN (insn))
238 if (INSN_P (insn))
240 if (GET_CODE (insn) == CALL_INSN
241 && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
243 mark_all_labels (XEXP (PATTERN (insn), 0));
244 mark_all_labels (XEXP (PATTERN (insn), 1));
245 mark_all_labels (XEXP (PATTERN (insn), 2));
247 /* Canonicalize the tail recursion label attached to the
248 CALL_PLACEHOLDER insn. */
249 if (XEXP (PATTERN (insn), 3))
251 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
252 XEXP (PATTERN (insn), 3));
253 mark_jump_label (label_ref, insn, 0);
254 XEXP (PATTERN (insn), 3) = XEXP (label_ref, 0);
257 continue;
260 mark_jump_label (PATTERN (insn), insn, 0);
261 if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
263 /* When we know the LABEL_REF contained in a REG used in
264 an indirect jump, we'll have a REG_LABEL note so that
265 flow can tell where it's going. */
266 if (JUMP_LABEL (insn) == 0)
268 rtx label_note = find_reg_note (insn, REG_LABEL, NULL_RTX);
269 if (label_note)
271 /* But a LABEL_REF around the REG_LABEL note, so
272 that we can canonicalize it. */
273 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
274 XEXP (label_note, 0));
276 mark_jump_label (label_ref, insn, 0);
277 XEXP (label_note, 0) = XEXP (label_ref, 0);
278 JUMP_LABEL (insn) = XEXP (label_note, 0);
285 /* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional
286 jump. Assume that this unconditional jump is to the exit test code. If
287 the code is sufficiently simple, make a copy of it before INSN,
288 followed by a jump to the exit of the loop. Then delete the unconditional
289 jump after INSN.
291 Return 1 if we made the change, else 0.
293 This is only safe immediately after a regscan pass because it uses the
294 values of regno_first_uid and regno_last_uid. */
296 static int
297 duplicate_loop_exit_test (loop_start)
298 rtx loop_start;
300 rtx insn, set, reg, p, link;
301 rtx copy = 0, first_copy = 0;
302 int num_insns = 0;
303 rtx exitcode = NEXT_INSN (JUMP_LABEL (next_nonnote_insn (loop_start)));
304 rtx lastexit;
305 int max_reg = max_reg_num ();
306 rtx *reg_map = 0;
307 rtx loop_pre_header_label;
309 /* Scan the exit code. We do not perform this optimization if any insn:
311 is a CALL_INSN
312 is a CODE_LABEL
313 has a REG_RETVAL or REG_LIBCALL note (hard to adjust)
314 is a NOTE_INSN_LOOP_BEG because this means we have a nested loop
315 is a NOTE_INSN_BLOCK_{BEG,END} because duplicating these notes
316 is not valid.
318 We also do not do this if we find an insn with ASM_OPERANDS. While
319 this restriction should not be necessary, copying an insn with
320 ASM_OPERANDS can confuse asm_noperands in some cases.
322 Also, don't do this if the exit code is more than 20 insns. */
324 for (insn = exitcode;
325 insn
326 && ! (GET_CODE (insn) == NOTE
327 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
328 insn = NEXT_INSN (insn))
330 switch (GET_CODE (insn))
332 case CODE_LABEL:
333 case CALL_INSN:
334 return 0;
335 case NOTE:
336 /* We could be in front of the wrong NOTE_INSN_LOOP_END if there is
337 a jump immediately after the loop start that branches outside
338 the loop but within an outer loop, near the exit test.
339 If we copied this exit test and created a phony
340 NOTE_INSN_LOOP_VTOP, this could make instructions immediately
341 before the exit test look like these could be safely moved
342 out of the loop even if they actually may be never executed.
343 This can be avoided by checking here for NOTE_INSN_LOOP_CONT. */
345 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
346 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT)
347 return 0;
349 if (optimize < 2
350 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
351 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
352 /* If we were to duplicate this code, we would not move
353 the BLOCK notes, and so debugging the moved code would
354 be difficult. Thus, we only move the code with -O2 or
355 higher. */
356 return 0;
358 break;
359 case JUMP_INSN:
360 case INSN:
361 /* The code below would grossly mishandle REG_WAS_0 notes,
362 so get rid of them here. */
363 while ((p = find_reg_note (insn, REG_WAS_0, NULL_RTX)) != 0)
364 remove_note (insn, p);
365 if (++num_insns > 20
366 || find_reg_note (insn, REG_RETVAL, NULL_RTX)
367 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
368 return 0;
369 break;
370 default:
371 break;
375 /* Unless INSN is zero, we can do the optimization. */
376 if (insn == 0)
377 return 0;
379 lastexit = insn;
381 /* See if any insn sets a register only used in the loop exit code and
382 not a user variable. If so, replace it with a new register. */
383 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
384 if (GET_CODE (insn) == INSN
385 && (set = single_set (insn)) != 0
386 && ((reg = SET_DEST (set), GET_CODE (reg) == REG)
387 || (GET_CODE (reg) == SUBREG
388 && (reg = SUBREG_REG (reg), GET_CODE (reg) == REG)))
389 && REGNO (reg) >= FIRST_PSEUDO_REGISTER
390 && REGNO_FIRST_UID (REGNO (reg)) == INSN_UID (insn))
392 for (p = NEXT_INSN (insn); p != lastexit; p = NEXT_INSN (p))
393 if (REGNO_LAST_UID (REGNO (reg)) == INSN_UID (p))
394 break;
396 if (p != lastexit)
398 /* We can do the replacement. Allocate reg_map if this is the
399 first replacement we found. */
400 if (reg_map == 0)
401 reg_map = (rtx *) xcalloc (max_reg, sizeof (rtx));
403 REG_LOOP_TEST_P (reg) = 1;
405 reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg));
408 loop_pre_header_label = gen_label_rtx ();
410 /* Now copy each insn. */
411 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
413 switch (GET_CODE (insn))
415 case BARRIER:
416 copy = emit_barrier_before (loop_start);
417 break;
418 case NOTE:
419 /* Only copy line-number notes. */
420 if (NOTE_LINE_NUMBER (insn) >= 0)
422 copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
423 NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
425 break;
427 case INSN:
428 copy = emit_insn_before (copy_insn (PATTERN (insn)), loop_start);
429 if (reg_map)
430 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
432 mark_jump_label (PATTERN (copy), copy, 0);
434 /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
435 make them. */
436 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
437 if (REG_NOTE_KIND (link) != REG_LABEL)
439 if (GET_CODE (link) == EXPR_LIST)
440 REG_NOTES (copy)
441 = copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
442 XEXP (link, 0),
443 REG_NOTES (copy)));
444 else
445 REG_NOTES (copy)
446 = copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
447 XEXP (link, 0),
448 REG_NOTES (copy)));
451 if (reg_map && REG_NOTES (copy))
452 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
453 break;
455 case JUMP_INSN:
456 copy = emit_jump_insn_before (copy_insn (PATTERN (insn)),
457 loop_start);
458 if (reg_map)
459 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
460 mark_jump_label (PATTERN (copy), copy, 0);
461 if (REG_NOTES (insn))
463 REG_NOTES (copy) = copy_insn_1 (REG_NOTES (insn));
464 if (reg_map)
465 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
468 /* Predict conditional jump that do make loop looping as taken.
469 Other jumps are probably exit conditions, so predict
470 them as untaken. */
471 if (any_condjump_p (copy))
473 rtx label = JUMP_LABEL (copy);
474 if (label)
476 /* The jump_insn after loop_start should be followed
477 by barrier and loopback label. */
478 if (prev_nonnote_insn (label)
479 && (prev_nonnote_insn (prev_nonnote_insn (label))
480 == next_nonnote_insn (loop_start)))
482 predict_insn_def (copy, PRED_LOOP_HEADER, TAKEN);
483 /* To keep pre-header, we need to redirect all loop
484 entrances before the LOOP_BEG note. */
485 redirect_jump (copy, loop_pre_header_label, 0);
487 else
488 predict_insn_def (copy, PRED_LOOP_HEADER, NOT_TAKEN);
491 break;
493 default:
494 abort ();
497 /* Record the first insn we copied. We need it so that we can
498 scan the copied insns for new pseudo registers. */
499 if (! first_copy)
500 first_copy = copy;
503 /* Now clean up by emitting a jump to the end label and deleting the jump
504 at the start of the loop. */
505 if (! copy || GET_CODE (copy) != BARRIER)
507 copy = emit_jump_insn_before (gen_jump (get_label_after (insn)),
508 loop_start);
510 /* Record the first insn we copied. We need it so that we can
511 scan the copied insns for new pseudo registers. This may not
512 be strictly necessary since we should have copied at least one
513 insn above. But I am going to be safe. */
514 if (! first_copy)
515 first_copy = copy;
517 mark_jump_label (PATTERN (copy), copy, 0);
518 emit_barrier_before (loop_start);
521 emit_label_before (loop_pre_header_label, loop_start);
523 /* Now scan from the first insn we copied to the last insn we copied
524 (copy) for new pseudo registers. Do this after the code to jump to
525 the end label since that might create a new pseudo too. */
526 reg_scan_update (first_copy, copy, max_reg);
528 /* Mark the exit code as the virtual top of the converted loop. */
529 emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode);
531 delete_related_insns (next_nonnote_insn (loop_start));
533 /* Clean up. */
534 if (reg_map)
535 free (reg_map);
537 return 1;
540 /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
541 notes between START and END out before START. START and END may be such
542 notes. Returns the values of the new starting and ending insns, which
543 may be different if the original ones were such notes.
544 Return true if there were only such notes and no real instructions. */
546 bool
547 squeeze_notes (startp, endp)
548 rtx* startp;
549 rtx* endp;
551 rtx start = *startp;
552 rtx end = *endp;
554 rtx insn;
555 rtx next;
556 rtx last = NULL;
557 rtx past_end = NEXT_INSN (end);
559 for (insn = start; insn != past_end; insn = next)
561 next = NEXT_INSN (insn);
562 if (GET_CODE (insn) == NOTE
563 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
564 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
565 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
566 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
567 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
568 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
570 if (insn == start)
571 start = next;
572 else
574 rtx prev = PREV_INSN (insn);
575 PREV_INSN (insn) = PREV_INSN (start);
576 NEXT_INSN (insn) = start;
577 NEXT_INSN (PREV_INSN (insn)) = insn;
578 PREV_INSN (NEXT_INSN (insn)) = insn;
579 NEXT_INSN (prev) = next;
580 PREV_INSN (next) = prev;
583 else
584 last = insn;
587 /* There were no real instructions. */
588 if (start == past_end)
589 return true;
591 end = last;
593 *startp = start;
594 *endp = end;
595 return false;
598 /* Return the label before INSN, or put a new label there. */
601 get_label_before (insn)
602 rtx insn;
604 rtx label;
606 /* Find an existing label at this point
607 or make a new one if there is none. */
608 label = prev_nonnote_insn (insn);
610 if (label == 0 || GET_CODE (label) != CODE_LABEL)
612 rtx prev = PREV_INSN (insn);
614 label = gen_label_rtx ();
615 emit_label_after (label, prev);
616 LABEL_NUSES (label) = 0;
618 return label;
621 /* Return the label after INSN, or put a new label there. */
624 get_label_after (insn)
625 rtx insn;
627 rtx label;
629 /* Find an existing label at this point
630 or make a new one if there is none. */
631 label = next_nonnote_insn (insn);
633 if (label == 0 || GET_CODE (label) != CODE_LABEL)
635 label = gen_label_rtx ();
636 emit_label_after (label, insn);
637 LABEL_NUSES (label) = 0;
639 return label;
642 /* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
643 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
644 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
645 know whether it's source is floating point or integer comparison. Machine
646 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
647 to help this function avoid overhead in these cases. */
648 enum rtx_code
649 reversed_comparison_code_parts (code, arg0, arg1, insn)
650 rtx insn, arg0, arg1;
651 enum rtx_code code;
653 enum machine_mode mode;
655 /* If this is not actually a comparison, we can't reverse it. */
656 if (GET_RTX_CLASS (code) != '<')
657 return UNKNOWN;
659 mode = GET_MODE (arg0);
660 if (mode == VOIDmode)
661 mode = GET_MODE (arg1);
663 /* First see if machine description supply us way to reverse the comparison.
664 Give it priority over everything else to allow machine description to do
665 tricks. */
666 #ifdef REVERSIBLE_CC_MODE
667 if (GET_MODE_CLASS (mode) == MODE_CC
668 && REVERSIBLE_CC_MODE (mode))
670 #ifdef REVERSE_CONDITION
671 return REVERSE_CONDITION (code, mode);
672 #endif
673 return reverse_condition (code);
675 #endif
677 /* Try a few special cases based on the comparison code. */
678 switch (code)
680 case GEU:
681 case GTU:
682 case LEU:
683 case LTU:
684 case NE:
685 case EQ:
686 /* It is always safe to reverse EQ and NE, even for the floating
687 point. Similary the unsigned comparisons are never used for
688 floating point so we can reverse them in the default way. */
689 return reverse_condition (code);
690 case ORDERED:
691 case UNORDERED:
692 case LTGT:
693 case UNEQ:
694 /* In case we already see unordered comparison, we can be sure to
695 be dealing with floating point so we don't need any more tests. */
696 return reverse_condition_maybe_unordered (code);
697 case UNLT:
698 case UNLE:
699 case UNGT:
700 case UNGE:
701 /* We don't have safe way to reverse these yet. */
702 return UNKNOWN;
703 default:
704 break;
707 /* In case we give up IEEE compatibility, all comparisons are reversible. */
708 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
709 || flag_unsafe_math_optimizations)
710 return reverse_condition (code);
712 if (GET_MODE_CLASS (mode) == MODE_CC
713 #ifdef HAVE_cc0
714 || arg0 == cc0_rtx
715 #endif
718 rtx prev;
719 /* Try to search for the comparison to determine the real mode.
720 This code is expensive, but with sane machine description it
721 will be never used, since REVERSIBLE_CC_MODE will return true
722 in all cases. */
723 if (! insn)
724 return UNKNOWN;
726 for (prev = prev_nonnote_insn (insn);
727 prev != 0 && GET_CODE (prev) != CODE_LABEL;
728 prev = prev_nonnote_insn (prev))
730 rtx set = set_of (arg0, prev);
731 if (set && GET_CODE (set) == SET
732 && rtx_equal_p (SET_DEST (set), arg0))
734 rtx src = SET_SRC (set);
736 if (GET_CODE (src) == COMPARE)
738 rtx comparison = src;
739 arg0 = XEXP (src, 0);
740 mode = GET_MODE (arg0);
741 if (mode == VOIDmode)
742 mode = GET_MODE (XEXP (comparison, 1));
743 break;
745 /* We can get past reg-reg moves. This may be useful for model
746 of i387 comparisons that first move flag registers around. */
747 if (REG_P (src))
749 arg0 = src;
750 continue;
753 /* If register is clobbered in some ununderstandable way,
754 give up. */
755 if (set)
756 return UNKNOWN;
760 /* An integer condition. */
761 if (GET_CODE (arg0) == CONST_INT
762 || (GET_MODE (arg0) != VOIDmode
763 && GET_MODE_CLASS (mode) != MODE_CC
764 && ! FLOAT_MODE_P (mode)))
765 return reverse_condition (code);
767 return UNKNOWN;
770 /* An wrapper around the previous function to take COMPARISON as rtx
771 expression. This simplifies many callers. */
772 enum rtx_code
773 reversed_comparison_code (comparison, insn)
774 rtx comparison, insn;
776 if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
777 return UNKNOWN;
778 return reversed_comparison_code_parts (GET_CODE (comparison),
779 XEXP (comparison, 0),
780 XEXP (comparison, 1), insn);
783 /* Given an rtx-code for a comparison, return the code for the negated
784 comparison. If no such code exists, return UNKNOWN.
786 WATCH OUT! reverse_condition is not safe to use on a jump that might
787 be acting on the results of an IEEE floating point comparison, because
788 of the special treatment of non-signaling nans in comparisons.
789 Use reversed_comparison_code instead. */
791 enum rtx_code
792 reverse_condition (code)
793 enum rtx_code code;
795 switch (code)
797 case EQ:
798 return NE;
799 case NE:
800 return EQ;
801 case GT:
802 return LE;
803 case GE:
804 return LT;
805 case LT:
806 return GE;
807 case LE:
808 return GT;
809 case GTU:
810 return LEU;
811 case GEU:
812 return LTU;
813 case LTU:
814 return GEU;
815 case LEU:
816 return GTU;
817 case UNORDERED:
818 return ORDERED;
819 case ORDERED:
820 return UNORDERED;
822 case UNLT:
823 case UNLE:
824 case UNGT:
825 case UNGE:
826 case UNEQ:
827 case LTGT:
828 return UNKNOWN;
830 default:
831 abort ();
835 /* Similar, but we're allowed to generate unordered comparisons, which
836 makes it safe for IEEE floating-point. Of course, we have to recognize
837 that the target will support them too... */
839 enum rtx_code
840 reverse_condition_maybe_unordered (code)
841 enum rtx_code code;
843 /* Non-IEEE formats don't have unordered conditions. */
844 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
845 return reverse_condition (code);
847 switch (code)
849 case EQ:
850 return NE;
851 case NE:
852 return EQ;
853 case GT:
854 return UNLE;
855 case GE:
856 return UNLT;
857 case LT:
858 return UNGE;
859 case LE:
860 return UNGT;
861 case LTGT:
862 return UNEQ;
863 case UNORDERED:
864 return ORDERED;
865 case ORDERED:
866 return UNORDERED;
867 case UNLT:
868 return GE;
869 case UNLE:
870 return GT;
871 case UNGT:
872 return LE;
873 case UNGE:
874 return LT;
875 case UNEQ:
876 return LTGT;
878 default:
879 abort ();
883 /* Similar, but return the code when two operands of a comparison are swapped.
884 This IS safe for IEEE floating-point. */
886 enum rtx_code
887 swap_condition (code)
888 enum rtx_code code;
890 switch (code)
892 case EQ:
893 case NE:
894 case UNORDERED:
895 case ORDERED:
896 case UNEQ:
897 case LTGT:
898 return code;
900 case GT:
901 return LT;
902 case GE:
903 return LE;
904 case LT:
905 return GT;
906 case LE:
907 return GE;
908 case GTU:
909 return LTU;
910 case GEU:
911 return LEU;
912 case LTU:
913 return GTU;
914 case LEU:
915 return GEU;
916 case UNLT:
917 return UNGT;
918 case UNLE:
919 return UNGE;
920 case UNGT:
921 return UNLT;
922 case UNGE:
923 return UNLE;
925 default:
926 abort ();
930 /* Given a comparison CODE, return the corresponding unsigned comparison.
931 If CODE is an equality comparison or already an unsigned comparison,
932 CODE is returned. */
934 enum rtx_code
935 unsigned_condition (code)
936 enum rtx_code code;
938 switch (code)
940 case EQ:
941 case NE:
942 case GTU:
943 case GEU:
944 case LTU:
945 case LEU:
946 return code;
948 case GT:
949 return GTU;
950 case GE:
951 return GEU;
952 case LT:
953 return LTU;
954 case LE:
955 return LEU;
957 default:
958 abort ();
962 /* Similarly, return the signed version of a comparison. */
964 enum rtx_code
965 signed_condition (code)
966 enum rtx_code code;
968 switch (code)
970 case EQ:
971 case NE:
972 case GT:
973 case GE:
974 case LT:
975 case LE:
976 return code;
978 case GTU:
979 return GT;
980 case GEU:
981 return GE;
982 case LTU:
983 return LT;
984 case LEU:
985 return LE;
987 default:
988 abort ();
992 /* Return non-zero if CODE1 is more strict than CODE2, i.e., if the
993 truth of CODE1 implies the truth of CODE2. */
996 comparison_dominates_p (code1, code2)
997 enum rtx_code code1, code2;
999 /* UNKNOWN comparison codes can happen as a result of trying to revert
1000 comparison codes.
1001 They can't match anything, so we have to reject them here. */
1002 if (code1 == UNKNOWN || code2 == UNKNOWN)
1003 return 0;
1005 if (code1 == code2)
1006 return 1;
1008 switch (code1)
1010 case UNEQ:
1011 if (code2 == UNLE || code2 == UNGE)
1012 return 1;
1013 break;
1015 case EQ:
1016 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
1017 || code2 == ORDERED)
1018 return 1;
1019 break;
1021 case UNLT:
1022 if (code2 == UNLE || code2 == NE)
1023 return 1;
1024 break;
1026 case LT:
1027 if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
1028 return 1;
1029 break;
1031 case UNGT:
1032 if (code2 == UNGE || code2 == NE)
1033 return 1;
1034 break;
1036 case GT:
1037 if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
1038 return 1;
1039 break;
1041 case GE:
1042 case LE:
1043 if (code2 == ORDERED)
1044 return 1;
1045 break;
1047 case LTGT:
1048 if (code2 == NE || code2 == ORDERED)
1049 return 1;
1050 break;
1052 case LTU:
1053 if (code2 == LEU || code2 == NE)
1054 return 1;
1055 break;
1057 case GTU:
1058 if (code2 == GEU || code2 == NE)
1059 return 1;
1060 break;
1062 case UNORDERED:
1063 if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
1064 || code2 == UNGE || code2 == UNGT)
1065 return 1;
1066 break;
1068 default:
1069 break;
1072 return 0;
1075 /* Return 1 if INSN is an unconditional jump and nothing else. */
1078 simplejump_p (insn)
1079 rtx insn;
1081 return (GET_CODE (insn) == JUMP_INSN
1082 && GET_CODE (PATTERN (insn)) == SET
1083 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
1084 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
1087 /* Return nonzero if INSN is a (possibly) conditional jump
1088 and nothing more.
1090 Use this function is deprecated, since we need to support combined
1091 branch and compare insns. Use any_condjump_p instead whenever possible. */
1094 condjump_p (insn)
1095 rtx insn;
1097 rtx x = PATTERN (insn);
1099 if (GET_CODE (x) != SET
1100 || GET_CODE (SET_DEST (x)) != PC)
1101 return 0;
1103 x = SET_SRC (x);
1104 if (GET_CODE (x) == LABEL_REF)
1105 return 1;
1106 else
1107 return (GET_CODE (x) == IF_THEN_ELSE
1108 && ((GET_CODE (XEXP (x, 2)) == PC
1109 && (GET_CODE (XEXP (x, 1)) == LABEL_REF
1110 || GET_CODE (XEXP (x, 1)) == RETURN))
1111 || (GET_CODE (XEXP (x, 1)) == PC
1112 && (GET_CODE (XEXP (x, 2)) == LABEL_REF
1113 || GET_CODE (XEXP (x, 2)) == RETURN))));
1115 return 0;
1118 /* Return nonzero if INSN is a (possibly) conditional jump inside a
1119 PARALLEL.
1121 Use this function is deprecated, since we need to support combined
1122 branch and compare insns. Use any_condjump_p instead whenever possible. */
1125 condjump_in_parallel_p (insn)
1126 rtx insn;
1128 rtx x = PATTERN (insn);
1130 if (GET_CODE (x) != PARALLEL)
1131 return 0;
1132 else
1133 x = XVECEXP (x, 0, 0);
1135 if (GET_CODE (x) != SET)
1136 return 0;
1137 if (GET_CODE (SET_DEST (x)) != PC)
1138 return 0;
1139 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
1140 return 1;
1141 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
1142 return 0;
1143 if (XEXP (SET_SRC (x), 2) == pc_rtx
1144 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
1145 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
1146 return 1;
1147 if (XEXP (SET_SRC (x), 1) == pc_rtx
1148 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
1149 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
1150 return 1;
1151 return 0;
1154 /* Return set of PC, otherwise NULL. */
1157 pc_set (insn)
1158 rtx insn;
1160 rtx pat;
1161 if (GET_CODE (insn) != JUMP_INSN)
1162 return NULL_RTX;
1163 pat = PATTERN (insn);
1165 /* The set is allowed to appear either as the insn pattern or
1166 the first set in a PARALLEL. */
1167 if (GET_CODE (pat) == PARALLEL)
1168 pat = XVECEXP (pat, 0, 0);
1169 if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
1170 return pat;
1172 return NULL_RTX;
1175 /* Return true when insn is an unconditional direct jump,
1176 possibly bundled inside a PARALLEL. */
1179 any_uncondjump_p (insn)
1180 rtx insn;
1182 rtx x = pc_set (insn);
1183 if (!x)
1184 return 0;
1185 if (GET_CODE (SET_SRC (x)) != LABEL_REF)
1186 return 0;
1187 return 1;
1190 /* Return true when insn is a conditional jump. This function works for
1191 instructions containing PC sets in PARALLELs. The instruction may have
1192 various other effects so before removing the jump you must verify
1193 onlyjump_p.
1195 Note that unlike condjump_p it returns false for unconditional jumps. */
1198 any_condjump_p (insn)
1199 rtx insn;
1201 rtx x = pc_set (insn);
1202 enum rtx_code a, b;
1204 if (!x)
1205 return 0;
1206 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
1207 return 0;
1209 a = GET_CODE (XEXP (SET_SRC (x), 1));
1210 b = GET_CODE (XEXP (SET_SRC (x), 2));
1212 return ((b == PC && (a == LABEL_REF || a == RETURN))
1213 || (a == PC && (b == LABEL_REF || b == RETURN)));
1216 /* Return the label of a conditional jump. */
1219 condjump_label (insn)
1220 rtx insn;
1222 rtx x = pc_set (insn);
1224 if (!x)
1225 return NULL_RTX;
1226 x = SET_SRC (x);
1227 if (GET_CODE (x) == LABEL_REF)
1228 return x;
1229 if (GET_CODE (x) != IF_THEN_ELSE)
1230 return NULL_RTX;
1231 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
1232 return XEXP (x, 1);
1233 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
1234 return XEXP (x, 2);
1235 return NULL_RTX;
1238 /* Return true if INSN is a (possibly conditional) return insn. */
1240 static int
1241 returnjump_p_1 (loc, data)
1242 rtx *loc;
1243 void *data ATTRIBUTE_UNUSED;
1245 rtx x = *loc;
1247 return x && (GET_CODE (x) == RETURN
1248 || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
1252 returnjump_p (insn)
1253 rtx insn;
1255 if (GET_CODE (insn) != JUMP_INSN)
1256 return 0;
1257 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
1260 /* Return true if INSN is a jump that only transfers control and
1261 nothing more. */
1264 onlyjump_p (insn)
1265 rtx insn;
1267 rtx set;
1269 if (GET_CODE (insn) != JUMP_INSN)
1270 return 0;
1272 set = single_set (insn);
1273 if (set == NULL)
1274 return 0;
1275 if (GET_CODE (SET_DEST (set)) != PC)
1276 return 0;
1277 if (side_effects_p (SET_SRC (set)))
1278 return 0;
1280 return 1;
1283 #ifdef HAVE_cc0
1285 /* Return non-zero if X is an RTX that only sets the condition codes
1286 and has no side effects. */
1289 only_sets_cc0_p (x)
1290 rtx x;
1293 if (! x)
1294 return 0;
1296 if (INSN_P (x))
1297 x = PATTERN (x);
1299 return sets_cc0_p (x) == 1 && ! side_effects_p (x);
1302 /* Return 1 if X is an RTX that does nothing but set the condition codes
1303 and CLOBBER or USE registers.
1304 Return -1 if X does explicitly set the condition codes,
1305 but also does other things. */
1308 sets_cc0_p (x)
1309 rtx x;
1312 if (! x)
1313 return 0;
1315 if (INSN_P (x))
1316 x = PATTERN (x);
1318 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
1319 return 1;
1320 if (GET_CODE (x) == PARALLEL)
1322 int i;
1323 int sets_cc0 = 0;
1324 int other_things = 0;
1325 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1327 if (GET_CODE (XVECEXP (x, 0, i)) == SET
1328 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
1329 sets_cc0 = 1;
1330 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
1331 other_things = 1;
1333 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
1335 return 0;
1337 #endif
1339 /* Follow any unconditional jump at LABEL;
1340 return the ultimate label reached by any such chain of jumps.
1341 If LABEL is not followed by a jump, return LABEL.
1342 If the chain loops or we can't find end, return LABEL,
1343 since that tells caller to avoid changing the insn.
1345 If RELOAD_COMPLETED is 0, we do not chain across a NOTE_INSN_LOOP_BEG or
1346 a USE or CLOBBER. */
1349 follow_jumps (label)
1350 rtx label;
1352 rtx insn;
1353 rtx next;
1354 rtx value = label;
1355 int depth;
1357 for (depth = 0;
1358 (depth < 10
1359 && (insn = next_active_insn (value)) != 0
1360 && GET_CODE (insn) == JUMP_INSN
1361 && ((JUMP_LABEL (insn) != 0 && any_uncondjump_p (insn)
1362 && onlyjump_p (insn))
1363 || GET_CODE (PATTERN (insn)) == RETURN)
1364 && (next = NEXT_INSN (insn))
1365 && GET_CODE (next) == BARRIER);
1366 depth++)
1368 /* Don't chain through the insn that jumps into a loop
1369 from outside the loop,
1370 since that would create multiple loop entry jumps
1371 and prevent loop optimization. */
1372 rtx tem;
1373 if (!reload_completed)
1374 for (tem = value; tem != insn; tem = NEXT_INSN (tem))
1375 if (GET_CODE (tem) == NOTE
1376 && (NOTE_LINE_NUMBER (tem) == NOTE_INSN_LOOP_BEG
1377 /* ??? Optional. Disables some optimizations, but makes
1378 gcov output more accurate with -O. */
1379 || (flag_test_coverage && NOTE_LINE_NUMBER (tem) > 0)))
1380 return value;
1382 /* If we have found a cycle, make the insn jump to itself. */
1383 if (JUMP_LABEL (insn) == label)
1384 return label;
1386 tem = next_active_insn (JUMP_LABEL (insn));
1387 if (tem && (GET_CODE (PATTERN (tem)) == ADDR_VEC
1388 || GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
1389 break;
1391 value = JUMP_LABEL (insn);
1393 if (depth == 10)
1394 return label;
1395 return value;
1399 /* Find all CODE_LABELs referred to in X, and increment their use counts.
1400 If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced
1401 in INSN, then store one of them in JUMP_LABEL (INSN).
1402 If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL
1403 referenced in INSN, add a REG_LABEL note containing that label to INSN.
1404 Also, when there are consecutive labels, canonicalize on the last of them.
1406 Note that two labels separated by a loop-beginning note
1407 must be kept distinct if we have not yet done loop-optimization,
1408 because the gap between them is where loop-optimize
1409 will want to move invariant code to. CROSS_JUMP tells us
1410 that loop-optimization is done with. */
1412 void
1413 mark_jump_label (x, insn, in_mem)
1414 rtx x;
1415 rtx insn;
1416 int in_mem;
1418 RTX_CODE code = GET_CODE (x);
1419 int i;
1420 const char *fmt;
1422 switch (code)
1424 case PC:
1425 case CC0:
1426 case REG:
1427 case SUBREG:
1428 case CONST_INT:
1429 case CONST_DOUBLE:
1430 case CLOBBER:
1431 case CALL:
1432 return;
1434 case MEM:
1435 in_mem = 1;
1436 break;
1438 case SYMBOL_REF:
1439 if (!in_mem)
1440 return;
1442 /* If this is a constant-pool reference, see if it is a label. */
1443 if (CONSTANT_POOL_ADDRESS_P (x))
1444 mark_jump_label (get_pool_constant (x), insn, in_mem);
1445 break;
1447 case LABEL_REF:
1449 rtx label = XEXP (x, 0);
1451 /* Ignore remaining references to unreachable labels that
1452 have been deleted. */
1453 if (GET_CODE (label) == NOTE
1454 && NOTE_LINE_NUMBER (label) == NOTE_INSN_DELETED_LABEL)
1455 break;
1457 if (GET_CODE (label) != CODE_LABEL)
1458 abort ();
1460 /* Ignore references to labels of containing functions. */
1461 if (LABEL_REF_NONLOCAL_P (x))
1462 break;
1464 XEXP (x, 0) = label;
1465 if (! insn || ! INSN_DELETED_P (insn))
1466 ++LABEL_NUSES (label);
1468 if (insn)
1470 if (GET_CODE (insn) == JUMP_INSN)
1471 JUMP_LABEL (insn) = label;
1472 else
1474 /* Add a REG_LABEL note for LABEL unless there already
1475 is one. All uses of a label, except for labels
1476 that are the targets of jumps, must have a
1477 REG_LABEL note. */
1478 if (! find_reg_note (insn, REG_LABEL, label))
1479 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, label,
1480 REG_NOTES (insn));
1483 return;
1486 /* Do walk the labels in a vector, but not the first operand of an
1487 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1488 case ADDR_VEC:
1489 case ADDR_DIFF_VEC:
1490 if (! INSN_DELETED_P (insn))
1492 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
1494 for (i = 0; i < XVECLEN (x, eltnum); i++)
1495 mark_jump_label (XVECEXP (x, eltnum, i), NULL_RTX, in_mem);
1497 return;
1499 default:
1500 break;
1503 fmt = GET_RTX_FORMAT (code);
1504 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1506 if (fmt[i] == 'e')
1507 mark_jump_label (XEXP (x, i), insn, in_mem);
1508 else if (fmt[i] == 'E')
1510 int j;
1511 for (j = 0; j < XVECLEN (x, i); j++)
1512 mark_jump_label (XVECEXP (x, i, j), insn, in_mem);
1517 /* If all INSN does is set the pc, delete it,
1518 and delete the insn that set the condition codes for it
1519 if that's what the previous thing was. */
1521 void
1522 delete_jump (insn)
1523 rtx insn;
1525 rtx set = single_set (insn);
1527 if (set && GET_CODE (SET_DEST (set)) == PC)
1528 delete_computation (insn);
1531 /* Verify INSN is a BARRIER and delete it. */
1533 void
1534 delete_barrier (insn)
1535 rtx insn;
1537 if (GET_CODE (insn) != BARRIER)
1538 abort ();
1540 delete_insn (insn);
1543 /* Recursively delete prior insns that compute the value (used only by INSN
1544 which the caller is deleting) stored in the register mentioned by NOTE
1545 which is a REG_DEAD note associated with INSN. */
1547 static void
1548 delete_prior_computation (note, insn)
1549 rtx note;
1550 rtx insn;
1552 rtx our_prev;
1553 rtx reg = XEXP (note, 0);
1555 for (our_prev = prev_nonnote_insn (insn);
1556 our_prev && (GET_CODE (our_prev) == INSN
1557 || GET_CODE (our_prev) == CALL_INSN);
1558 our_prev = prev_nonnote_insn (our_prev))
1560 rtx pat = PATTERN (our_prev);
1562 /* If we reach a CALL which is not calling a const function
1563 or the callee pops the arguments, then give up. */
1564 if (GET_CODE (our_prev) == CALL_INSN
1565 && (! CONST_OR_PURE_CALL_P (our_prev)
1566 || GET_CODE (pat) != SET || GET_CODE (SET_SRC (pat)) != CALL))
1567 break;
1569 /* If we reach a SEQUENCE, it is too complex to try to
1570 do anything with it, so give up. */
1571 if (GET_CODE (pat) == SEQUENCE)
1572 break;
1574 if (GET_CODE (pat) == USE
1575 && GET_CODE (XEXP (pat, 0)) == INSN)
1576 /* reorg creates USEs that look like this. We leave them
1577 alone because reorg needs them for its own purposes. */
1578 break;
1580 if (reg_set_p (reg, pat))
1582 if (side_effects_p (pat) && GET_CODE (our_prev) != CALL_INSN)
1583 break;
1585 if (GET_CODE (pat) == PARALLEL)
1587 /* If we find a SET of something else, we can't
1588 delete the insn. */
1590 int i;
1592 for (i = 0; i < XVECLEN (pat, 0); i++)
1594 rtx part = XVECEXP (pat, 0, i);
1596 if (GET_CODE (part) == SET
1597 && SET_DEST (part) != reg)
1598 break;
1601 if (i == XVECLEN (pat, 0))
1602 delete_computation (our_prev);
1604 else if (GET_CODE (pat) == SET
1605 && GET_CODE (SET_DEST (pat)) == REG)
1607 int dest_regno = REGNO (SET_DEST (pat));
1608 int dest_endregno
1609 = (dest_regno
1610 + (dest_regno < FIRST_PSEUDO_REGISTER
1611 ? HARD_REGNO_NREGS (dest_regno,
1612 GET_MODE (SET_DEST (pat))) : 1));
1613 int regno = REGNO (reg);
1614 int endregno
1615 = (regno
1616 + (regno < FIRST_PSEUDO_REGISTER
1617 ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1));
1619 if (dest_regno >= regno
1620 && dest_endregno <= endregno)
1621 delete_computation (our_prev);
1623 /* We may have a multi-word hard register and some, but not
1624 all, of the words of the register are needed in subsequent
1625 insns. Write REG_UNUSED notes for those parts that were not
1626 needed. */
1627 else if (dest_regno <= regno
1628 && dest_endregno >= endregno)
1630 int i;
1632 REG_NOTES (our_prev)
1633 = gen_rtx_EXPR_LIST (REG_UNUSED, reg,
1634 REG_NOTES (our_prev));
1636 for (i = dest_regno; i < dest_endregno; i++)
1637 if (! find_regno_note (our_prev, REG_UNUSED, i))
1638 break;
1640 if (i == dest_endregno)
1641 delete_computation (our_prev);
1645 break;
1648 /* If PAT references the register that dies here, it is an
1649 additional use. Hence any prior SET isn't dead. However, this
1650 insn becomes the new place for the REG_DEAD note. */
1651 if (reg_overlap_mentioned_p (reg, pat))
1653 XEXP (note, 1) = REG_NOTES (our_prev);
1654 REG_NOTES (our_prev) = note;
1655 break;
1660 /* Delete INSN and recursively delete insns that compute values used only
1661 by INSN. This uses the REG_DEAD notes computed during flow analysis.
1662 If we are running before flow.c, we need do nothing since flow.c will
1663 delete dead code. We also can't know if the registers being used are
1664 dead or not at this point.
1666 Otherwise, look at all our REG_DEAD notes. If a previous insn does
1667 nothing other than set a register that dies in this insn, we can delete
1668 that insn as well.
1670 On machines with CC0, if CC0 is used in this insn, we may be able to
1671 delete the insn that set it. */
1673 static void
1674 delete_computation (insn)
1675 rtx insn;
1677 rtx note, next;
1679 #ifdef HAVE_cc0
1680 if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
1682 rtx prev = prev_nonnote_insn (insn);
1683 /* We assume that at this stage
1684 CC's are always set explicitly
1685 and always immediately before the jump that
1686 will use them. So if the previous insn
1687 exists to set the CC's, delete it
1688 (unless it performs auto-increments, etc.). */
1689 if (prev && GET_CODE (prev) == INSN
1690 && sets_cc0_p (PATTERN (prev)))
1692 if (sets_cc0_p (PATTERN (prev)) > 0
1693 && ! side_effects_p (PATTERN (prev)))
1694 delete_computation (prev);
1695 else
1696 /* Otherwise, show that cc0 won't be used. */
1697 REG_NOTES (prev) = gen_rtx_EXPR_LIST (REG_UNUSED,
1698 cc0_rtx, REG_NOTES (prev));
1701 #endif
1703 for (note = REG_NOTES (insn); note; note = next)
1705 next = XEXP (note, 1);
1707 if (REG_NOTE_KIND (note) != REG_DEAD
1708 /* Verify that the REG_NOTE is legitimate. */
1709 || GET_CODE (XEXP (note, 0)) != REG)
1710 continue;
1712 delete_prior_computation (note, insn);
1715 delete_related_insns (insn);
1718 /* Delete insn INSN from the chain of insns and update label ref counts
1719 and delete insns now unreachable.
1721 Returns the first insn after INSN that was not deleted.
1723 Usage of this instruction is deprecated. Use delete_insn instead and
1724 subsequent cfg_cleanup pass to delete unreachable code if needed. */
1727 delete_related_insns (insn)
1728 rtx insn;
1730 int was_code_label = (GET_CODE (insn) == CODE_LABEL);
1731 rtx note;
1732 rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
1734 while (next && INSN_DELETED_P (next))
1735 next = NEXT_INSN (next);
1737 /* This insn is already deleted => return first following nondeleted. */
1738 if (INSN_DELETED_P (insn))
1739 return next;
1741 delete_insn (insn);
1743 /* If instruction is followed by a barrier,
1744 delete the barrier too. */
1746 if (next != 0 && GET_CODE (next) == BARRIER)
1747 delete_insn (next);
1749 /* If deleting a jump, decrement the count of the label,
1750 and delete the label if it is now unused. */
1752 if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
1754 rtx lab = JUMP_LABEL (insn), lab_next;
1756 if (LABEL_NUSES (lab) == 0)
1758 /* This can delete NEXT or PREV,
1759 either directly if NEXT is JUMP_LABEL (INSN),
1760 or indirectly through more levels of jumps. */
1761 delete_related_insns (lab);
1763 /* I feel a little doubtful about this loop,
1764 but I see no clean and sure alternative way
1765 to find the first insn after INSN that is not now deleted.
1766 I hope this works. */
1767 while (next && INSN_DELETED_P (next))
1768 next = NEXT_INSN (next);
1769 return next;
1771 else if ((lab_next = next_nonnote_insn (lab)) != NULL
1772 && GET_CODE (lab_next) == JUMP_INSN
1773 && (GET_CODE (PATTERN (lab_next)) == ADDR_VEC
1774 || GET_CODE (PATTERN (lab_next)) == ADDR_DIFF_VEC))
1776 /* If we're deleting the tablejump, delete the dispatch table.
1777 We may not be able to kill the label immediately preceding
1778 just yet, as it might be referenced in code leading up to
1779 the tablejump. */
1780 delete_related_insns (lab_next);
1784 /* Likewise if we're deleting a dispatch table. */
1786 if (GET_CODE (insn) == JUMP_INSN
1787 && (GET_CODE (PATTERN (insn)) == ADDR_VEC
1788 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
1790 rtx pat = PATTERN (insn);
1791 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1792 int len = XVECLEN (pat, diff_vec_p);
1794 for (i = 0; i < len; i++)
1795 if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1796 delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
1797 while (next && INSN_DELETED_P (next))
1798 next = NEXT_INSN (next);
1799 return next;
1802 /* Likewise for an ordinary INSN / CALL_INSN with a REG_LABEL note. */
1803 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
1804 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1805 if (REG_NOTE_KIND (note) == REG_LABEL
1806 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1807 && GET_CODE (XEXP (note, 0)) == CODE_LABEL)
1808 if (LABEL_NUSES (XEXP (note, 0)) == 0)
1809 delete_related_insns (XEXP (note, 0));
1811 while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
1812 prev = PREV_INSN (prev);
1814 /* If INSN was a label and a dispatch table follows it,
1815 delete the dispatch table. The tablejump must have gone already.
1816 It isn't useful to fall through into a table. */
1818 if (was_code_label
1819 && NEXT_INSN (insn) != 0
1820 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
1821 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
1822 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
1823 next = delete_related_insns (NEXT_INSN (insn));
1825 /* If INSN was a label, delete insns following it if now unreachable. */
1827 if (was_code_label && prev && GET_CODE (prev) == BARRIER)
1829 RTX_CODE code;
1830 while (next != 0
1831 && (GET_RTX_CLASS (code = GET_CODE (next)) == 'i'
1832 || code == NOTE || code == BARRIER
1833 || (code == CODE_LABEL && INSN_DELETED_P (next))))
1835 if (code == NOTE
1836 && NOTE_LINE_NUMBER (next) != NOTE_INSN_FUNCTION_END)
1837 next = NEXT_INSN (next);
1838 /* Keep going past other deleted labels to delete what follows. */
1839 else if (code == CODE_LABEL && INSN_DELETED_P (next))
1840 next = NEXT_INSN (next);
1841 else
1842 /* Note: if this deletes a jump, it can cause more
1843 deletion of unreachable code, after a different label.
1844 As long as the value from this recursive call is correct,
1845 this invocation functions correctly. */
1846 next = delete_related_insns (next);
1850 return next;
1853 /* Advance from INSN till reaching something not deleted
1854 then return that. May return INSN itself. */
1857 next_nondeleted_insn (insn)
1858 rtx insn;
1860 while (INSN_DELETED_P (insn))
1861 insn = NEXT_INSN (insn);
1862 return insn;
1865 /* Delete a range of insns from FROM to TO, inclusive.
1866 This is for the sake of peephole optimization, so assume
1867 that whatever these insns do will still be done by a new
1868 peephole insn that will replace them. */
1870 void
1871 delete_for_peephole (from, to)
1872 rtx from, to;
1874 rtx insn = from;
1876 while (1)
1878 rtx next = NEXT_INSN (insn);
1879 rtx prev = PREV_INSN (insn);
1881 if (GET_CODE (insn) != NOTE)
1883 INSN_DELETED_P (insn) = 1;
1885 /* Patch this insn out of the chain. */
1886 /* We don't do this all at once, because we
1887 must preserve all NOTEs. */
1888 if (prev)
1889 NEXT_INSN (prev) = next;
1891 if (next)
1892 PREV_INSN (next) = prev;
1895 if (insn == to)
1896 break;
1897 insn = next;
1900 /* Note that if TO is an unconditional jump
1901 we *do not* delete the BARRIER that follows,
1902 since the peephole that replaces this sequence
1903 is also an unconditional jump in that case. */
1906 /* We have determined that INSN is never reached, and are about to
1907 delete it. Print a warning if the user asked for one.
1909 To try to make this warning more useful, this should only be called
1910 once per basic block not reached, and it only warns when the basic
1911 block contains more than one line from the current function, and
1912 contains at least one operation. CSE and inlining can duplicate insns,
1913 so it's possible to get spurious warnings from this. */
1915 void
1916 never_reached_warning (avoided_insn)
1917 rtx avoided_insn;
1919 rtx insn;
1920 rtx a_line_note = NULL;
1921 int two_avoided_lines = 0;
1922 int contains_insn = 0;
1924 if (! warn_notreached)
1925 return;
1927 /* Scan forwards, looking at LINE_NUMBER notes, until
1928 we hit a LABEL or we run out of insns. */
1930 for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
1932 if (GET_CODE (insn) == CODE_LABEL)
1933 break;
1934 else if (GET_CODE (insn) == NOTE /* A line number note? */
1935 && NOTE_LINE_NUMBER (insn) >= 0)
1937 if (a_line_note == NULL)
1938 a_line_note = insn;
1939 else
1940 two_avoided_lines |= (NOTE_LINE_NUMBER (a_line_note)
1941 != NOTE_LINE_NUMBER (insn));
1943 else if (INSN_P (insn))
1944 contains_insn = 1;
1946 if (two_avoided_lines && contains_insn)
1947 warning_with_file_and_line (NOTE_SOURCE_FILE (a_line_note),
1948 NOTE_LINE_NUMBER (a_line_note),
1949 "will never be executed");
1952 /* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1953 NLABEL as a return. Accrue modifications into the change group. */
1955 static void
1956 redirect_exp_1 (loc, olabel, nlabel, insn)
1957 rtx *loc;
1958 rtx olabel, nlabel;
1959 rtx insn;
1961 rtx x = *loc;
1962 RTX_CODE code = GET_CODE (x);
1963 int i;
1964 const char *fmt;
1966 if (code == LABEL_REF)
1968 if (XEXP (x, 0) == olabel)
1970 rtx n;
1971 if (nlabel)
1972 n = gen_rtx_LABEL_REF (VOIDmode, nlabel);
1973 else
1974 n = gen_rtx_RETURN (VOIDmode);
1976 validate_change (insn, loc, n, 1);
1977 return;
1980 else if (code == RETURN && olabel == 0)
1982 x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
1983 if (loc == &PATTERN (insn))
1984 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1985 validate_change (insn, loc, x, 1);
1986 return;
1989 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1990 && GET_CODE (SET_SRC (x)) == LABEL_REF
1991 && XEXP (SET_SRC (x), 0) == olabel)
1993 validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1994 return;
1997 fmt = GET_RTX_FORMAT (code);
1998 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2000 if (fmt[i] == 'e')
2001 redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
2002 else if (fmt[i] == 'E')
2004 int j;
2005 for (j = 0; j < XVECLEN (x, i); j++)
2006 redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
2011 /* Similar, but apply the change group and report success or failure. */
2013 static int
2014 redirect_exp (olabel, nlabel, insn)
2015 rtx olabel, nlabel;
2016 rtx insn;
2018 rtx *loc;
2020 if (GET_CODE (PATTERN (insn)) == PARALLEL)
2021 loc = &XVECEXP (PATTERN (insn), 0, 0);
2022 else
2023 loc = &PATTERN (insn);
2025 redirect_exp_1 (loc, olabel, nlabel, insn);
2026 if (num_validated_changes () == 0)
2027 return 0;
2029 return apply_change_group ();
2032 /* Make JUMP go to NLABEL instead of where it jumps now. Accrue
2033 the modifications into the change group. Return false if we did
2034 not see how to do that. */
2037 redirect_jump_1 (jump, nlabel)
2038 rtx jump, nlabel;
2040 int ochanges = num_validated_changes ();
2041 rtx *loc;
2043 if (GET_CODE (PATTERN (jump)) == PARALLEL)
2044 loc = &XVECEXP (PATTERN (jump), 0, 0);
2045 else
2046 loc = &PATTERN (jump);
2048 redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
2049 return num_validated_changes () > ochanges;
2052 /* Make JUMP go to NLABEL instead of where it jumps now. If the old
2053 jump target label is unused as a result, it and the code following
2054 it may be deleted.
2056 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
2057 RETURN insn.
2059 The return value will be 1 if the change was made, 0 if it wasn't
2060 (this can only occur for NLABEL == 0). */
2063 redirect_jump (jump, nlabel, delete_unused)
2064 rtx jump, nlabel;
2065 int delete_unused;
2067 rtx olabel = JUMP_LABEL (jump);
2069 if (nlabel == olabel)
2070 return 1;
2072 if (! redirect_exp (olabel, nlabel, jump))
2073 return 0;
2075 JUMP_LABEL (jump) = nlabel;
2076 if (nlabel)
2077 ++LABEL_NUSES (nlabel);
2079 /* If we're eliding the jump over exception cleanups at the end of a
2080 function, move the function end note so that -Wreturn-type works. */
2081 if (olabel && nlabel
2082 && NEXT_INSN (olabel)
2083 && GET_CODE (NEXT_INSN (olabel)) == NOTE
2084 && NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END)
2085 emit_note_after (NOTE_INSN_FUNCTION_END, nlabel);
2087 if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused)
2088 delete_related_insns (olabel);
2090 return 1;
2093 /* Invert the jump condition of rtx X contained in jump insn, INSN.
2094 Accrue the modifications into the change group. */
2096 static void
2097 invert_exp_1 (insn)
2098 rtx insn;
2100 RTX_CODE code;
2101 rtx x = pc_set (insn);
2103 if (!x)
2104 abort ();
2105 x = SET_SRC (x);
2107 code = GET_CODE (x);
2109 if (code == IF_THEN_ELSE)
2111 rtx comp = XEXP (x, 0);
2112 rtx tem;
2113 enum rtx_code reversed_code;
2115 /* We can do this in two ways: The preferable way, which can only
2116 be done if this is not an integer comparison, is to reverse
2117 the comparison code. Otherwise, swap the THEN-part and ELSE-part
2118 of the IF_THEN_ELSE. If we can't do either, fail. */
2120 reversed_code = reversed_comparison_code (comp, insn);
2122 if (reversed_code != UNKNOWN)
2124 validate_change (insn, &XEXP (x, 0),
2125 gen_rtx_fmt_ee (reversed_code,
2126 GET_MODE (comp), XEXP (comp, 0),
2127 XEXP (comp, 1)),
2129 return;
2132 tem = XEXP (x, 1);
2133 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
2134 validate_change (insn, &XEXP (x, 2), tem, 1);
2136 else
2137 abort ();
2140 /* Invert the jump condition of conditional jump insn, INSN.
2142 Return 1 if we can do so, 0 if we cannot find a way to do so that
2143 matches a pattern. */
2145 static int
2146 invert_exp (insn)
2147 rtx insn;
2149 invert_exp_1 (insn);
2150 if (num_validated_changes () == 0)
2151 return 0;
2153 return apply_change_group ();
2156 /* Invert the condition of the jump JUMP, and make it jump to label
2157 NLABEL instead of where it jumps now. Accrue changes into the
2158 change group. Return false if we didn't see how to perform the
2159 inversion and redirection. */
2162 invert_jump_1 (jump, nlabel)
2163 rtx jump, nlabel;
2165 int ochanges;
2167 ochanges = num_validated_changes ();
2168 invert_exp_1 (jump);
2169 if (num_validated_changes () == ochanges)
2170 return 0;
2172 return redirect_jump_1 (jump, nlabel);
2175 /* Invert the condition of the jump JUMP, and make it jump to label
2176 NLABEL instead of where it jumps now. Return true if successful. */
2179 invert_jump (jump, nlabel, delete_unused)
2180 rtx jump, nlabel;
2181 int delete_unused;
2183 /* We have to either invert the condition and change the label or
2184 do neither. Either operation could fail. We first try to invert
2185 the jump. If that succeeds, we try changing the label. If that fails,
2186 we invert the jump back to what it was. */
2188 if (! invert_exp (jump))
2189 return 0;
2191 if (redirect_jump (jump, nlabel, delete_unused))
2193 invert_br_probabilities (jump);
2195 return 1;
2198 if (! invert_exp (jump))
2199 /* This should just be putting it back the way it was. */
2200 abort ();
2202 return 0;
2206 /* Like rtx_equal_p except that it considers two REGs as equal
2207 if they renumber to the same value and considers two commutative
2208 operations to be the same if the order of the operands has been
2209 reversed.
2211 ??? Addition is not commutative on the PA due to the weird implicit
2212 space register selection rules for memory addresses. Therefore, we
2213 don't consider a + b == b + a.
2215 We could/should make this test a little tighter. Possibly only
2216 disabling it on the PA via some backend macro or only disabling this
2217 case when the PLUS is inside a MEM. */
2220 rtx_renumbered_equal_p (x, y)
2221 rtx x, y;
2223 int i;
2224 RTX_CODE code = GET_CODE (x);
2225 const char *fmt;
2227 if (x == y)
2228 return 1;
2230 if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
2231 && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
2232 && GET_CODE (SUBREG_REG (y)) == REG)))
2234 int reg_x = -1, reg_y = -1;
2235 int byte_x = 0, byte_y = 0;
2237 if (GET_MODE (x) != GET_MODE (y))
2238 return 0;
2240 /* If we haven't done any renumbering, don't
2241 make any assumptions. */
2242 if (reg_renumber == 0)
2243 return rtx_equal_p (x, y);
2245 if (code == SUBREG)
2247 reg_x = REGNO (SUBREG_REG (x));
2248 byte_x = SUBREG_BYTE (x);
2250 if (reg_renumber[reg_x] >= 0)
2252 reg_x = subreg_regno_offset (reg_renumber[reg_x],
2253 GET_MODE (SUBREG_REG (x)),
2254 byte_x,
2255 GET_MODE (x));
2256 byte_x = 0;
2259 else
2261 reg_x = REGNO (x);
2262 if (reg_renumber[reg_x] >= 0)
2263 reg_x = reg_renumber[reg_x];
2266 if (GET_CODE (y) == SUBREG)
2268 reg_y = REGNO (SUBREG_REG (y));
2269 byte_y = SUBREG_BYTE (y);
2271 if (reg_renumber[reg_y] >= 0)
2273 reg_y = subreg_regno_offset (reg_renumber[reg_y],
2274 GET_MODE (SUBREG_REG (y)),
2275 byte_y,
2276 GET_MODE (y));
2277 byte_y = 0;
2280 else
2282 reg_y = REGNO (y);
2283 if (reg_renumber[reg_y] >= 0)
2284 reg_y = reg_renumber[reg_y];
2287 return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
2290 /* Now we have disposed of all the cases
2291 in which different rtx codes can match. */
2292 if (code != GET_CODE (y))
2293 return 0;
2295 switch (code)
2297 case PC:
2298 case CC0:
2299 case ADDR_VEC:
2300 case ADDR_DIFF_VEC:
2301 return 0;
2303 case CONST_INT:
2304 return INTVAL (x) == INTVAL (y);
2306 case LABEL_REF:
2307 /* We can't assume nonlocal labels have their following insns yet. */
2308 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
2309 return XEXP (x, 0) == XEXP (y, 0);
2311 /* Two label-refs are equivalent if they point at labels
2312 in the same position in the instruction stream. */
2313 return (next_real_insn (XEXP (x, 0))
2314 == next_real_insn (XEXP (y, 0)));
2316 case SYMBOL_REF:
2317 return XSTR (x, 0) == XSTR (y, 0);
2319 case CODE_LABEL:
2320 /* If we didn't match EQ equality above, they aren't the same. */
2321 return 0;
2323 default:
2324 break;
2327 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
2329 if (GET_MODE (x) != GET_MODE (y))
2330 return 0;
2332 /* For commutative operations, the RTX match if the operand match in any
2333 order. Also handle the simple binary and unary cases without a loop.
2335 ??? Don't consider PLUS a commutative operator; see comments above. */
2336 if ((code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
2337 && code != PLUS)
2338 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
2339 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
2340 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
2341 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
2342 else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
2343 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
2344 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
2345 else if (GET_RTX_CLASS (code) == '1')
2346 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
2348 /* Compare the elements. If any pair of corresponding elements
2349 fail to match, return 0 for the whole things. */
2351 fmt = GET_RTX_FORMAT (code);
2352 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2354 int j;
2355 switch (fmt[i])
2357 case 'w':
2358 if (XWINT (x, i) != XWINT (y, i))
2359 return 0;
2360 break;
2362 case 'i':
2363 if (XINT (x, i) != XINT (y, i))
2364 return 0;
2365 break;
2367 case 't':
2368 if (XTREE (x, i) != XTREE (y, i))
2369 return 0;
2370 break;
2372 case 's':
2373 if (strcmp (XSTR (x, i), XSTR (y, i)))
2374 return 0;
2375 break;
2377 case 'e':
2378 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
2379 return 0;
2380 break;
2382 case 'u':
2383 if (XEXP (x, i) != XEXP (y, i))
2384 return 0;
2385 /* fall through. */
2386 case '0':
2387 break;
2389 case 'E':
2390 if (XVECLEN (x, i) != XVECLEN (y, i))
2391 return 0;
2392 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2393 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
2394 return 0;
2395 break;
2397 default:
2398 abort ();
2401 return 1;
2404 /* If X is a hard register or equivalent to one or a subregister of one,
2405 return the hard register number. If X is a pseudo register that was not
2406 assigned a hard register, return the pseudo register number. Otherwise,
2407 return -1. Any rtx is valid for X. */
2410 true_regnum (x)
2411 rtx x;
2413 if (GET_CODE (x) == REG)
2415 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
2416 return reg_renumber[REGNO (x)];
2417 return REGNO (x);
2419 if (GET_CODE (x) == SUBREG)
2421 int base = true_regnum (SUBREG_REG (x));
2422 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
2423 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
2424 GET_MODE (SUBREG_REG (x)),
2425 SUBREG_BYTE (x), GET_MODE (x));
2427 return -1;