]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/jump.c
PR c++/33342
[thirdparty/gcc.git] / gcc / jump.c
CommitLineData
5924de0b 1/* Optimize jump instructions, for GNU compiler.
c773fc10 2 Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
8c4c00c1 3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
72fae5d0 4 Free Software Foundation, Inc.
5924de0b 5
f12b58b3 6This file is part of GCC.
5924de0b 7
f12b58b3 8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
8c4c00c1 10Software Foundation; either version 3, or (at your option) any later
f12b58b3 11version.
5924de0b 12
f12b58b3 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
5924de0b 17
18You should have received a copy of the GNU General Public License
8c4c00c1 19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
5924de0b 21
fc4eaab7 22/* This is the pathetic reminder of old fame of the jump-optimization pass
d961ae3a 23 of the compiler. Now it contains basically a set of utility functions to
fc4eaab7 24 operate with jumps.
5924de0b 25
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.
33
5f3447b0 34 The subroutines redirect_jump and invert_jump are used
5924de0b 35 from other passes as well. */
36
37#include "config.h"
405711de 38#include "system.h"
805e22b2 39#include "coretypes.h"
40#include "tm.h"
5924de0b 41#include "rtl.h"
7953c610 42#include "tm_p.h"
5924de0b 43#include "flags.h"
44#include "hard-reg-set.h"
45#include "regs.h"
5924de0b 46#include "insn-config.h"
fe3b47be 47#include "insn-attr.h"
0dbd1c74 48#include "recog.h"
0a893c29 49#include "function.h"
fa9157fe 50#include "expr.h"
5924de0b 51#include "real.h"
485aaaaf 52#include "except.h"
69579044 53#include "diagnostic.h"
ce1fd7fc 54#include "toplev.h"
75eb327c 55#include "reload.h"
13488c51 56#include "predict.h"
376c21d1 57#include "timevar.h"
77fce4cd 58#include "tree-pass.h"
280566a7 59#include "target.h"
5924de0b 60
5924de0b 61/* Optimize jump y; x: ... y: jumpif... x?
62 Don't know if it is worth bothering with. */
63/* Optimize two cases of conditional jump to conditional jump?
64 This can never delete any instruction or make anything dead,
65 or even change what is live at any point.
66 So perhaps let combiner do it. */
67
3ad4992f 68static void init_label_info (rtx);
69static void mark_all_labels (rtx);
3ad4992f 70static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
82880dfd 71static int invert_exp_1 (rtx, rtx);
3ad4992f 72static int returnjump_p_1 (rtx *, void *);
60ecc450 73\f
8b946ced 74/* Alternate entry into the jump optimizer. This entry point only rebuilds
75 the JUMP_LABEL field in jumping insns and REG_LABEL notes in non-jumping
76 instructions. */
77void
3ad4992f 78rebuild_jump_labels (rtx f)
8b946ced 79{
19cb6b50 80 rtx insn;
5924de0b 81
376c21d1 82 timevar_push (TV_REBUILD_JUMP);
805e22b2 83 init_label_info (f);
bf73fcf4 84 mark_all_labels (f);
5924de0b 85
cbd914e1 86 /* Keep track of labels used from static data; we don't track them
87 closely enough to delete them here, so make sure their reference
88 count doesn't drop to zero. */
5924de0b 89
90 for (insn = forced_labels; insn; insn = XEXP (insn, 1))
6d7dc5b9 91 if (LABEL_P (XEXP (insn, 0)))
cbd914e1 92 LABEL_NUSES (XEXP (insn, 0))++;
376c21d1 93 timevar_pop (TV_REBUILD_JUMP);
fc4eaab7 94}
95\f
fb3c15bc 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.
100
101 This simple pass moves barriers and removes duplicates so that the
102 old code is happy.
103 */
2a1990e9 104unsigned int
3ad4992f 105cleanup_barriers (void)
fb3c15bc 106{
107 rtx insn, next, prev;
108 for (insn = get_insns (); insn; insn = next)
109 {
110 next = NEXT_INSN (insn);
6d7dc5b9 111 if (BARRIER_P (insn))
fb3c15bc 112 {
113 prev = prev_nonnote_insn (insn);
6d7dc5b9 114 if (BARRIER_P (prev))
749a971f 115 delete_insn (insn);
fb3c15bc 116 else if (prev != PREV_INSN (insn))
117 reorder_insns (insn, insn, prev);
118 }
119 }
2a1990e9 120 return 0;
fb3c15bc 121}
5924de0b 122
77fce4cd 123struct tree_opt_pass pass_cleanup_barriers =
124{
228967a9 125 "barriers", /* name */
77fce4cd 126 NULL, /* gate */
127 cleanup_barriers, /* execute */
128 NULL, /* sub */
129 NULL, /* next */
130 0, /* static_pass_number */
131 0, /* tv_id */
132 0, /* properties_required */
133 0, /* properties_provided */
134 0, /* properties_destroyed */
135 0, /* todo_flags_start */
228967a9 136 TODO_dump_func, /* todo_flags_finish */
77fce4cd 137 0 /* letter */
138};
139
e8d75e01 140\f
141/* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
142 notes whose labels don't occur in the insn any more. Returns the
143 largest INSN_UID found. */
805e22b2 144static void
3ad4992f 145init_label_info (rtx f)
e8d75e01 146{
e8d75e01 147 rtx insn;
148
149 for (insn = f; insn; insn = NEXT_INSN (insn))
6d7dc5b9 150 if (LABEL_P (insn))
805e22b2 151 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
6d7dc5b9 152 else if (JUMP_P (insn))
805e22b2 153 JUMP_LABEL (insn) = 0;
6d7dc5b9 154 else if (NONJUMP_INSN_P (insn) || CALL_P (insn))
805e22b2 155 {
156 rtx note, next;
e8d75e01 157
805e22b2 158 for (note = REG_NOTES (insn); note; note = next)
159 {
160 next = XEXP (note, 1);
161 if (REG_NOTE_KIND (note) == REG_LABEL
162 && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
163 remove_note (insn, note);
164 }
165 }
e8d75e01 166}
167
e8d75e01 168/* Mark the label each jump jumps to.
fc4eaab7 169 Combine consecutive labels, and count uses of labels. */
e8d75e01 170
171static void
3ad4992f 172mark_all_labels (rtx f)
e8d75e01 173{
174 rtx insn;
175
176 for (insn = f; insn; insn = NEXT_INSN (insn))
9204e736 177 if (INSN_P (insn))
e8d75e01 178 {
bf73fcf4 179 mark_jump_label (PATTERN (insn), insn, 0);
6d7dc5b9 180 if (! INSN_DELETED_P (insn) && JUMP_P (insn))
e8d75e01 181 {
d3ff0f75 182 /* When we know the LABEL_REF contained in a REG used in
183 an indirect jump, we'll have a REG_LABEL note so that
184 flow can tell where it's going. */
185 if (JUMP_LABEL (insn) == 0)
186 {
187 rtx label_note = find_reg_note (insn, REG_LABEL, NULL_RTX);
188 if (label_note)
189 {
190 /* But a LABEL_REF around the REG_LABEL note, so
191 that we can canonicalize it. */
514b43f8 192 rtx label_ref = gen_rtx_LABEL_REF (Pmode,
d3ff0f75 193 XEXP (label_note, 0));
194
bf73fcf4 195 mark_jump_label (label_ref, insn, 0);
d3ff0f75 196 XEXP (label_note, 0) = XEXP (label_ref, 0);
197 JUMP_LABEL (insn) = XEXP (label_note, 0);
198 }
199 }
e8d75e01 200 }
201 }
eea7b156 202
203 /* If we are in cfglayout mode, there may be non-insns between the
204 basic blocks. If those non-insns represent tablejump data, they
205 contain label references that we must record. */
206 if (current_ir_type () == IR_RTL_CFGLAYOUT)
207 {
208 basic_block bb;
209 rtx insn;
210 FOR_EACH_BB (bb)
211 {
212 for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
213 if (INSN_P (insn))
214 {
215 gcc_assert (JUMP_TABLE_DATA_P (insn));
216 mark_jump_label (PATTERN (insn), insn, 0);
217 }
218
219 for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
220 if (INSN_P (insn))
221 {
222 gcc_assert (JUMP_TABLE_DATA_P (insn));
223 mark_jump_label (PATTERN (insn), insn, 0);
224 }
225 }
226 }
e8d75e01 227}
5924de0b 228\f
fa8b3d85 229/* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
8e98892d 230 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
231 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
232 know whether it's source is floating point or integer comparison. Machine
233 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
234 to help this function avoid overhead in these cases. */
235enum rtx_code
5493cb9a 236reversed_comparison_code_parts (enum rtx_code code, const_rtx arg0,
237 const_rtx arg1, const_rtx insn)
5924de0b 238{
8e98892d 239 enum machine_mode mode;
5924de0b 240
241 /* If this is not actually a comparison, we can't reverse it. */
6720e96c 242 if (GET_RTX_CLASS (code) != RTX_COMPARE
243 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
8e98892d 244 return UNKNOWN;
245
246 mode = GET_MODE (arg0);
247 if (mode == VOIDmode)
248 mode = GET_MODE (arg1);
249
3927afe0 250 /* First see if machine description supplies us way to reverse the
251 comparison. Give it priority over everything else to allow
252 machine description to do tricks. */
0ec244e1 253 if (GET_MODE_CLASS (mode) == MODE_CC
8e98892d 254 && REVERSIBLE_CC_MODE (mode))
255 {
256#ifdef REVERSE_CONDITION
85fc0ad1 257 return REVERSE_CONDITION (code, mode);
8e98892d 258#endif
85fc0ad1 259 return reverse_condition (code);
260 }
5924de0b 261
fa8b3d85 262 /* Try a few special cases based on the comparison code. */
8e98892d 263 switch (code)
264 {
85fc0ad1 265 case GEU:
266 case GTU:
267 case LEU:
268 case LTU:
269 case NE:
270 case EQ:
271 /* It is always safe to reverse EQ and NE, even for the floating
917bbcab 272 point. Similarly the unsigned comparisons are never used for
85fc0ad1 273 floating point so we can reverse them in the default way. */
274 return reverse_condition (code);
275 case ORDERED:
276 case UNORDERED:
277 case LTGT:
278 case UNEQ:
279 /* In case we already see unordered comparison, we can be sure to
280 be dealing with floating point so we don't need any more tests. */
281 return reverse_condition_maybe_unordered (code);
282 case UNLT:
283 case UNLE:
284 case UNGT:
285 case UNGE:
286 /* We don't have safe way to reverse these yet. */
287 return UNKNOWN;
288 default:
289 break;
8e98892d 290 }
291
a4589b78 292 if (GET_MODE_CLASS (mode) == MODE_CC || CC0_P (arg0))
5924de0b 293 {
5493cb9a 294 const_rtx prev;
8e98892d 295 /* Try to search for the comparison to determine the real mode.
296 This code is expensive, but with sane machine description it
297 will be never used, since REVERSIBLE_CC_MODE will return true
298 in all cases. */
111f2389 299 if (! insn)
8e98892d 300 return UNKNOWN;
7113a566 301
ce4469fa 302 /* These CONST_CAST's are okay because prev_nonnote_insn just
303 returns it's argument and we assign it to a const_rtx
304 variable. */
e47a6f81 305 for (prev = prev_nonnote_insn (CONST_CAST_RTX(insn));
6d7dc5b9 306 prev != 0 && !LABEL_P (prev);
e47a6f81 307 prev = prev_nonnote_insn (CONST_CAST_RTX(prev)))
8e98892d 308 {
81a410b1 309 const_rtx set = set_of (arg0, prev);
8e98892d 310 if (set && GET_CODE (set) == SET
311 && rtx_equal_p (SET_DEST (set), arg0))
312 {
313 rtx src = SET_SRC (set);
5924de0b 314
8e98892d 315 if (GET_CODE (src) == COMPARE)
316 {
317 rtx comparison = src;
318 arg0 = XEXP (src, 0);
319 mode = GET_MODE (arg0);
320 if (mode == VOIDmode)
321 mode = GET_MODE (XEXP (comparison, 1));
322 break;
323 }
dd5b4b36 324 /* We can get past reg-reg moves. This may be useful for model
8e98892d 325 of i387 comparisons that first move flag registers around. */
326 if (REG_P (src))
327 {
328 arg0 = src;
329 continue;
330 }
331 }
332 /* If register is clobbered in some ununderstandable way,
333 give up. */
334 if (set)
335 return UNKNOWN;
336 }
5924de0b 337 }
338
920d0fb5 339 /* Test for an integer condition, or a floating-point comparison
340 in which NaNs can be ignored. */
8e98892d 341 if (GET_CODE (arg0) == CONST_INT
342 || (GET_MODE (arg0) != VOIDmode
343 && GET_MODE_CLASS (mode) != MODE_CC
920d0fb5 344 && !HONOR_NANS (mode)))
8e98892d 345 return reverse_condition (code);
346
347 return UNKNOWN;
348}
349
df07c3ae 350/* A wrapper around the previous function to take COMPARISON as rtx
8e98892d 351 expression. This simplifies many callers. */
352enum rtx_code
5493cb9a 353reversed_comparison_code (const_rtx comparison, const_rtx insn)
8e98892d 354{
6720e96c 355 if (!COMPARISON_P (comparison))
8e98892d 356 return UNKNOWN;
357 return reversed_comparison_code_parts (GET_CODE (comparison),
358 XEXP (comparison, 0),
359 XEXP (comparison, 1), insn);
360}
0fc1e6fa 361
362/* Return comparison with reversed code of EXP.
363 Return NULL_RTX in case we fail to do the reversal. */
364rtx
5493cb9a 365reversed_comparison (const_rtx exp, enum machine_mode mode)
0fc1e6fa 366{
367 enum rtx_code reversed_code = reversed_comparison_code (exp, NULL_RTX);
368 if (reversed_code == UNKNOWN)
369 return NULL_RTX;
370 else
371 return simplify_gen_relational (reversed_code, mode, VOIDmode,
372 XEXP (exp, 0), XEXP (exp, 1));
373}
374
8e98892d 375\f
a4110d9a 376/* Given an rtx-code for a comparison, return the code for the negated
377 comparison. If no such code exists, return UNKNOWN.
378
379 WATCH OUT! reverse_condition is not safe to use on a jump that might
380 be acting on the results of an IEEE floating point comparison, because
7113a566 381 of the special treatment of non-signaling nans in comparisons.
8e98892d 382 Use reversed_comparison_code instead. */
5924de0b 383
384enum rtx_code
3ad4992f 385reverse_condition (enum rtx_code code)
5924de0b 386{
387 switch (code)
388 {
389 case EQ:
390 return NE;
5924de0b 391 case NE:
392 return EQ;
5924de0b 393 case GT:
394 return LE;
5924de0b 395 case GE:
396 return LT;
5924de0b 397 case LT:
398 return GE;
5924de0b 399 case LE:
400 return GT;
5924de0b 401 case GTU:
402 return LEU;
5924de0b 403 case GEU:
404 return LTU;
5924de0b 405 case LTU:
406 return GEU;
5924de0b 407 case LEU:
408 return GTU;
a4110d9a 409 case UNORDERED:
410 return ORDERED;
411 case ORDERED:
412 return UNORDERED;
413
414 case UNLT:
415 case UNLE:
416 case UNGT:
417 case UNGE:
418 case UNEQ:
79777bad 419 case LTGT:
a4110d9a 420 return UNKNOWN;
5924de0b 421
422 default:
a53ff4c1 423 gcc_unreachable ();
5924de0b 424 }
425}
426
79777bad 427/* Similar, but we're allowed to generate unordered comparisons, which
428 makes it safe for IEEE floating-point. Of course, we have to recognize
429 that the target will support them too... */
430
431enum rtx_code
3ad4992f 432reverse_condition_maybe_unordered (enum rtx_code code)
79777bad 433{
79777bad 434 switch (code)
435 {
436 case EQ:
437 return NE;
438 case NE:
439 return EQ;
440 case GT:
441 return UNLE;
442 case GE:
443 return UNLT;
444 case LT:
445 return UNGE;
446 case LE:
447 return UNGT;
448 case LTGT:
449 return UNEQ;
79777bad 450 case UNORDERED:
451 return ORDERED;
452 case ORDERED:
453 return UNORDERED;
454 case UNLT:
455 return GE;
456 case UNLE:
457 return GT;
458 case UNGT:
459 return LE;
460 case UNGE:
461 return LT;
462 case UNEQ:
463 return LTGT;
464
465 default:
a53ff4c1 466 gcc_unreachable ();
79777bad 467 }
468}
469
5924de0b 470/* Similar, but return the code when two operands of a comparison are swapped.
471 This IS safe for IEEE floating-point. */
472
473enum rtx_code
3ad4992f 474swap_condition (enum rtx_code code)
5924de0b 475{
476 switch (code)
477 {
478 case EQ:
479 case NE:
a4110d9a 480 case UNORDERED:
481 case ORDERED:
482 case UNEQ:
79777bad 483 case LTGT:
5924de0b 484 return code;
485
486 case GT:
487 return LT;
5924de0b 488 case GE:
489 return LE;
5924de0b 490 case LT:
491 return GT;
5924de0b 492 case LE:
493 return GE;
5924de0b 494 case GTU:
495 return LTU;
5924de0b 496 case GEU:
497 return LEU;
5924de0b 498 case LTU:
499 return GTU;
5924de0b 500 case LEU:
501 return GEU;
a4110d9a 502 case UNLT:
503 return UNGT;
504 case UNLE:
505 return UNGE;
506 case UNGT:
507 return UNLT;
508 case UNGE:
509 return UNLE;
510
5924de0b 511 default:
a53ff4c1 512 gcc_unreachable ();
5924de0b 513 }
514}
515
516/* Given a comparison CODE, return the corresponding unsigned comparison.
517 If CODE is an equality comparison or already an unsigned comparison,
518 CODE is returned. */
519
520enum rtx_code
3ad4992f 521unsigned_condition (enum rtx_code code)
5924de0b 522{
523 switch (code)
524 {
525 case EQ:
526 case NE:
527 case GTU:
528 case GEU:
529 case LTU:
530 case LEU:
531 return code;
532
533 case GT:
534 return GTU;
5924de0b 535 case GE:
536 return GEU;
5924de0b 537 case LT:
538 return LTU;
5924de0b 539 case LE:
540 return LEU;
541
542 default:
a53ff4c1 543 gcc_unreachable ();
5924de0b 544 }
545}
546
547/* Similarly, return the signed version of a comparison. */
548
549enum rtx_code
3ad4992f 550signed_condition (enum rtx_code code)
5924de0b 551{
552 switch (code)
553 {
554 case EQ:
555 case NE:
556 case GT:
557 case GE:
558 case LT:
559 case LE:
560 return code;
561
562 case GTU:
563 return GT;
5924de0b 564 case GEU:
565 return GE;
5924de0b 566 case LTU:
567 return LT;
5924de0b 568 case LEU:
569 return LE;
570
571 default:
a53ff4c1 572 gcc_unreachable ();
5924de0b 573 }
574}
575\f
6ef828f9 576/* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
5924de0b 577 truth of CODE1 implies the truth of CODE2. */
578
579int
3ad4992f 580comparison_dominates_p (enum rtx_code code1, enum rtx_code code2)
5924de0b 581{
ca7744c6 582 /* UNKNOWN comparison codes can happen as a result of trying to revert
583 comparison codes.
584 They can't match anything, so we have to reject them here. */
585 if (code1 == UNKNOWN || code2 == UNKNOWN)
586 return 0;
587
5924de0b 588 if (code1 == code2)
589 return 1;
590
591 switch (code1)
592 {
5aa3f5e2 593 case UNEQ:
594 if (code2 == UNLE || code2 == UNGE)
595 return 1;
596 break;
597
5924de0b 598 case EQ:
79777bad 599 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
600 || code2 == ORDERED)
5924de0b 601 return 1;
602 break;
603
5aa3f5e2 604 case UNLT:
605 if (code2 == UNLE || code2 == NE)
606 return 1;
607 break;
608
5924de0b 609 case LT:
5aa3f5e2 610 if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
611 return 1;
612 break;
613
614 case UNGT:
615 if (code2 == UNGE || code2 == NE)
5924de0b 616 return 1;
617 break;
618
619 case GT:
5aa3f5e2 620 if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
79777bad 621 return 1;
622 break;
623
624 case GE:
625 case LE:
626 if (code2 == ORDERED)
627 return 1;
628 break;
629
630 case LTGT:
631 if (code2 == NE || code2 == ORDERED)
5924de0b 632 return 1;
633 break;
634
635 case LTU:
11088b43 636 if (code2 == LEU || code2 == NE)
5924de0b 637 return 1;
638 break;
639
640 case GTU:
11088b43 641 if (code2 == GEU || code2 == NE)
5924de0b 642 return 1;
643 break;
79777bad 644
645 case UNORDERED:
5aa3f5e2 646 if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
647 || code2 == UNGE || code2 == UNGT)
79777bad 648 return 1;
649 break;
7113a566 650
0dbd1c74 651 default:
652 break;
5924de0b 653 }
654
655 return 0;
656}
657\f
658/* Return 1 if INSN is an unconditional jump and nothing else. */
659
660int
52d07779 661simplejump_p (const_rtx insn)
5924de0b 662{
6d7dc5b9 663 return (JUMP_P (insn)
8d472058 664 && GET_CODE (PATTERN (insn)) == SET
665 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
666 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
5924de0b 667}
668
669/* Return nonzero if INSN is a (possibly) conditional jump
7113a566 670 and nothing more.
671
4885b286 672 Use of this function is deprecated, since we need to support combined
d670e794 673 branch and compare insns. Use any_condjump_p instead whenever possible. */
5924de0b 674
675int
52d07779 676condjump_p (const_rtx insn)
5924de0b 677{
52d07779 678 const_rtx x = PATTERN (insn);
7014838c 679
680 if (GET_CODE (x) != SET
681 || GET_CODE (SET_DEST (x)) != PC)
4fbe8fa7 682 return 0;
7014838c 683
684 x = SET_SRC (x);
685 if (GET_CODE (x) == LABEL_REF)
4fbe8fa7 686 return 1;
7113a566 687 else
688 return (GET_CODE (x) == IF_THEN_ELSE
689 && ((GET_CODE (XEXP (x, 2)) == PC
690 && (GET_CODE (XEXP (x, 1)) == LABEL_REF
691 || GET_CODE (XEXP (x, 1)) == RETURN))
692 || (GET_CODE (XEXP (x, 1)) == PC
693 && (GET_CODE (XEXP (x, 2)) == LABEL_REF
694 || GET_CODE (XEXP (x, 2)) == RETURN))));
4fbe8fa7 695}
696
7014838c 697/* Return nonzero if INSN is a (possibly) conditional jump inside a
3a941ad5 698 PARALLEL.
7113a566 699
d670e794 700 Use this function is deprecated, since we need to support combined
701 branch and compare insns. Use any_condjump_p instead whenever possible. */
4fbe8fa7 702
703int
52d07779 704condjump_in_parallel_p (const_rtx insn)
4fbe8fa7 705{
52d07779 706 const_rtx x = PATTERN (insn);
4fbe8fa7 707
708 if (GET_CODE (x) != PARALLEL)
709 return 0;
710 else
711 x = XVECEXP (x, 0, 0);
712
5924de0b 713 if (GET_CODE (x) != SET)
714 return 0;
715 if (GET_CODE (SET_DEST (x)) != PC)
716 return 0;
717 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
718 return 1;
719 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
720 return 0;
721 if (XEXP (SET_SRC (x), 2) == pc_rtx
722 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
723 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
724 return 1;
725 if (XEXP (SET_SRC (x), 1) == pc_rtx
726 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
727 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
728 return 1;
729 return 0;
730}
731
d670e794 732/* Return set of PC, otherwise NULL. */
733
3a941ad5 734rtx
52d07779 735pc_set (const_rtx insn)
3a941ad5 736{
737 rtx pat;
6d7dc5b9 738 if (!JUMP_P (insn))
d670e794 739 return NULL_RTX;
3a941ad5 740 pat = PATTERN (insn);
d670e794 741
742 /* The set is allowed to appear either as the insn pattern or
743 the first set in a PARALLEL. */
744 if (GET_CODE (pat) == PARALLEL)
745 pat = XVECEXP (pat, 0, 0);
3a941ad5 746 if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
747 return pat;
d670e794 748
749 return NULL_RTX;
3a941ad5 750}
751
d670e794 752/* Return true when insn is an unconditional direct jump,
753 possibly bundled inside a PARALLEL. */
754
3a941ad5 755int
52d07779 756any_uncondjump_p (const_rtx insn)
3a941ad5 757{
52d07779 758 const_rtx x = pc_set (insn);
3a941ad5 759 if (!x)
760 return 0;
761 if (GET_CODE (SET_SRC (x)) != LABEL_REF)
762 return 0;
4ee9c684 763 if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
764 return 0;
3a941ad5 765 return 1;
766}
767
d670e794 768/* Return true when insn is a conditional jump. This function works for
3a941ad5 769 instructions containing PC sets in PARALLELs. The instruction may have
770 various other effects so before removing the jump you must verify
9641f63c 771 onlyjump_p.
3a941ad5 772
d670e794 773 Note that unlike condjump_p it returns false for unconditional jumps. */
774
3a941ad5 775int
52d07779 776any_condjump_p (const_rtx insn)
3a941ad5 777{
52d07779 778 const_rtx x = pc_set (insn);
d670e794 779 enum rtx_code a, b;
780
3a941ad5 781 if (!x)
782 return 0;
d670e794 783 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
784 return 0;
3a941ad5 785
d670e794 786 a = GET_CODE (XEXP (SET_SRC (x), 1));
787 b = GET_CODE (XEXP (SET_SRC (x), 2));
3a941ad5 788
d670e794 789 return ((b == PC && (a == LABEL_REF || a == RETURN))
7113a566 790 || (a == PC && (b == LABEL_REF || b == RETURN)));
3a941ad5 791}
792
8f7b24f3 793/* Return the label of a conditional jump. */
794
795rtx
5493cb9a 796condjump_label (const_rtx insn)
8f7b24f3 797{
d670e794 798 rtx x = pc_set (insn);
8f7b24f3 799
d670e794 800 if (!x)
8f7b24f3 801 return NULL_RTX;
802 x = SET_SRC (x);
803 if (GET_CODE (x) == LABEL_REF)
804 return x;
805 if (GET_CODE (x) != IF_THEN_ELSE)
806 return NULL_RTX;
807 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
808 return XEXP (x, 1);
809 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
810 return XEXP (x, 2);
811 return NULL_RTX;
812}
813
71caadc0 814/* Return true if INSN is a (possibly conditional) return insn. */
815
816static int
3ad4992f 817returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
71caadc0 818{
819 rtx x = *loc;
c3987c92 820
821 return x && (GET_CODE (x) == RETURN
822 || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
71caadc0 823}
824
825int
3ad4992f 826returnjump_p (rtx insn)
71caadc0 827{
6d7dc5b9 828 if (!JUMP_P (insn))
cbd914e1 829 return 0;
71caadc0 830 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
831}
832
459e9193 833/* Return true if INSN is a jump that only transfers control and
834 nothing more. */
835
836int
52d07779 837onlyjump_p (const_rtx insn)
459e9193 838{
839 rtx set;
840
6d7dc5b9 841 if (!JUMP_P (insn))
459e9193 842 return 0;
843
844 set = single_set (insn);
845 if (set == NULL)
846 return 0;
847 if (GET_CODE (SET_DEST (set)) != PC)
848 return 0;
849 if (side_effects_p (SET_SRC (set)))
850 return 0;
851
852 return 1;
853}
854
9bf8c346 855#ifdef HAVE_cc0
856
6ef828f9 857/* Return nonzero if X is an RTX that only sets the condition codes
2dcd83ba 858 and has no side effects. */
859
860int
52d07779 861only_sets_cc0_p (const_rtx x)
2dcd83ba 862{
2dcd83ba 863 if (! x)
864 return 0;
865
866 if (INSN_P (x))
867 x = PATTERN (x);
868
869 return sets_cc0_p (x) == 1 && ! side_effects_p (x);
870}
871
5924de0b 872/* Return 1 if X is an RTX that does nothing but set the condition codes
873 and CLOBBER or USE registers.
874 Return -1 if X does explicitly set the condition codes,
875 but also does other things. */
876
877int
52d07779 878sets_cc0_p (const_rtx x)
5924de0b 879{
2dcd83ba 880 if (! x)
881 return 0;
882
883 if (INSN_P (x))
884 x = PATTERN (x);
885
5924de0b 886 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
887 return 1;
888 if (GET_CODE (x) == PARALLEL)
889 {
890 int i;
891 int sets_cc0 = 0;
892 int other_things = 0;
893 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
894 {
895 if (GET_CODE (XVECEXP (x, 0, i)) == SET
896 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
897 sets_cc0 = 1;
898 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
899 other_things = 1;
900 }
901 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
902 }
903 return 0;
5924de0b 904}
9bf8c346 905#endif
5924de0b 906\f
907/* Find all CODE_LABELs referred to in X, and increment their use counts.
908 If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced
909 in INSN, then store one of them in JUMP_LABEL (INSN).
910 If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL
911 referenced in INSN, add a REG_LABEL note containing that label to INSN.
912 Also, when there are consecutive labels, canonicalize on the last of them.
913
914 Note that two labels separated by a loop-beginning note
915 must be kept distinct if we have not yet done loop-optimization,
916 because the gap between them is where loop-optimize
917 will want to move invariant code to. CROSS_JUMP tells us
bf73fcf4 918 that loop-optimization is done with. */
5924de0b 919
5377f687 920void
3ad4992f 921mark_jump_label (rtx x, rtx insn, int in_mem)
5924de0b 922{
19cb6b50 923 RTX_CODE code = GET_CODE (x);
924 int i;
925 const char *fmt;
5924de0b 926
927 switch (code)
928 {
929 case PC:
930 case CC0:
931 case REG:
5924de0b 932 case CONST_INT:
5924de0b 933 case CONST_DOUBLE:
934 case CLOBBER:
935 case CALL:
936 return;
937
d8e0d332 938 case MEM:
190099a6 939 in_mem = 1;
940 break;
941
76021441 942 case SEQUENCE:
943 for (i = 0; i < XVECLEN (x, 0); i++)
944 mark_jump_label (PATTERN (XVECEXP (x, 0, i)),
945 XVECEXP (x, 0, i), 0);
946 return;
947
190099a6 948 case SYMBOL_REF:
949 if (!in_mem)
7113a566 950 return;
190099a6 951
d8e0d332 952 /* If this is a constant-pool reference, see if it is a label. */
190099a6 953 if (CONSTANT_POOL_ADDRESS_P (x))
bf73fcf4 954 mark_jump_label (get_pool_constant (x), insn, in_mem);
d8e0d332 955 break;
956
5924de0b 957 case LABEL_REF:
958 {
b4d3bcce 959 rtx label = XEXP (x, 0);
b4d3bcce 960
74b0991d 961 /* Ignore remaining references to unreachable labels that
962 have been deleted. */
6d7dc5b9 963 if (NOTE_P (label)
ad4583d9 964 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL)
74b0991d 965 break;
966
a53ff4c1 967 gcc_assert (LABEL_P (label));
b4d3bcce 968
f08cae9d 969 /* Ignore references to labels of containing functions. */
970 if (LABEL_REF_NONLOCAL_P (x))
971 break;
b4d3bcce 972
5924de0b 973 XEXP (x, 0) = label;
943e16d8 974 if (! insn || ! INSN_DELETED_P (insn))
975 ++LABEL_NUSES (label);
b4d3bcce 976
5924de0b 977 if (insn)
978 {
6d7dc5b9 979 if (JUMP_P (insn))
5924de0b 980 JUMP_LABEL (insn) = label;
ab2237b5 981 else
e89849bd 982 {
ab2237b5 983 /* Add a REG_LABEL note for LABEL unless there already
984 is one. All uses of a label, except for labels
985 that are the targets of jumps, must have a
986 REG_LABEL note. */
987 if (! find_reg_note (insn, REG_LABEL, label))
60d9e0ee 988 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, label,
ab2237b5 989 REG_NOTES (insn));
5924de0b 990 }
991 }
992 return;
993 }
994
995 /* Do walk the labels in a vector, but not the first operand of an
996 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
997 case ADDR_VEC:
998 case ADDR_DIFF_VEC:
943e16d8 999 if (! INSN_DELETED_P (insn))
1000 {
1001 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
5924de0b 1002
943e16d8 1003 for (i = 0; i < XVECLEN (x, eltnum); i++)
bf73fcf4 1004 mark_jump_label (XVECEXP (x, eltnum, i), NULL_RTX, in_mem);
943e16d8 1005 }
0dbd1c74 1006 return;
7113a566 1007
0dbd1c74 1008 default:
1009 break;
5924de0b 1010 }
1011
1012 fmt = GET_RTX_FORMAT (code);
1013 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1014 {
1015 if (fmt[i] == 'e')
bf73fcf4 1016 mark_jump_label (XEXP (x, i), insn, in_mem);
5924de0b 1017 else if (fmt[i] == 'E')
1018 {
19cb6b50 1019 int j;
5924de0b 1020 for (j = 0; j < XVECLEN (x, i); j++)
bf73fcf4 1021 mark_jump_label (XVECEXP (x, i, j), insn, in_mem);
5924de0b 1022 }
1023 }
1024}
1025
5924de0b 1026\f
e4bf866d 1027/* Delete insn INSN from the chain of insns and update label ref counts
17a74abe 1028 and delete insns now unreachable.
e4bf866d 1029
17a74abe 1030 Returns the first insn after INSN that was not deleted.
5924de0b 1031
e4bf866d 1032 Usage of this instruction is deprecated. Use delete_insn instead and
1033 subsequent cfg_cleanup pass to delete unreachable code if needed. */
5924de0b 1034
1035rtx
3ad4992f 1036delete_related_insns (rtx insn)
5924de0b 1037{
6d7dc5b9 1038 int was_code_label = (LABEL_P (insn));
d3df77e9 1039 rtx note;
e4bf866d 1040 rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
5924de0b 1041
1042 while (next && INSN_DELETED_P (next))
1043 next = NEXT_INSN (next);
1044
1045 /* This insn is already deleted => return first following nondeleted. */
1046 if (INSN_DELETED_P (insn))
1047 return next;
1048
e4bf866d 1049 delete_insn (insn);
5924de0b 1050
5924de0b 1051 /* If instruction is followed by a barrier,
1052 delete the barrier too. */
1053
6d7dc5b9 1054 if (next != 0 && BARRIER_P (next))
e4bf866d 1055 delete_insn (next);
5924de0b 1056
1057 /* If deleting a jump, decrement the count of the label,
1058 and delete the label if it is now unused. */
1059
6d7dc5b9 1060 if (JUMP_P (insn) && JUMP_LABEL (insn))
1793cd6b 1061 {
1062 rtx lab = JUMP_LABEL (insn), lab_next;
1063
e4bf866d 1064 if (LABEL_NUSES (lab) == 0)
1793cd6b 1065 {
1066 /* This can delete NEXT or PREV,
1067 either directly if NEXT is JUMP_LABEL (INSN),
1068 or indirectly through more levels of jumps. */
e4bf866d 1069 delete_related_insns (lab);
1793cd6b 1070
1071 /* I feel a little doubtful about this loop,
1072 but I see no clean and sure alternative way
1073 to find the first insn after INSN that is not now deleted.
1074 I hope this works. */
1075 while (next && INSN_DELETED_P (next))
1076 next = NEXT_INSN (next);
1077 return next;
1078 }
b19beda9 1079 else if (tablejump_p (insn, NULL, &lab_next))
1793cd6b 1080 {
1081 /* If we're deleting the tablejump, delete the dispatch table.
4a82352a 1082 We may not be able to kill the label immediately preceding
1793cd6b 1083 just yet, as it might be referenced in code leading up to
1084 the tablejump. */
e4bf866d 1085 delete_related_insns (lab_next);
1793cd6b 1086 }
1087 }
5924de0b 1088
9c9e0c01 1089 /* Likewise if we're deleting a dispatch table. */
1090
6d7dc5b9 1091 if (JUMP_P (insn)
9c9e0c01 1092 && (GET_CODE (PATTERN (insn)) == ADDR_VEC
1093 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
1094 {
1095 rtx pat = PATTERN (insn);
1096 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1097 int len = XVECLEN (pat, diff_vec_p);
1098
1099 for (i = 0; i < len; i++)
e4bf866d 1100 if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1101 delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
9c9e0c01 1102 while (next && INSN_DELETED_P (next))
1103 next = NEXT_INSN (next);
1104 return next;
1105 }
1106
d3df77e9 1107 /* Likewise for an ordinary INSN / CALL_INSN with a REG_LABEL note. */
6d7dc5b9 1108 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
d3df77e9 1109 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
0c97f529 1110 if (REG_NOTE_KIND (note) == REG_LABEL
1111 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
6d7dc5b9 1112 && LABEL_P (XEXP (note, 0)))
e4bf866d 1113 if (LABEL_NUSES (XEXP (note, 0)) == 0)
1114 delete_related_insns (XEXP (note, 0));
d3df77e9 1115
6d7dc5b9 1116 while (prev && (INSN_DELETED_P (prev) || NOTE_P (prev)))
5924de0b 1117 prev = PREV_INSN (prev);
1118
1119 /* If INSN was a label and a dispatch table follows it,
1120 delete the dispatch table. The tablejump must have gone already.
1121 It isn't useful to fall through into a table. */
1122
9cdc08c6 1123 if (was_code_label
5924de0b 1124 && NEXT_INSN (insn) != 0
6d7dc5b9 1125 && JUMP_P (NEXT_INSN (insn))
5924de0b 1126 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
1127 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
e4bf866d 1128 next = delete_related_insns (NEXT_INSN (insn));
5924de0b 1129
1130 /* If INSN was a label, delete insns following it if now unreachable. */
1131
6d7dc5b9 1132 if (was_code_label && prev && BARRIER_P (prev))
5924de0b 1133 {
6720e96c 1134 enum rtx_code code;
1135 while (next)
5924de0b 1136 {
6720e96c 1137 code = GET_CODE (next);
737251e7 1138 if (code == NOTE)
5924de0b 1139 next = NEXT_INSN (next);
59bee35e 1140 /* Keep going past other deleted labels to delete what follows. */
1141 else if (code == CODE_LABEL && INSN_DELETED_P (next))
1142 next = NEXT_INSN (next);
6720e96c 1143 else if (code == BARRIER || INSN_P (next))
5924de0b 1144 /* Note: if this deletes a jump, it can cause more
1145 deletion of unreachable code, after a different label.
1146 As long as the value from this recursive call is correct,
1147 this invocation functions correctly. */
e4bf866d 1148 next = delete_related_insns (next);
6720e96c 1149 else
1150 break;
5924de0b 1151 }
1152 }
1153
1154 return next;
1155}
5924de0b 1156\f
1157/* Delete a range of insns from FROM to TO, inclusive.
1158 This is for the sake of peephole optimization, so assume
1159 that whatever these insns do will still be done by a new
1160 peephole insn that will replace them. */
1161
1162void
3ad4992f 1163delete_for_peephole (rtx from, rtx to)
5924de0b 1164{
19cb6b50 1165 rtx insn = from;
5924de0b 1166
1167 while (1)
1168 {
19cb6b50 1169 rtx next = NEXT_INSN (insn);
1170 rtx prev = PREV_INSN (insn);
5924de0b 1171
6d7dc5b9 1172 if (!NOTE_P (insn))
5924de0b 1173 {
1174 INSN_DELETED_P (insn) = 1;
1175
1176 /* Patch this insn out of the chain. */
1177 /* We don't do this all at once, because we
1178 must preserve all NOTEs. */
1179 if (prev)
1180 NEXT_INSN (prev) = next;
1181
1182 if (next)
1183 PREV_INSN (next) = prev;
1184 }
1185
1186 if (insn == to)
1187 break;
1188 insn = next;
1189 }
1190
1191 /* Note that if TO is an unconditional jump
1192 we *do not* delete the BARRIER that follows,
1193 since the peephole that replaces this sequence
1194 is also an unconditional jump in that case. */
1195}
1196\f
a8b5d014 1197/* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1198 NLABEL as a return. Accrue modifications into the change group. */
5924de0b 1199
a8b5d014 1200static void
3ad4992f 1201redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
5924de0b 1202{
19cb6b50 1203 rtx x = *loc;
1204 RTX_CODE code = GET_CODE (x);
1205 int i;
1206 const char *fmt;
5924de0b 1207
a8b5d014 1208 if (code == LABEL_REF)
5924de0b 1209 {
a8b5d014 1210 if (XEXP (x, 0) == olabel)
1211 {
1212 rtx n;
1213 if (nlabel)
514b43f8 1214 n = gen_rtx_LABEL_REF (Pmode, nlabel);
a8b5d014 1215 else
7113a566 1216 n = gen_rtx_RETURN (VOIDmode);
5924de0b 1217
a8b5d014 1218 validate_change (insn, loc, n, 1);
1219 return;
1220 }
1221 }
1222 else if (code == RETURN && olabel == 0)
1223 {
ae6fb586 1224 if (nlabel)
514b43f8 1225 x = gen_rtx_LABEL_REF (Pmode, nlabel);
ae6fb586 1226 else
1227 x = gen_rtx_RETURN (VOIDmode);
a8b5d014 1228 if (loc == &PATTERN (insn))
1229 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1230 validate_change (insn, loc, x, 1);
1231 return;
1232 }
5924de0b 1233
a8b5d014 1234 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1235 && GET_CODE (SET_SRC (x)) == LABEL_REF
1236 && XEXP (SET_SRC (x), 0) == olabel)
1237 {
1238 validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1239 return;
5924de0b 1240 }
1241
1242 fmt = GET_RTX_FORMAT (code);
1243 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1244 {
1245 if (fmt[i] == 'e')
a8b5d014 1246 redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1bd8ca86 1247 else if (fmt[i] == 'E')
5924de0b 1248 {
19cb6b50 1249 int j;
5924de0b 1250 for (j = 0; j < XVECLEN (x, i); j++)
a8b5d014 1251 redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
5924de0b 1252 }
1253 }
a8b5d014 1254}
5924de0b 1255
a8b5d014 1256/* Make JUMP go to NLABEL instead of where it jumps now. Accrue
1257 the modifications into the change group. Return false if we did
1258 not see how to do that. */
1259
1260int
3ad4992f 1261redirect_jump_1 (rtx jump, rtx nlabel)
a8b5d014 1262{
1263 int ochanges = num_validated_changes ();
ba08b7e7 1264 rtx *loc;
1265
1266 if (GET_CODE (PATTERN (jump)) == PARALLEL)
1267 loc = &XVECEXP (PATTERN (jump), 0, 0);
1268 else
1269 loc = &PATTERN (jump);
1270
1271 redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
a8b5d014 1272 return num_validated_changes () > ochanges;
1273}
1274
1275/* Make JUMP go to NLABEL instead of where it jumps now. If the old
1276 jump target label is unused as a result, it and the code following
1277 it may be deleted.
5924de0b 1278
1279 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
1280 RETURN insn.
1281
a8b5d014 1282 The return value will be 1 if the change was made, 0 if it wasn't
1283 (this can only occur for NLABEL == 0). */
5924de0b 1284
1285int
3ad4992f 1286redirect_jump (rtx jump, rtx nlabel, int delete_unused)
5924de0b 1287{
19cb6b50 1288 rtx olabel = JUMP_LABEL (jump);
5924de0b 1289
1290 if (nlabel == olabel)
1291 return 1;
1292
82880dfd 1293 if (! redirect_jump_1 (jump, nlabel) || ! apply_change_group ())
5924de0b 1294 return 0;
1295
82880dfd 1296 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 0);
1297 return 1;
1298}
1299
1300/* Fix up JUMP_LABEL and label ref counts after OLABEL has been replaced with
737251e7 1301 NLABEL in JUMP.
82880dfd 1302 If DELETE_UNUSED is positive, delete related insn to OLABEL if its ref
1303 count has dropped to zero. */
1304void
1305redirect_jump_2 (rtx jump, rtx olabel, rtx nlabel, int delete_unused,
1306 int invert)
1307{
1308 rtx note;
1309
f2b32076 1310 /* Negative DELETE_UNUSED used to be used to signalize behavior on
737251e7 1311 moving FUNCTION_END note. Just sanity check that no user still worry
1312 about this. */
1313 gcc_assert (delete_unused >= 0);
5924de0b 1314 JUMP_LABEL (jump) = nlabel;
1315 if (nlabel)
1316 ++LABEL_NUSES (nlabel);
1317
1e0703ac 1318 /* Update labels in any REG_EQUAL note. */
1319 if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
1320 {
82880dfd 1321 if (!nlabel || (invert && !invert_exp_1 (XEXP (note, 0), jump)))
1322 remove_note (jump, note);
1323 else
1e0703ac 1324 {
82880dfd 1325 redirect_exp_1 (&XEXP (note, 0), olabel, nlabel, jump);
1326 confirm_change_group ();
1e0703ac 1327 }
1e0703ac 1328 }
1329
82880dfd 1330 if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused > 0
7f8c3466 1331 /* Undefined labels will remain outside the insn stream. */
1332 && INSN_UID (olabel))
e4bf866d 1333 delete_related_insns (olabel);
82880dfd 1334 if (invert)
1335 invert_br_probabilities (jump);
5924de0b 1336}
1337
82880dfd 1338/* Invert the jump condition X contained in jump insn INSN. Accrue the
1339 modifications into the change group. Return nonzero for success. */
1340static int
1341invert_exp_1 (rtx x, rtx insn)
a8b5d014 1342{
82880dfd 1343 RTX_CODE code = GET_CODE (x);
a8b5d014 1344
1345 if (code == IF_THEN_ELSE)
1346 {
19cb6b50 1347 rtx comp = XEXP (x, 0);
1348 rtx tem;
7da6ea0c 1349 enum rtx_code reversed_code;
a8b5d014 1350
1351 /* We can do this in two ways: The preferable way, which can only
1352 be done if this is not an integer comparison, is to reverse
1353 the comparison code. Otherwise, swap the THEN-part and ELSE-part
1354 of the IF_THEN_ELSE. If we can't do either, fail. */
1355
7da6ea0c 1356 reversed_code = reversed_comparison_code (comp, insn);
1357
1358 if (reversed_code != UNKNOWN)
a8b5d014 1359 {
1360 validate_change (insn, &XEXP (x, 0),
7da6ea0c 1361 gen_rtx_fmt_ee (reversed_code,
a8b5d014 1362 GET_MODE (comp), XEXP (comp, 0),
1363 XEXP (comp, 1)),
1364 1);
82880dfd 1365 return 1;
a8b5d014 1366 }
7113a566 1367
a8b5d014 1368 tem = XEXP (x, 1);
1369 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
1370 validate_change (insn, &XEXP (x, 2), tem, 1);
82880dfd 1371 return 1;
a8b5d014 1372 }
ba08b7e7 1373 else
a8b5d014 1374 return 0;
a8b5d014 1375}
1376
1377/* Invert the condition of the jump JUMP, and make it jump to label
1378 NLABEL instead of where it jumps now. Accrue changes into the
1379 change group. Return false if we didn't see how to perform the
1380 inversion and redirection. */
1381
1382int
3ad4992f 1383invert_jump_1 (rtx jump, rtx nlabel)
a8b5d014 1384{
82880dfd 1385 rtx x = pc_set (jump);
a8b5d014 1386 int ochanges;
a53ff4c1 1387 int ok;
a8b5d014 1388
1389 ochanges = num_validated_changes ();
a53ff4c1 1390 gcc_assert (x);
1391 ok = invert_exp_1 (SET_SRC (x), jump);
1392 gcc_assert (ok);
1393
a8b5d014 1394 if (num_validated_changes () == ochanges)
1395 return 0;
1396
50f46d50 1397 /* redirect_jump_1 will fail of nlabel == olabel, and the current use is
1398 in Pmode, so checking this is not merely an optimization. */
1399 return nlabel == JUMP_LABEL (jump) || redirect_jump_1 (jump, nlabel);
a8b5d014 1400}
1401
1402/* Invert the condition of the jump JUMP, and make it jump to label
1403 NLABEL instead of where it jumps now. Return true if successful. */
1404
1405int
3ad4992f 1406invert_jump (rtx jump, rtx nlabel, int delete_unused)
a8b5d014 1407{
82880dfd 1408 rtx olabel = JUMP_LABEL (jump);
a8b5d014 1409
82880dfd 1410 if (invert_jump_1 (jump, nlabel) && apply_change_group ())
a8b5d014 1411 {
82880dfd 1412 redirect_jump_2 (jump, olabel, nlabel, delete_unused, 1);
a8b5d014 1413 return 1;
1414 }
82880dfd 1415 cancel_changes (0);
a8b5d014 1416 return 0;
1417}
1418
5924de0b 1419\f
1420/* Like rtx_equal_p except that it considers two REGs as equal
6c60c295 1421 if they renumber to the same value and considers two commutative
1422 operations to be the same if the order of the operands has been
280566a7 1423 reversed. */
5924de0b 1424
1425int
a9f1838b 1426rtx_renumbered_equal_p (const_rtx x, const_rtx y)
5924de0b 1427{
19cb6b50 1428 int i;
52d07779 1429 const enum rtx_code code = GET_CODE (x);
19cb6b50 1430 const char *fmt;
7113a566 1431
5924de0b 1432 if (x == y)
1433 return 1;
6c60c295 1434
8ad4c111 1435 if ((code == REG || (code == SUBREG && REG_P (SUBREG_REG (x))))
1436 && (REG_P (y) || (GET_CODE (y) == SUBREG
1437 && REG_P (SUBREG_REG (y)))))
5924de0b 1438 {
6c60c295 1439 int reg_x = -1, reg_y = -1;
701e46d0 1440 int byte_x = 0, byte_y = 0;
5924de0b 1441
1442 if (GET_MODE (x) != GET_MODE (y))
1443 return 0;
1444
1445 /* If we haven't done any renumbering, don't
1446 make any assumptions. */
1447 if (reg_renumber == 0)
1448 return rtx_equal_p (x, y);
1449
1450 if (code == SUBREG)
1451 {
6c60c295 1452 reg_x = REGNO (SUBREG_REG (x));
701e46d0 1453 byte_x = SUBREG_BYTE (x);
6c60c295 1454
1455 if (reg_renumber[reg_x] >= 0)
1456 {
701e46d0 1457 reg_x = subreg_regno_offset (reg_renumber[reg_x],
1458 GET_MODE (SUBREG_REG (x)),
1459 byte_x,
1460 GET_MODE (x));
1461 byte_x = 0;
6c60c295 1462 }
5924de0b 1463 }
1464 else
1465 {
6c60c295 1466 reg_x = REGNO (x);
1467 if (reg_renumber[reg_x] >= 0)
1468 reg_x = reg_renumber[reg_x];
5924de0b 1469 }
6c60c295 1470
5924de0b 1471 if (GET_CODE (y) == SUBREG)
1472 {
6c60c295 1473 reg_y = REGNO (SUBREG_REG (y));
701e46d0 1474 byte_y = SUBREG_BYTE (y);
6c60c295 1475
1476 if (reg_renumber[reg_y] >= 0)
1477 {
701e46d0 1478 reg_y = subreg_regno_offset (reg_renumber[reg_y],
1479 GET_MODE (SUBREG_REG (y)),
1480 byte_y,
1481 GET_MODE (y));
1482 byte_y = 0;
6c60c295 1483 }
5924de0b 1484 }
1485 else
1486 {
6c60c295 1487 reg_y = REGNO (y);
1488 if (reg_renumber[reg_y] >= 0)
1489 reg_y = reg_renumber[reg_y];
5924de0b 1490 }
6c60c295 1491
701e46d0 1492 return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
5924de0b 1493 }
6c60c295 1494
7113a566 1495 /* Now we have disposed of all the cases
5924de0b 1496 in which different rtx codes can match. */
1497 if (code != GET_CODE (y))
1498 return 0;
6c60c295 1499
5924de0b 1500 switch (code)
1501 {
1502 case PC:
1503 case CC0:
1504 case ADDR_VEC:
1505 case ADDR_DIFF_VEC:
5924de0b 1506 case CONST_INT:
d618034b 1507 case CONST_DOUBLE:
70b1bccd 1508 return 0;
5924de0b 1509
1510 case LABEL_REF:
f08cae9d 1511 /* We can't assume nonlocal labels have their following insns yet. */
1512 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
1513 return XEXP (x, 0) == XEXP (y, 0);
6c60c295 1514
5924de0b 1515 /* Two label-refs are equivalent if they point at labels
1516 in the same position in the instruction stream. */
1517 return (next_real_insn (XEXP (x, 0))
1518 == next_real_insn (XEXP (y, 0)));
1519
1520 case SYMBOL_REF:
1521 return XSTR (x, 0) == XSTR (y, 0);
0dbd1c74 1522
fc41ccae 1523 case CODE_LABEL:
1524 /* If we didn't match EQ equality above, they aren't the same. */
1525 return 0;
1526
0dbd1c74 1527 default:
1528 break;
5924de0b 1529 }
1530
1531 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
1532
1533 if (GET_MODE (x) != GET_MODE (y))
1534 return 0;
1535
6c60c295 1536 /* For commutative operations, the RTX match if the operand match in any
280566a7 1537 order. Also handle the simple binary and unary cases without a loop. */
1538 if (targetm.commutative_p (x, UNKNOWN))
6c60c295 1539 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1540 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
1541 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
1542 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
6720e96c 1543 else if (NON_COMMUTATIVE_P (x))
6c60c295 1544 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
1545 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
6720e96c 1546 else if (UNARY_P (x))
6c60c295 1547 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
1548
5924de0b 1549 /* Compare the elements. If any pair of corresponding elements
1550 fail to match, return 0 for the whole things. */
1551
1552 fmt = GET_RTX_FORMAT (code);
1553 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1554 {
19cb6b50 1555 int j;
5924de0b 1556 switch (fmt[i])
1557 {
1bb04728 1558 case 'w':
1559 if (XWINT (x, i) != XWINT (y, i))
1560 return 0;
1561 break;
1562
5924de0b 1563 case 'i':
1564 if (XINT (x, i) != XINT (y, i))
1565 return 0;
1566 break;
1567
a0d79d69 1568 case 't':
1569 if (XTREE (x, i) != XTREE (y, i))
1570 return 0;
1571 break;
1572
5924de0b 1573 case 's':
1574 if (strcmp (XSTR (x, i), XSTR (y, i)))
1575 return 0;
1576 break;
1577
1578 case 'e':
1579 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
1580 return 0;
1581 break;
1582
1583 case 'u':
1584 if (XEXP (x, i) != XEXP (y, i))
1585 return 0;
b4b174c3 1586 /* Fall through. */
5924de0b 1587 case '0':
1588 break;
1589
1590 case 'E':
1591 if (XVECLEN (x, i) != XVECLEN (y, i))
1592 return 0;
1593 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1594 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
1595 return 0;
1596 break;
1597
1598 default:
a53ff4c1 1599 gcc_unreachable ();
5924de0b 1600 }
1601 }
1602 return 1;
1603}
1604\f
1605/* If X is a hard register or equivalent to one or a subregister of one,
1606 return the hard register number. If X is a pseudo register that was not
1607 assigned a hard register, return the pseudo register number. Otherwise,
1608 return -1. Any rtx is valid for X. */
1609
1610int
52d07779 1611true_regnum (const_rtx x)
5924de0b 1612{
8ad4c111 1613 if (REG_P (x))
5924de0b 1614 {
1615 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
1616 return reg_renumber[REGNO (x)];
1617 return REGNO (x);
1618 }
1619 if (GET_CODE (x) == SUBREG)
1620 {
1621 int base = true_regnum (SUBREG_REG (x));
90489f58 1622 if (base >= 0
1623 && base < FIRST_PSEUDO_REGISTER
1624 && subreg_offset_representable_p (REGNO (SUBREG_REG (x)),
1625 GET_MODE (SUBREG_REG (x)),
1626 SUBREG_BYTE (x), GET_MODE (x)))
701e46d0 1627 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
1628 GET_MODE (SUBREG_REG (x)),
1629 SUBREG_BYTE (x), GET_MODE (x));
5924de0b 1630 }
1631 return -1;
1632}
b627bae7 1633
1634/* Return regno of the register REG and handle subregs too. */
1635unsigned int
52d07779 1636reg_or_subregno (const_rtx reg)
b627bae7 1637{
b627bae7 1638 if (GET_CODE (reg) == SUBREG)
a53ff4c1 1639 reg = SUBREG_REG (reg);
1640 gcc_assert (REG_P (reg));
1641 return REGNO (reg);
b627bae7 1642}