]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/jump.c
Merge basic-improvements-branch to trunk
[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
080f56ab 3 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
5924de0b 4
f12b58b3 5This file is part of GCC.
5924de0b 6
f12b58b3 7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
5924de0b 11
f12b58b3 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
5924de0b 16
17You should have received a copy of the GNU General Public License
f12b58b3 18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
5924de0b 21
fc4eaab7 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.
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
5924de0b 34 The subroutines delete_insn, redirect_jump, and invert_jump are used
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"
ce1fd7fc 53#include "toplev.h"
75eb327c 54#include "reload.h"
13488c51 55#include "predict.h"
5924de0b 56
5924de0b 57/* Optimize jump y; x: ... y: jumpif... x?
58 Don't know if it is worth bothering with. */
59/* Optimize two cases of conditional jump to conditional jump?
60 This can never delete any instruction or make anything dead,
61 or even change what is live at any point.
62 So perhaps let combiner do it. */
63
805e22b2 64static void init_label_info PARAMS ((rtx));
bf73fcf4 65static void mark_all_labels PARAMS ((rtx));
38b9004f 66static int duplicate_loop_exit_test PARAMS ((rtx));
38b9004f 67static void delete_computation PARAMS ((rtx));
a8b5d014 68static void redirect_exp_1 PARAMS ((rtx *, rtx, rtx, rtx));
ba08b7e7 69static int redirect_exp PARAMS ((rtx, rtx, rtx));
70static void invert_exp_1 PARAMS ((rtx));
71static int invert_exp PARAMS ((rtx));
38b9004f 72static int returnjump_p_1 PARAMS ((rtx *, void *));
73static void delete_prior_computation PARAMS ((rtx, rtx));
60ecc450 74\f
8b946ced 75/* Alternate entry into the jump optimizer. This entry point only rebuilds
76 the JUMP_LABEL field in jumping insns and REG_LABEL notes in non-jumping
77 instructions. */
78void
79rebuild_jump_labels (f)
80 rtx f;
81{
19cb6b50 82 rtx insn;
5924de0b 83
805e22b2 84 init_label_info (f);
bf73fcf4 85 mark_all_labels (f);
5924de0b 86
cbd914e1 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. */
5924de0b 90
91 for (insn = forced_labels; insn; insn = XEXP (insn, 1))
cbd914e1 92 if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL)
93 LABEL_NUSES (XEXP (insn, 0))++;
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 */
104void
105cleanup_barriers ()
106{
107 rtx insn, next, prev;
108 for (insn = get_insns (); insn; insn = next)
109 {
110 next = NEXT_INSN (insn);
111 if (GET_CODE (insn) == BARRIER)
112 {
113 prev = prev_nonnote_insn (insn);
114 if (GET_CODE (prev) == BARRIER)
115 delete_barrier (insn);
116 else if (prev != PREV_INSN (insn))
117 reorder_insns (insn, insn, prev);
118 }
119 }
120}
121\f
fc4eaab7 122void
123copy_loop_headers (f)
124 rtx f;
125{
19cb6b50 126 rtx insn, next;
5924de0b 127 /* Now iterate optimizing jumps until nothing changes over one pass. */
fc4eaab7 128 for (insn = f; insn; insn = next)
5924de0b 129 {
fc4eaab7 130 rtx temp, temp1;
5924de0b 131
fc4eaab7 132 next = NEXT_INSN (insn);
7014838c 133
fc4eaab7 134 /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional
135 jump. Try to optimize by duplicating the loop exit test if so.
136 This is only safe immediately after regscan, because it uses
137 the values of regno_first_uid and regno_last_uid. */
138 if (GET_CODE (insn) == NOTE
139 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
140 && (temp1 = next_nonnote_insn (insn)) != 0
141 && any_uncondjump_p (temp1) && onlyjump_p (temp1))
142 {
143 temp = PREV_INSN (insn);
144 if (duplicate_loop_exit_test (insn))
5924de0b 145 {
fc4eaab7 146 next = NEXT_INSN (temp);
5924de0b 147 }
5924de0b 148 }
5924de0b 149 }
fc4eaab7 150}
5924de0b 151
fc4eaab7 152void
153purge_line_number_notes (f)
154 rtx f;
155{
156 rtx last_note = 0;
157 rtx insn;
5924de0b 158 /* Delete extraneous line number notes.
159 Note that two consecutive notes for different lines are not really
160 extraneous. There should be some indication where that line belonged,
161 even if it became empty. */
162
fc4eaab7 163 for (insn = f; insn; insn = NEXT_INSN (insn))
164 if (GET_CODE (insn) == NOTE)
165 {
166 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
167 /* Any previous line note was for the prologue; gdb wants a new
168 note after the prologue even if it is for the same line. */
169 last_note = NULL_RTX;
170 else if (NOTE_LINE_NUMBER (insn) >= 0)
171 {
172 /* Delete this note if it is identical to previous note. */
173 if (last_note
174 && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
175 && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
176 {
e4bf866d 177 delete_related_insns (insn);
fc4eaab7 178 continue;
179 }
5924de0b 180
fc4eaab7 181 last_note = insn;
182 }
183 }
e8d75e01 184}
185\f
186/* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
187 notes whose labels don't occur in the insn any more. Returns the
188 largest INSN_UID found. */
805e22b2 189static void
e8d75e01 190init_label_info (f)
191 rtx f;
192{
e8d75e01 193 rtx insn;
194
195 for (insn = f; insn; insn = NEXT_INSN (insn))
805e22b2 196 if (GET_CODE (insn) == CODE_LABEL)
197 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
198 else if (GET_CODE (insn) == JUMP_INSN)
199 JUMP_LABEL (insn) = 0;
200 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
201 {
202 rtx note, next;
e8d75e01 203
805e22b2 204 for (note = REG_NOTES (insn); note; note = next)
205 {
206 next = XEXP (note, 1);
207 if (REG_NOTE_KIND (note) == REG_LABEL
208 && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
209 remove_note (insn, note);
210 }
211 }
e8d75e01 212}
213
e8d75e01 214/* Mark the label each jump jumps to.
fc4eaab7 215 Combine consecutive labels, and count uses of labels. */
e8d75e01 216
217static void
bf73fcf4 218mark_all_labels (f)
e8d75e01 219 rtx f;
e8d75e01 220{
221 rtx insn;
222
223 for (insn = f; insn; insn = NEXT_INSN (insn))
9204e736 224 if (INSN_P (insn))
e8d75e01 225 {
0e3150ce 226 if (GET_CODE (insn) == CALL_INSN
227 && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
228 {
bf73fcf4 229 mark_all_labels (XEXP (PATTERN (insn), 0));
230 mark_all_labels (XEXP (PATTERN (insn), 1));
231 mark_all_labels (XEXP (PATTERN (insn), 2));
af29e037 232
233 /* Canonicalize the tail recursion label attached to the
234 CALL_PLACEHOLDER insn. */
235 if (XEXP (PATTERN (insn), 3))
236 {
237 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
238 XEXP (PATTERN (insn), 3));
bf73fcf4 239 mark_jump_label (label_ref, insn, 0);
af29e037 240 XEXP (PATTERN (insn), 3) = XEXP (label_ref, 0);
241 }
242
0e3150ce 243 continue;
244 }
7113a566 245
bf73fcf4 246 mark_jump_label (PATTERN (insn), insn, 0);
e8d75e01 247 if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
248 {
d3ff0f75 249 /* When we know the LABEL_REF contained in a REG used in
250 an indirect jump, we'll have a REG_LABEL note so that
251 flow can tell where it's going. */
252 if (JUMP_LABEL (insn) == 0)
253 {
254 rtx label_note = find_reg_note (insn, REG_LABEL, NULL_RTX);
255 if (label_note)
256 {
257 /* But a LABEL_REF around the REG_LABEL note, so
258 that we can canonicalize it. */
259 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
260 XEXP (label_note, 0));
261
bf73fcf4 262 mark_jump_label (label_ref, insn, 0);
d3ff0f75 263 XEXP (label_note, 0) = XEXP (label_ref, 0);
264 JUMP_LABEL (insn) = XEXP (label_note, 0);
265 }
266 }
e8d75e01 267 }
268 }
269}
270
5924de0b 271/* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional
272 jump. Assume that this unconditional jump is to the exit test code. If
273 the code is sufficiently simple, make a copy of it before INSN,
274 followed by a jump to the exit of the loop. Then delete the unconditional
275 jump after INSN.
276
5924de0b 277 Return 1 if we made the change, else 0.
278
279 This is only safe immediately after a regscan pass because it uses the
280 values of regno_first_uid and regno_last_uid. */
281
282static int
283duplicate_loop_exit_test (loop_start)
284 rtx loop_start;
285{
3a348c93 286 rtx insn, set, reg, p, link;
4e717234 287 rtx copy = 0, first_copy = 0;
5924de0b 288 int num_insns = 0;
289 rtx exitcode = NEXT_INSN (JUMP_LABEL (next_nonnote_insn (loop_start)));
290 rtx lastexit;
291 int max_reg = max_reg_num ();
292 rtx *reg_map = 0;
ea918419 293 rtx loop_pre_header_label;
5924de0b 294
295 /* Scan the exit code. We do not perform this optimization if any insn:
296
297 is a CALL_INSN
298 is a CODE_LABEL
299 has a REG_RETVAL or REG_LIBCALL note (hard to adjust)
300 is a NOTE_INSN_LOOP_BEG because this means we have a nested loop
17b1950c 301
302 We also do not do this if we find an insn with ASM_OPERANDS. While
303 this restriction should not be necessary, copying an insn with
304 ASM_OPERANDS can confuse asm_noperands in some cases.
5924de0b 305
306 Also, don't do this if the exit code is more than 20 insns. */
307
308 for (insn = exitcode;
309 insn
310 && ! (GET_CODE (insn) == NOTE
311 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
312 insn = NEXT_INSN (insn))
313 {
314 switch (GET_CODE (insn))
315 {
316 case CODE_LABEL:
317 case CALL_INSN:
318 return 0;
319 case NOTE:
ec6be638 320
321 if (optimize < 2
322 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
323 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
324 /* If we were to duplicate this code, we would not move
325 the BLOCK notes, and so debugging the moved code would
326 be difficult. Thus, we only move the code with -O2 or
327 higher. */
328 return 0;
329
5924de0b 330 break;
331 case JUMP_INSN:
332 case INSN:
7665c376 333 /* The code below would grossly mishandle REG_WAS_0 notes,
334 so get rid of them here. */
335 while ((p = find_reg_note (insn, REG_WAS_0, NULL_RTX)) != 0)
336 remove_note (insn, p);
5924de0b 337 if (++num_insns > 20
1bb04728 338 || find_reg_note (insn, REG_RETVAL, NULL_RTX)
928d57e3 339 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
5924de0b 340 return 0;
341 break;
0dbd1c74 342 default:
343 break;
5924de0b 344 }
345 }
346
347 /* Unless INSN is zero, we can do the optimization. */
348 if (insn == 0)
349 return 0;
350
351 lastexit = insn;
352
353 /* See if any insn sets a register only used in the loop exit code and
354 not a user variable. If so, replace it with a new register. */
355 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
356 if (GET_CODE (insn) == INSN
357 && (set = single_set (insn)) != 0
3a348c93 358 && ((reg = SET_DEST (set), GET_CODE (reg) == REG)
359 || (GET_CODE (reg) == SUBREG
360 && (reg = SUBREG_REG (reg), GET_CODE (reg) == REG)))
361 && REGNO (reg) >= FIRST_PSEUDO_REGISTER
394685a4 362 && REGNO_FIRST_UID (REGNO (reg)) == INSN_UID (insn))
5924de0b 363 {
364 for (p = NEXT_INSN (insn); p != lastexit; p = NEXT_INSN (p))
394685a4 365 if (REGNO_LAST_UID (REGNO (reg)) == INSN_UID (p))
5924de0b 366 break;
367
368 if (p != lastexit)
369 {
370 /* We can do the replacement. Allocate reg_map if this is the
371 first replacement we found. */
372 if (reg_map == 0)
8b861be4 373 reg_map = (rtx *) xcalloc (max_reg, sizeof (rtx));
5924de0b 374
3a348c93 375 REG_LOOP_TEST_P (reg) = 1;
5924de0b 376
3a348c93 377 reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg));
5924de0b 378 }
379 }
ea918419 380 loop_pre_header_label = gen_label_rtx ();
5924de0b 381
382 /* Now copy each insn. */
383 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
4e717234 384 {
385 switch (GET_CODE (insn))
386 {
387 case BARRIER:
388 copy = emit_barrier_before (loop_start);
389 break;
390 case NOTE:
391 /* Only copy line-number notes. */
392 if (NOTE_LINE_NUMBER (insn) >= 0)
393 {
394 copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
395 NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
396 }
397 break;
7113a566 398
4e717234 399 case INSN:
928d57e3 400 copy = emit_insn_before (copy_insn (PATTERN (insn)), loop_start);
4e717234 401 if (reg_map)
402 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
7113a566 403
bf73fcf4 404 mark_jump_label (PATTERN (copy), copy, 0);
ab87d1bc 405 INSN_SCOPE (copy) = INSN_SCOPE (insn);
7113a566 406
4e717234 407 /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
408 make them. */
409 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
410 if (REG_NOTE_KIND (link) != REG_LABEL)
74b0991d 411 {
412 if (GET_CODE (link) == EXPR_LIST)
413 REG_NOTES (copy)
414 = copy_insn_1 (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
415 XEXP (link, 0),
416 REG_NOTES (copy)));
417 else
418 REG_NOTES (copy)
419 = copy_insn_1 (gen_rtx_INSN_LIST (REG_NOTE_KIND (link),
420 XEXP (link, 0),
421 REG_NOTES (copy)));
422 }
423
4e717234 424 if (reg_map && REG_NOTES (copy))
425 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
426 break;
7113a566 427
4e717234 428 case JUMP_INSN:
7113a566 429 copy = emit_jump_insn_before (copy_insn (PATTERN (insn)),
430 loop_start);
ab87d1bc 431 INSN_SCOPE (copy) = INSN_SCOPE (insn);
4e717234 432 if (reg_map)
433 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
bf73fcf4 434 mark_jump_label (PATTERN (copy), copy, 0);
4e717234 435 if (REG_NOTES (insn))
436 {
928d57e3 437 REG_NOTES (copy) = copy_insn_1 (REG_NOTES (insn));
4e717234 438 if (reg_map)
439 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
440 }
7113a566 441
13488c51 442 /* Predict conditional jump that do make loop looping as taken.
443 Other jumps are probably exit conditions, so predict
444 them as untaken. */
445 if (any_condjump_p (copy))
446 {
447 rtx label = JUMP_LABEL (copy);
448 if (label)
449 {
4361b500 450 /* The jump_insn after loop_start should be followed
451 by barrier and loopback label. */
452 if (prev_nonnote_insn (label)
ea918419 453 && (prev_nonnote_insn (prev_nonnote_insn (label))
454 == next_nonnote_insn (loop_start)))
455 {
456 predict_insn_def (copy, PRED_LOOP_HEADER, TAKEN);
457 /* To keep pre-header, we need to redirect all loop
458 entrances before the LOOP_BEG note. */
459 redirect_jump (copy, loop_pre_header_label, 0);
460 }
13488c51 461 else
462 predict_insn_def (copy, PRED_LOOP_HEADER, NOT_TAKEN);
463 }
464 }
4e717234 465 break;
7113a566 466
4e717234 467 default:
468 abort ();
469 }
5924de0b 470
4e717234 471 /* Record the first insn we copied. We need it so that we can
472 scan the copied insns for new pseudo registers. */
473 if (! first_copy)
474 first_copy = copy;
475 }
5924de0b 476
477 /* Now clean up by emitting a jump to the end label and deleting the jump
478 at the start of the loop. */
b8778d98 479 if (! copy || GET_CODE (copy) != BARRIER)
5924de0b 480 {
481 copy = emit_jump_insn_before (gen_jump (get_label_after (insn)),
482 loop_start);
4e717234 483
484 /* Record the first insn we copied. We need it so that we can
485 scan the copied insns for new pseudo registers. This may not
486 be strictly necessary since we should have copied at least one
487 insn above. But I am going to be safe. */
488 if (! first_copy)
489 first_copy = copy;
490
bf73fcf4 491 mark_jump_label (PATTERN (copy), copy, 0);
5924de0b 492 emit_barrier_before (loop_start);
493 }
494
ea918419 495 emit_label_before (loop_pre_header_label, loop_start);
496
4e717234 497 /* Now scan from the first insn we copied to the last insn we copied
498 (copy) for new pseudo registers. Do this after the code to jump to
499 the end label since that might create a new pseudo too. */
500 reg_scan_update (first_copy, copy, max_reg);
501
5924de0b 502 /* Mark the exit code as the virtual top of the converted loop. */
503 emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode);
504
e4bf866d 505 delete_related_insns (next_nonnote_insn (loop_start));
7113a566 506
8b861be4 507 /* Clean up. */
508 if (reg_map)
509 free (reg_map);
92d3c3ad 510
5924de0b 511 return 1;
512}
513\f
74b0991d 514/* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, loop-end,
3612339f 515 notes between START and END out before START. START and END may be such
516 notes. Returns the values of the new starting and ending insns, which
87dc0300 517 may be different if the original ones were such notes.
518 Return true if there were only such notes and no real instructions. */
5924de0b 519
87dc0300 520bool
3612339f 521squeeze_notes (startp, endp)
522 rtx* startp;
523 rtx* endp;
5924de0b 524{
3612339f 525 rtx start = *startp;
526 rtx end = *endp;
527
5924de0b 528 rtx insn;
529 rtx next;
3612339f 530 rtx last = NULL;
531 rtx past_end = NEXT_INSN (end);
5924de0b 532
3612339f 533 for (insn = start; insn != past_end; insn = next)
5924de0b 534 {
535 next = NEXT_INSN (insn);
536 if (GET_CODE (insn) == NOTE
537 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
538 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
539 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
540 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
541 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
a196d160 542 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
5924de0b 543 {
d2d45541 544 if (insn == start)
545 start = next;
546 else
547 {
548 rtx prev = PREV_INSN (insn);
549 PREV_INSN (insn) = PREV_INSN (start);
550 NEXT_INSN (insn) = start;
551 NEXT_INSN (PREV_INSN (insn)) = insn;
552 PREV_INSN (NEXT_INSN (insn)) = insn;
553 NEXT_INSN (prev) = next;
554 PREV_INSN (next) = prev;
555 }
5924de0b 556 }
3612339f 557 else
558 last = insn;
5924de0b 559 }
d2d45541 560
87dc0300 561 /* There were no real instructions. */
3612339f 562 if (start == past_end)
87dc0300 563 return true;
3612339f 564
565 end = last;
566
567 *startp = start;
568 *endp = end;
87dc0300 569 return false;
5924de0b 570}
571\f
5924de0b 572/* Return the label before INSN, or put a new label there. */
573
574rtx
575get_label_before (insn)
576 rtx insn;
577{
578 rtx label;
579
580 /* Find an existing label at this point
581 or make a new one if there is none. */
582 label = prev_nonnote_insn (insn);
583
584 if (label == 0 || GET_CODE (label) != CODE_LABEL)
585 {
586 rtx prev = PREV_INSN (insn);
587
5924de0b 588 label = gen_label_rtx ();
589 emit_label_after (label, prev);
590 LABEL_NUSES (label) = 0;
591 }
592 return label;
593}
594
595/* Return the label after INSN, or put a new label there. */
596
597rtx
598get_label_after (insn)
599 rtx insn;
600{
601 rtx label;
602
603 /* Find an existing label at this point
604 or make a new one if there is none. */
605 label = next_nonnote_insn (insn);
606
607 if (label == 0 || GET_CODE (label) != CODE_LABEL)
608 {
5924de0b 609 label = gen_label_rtx ();
610 emit_label_after (label, insn);
611 LABEL_NUSES (label) = 0;
612 }
613 return label;
614}
615\f
fa8b3d85 616/* Given a comparison (CODE ARG0 ARG1), inside an insn, INSN, return a code
8e98892d 617 of reversed comparison if it is possible to do so. Otherwise return UNKNOWN.
618 UNKNOWN may be returned in case we are having CC_MODE compare and we don't
619 know whether it's source is floating point or integer comparison. Machine
620 description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
621 to help this function avoid overhead in these cases. */
622enum rtx_code
623reversed_comparison_code_parts (code, arg0, arg1, insn)
624 rtx insn, arg0, arg1;
625 enum rtx_code code;
5924de0b 626{
8e98892d 627 enum machine_mode mode;
5924de0b 628
629 /* If this is not actually a comparison, we can't reverse it. */
8e98892d 630 if (GET_RTX_CLASS (code) != '<')
631 return UNKNOWN;
632
633 mode = GET_MODE (arg0);
634 if (mode == VOIDmode)
635 mode = GET_MODE (arg1);
636
637 /* First see if machine description supply us way to reverse the comparison.
638 Give it priority over everything else to allow machine description to do
639 tricks. */
640#ifdef REVERSIBLE_CC_MODE
0ec244e1 641 if (GET_MODE_CLASS (mode) == MODE_CC
8e98892d 642 && REVERSIBLE_CC_MODE (mode))
643 {
644#ifdef REVERSE_CONDITION
85fc0ad1 645 return REVERSE_CONDITION (code, mode);
8e98892d 646#endif
85fc0ad1 647 return reverse_condition (code);
648 }
8e98892d 649#endif
5924de0b 650
fa8b3d85 651 /* Try a few special cases based on the comparison code. */
8e98892d 652 switch (code)
653 {
85fc0ad1 654 case GEU:
655 case GTU:
656 case LEU:
657 case LTU:
658 case NE:
659 case EQ:
660 /* It is always safe to reverse EQ and NE, even for the floating
661 point. Similary the unsigned comparisons are never used for
662 floating point so we can reverse them in the default way. */
663 return reverse_condition (code);
664 case ORDERED:
665 case UNORDERED:
666 case LTGT:
667 case UNEQ:
668 /* In case we already see unordered comparison, we can be sure to
669 be dealing with floating point so we don't need any more tests. */
670 return reverse_condition_maybe_unordered (code);
671 case UNLT:
672 case UNLE:
673 case UNGT:
674 case UNGE:
675 /* We don't have safe way to reverse these yet. */
676 return UNKNOWN;
677 default:
678 break;
8e98892d 679 }
680
8e98892d 681 if (GET_MODE_CLASS (mode) == MODE_CC
5924de0b 682#ifdef HAVE_cc0
683 || arg0 == cc0_rtx
684#endif
685 )
686 {
8e98892d 687 rtx prev;
688 /* Try to search for the comparison to determine the real mode.
689 This code is expensive, but with sane machine description it
690 will be never used, since REVERSIBLE_CC_MODE will return true
691 in all cases. */
111f2389 692 if (! insn)
8e98892d 693 return UNKNOWN;
7113a566 694
7014838c 695 for (prev = prev_nonnote_insn (insn);
696 prev != 0 && GET_CODE (prev) != CODE_LABEL;
697 prev = prev_nonnote_insn (prev))
8e98892d 698 {
699 rtx set = set_of (arg0, prev);
700 if (set && GET_CODE (set) == SET
701 && rtx_equal_p (SET_DEST (set), arg0))
702 {
703 rtx src = SET_SRC (set);
5924de0b 704
8e98892d 705 if (GET_CODE (src) == COMPARE)
706 {
707 rtx comparison = src;
708 arg0 = XEXP (src, 0);
709 mode = GET_MODE (arg0);
710 if (mode == VOIDmode)
711 mode = GET_MODE (XEXP (comparison, 1));
712 break;
713 }
dd5b4b36 714 /* We can get past reg-reg moves. This may be useful for model
8e98892d 715 of i387 comparisons that first move flag registers around. */
716 if (REG_P (src))
717 {
718 arg0 = src;
719 continue;
720 }
721 }
722 /* If register is clobbered in some ununderstandable way,
723 give up. */
724 if (set)
725 return UNKNOWN;
726 }
5924de0b 727 }
728
920d0fb5 729 /* Test for an integer condition, or a floating-point comparison
730 in which NaNs can be ignored. */
8e98892d 731 if (GET_CODE (arg0) == CONST_INT
732 || (GET_MODE (arg0) != VOIDmode
733 && GET_MODE_CLASS (mode) != MODE_CC
920d0fb5 734 && !HONOR_NANS (mode)))
8e98892d 735 return reverse_condition (code);
736
737 return UNKNOWN;
738}
739
740/* An wrapper around the previous function to take COMPARISON as rtx
741 expression. This simplifies many callers. */
742enum rtx_code
743reversed_comparison_code (comparison, insn)
744 rtx comparison, insn;
745{
746 if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
747 return UNKNOWN;
748 return reversed_comparison_code_parts (GET_CODE (comparison),
749 XEXP (comparison, 0),
750 XEXP (comparison, 1), insn);
751}
752\f
a4110d9a 753/* Given an rtx-code for a comparison, return the code for the negated
754 comparison. If no such code exists, return UNKNOWN.
755
756 WATCH OUT! reverse_condition is not safe to use on a jump that might
757 be acting on the results of an IEEE floating point comparison, because
7113a566 758 of the special treatment of non-signaling nans in comparisons.
8e98892d 759 Use reversed_comparison_code instead. */
5924de0b 760
761enum rtx_code
762reverse_condition (code)
763 enum rtx_code code;
764{
765 switch (code)
766 {
767 case EQ:
768 return NE;
5924de0b 769 case NE:
770 return EQ;
5924de0b 771 case GT:
772 return LE;
5924de0b 773 case GE:
774 return LT;
5924de0b 775 case LT:
776 return GE;
5924de0b 777 case LE:
778 return GT;
5924de0b 779 case GTU:
780 return LEU;
5924de0b 781 case GEU:
782 return LTU;
5924de0b 783 case LTU:
784 return GEU;
5924de0b 785 case LEU:
786 return GTU;
a4110d9a 787 case UNORDERED:
788 return ORDERED;
789 case ORDERED:
790 return UNORDERED;
791
792 case UNLT:
793 case UNLE:
794 case UNGT:
795 case UNGE:
796 case UNEQ:
79777bad 797 case LTGT:
a4110d9a 798 return UNKNOWN;
5924de0b 799
800 default:
801 abort ();
5924de0b 802 }
803}
804
79777bad 805/* Similar, but we're allowed to generate unordered comparisons, which
806 makes it safe for IEEE floating-point. Of course, we have to recognize
807 that the target will support them too... */
808
809enum rtx_code
810reverse_condition_maybe_unordered (code)
811 enum rtx_code code;
812{
79777bad 813 switch (code)
814 {
815 case EQ:
816 return NE;
817 case NE:
818 return EQ;
819 case GT:
820 return UNLE;
821 case GE:
822 return UNLT;
823 case LT:
824 return UNGE;
825 case LE:
826 return UNGT;
827 case LTGT:
828 return UNEQ;
79777bad 829 case UNORDERED:
830 return ORDERED;
831 case ORDERED:
832 return UNORDERED;
833 case UNLT:
834 return GE;
835 case UNLE:
836 return GT;
837 case UNGT:
838 return LE;
839 case UNGE:
840 return LT;
841 case UNEQ:
842 return LTGT;
843
844 default:
845 abort ();
846 }
847}
848
5924de0b 849/* Similar, but return the code when two operands of a comparison are swapped.
850 This IS safe for IEEE floating-point. */
851
852enum rtx_code
853swap_condition (code)
854 enum rtx_code code;
855{
856 switch (code)
857 {
858 case EQ:
859 case NE:
a4110d9a 860 case UNORDERED:
861 case ORDERED:
862 case UNEQ:
79777bad 863 case LTGT:
5924de0b 864 return code;
865
866 case GT:
867 return LT;
5924de0b 868 case GE:
869 return LE;
5924de0b 870 case LT:
871 return GT;
5924de0b 872 case LE:
873 return GE;
5924de0b 874 case GTU:
875 return LTU;
5924de0b 876 case GEU:
877 return LEU;
5924de0b 878 case LTU:
879 return GTU;
5924de0b 880 case LEU:
881 return GEU;
a4110d9a 882 case UNLT:
883 return UNGT;
884 case UNLE:
885 return UNGE;
886 case UNGT:
887 return UNLT;
888 case UNGE:
889 return UNLE;
890
5924de0b 891 default:
892 abort ();
5924de0b 893 }
894}
895
896/* Given a comparison CODE, return the corresponding unsigned comparison.
897 If CODE is an equality comparison or already an unsigned comparison,
898 CODE is returned. */
899
900enum rtx_code
901unsigned_condition (code)
902 enum rtx_code code;
903{
904 switch (code)
905 {
906 case EQ:
907 case NE:
908 case GTU:
909 case GEU:
910 case LTU:
911 case LEU:
912 return code;
913
914 case GT:
915 return GTU;
5924de0b 916 case GE:
917 return GEU;
5924de0b 918 case LT:
919 return LTU;
5924de0b 920 case LE:
921 return LEU;
922
923 default:
924 abort ();
925 }
926}
927
928/* Similarly, return the signed version of a comparison. */
929
930enum rtx_code
931signed_condition (code)
932 enum rtx_code code;
933{
934 switch (code)
935 {
936 case EQ:
937 case NE:
938 case GT:
939 case GE:
940 case LT:
941 case LE:
942 return code;
943
944 case GTU:
945 return GT;
5924de0b 946 case GEU:
947 return GE;
5924de0b 948 case LTU:
949 return LT;
5924de0b 950 case LEU:
951 return LE;
952
953 default:
954 abort ();
955 }
956}
957\f
6ef828f9 958/* Return nonzero if CODE1 is more strict than CODE2, i.e., if the
5924de0b 959 truth of CODE1 implies the truth of CODE2. */
960
961int
962comparison_dominates_p (code1, code2)
963 enum rtx_code code1, code2;
964{
ca7744c6 965 /* UNKNOWN comparison codes can happen as a result of trying to revert
966 comparison codes.
967 They can't match anything, so we have to reject them here. */
968 if (code1 == UNKNOWN || code2 == UNKNOWN)
969 return 0;
970
5924de0b 971 if (code1 == code2)
972 return 1;
973
974 switch (code1)
975 {
5aa3f5e2 976 case UNEQ:
977 if (code2 == UNLE || code2 == UNGE)
978 return 1;
979 break;
980
5924de0b 981 case EQ:
79777bad 982 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU
983 || code2 == ORDERED)
5924de0b 984 return 1;
985 break;
986
5aa3f5e2 987 case UNLT:
988 if (code2 == UNLE || code2 == NE)
989 return 1;
990 break;
991
5924de0b 992 case LT:
5aa3f5e2 993 if (code2 == LE || code2 == NE || code2 == ORDERED || code2 == LTGT)
994 return 1;
995 break;
996
997 case UNGT:
998 if (code2 == UNGE || code2 == NE)
5924de0b 999 return 1;
1000 break;
1001
1002 case GT:
5aa3f5e2 1003 if (code2 == GE || code2 == NE || code2 == ORDERED || code2 == LTGT)
79777bad 1004 return 1;
1005 break;
1006
1007 case GE:
1008 case LE:
1009 if (code2 == ORDERED)
1010 return 1;
1011 break;
1012
1013 case LTGT:
1014 if (code2 == NE || code2 == ORDERED)
5924de0b 1015 return 1;
1016 break;
1017
1018 case LTU:
11088b43 1019 if (code2 == LEU || code2 == NE)
5924de0b 1020 return 1;
1021 break;
1022
1023 case GTU:
11088b43 1024 if (code2 == GEU || code2 == NE)
5924de0b 1025 return 1;
1026 break;
79777bad 1027
1028 case UNORDERED:
5aa3f5e2 1029 if (code2 == NE || code2 == UNEQ || code2 == UNLE || code2 == UNLT
1030 || code2 == UNGE || code2 == UNGT)
79777bad 1031 return 1;
1032 break;
7113a566 1033
0dbd1c74 1034 default:
1035 break;
5924de0b 1036 }
1037
1038 return 0;
1039}
1040\f
1041/* Return 1 if INSN is an unconditional jump and nothing else. */
1042
1043int
1044simplejump_p (insn)
1045 rtx insn;
1046{
8d472058 1047 return (GET_CODE (insn) == JUMP_INSN
1048 && GET_CODE (PATTERN (insn)) == SET
1049 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
1050 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
5924de0b 1051}
1052
1053/* Return nonzero if INSN is a (possibly) conditional jump
7113a566 1054 and nothing more.
1055
d670e794 1056 Use this function is deprecated, since we need to support combined
1057 branch and compare insns. Use any_condjump_p instead whenever possible. */
5924de0b 1058
1059int
1060condjump_p (insn)
1061 rtx insn;
1062{
19cb6b50 1063 rtx x = PATTERN (insn);
7014838c 1064
1065 if (GET_CODE (x) != SET
1066 || GET_CODE (SET_DEST (x)) != PC)
4fbe8fa7 1067 return 0;
7014838c 1068
1069 x = SET_SRC (x);
1070 if (GET_CODE (x) == LABEL_REF)
4fbe8fa7 1071 return 1;
7113a566 1072 else
1073 return (GET_CODE (x) == IF_THEN_ELSE
1074 && ((GET_CODE (XEXP (x, 2)) == PC
1075 && (GET_CODE (XEXP (x, 1)) == LABEL_REF
1076 || GET_CODE (XEXP (x, 1)) == RETURN))
1077 || (GET_CODE (XEXP (x, 1)) == PC
1078 && (GET_CODE (XEXP (x, 2)) == LABEL_REF
1079 || GET_CODE (XEXP (x, 2)) == RETURN))));
7014838c 1080
4fbe8fa7 1081 return 0;
1082}
1083
7014838c 1084/* Return nonzero if INSN is a (possibly) conditional jump inside a
3a941ad5 1085 PARALLEL.
7113a566 1086
d670e794 1087 Use this function is deprecated, since we need to support combined
1088 branch and compare insns. Use any_condjump_p instead whenever possible. */
4fbe8fa7 1089
1090int
1091condjump_in_parallel_p (insn)
1092 rtx insn;
1093{
19cb6b50 1094 rtx x = PATTERN (insn);
4fbe8fa7 1095
1096 if (GET_CODE (x) != PARALLEL)
1097 return 0;
1098 else
1099 x = XVECEXP (x, 0, 0);
1100
5924de0b 1101 if (GET_CODE (x) != SET)
1102 return 0;
1103 if (GET_CODE (SET_DEST (x)) != PC)
1104 return 0;
1105 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
1106 return 1;
1107 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
1108 return 0;
1109 if (XEXP (SET_SRC (x), 2) == pc_rtx
1110 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
1111 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
1112 return 1;
1113 if (XEXP (SET_SRC (x), 1) == pc_rtx
1114 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
1115 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
1116 return 1;
1117 return 0;
1118}
1119
d670e794 1120/* Return set of PC, otherwise NULL. */
1121
3a941ad5 1122rtx
1123pc_set (insn)
1124 rtx insn;
1125{
1126 rtx pat;
1127 if (GET_CODE (insn) != JUMP_INSN)
d670e794 1128 return NULL_RTX;
3a941ad5 1129 pat = PATTERN (insn);
d670e794 1130
1131 /* The set is allowed to appear either as the insn pattern or
1132 the first set in a PARALLEL. */
1133 if (GET_CODE (pat) == PARALLEL)
1134 pat = XVECEXP (pat, 0, 0);
3a941ad5 1135 if (GET_CODE (pat) == SET && GET_CODE (SET_DEST (pat)) == PC)
1136 return pat;
d670e794 1137
1138 return NULL_RTX;
3a941ad5 1139}
1140
d670e794 1141/* Return true when insn is an unconditional direct jump,
1142 possibly bundled inside a PARALLEL. */
1143
3a941ad5 1144int
1145any_uncondjump_p (insn)
1146 rtx insn;
1147{
1148 rtx x = pc_set (insn);
1149 if (!x)
1150 return 0;
1151 if (GET_CODE (SET_SRC (x)) != LABEL_REF)
1152 return 0;
1153 return 1;
1154}
1155
d670e794 1156/* Return true when insn is a conditional jump. This function works for
3a941ad5 1157 instructions containing PC sets in PARALLELs. The instruction may have
1158 various other effects so before removing the jump you must verify
9641f63c 1159 onlyjump_p.
3a941ad5 1160
d670e794 1161 Note that unlike condjump_p it returns false for unconditional jumps. */
1162
3a941ad5 1163int
1164any_condjump_p (insn)
1165 rtx insn;
1166{
1167 rtx x = pc_set (insn);
d670e794 1168 enum rtx_code a, b;
1169
3a941ad5 1170 if (!x)
1171 return 0;
d670e794 1172 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
1173 return 0;
3a941ad5 1174
d670e794 1175 a = GET_CODE (XEXP (SET_SRC (x), 1));
1176 b = GET_CODE (XEXP (SET_SRC (x), 2));
3a941ad5 1177
d670e794 1178 return ((b == PC && (a == LABEL_REF || a == RETURN))
7113a566 1179 || (a == PC && (b == LABEL_REF || b == RETURN)));
3a941ad5 1180}
1181
8f7b24f3 1182/* Return the label of a conditional jump. */
1183
1184rtx
1185condjump_label (insn)
1186 rtx insn;
1187{
d670e794 1188 rtx x = pc_set (insn);
8f7b24f3 1189
d670e794 1190 if (!x)
8f7b24f3 1191 return NULL_RTX;
1192 x = SET_SRC (x);
1193 if (GET_CODE (x) == LABEL_REF)
1194 return x;
1195 if (GET_CODE (x) != IF_THEN_ELSE)
1196 return NULL_RTX;
1197 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
1198 return XEXP (x, 1);
1199 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
1200 return XEXP (x, 2);
1201 return NULL_RTX;
1202}
1203
71caadc0 1204/* Return true if INSN is a (possibly conditional) return insn. */
1205
1206static int
1207returnjump_p_1 (loc, data)
1208 rtx *loc;
1209 void *data ATTRIBUTE_UNUSED;
1210{
1211 rtx x = *loc;
c3987c92 1212
1213 return x && (GET_CODE (x) == RETURN
1214 || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
71caadc0 1215}
1216
1217int
1218returnjump_p (insn)
1219 rtx insn;
1220{
cbd914e1 1221 if (GET_CODE (insn) != JUMP_INSN)
1222 return 0;
71caadc0 1223 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
1224}
1225
459e9193 1226/* Return true if INSN is a jump that only transfers control and
1227 nothing more. */
1228
1229int
1230onlyjump_p (insn)
1231 rtx insn;
1232{
1233 rtx set;
1234
1235 if (GET_CODE (insn) != JUMP_INSN)
1236 return 0;
1237
1238 set = single_set (insn);
1239 if (set == NULL)
1240 return 0;
1241 if (GET_CODE (SET_DEST (set)) != PC)
1242 return 0;
1243 if (side_effects_p (SET_SRC (set)))
1244 return 0;
1245
1246 return 1;
1247}
1248
9bf8c346 1249#ifdef HAVE_cc0
1250
6ef828f9 1251/* Return nonzero if X is an RTX that only sets the condition codes
2dcd83ba 1252 and has no side effects. */
1253
1254int
1255only_sets_cc0_p (x)
1256 rtx x;
1257{
1258
1259 if (! x)
1260 return 0;
1261
1262 if (INSN_P (x))
1263 x = PATTERN (x);
1264
1265 return sets_cc0_p (x) == 1 && ! side_effects_p (x);
1266}
1267
5924de0b 1268/* Return 1 if X is an RTX that does nothing but set the condition codes
1269 and CLOBBER or USE registers.
1270 Return -1 if X does explicitly set the condition codes,
1271 but also does other things. */
1272
1273int
1274sets_cc0_p (x)
2dcd83ba 1275 rtx x;
5924de0b 1276{
2dcd83ba 1277
1278 if (! x)
1279 return 0;
1280
1281 if (INSN_P (x))
1282 x = PATTERN (x);
1283
5924de0b 1284 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
1285 return 1;
1286 if (GET_CODE (x) == PARALLEL)
1287 {
1288 int i;
1289 int sets_cc0 = 0;
1290 int other_things = 0;
1291 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1292 {
1293 if (GET_CODE (XVECEXP (x, 0, i)) == SET
1294 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
1295 sets_cc0 = 1;
1296 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
1297 other_things = 1;
1298 }
1299 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
1300 }
1301 return 0;
5924de0b 1302}
9bf8c346 1303#endif
5924de0b 1304\f
1305/* Follow any unconditional jump at LABEL;
1306 return the ultimate label reached by any such chain of jumps.
1307 If LABEL is not followed by a jump, return LABEL.
35e0b416 1308 If the chain loops or we can't find end, return LABEL,
1309 since that tells caller to avoid changing the insn.
5924de0b 1310
1311 If RELOAD_COMPLETED is 0, we do not chain across a NOTE_INSN_LOOP_BEG or
1312 a USE or CLOBBER. */
1313
1314rtx
1315follow_jumps (label)
1316 rtx label;
1317{
19cb6b50 1318 rtx insn;
1319 rtx next;
1320 rtx value = label;
1321 int depth;
5924de0b 1322
1323 for (depth = 0;
1324 (depth < 10
1325 && (insn = next_active_insn (value)) != 0
1326 && GET_CODE (insn) == JUMP_INSN
ba08b7e7 1327 && ((JUMP_LABEL (insn) != 0 && any_uncondjump_p (insn)
1328 && onlyjump_p (insn))
f93ed41b 1329 || GET_CODE (PATTERN (insn)) == RETURN)
5924de0b 1330 && (next = NEXT_INSN (insn))
1331 && GET_CODE (next) == BARRIER);
1332 depth++)
1333 {
1334 /* Don't chain through the insn that jumps into a loop
1335 from outside the loop,
1336 since that would create multiple loop entry jumps
1337 and prevent loop optimization. */
1338 rtx tem;
1339 if (!reload_completed)
1340 for (tem = value; tem != insn; tem = NEXT_INSN (tem))
1341 if (GET_CODE (tem) == NOTE
55b8f81a 1342 && (NOTE_LINE_NUMBER (tem) == NOTE_INSN_LOOP_BEG
1343 /* ??? Optional. Disables some optimizations, but makes
1344 gcov output more accurate with -O. */
1345 || (flag_test_coverage && NOTE_LINE_NUMBER (tem) > 0)))
5924de0b 1346 return value;
1347
1348 /* If we have found a cycle, make the insn jump to itself. */
1349 if (JUMP_LABEL (insn) == label)
35e0b416 1350 return label;
cf03b15b 1351
1352 tem = next_active_insn (JUMP_LABEL (insn));
1353 if (tem && (GET_CODE (PATTERN (tem)) == ADDR_VEC
1354 || GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
1355 break;
1356
5924de0b 1357 value = JUMP_LABEL (insn);
1358 }
35e0b416 1359 if (depth == 10)
1360 return label;
5924de0b 1361 return value;
1362}
1363
5924de0b 1364\f
1365/* Find all CODE_LABELs referred to in X, and increment their use counts.
1366 If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced
1367 in INSN, then store one of them in JUMP_LABEL (INSN).
1368 If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL
1369 referenced in INSN, add a REG_LABEL note containing that label to INSN.
1370 Also, when there are consecutive labels, canonicalize on the last of them.
1371
1372 Note that two labels separated by a loop-beginning note
1373 must be kept distinct if we have not yet done loop-optimization,
1374 because the gap between them is where loop-optimize
1375 will want to move invariant code to. CROSS_JUMP tells us
bf73fcf4 1376 that loop-optimization is done with. */
5924de0b 1377
5377f687 1378void
bf73fcf4 1379mark_jump_label (x, insn, in_mem)
19cb6b50 1380 rtx x;
5924de0b 1381 rtx insn;
190099a6 1382 int in_mem;
5924de0b 1383{
19cb6b50 1384 RTX_CODE code = GET_CODE (x);
1385 int i;
1386 const char *fmt;
5924de0b 1387
1388 switch (code)
1389 {
1390 case PC:
1391 case CC0:
1392 case REG:
5924de0b 1393 case CONST_INT:
5924de0b 1394 case CONST_DOUBLE:
1395 case CLOBBER:
1396 case CALL:
1397 return;
1398
d8e0d332 1399 case MEM:
190099a6 1400 in_mem = 1;
1401 break;
1402
1403 case SYMBOL_REF:
1404 if (!in_mem)
7113a566 1405 return;
190099a6 1406
d8e0d332 1407 /* If this is a constant-pool reference, see if it is a label. */
190099a6 1408 if (CONSTANT_POOL_ADDRESS_P (x))
bf73fcf4 1409 mark_jump_label (get_pool_constant (x), insn, in_mem);
d8e0d332 1410 break;
1411
5924de0b 1412 case LABEL_REF:
1413 {
b4d3bcce 1414 rtx label = XEXP (x, 0);
b4d3bcce 1415
74b0991d 1416 /* Ignore remaining references to unreachable labels that
1417 have been deleted. */
7113a566 1418 if (GET_CODE (label) == NOTE
74b0991d 1419 && NOTE_LINE_NUMBER (label) == NOTE_INSN_DELETED_LABEL)
1420 break;
1421
5924de0b 1422 if (GET_CODE (label) != CODE_LABEL)
1423 abort ();
b4d3bcce 1424
f08cae9d 1425 /* Ignore references to labels of containing functions. */
1426 if (LABEL_REF_NONLOCAL_P (x))
1427 break;
b4d3bcce 1428
5924de0b 1429 XEXP (x, 0) = label;
943e16d8 1430 if (! insn || ! INSN_DELETED_P (insn))
1431 ++LABEL_NUSES (label);
b4d3bcce 1432
5924de0b 1433 if (insn)
1434 {
1435 if (GET_CODE (insn) == JUMP_INSN)
1436 JUMP_LABEL (insn) = label;
ab2237b5 1437 else
e89849bd 1438 {
ab2237b5 1439 /* Add a REG_LABEL note for LABEL unless there already
1440 is one. All uses of a label, except for labels
1441 that are the targets of jumps, must have a
1442 REG_LABEL note. */
1443 if (! find_reg_note (insn, REG_LABEL, label))
60d9e0ee 1444 REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_LABEL, label,
ab2237b5 1445 REG_NOTES (insn));
5924de0b 1446 }
1447 }
1448 return;
1449 }
1450
1451 /* Do walk the labels in a vector, but not the first operand of an
1452 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
1453 case ADDR_VEC:
1454 case ADDR_DIFF_VEC:
943e16d8 1455 if (! INSN_DELETED_P (insn))
1456 {
1457 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
5924de0b 1458
943e16d8 1459 for (i = 0; i < XVECLEN (x, eltnum); i++)
bf73fcf4 1460 mark_jump_label (XVECEXP (x, eltnum, i), NULL_RTX, in_mem);
943e16d8 1461 }
0dbd1c74 1462 return;
7113a566 1463
0dbd1c74 1464 default:
1465 break;
5924de0b 1466 }
1467
1468 fmt = GET_RTX_FORMAT (code);
1469 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1470 {
1471 if (fmt[i] == 'e')
bf73fcf4 1472 mark_jump_label (XEXP (x, i), insn, in_mem);
5924de0b 1473 else if (fmt[i] == 'E')
1474 {
19cb6b50 1475 int j;
5924de0b 1476 for (j = 0; j < XVECLEN (x, i); j++)
bf73fcf4 1477 mark_jump_label (XVECEXP (x, i, j), insn, in_mem);
5924de0b 1478 }
1479 }
1480}
1481
1482/* If all INSN does is set the pc, delete it,
1483 and delete the insn that set the condition codes for it
1484 if that's what the previous thing was. */
1485
1486void
1487delete_jump (insn)
1488 rtx insn;
1489{
19cb6b50 1490 rtx set = single_set (insn);
f4ef05ab 1491
1492 if (set && GET_CODE (SET_DEST (set)) == PC)
1493 delete_computation (insn);
1494}
1495
155b05dc 1496/* Verify INSN is a BARRIER and delete it. */
1497
1498void
1499delete_barrier (insn)
1500 rtx insn;
1501{
1502 if (GET_CODE (insn) != BARRIER)
1503 abort ();
1504
1505 delete_insn (insn);
1506}
1507
ab1241f2 1508/* Recursively delete prior insns that compute the value (used only by INSN
1509 which the caller is deleting) stored in the register mentioned by NOTE
1510 which is a REG_DEAD note associated with INSN. */
1511
1512static void
1513delete_prior_computation (note, insn)
1514 rtx note;
1515 rtx insn;
1516{
1517 rtx our_prev;
1518 rtx reg = XEXP (note, 0);
1519
1520 for (our_prev = prev_nonnote_insn (insn);
272a2170 1521 our_prev && (GET_CODE (our_prev) == INSN
1522 || GET_CODE (our_prev) == CALL_INSN);
ab1241f2 1523 our_prev = prev_nonnote_insn (our_prev))
1524 {
1525 rtx pat = PATTERN (our_prev);
1526
272a2170 1527 /* If we reach a CALL which is not calling a const function
1528 or the callee pops the arguments, then give up. */
1529 if (GET_CODE (our_prev) == CALL_INSN
06a652d1 1530 && (! CONST_OR_PURE_CALL_P (our_prev)
272a2170 1531 || GET_CODE (pat) != SET || GET_CODE (SET_SRC (pat)) != CALL))
1532 break;
1533
ab1241f2 1534 /* If we reach a SEQUENCE, it is too complex to try to
31d3e01c 1535 do anything with it, so give up. We can be run during
1536 and after reorg, so SEQUENCE rtl can legitimately show
1537 up here. */
ab1241f2 1538 if (GET_CODE (pat) == SEQUENCE)
1539 break;
1540
1541 if (GET_CODE (pat) == USE
1542 && GET_CODE (XEXP (pat, 0)) == INSN)
1543 /* reorg creates USEs that look like this. We leave them
1544 alone because reorg needs them for its own purposes. */
1545 break;
1546
1547 if (reg_set_p (reg, pat))
1548 {
272a2170 1549 if (side_effects_p (pat) && GET_CODE (our_prev) != CALL_INSN)
ab1241f2 1550 break;
1551
1552 if (GET_CODE (pat) == PARALLEL)
1553 {
1554 /* If we find a SET of something else, we can't
1555 delete the insn. */
1556
1557 int i;
1558
1559 for (i = 0; i < XVECLEN (pat, 0); i++)
1560 {
1561 rtx part = XVECEXP (pat, 0, i);
1562
1563 if (GET_CODE (part) == SET
1564 && SET_DEST (part) != reg)
1565 break;
1566 }
1567
1568 if (i == XVECLEN (pat, 0))
1569 delete_computation (our_prev);
1570 }
1571 else if (GET_CODE (pat) == SET
1572 && GET_CODE (SET_DEST (pat)) == REG)
1573 {
1574 int dest_regno = REGNO (SET_DEST (pat));
1575 int dest_endregno
7113a566 1576 = (dest_regno
1577 + (dest_regno < FIRST_PSEUDO_REGISTER
ab1241f2 1578 ? HARD_REGNO_NREGS (dest_regno,
7113a566 1579 GET_MODE (SET_DEST (pat))) : 1));
ab1241f2 1580 int regno = REGNO (reg);
7113a566 1581 int endregno
1582 = (regno
1583 + (regno < FIRST_PSEUDO_REGISTER
1584 ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1));
ab1241f2 1585
1586 if (dest_regno >= regno
1587 && dest_endregno <= endregno)
1588 delete_computation (our_prev);
1589
1590 /* We may have a multi-word hard register and some, but not
1591 all, of the words of the register are needed in subsequent
1592 insns. Write REG_UNUSED notes for those parts that were not
1593 needed. */
1594 else if (dest_regno <= regno
272a2170 1595 && dest_endregno >= endregno)
ab1241f2 1596 {
1597 int i;
1598
1599 REG_NOTES (our_prev)
7113a566 1600 = gen_rtx_EXPR_LIST (REG_UNUSED, reg,
1601 REG_NOTES (our_prev));
ab1241f2 1602
1603 for (i = dest_regno; i < dest_endregno; i++)
1604 if (! find_regno_note (our_prev, REG_UNUSED, i))
1605 break;
1606
1607 if (i == dest_endregno)
1608 delete_computation (our_prev);
1609 }
1610 }
1611
1612 break;
1613 }
1614
1615 /* If PAT references the register that dies here, it is an
1616 additional use. Hence any prior SET isn't dead. However, this
1617 insn becomes the new place for the REG_DEAD note. */
1618 if (reg_overlap_mentioned_p (reg, pat))
1619 {
1620 XEXP (note, 1) = REG_NOTES (our_prev);
1621 REG_NOTES (our_prev) = note;
1622 break;
1623 }
1624 }
1625}
1626
f4ef05ab 1627/* Delete INSN and recursively delete insns that compute values used only
1628 by INSN. This uses the REG_DEAD notes computed during flow analysis.
1629 If we are running before flow.c, we need do nothing since flow.c will
1630 delete dead code. We also can't know if the registers being used are
1631 dead or not at this point.
1632
1633 Otherwise, look at all our REG_DEAD notes. If a previous insn does
1634 nothing other than set a register that dies in this insn, we can delete
1635 that insn as well.
1636
1637 On machines with CC0, if CC0 is used in this insn, we may be able to
1638 delete the insn that set it. */
1639
fb374064 1640static void
f4ef05ab 1641delete_computation (insn)
1642 rtx insn;
1643{
1644 rtx note, next;
5924de0b 1645
5924de0b 1646#ifdef HAVE_cc0
41d75671 1647 if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
f4ef05ab 1648 {
5b39732e 1649 rtx prev = prev_nonnote_insn (insn);
5924de0b 1650 /* We assume that at this stage
1651 CC's are always set explicitly
1652 and always immediately before the jump that
1653 will use them. So if the previous insn
1654 exists to set the CC's, delete it
1655 (unless it performs auto-increments, etc.). */
1656 if (prev && GET_CODE (prev) == INSN
1657 && sets_cc0_p (PATTERN (prev)))
1658 {
1659 if (sets_cc0_p (PATTERN (prev)) > 0
ab1241f2 1660 && ! side_effects_p (PATTERN (prev)))
f4ef05ab 1661 delete_computation (prev);
5924de0b 1662 else
1663 /* Otherwise, show that cc0 won't be used. */
941522d6 1664 REG_NOTES (prev) = gen_rtx_EXPR_LIST (REG_UNUSED,
1665 cc0_rtx, REG_NOTES (prev));
5924de0b 1666 }
5b39732e 1667 }
f4ef05ab 1668#endif
5924de0b 1669
5b39732e 1670 for (note = REG_NOTES (insn); note; note = next)
1671 {
5b39732e 1672 next = XEXP (note, 1);
5924de0b 1673
5b39732e 1674 if (REG_NOTE_KIND (note) != REG_DEAD
1675 /* Verify that the REG_NOTE is legitimate. */
1676 || GET_CODE (XEXP (note, 0)) != REG)
1677 continue;
5924de0b 1678
ab1241f2 1679 delete_prior_computation (note, insn);
5924de0b 1680 }
f4ef05ab 1681
e4bf866d 1682 delete_related_insns (insn);
5924de0b 1683}
1684\f
e4bf866d 1685/* Delete insn INSN from the chain of insns and update label ref counts
1686 and delete insns now unreachable.
1687
1688 Returns the first insn after INSN that was not deleted.
5924de0b 1689
e4bf866d 1690 Usage of this instruction is deprecated. Use delete_insn instead and
1691 subsequent cfg_cleanup pass to delete unreachable code if needed. */
5924de0b 1692
1693rtx
e4bf866d 1694delete_related_insns (insn)
19cb6b50 1695 rtx insn;
5924de0b 1696{
19cb6b50 1697 int was_code_label = (GET_CODE (insn) == CODE_LABEL);
d3df77e9 1698 rtx note;
e4bf866d 1699 rtx next = NEXT_INSN (insn), prev = PREV_INSN (insn);
5924de0b 1700
1701 while (next && INSN_DELETED_P (next))
1702 next = NEXT_INSN (next);
1703
1704 /* This insn is already deleted => return first following nondeleted. */
1705 if (INSN_DELETED_P (insn))
1706 return next;
1707
e4bf866d 1708 delete_insn (insn);
5924de0b 1709
5924de0b 1710 /* If instruction is followed by a barrier,
1711 delete the barrier too. */
1712
1713 if (next != 0 && GET_CODE (next) == BARRIER)
e4bf866d 1714 delete_insn (next);
5924de0b 1715
1716 /* If deleting a jump, decrement the count of the label,
1717 and delete the label if it is now unused. */
1718
1719 if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
1793cd6b 1720 {
1721 rtx lab = JUMP_LABEL (insn), lab_next;
1722
e4bf866d 1723 if (LABEL_NUSES (lab) == 0)
1793cd6b 1724 {
1725 /* This can delete NEXT or PREV,
1726 either directly if NEXT is JUMP_LABEL (INSN),
1727 or indirectly through more levels of jumps. */
e4bf866d 1728 delete_related_insns (lab);
1793cd6b 1729
1730 /* I feel a little doubtful about this loop,
1731 but I see no clean and sure alternative way
1732 to find the first insn after INSN that is not now deleted.
1733 I hope this works. */
1734 while (next && INSN_DELETED_P (next))
1735 next = NEXT_INSN (next);
1736 return next;
1737 }
1738 else if ((lab_next = next_nonnote_insn (lab)) != NULL
1739 && GET_CODE (lab_next) == JUMP_INSN
1740 && (GET_CODE (PATTERN (lab_next)) == ADDR_VEC
1741 || GET_CODE (PATTERN (lab_next)) == ADDR_DIFF_VEC))
1742 {
1743 /* If we're deleting the tablejump, delete the dispatch table.
4a82352a 1744 We may not be able to kill the label immediately preceding
1793cd6b 1745 just yet, as it might be referenced in code leading up to
1746 the tablejump. */
e4bf866d 1747 delete_related_insns (lab_next);
1793cd6b 1748 }
1749 }
5924de0b 1750
9c9e0c01 1751 /* Likewise if we're deleting a dispatch table. */
1752
1753 if (GET_CODE (insn) == JUMP_INSN
1754 && (GET_CODE (PATTERN (insn)) == ADDR_VEC
1755 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
1756 {
1757 rtx pat = PATTERN (insn);
1758 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
1759 int len = XVECLEN (pat, diff_vec_p);
1760
1761 for (i = 0; i < len; i++)
e4bf866d 1762 if (LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
1763 delete_related_insns (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
9c9e0c01 1764 while (next && INSN_DELETED_P (next))
1765 next = NEXT_INSN (next);
1766 return next;
1767 }
1768
d3df77e9 1769 /* Likewise for an ordinary INSN / CALL_INSN with a REG_LABEL note. */
1770 if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
1771 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
0c97f529 1772 if (REG_NOTE_KIND (note) == REG_LABEL
1773 /* This could also be a NOTE_INSN_DELETED_LABEL note. */
1774 && GET_CODE (XEXP (note, 0)) == CODE_LABEL)
e4bf866d 1775 if (LABEL_NUSES (XEXP (note, 0)) == 0)
1776 delete_related_insns (XEXP (note, 0));
d3df77e9 1777
5924de0b 1778 while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
1779 prev = PREV_INSN (prev);
1780
1781 /* If INSN was a label and a dispatch table follows it,
1782 delete the dispatch table. The tablejump must have gone already.
1783 It isn't useful to fall through into a table. */
1784
9cdc08c6 1785 if (was_code_label
5924de0b 1786 && NEXT_INSN (insn) != 0
1787 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
1788 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
1789 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
e4bf866d 1790 next = delete_related_insns (NEXT_INSN (insn));
5924de0b 1791
1792 /* If INSN was a label, delete insns following it if now unreachable. */
1793
9cdc08c6 1794 if (was_code_label && prev && GET_CODE (prev) == BARRIER)
5924de0b 1795 {
19cb6b50 1796 RTX_CODE code;
5924de0b 1797 while (next != 0
fb374064 1798 && (GET_RTX_CLASS (code = GET_CODE (next)) == 'i'
64f0b11f 1799 || code == NOTE || code == BARRIER
59bee35e 1800 || (code == CODE_LABEL && INSN_DELETED_P (next))))
5924de0b 1801 {
1802 if (code == NOTE
1803 && NOTE_LINE_NUMBER (next) != NOTE_INSN_FUNCTION_END)
1804 next = NEXT_INSN (next);
59bee35e 1805 /* Keep going past other deleted labels to delete what follows. */
1806 else if (code == CODE_LABEL && INSN_DELETED_P (next))
1807 next = NEXT_INSN (next);
5924de0b 1808 else
1809 /* Note: if this deletes a jump, it can cause more
1810 deletion of unreachable code, after a different label.
1811 As long as the value from this recursive call is correct,
1812 this invocation functions correctly. */
e4bf866d 1813 next = delete_related_insns (next);
5924de0b 1814 }
1815 }
1816
1817 return next;
1818}
1819
1820/* Advance from INSN till reaching something not deleted
1821 then return that. May return INSN itself. */
1822
1823rtx
1824next_nondeleted_insn (insn)
1825 rtx insn;
1826{
1827 while (INSN_DELETED_P (insn))
1828 insn = NEXT_INSN (insn);
1829 return insn;
1830}
1831\f
1832/* Delete a range of insns from FROM to TO, inclusive.
1833 This is for the sake of peephole optimization, so assume
1834 that whatever these insns do will still be done by a new
1835 peephole insn that will replace them. */
1836
1837void
1838delete_for_peephole (from, to)
19cb6b50 1839 rtx from, to;
5924de0b 1840{
19cb6b50 1841 rtx insn = from;
5924de0b 1842
1843 while (1)
1844 {
19cb6b50 1845 rtx next = NEXT_INSN (insn);
1846 rtx prev = PREV_INSN (insn);
5924de0b 1847
1848 if (GET_CODE (insn) != NOTE)
1849 {
1850 INSN_DELETED_P (insn) = 1;
1851
1852 /* Patch this insn out of the chain. */
1853 /* We don't do this all at once, because we
1854 must preserve all NOTEs. */
1855 if (prev)
1856 NEXT_INSN (prev) = next;
1857
1858 if (next)
1859 PREV_INSN (next) = prev;
1860 }
1861
1862 if (insn == to)
1863 break;
1864 insn = next;
1865 }
1866
1867 /* Note that if TO is an unconditional jump
1868 we *do not* delete the BARRIER that follows,
1869 since the peephole that replaces this sequence
1870 is also an unconditional jump in that case. */
1871}
1872\f
71a3455a 1873/* We have determined that INSN is never reached, and are about to
1874 delete it. Print a warning if the user asked for one.
1875
1876 To try to make this warning more useful, this should only be called
1877 once per basic block not reached, and it only warns when the basic
1878 block contains more than one line from the current function, and
1879 contains at least one operation. CSE and inlining can duplicate insns,
1880 so it's possible to get spurious warnings from this. */
1881
1882void
5b154f04 1883never_reached_warning (avoided_insn, finish)
1884 rtx avoided_insn, finish;
71a3455a 1885{
1886 rtx insn;
1887 rtx a_line_note = NULL;
5b154f04 1888 int two_avoided_lines = 0, contains_insn = 0, reached_end = 0;
7113a566 1889
71a3455a 1890 if (! warn_notreached)
1891 return;
1892
1893 /* Scan forwards, looking at LINE_NUMBER notes, until
1894 we hit a LABEL or we run out of insns. */
7113a566 1895
71a3455a 1896 for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
1897 {
5b154f04 1898 if (finish == NULL && GET_CODE (insn) == CODE_LABEL)
7113a566 1899 break;
5b154f04 1900
1901 if (GET_CODE (insn) == NOTE /* A line number note? */
1902 && NOTE_LINE_NUMBER (insn) >= 0)
71a3455a 1903 {
1904 if (a_line_note == NULL)
1905 a_line_note = insn;
1906 else
1907 two_avoided_lines |= (NOTE_LINE_NUMBER (a_line_note)
1908 != NOTE_LINE_NUMBER (insn));
1909 }
9204e736 1910 else if (INSN_P (insn))
5b154f04 1911 {
db15c0db 1912 if (reached_end || a_line_note == NULL)
5b154f04 1913 break;
1914 contains_insn = 1;
1915 }
1916
1917 if (insn == finish)
1918 reached_end = 1;
71a3455a 1919 }
1920 if (two_avoided_lines && contains_insn)
1921 warning_with_file_and_line (NOTE_SOURCE_FILE (a_line_note),
1922 NOTE_LINE_NUMBER (a_line_note),
1923 "will never be executed");
1924}
1925\f
a8b5d014 1926/* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
1927 NLABEL as a return. Accrue modifications into the change group. */
5924de0b 1928
a8b5d014 1929static void
1930redirect_exp_1 (loc, olabel, nlabel, insn)
1931 rtx *loc;
1932 rtx olabel, nlabel;
5924de0b 1933 rtx insn;
1934{
19cb6b50 1935 rtx x = *loc;
1936 RTX_CODE code = GET_CODE (x);
1937 int i;
1938 const char *fmt;
5924de0b 1939
a8b5d014 1940 if (code == LABEL_REF)
5924de0b 1941 {
a8b5d014 1942 if (XEXP (x, 0) == olabel)
1943 {
1944 rtx n;
1945 if (nlabel)
1946 n = gen_rtx_LABEL_REF (VOIDmode, nlabel);
1947 else
7113a566 1948 n = gen_rtx_RETURN (VOIDmode);
5924de0b 1949
a8b5d014 1950 validate_change (insn, loc, n, 1);
1951 return;
1952 }
1953 }
1954 else if (code == RETURN && olabel == 0)
1955 {
1956 x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
1957 if (loc == &PATTERN (insn))
1958 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
1959 validate_change (insn, loc, x, 1);
1960 return;
1961 }
5924de0b 1962
a8b5d014 1963 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
1964 && GET_CODE (SET_SRC (x)) == LABEL_REF
1965 && XEXP (SET_SRC (x), 0) == olabel)
1966 {
1967 validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 1);
1968 return;
5924de0b 1969 }
1970
1971 fmt = GET_RTX_FORMAT (code);
1972 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1973 {
1974 if (fmt[i] == 'e')
a8b5d014 1975 redirect_exp_1 (&XEXP (x, i), olabel, nlabel, insn);
1bd8ca86 1976 else if (fmt[i] == 'E')
5924de0b 1977 {
19cb6b50 1978 int j;
5924de0b 1979 for (j = 0; j < XVECLEN (x, i); j++)
a8b5d014 1980 redirect_exp_1 (&XVECEXP (x, i, j), olabel, nlabel, insn);
5924de0b 1981 }
1982 }
a8b5d014 1983}
5924de0b 1984
a8b5d014 1985/* Similar, but apply the change group and report success or failure. */
1986
ba08b7e7 1987static int
1988redirect_exp (olabel, nlabel, insn)
a8b5d014 1989 rtx olabel, nlabel;
1990 rtx insn;
1991{
ba08b7e7 1992 rtx *loc;
1993
1994 if (GET_CODE (PATTERN (insn)) == PARALLEL)
1995 loc = &XVECEXP (PATTERN (insn), 0, 0);
1996 else
1997 loc = &PATTERN (insn);
1998
a8b5d014 1999 redirect_exp_1 (loc, olabel, nlabel, insn);
2000 if (num_validated_changes () == 0)
2001 return 0;
2002
2003 return apply_change_group ();
5924de0b 2004}
a8b5d014 2005
2006/* Make JUMP go to NLABEL instead of where it jumps now. Accrue
2007 the modifications into the change group. Return false if we did
2008 not see how to do that. */
2009
2010int
2011redirect_jump_1 (jump, nlabel)
2012 rtx jump, nlabel;
2013{
2014 int ochanges = num_validated_changes ();
ba08b7e7 2015 rtx *loc;
2016
2017 if (GET_CODE (PATTERN (jump)) == PARALLEL)
2018 loc = &XVECEXP (PATTERN (jump), 0, 0);
2019 else
2020 loc = &PATTERN (jump);
2021
2022 redirect_exp_1 (loc, JUMP_LABEL (jump), nlabel, jump);
a8b5d014 2023 return num_validated_changes () > ochanges;
2024}
2025
2026/* Make JUMP go to NLABEL instead of where it jumps now. If the old
2027 jump target label is unused as a result, it and the code following
2028 it may be deleted.
5924de0b 2029
2030 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
2031 RETURN insn.
2032
a8b5d014 2033 The return value will be 1 if the change was made, 0 if it wasn't
2034 (this can only occur for NLABEL == 0). */
5924de0b 2035
2036int
f8cacb57 2037redirect_jump (jump, nlabel, delete_unused)
5924de0b 2038 rtx jump, nlabel;
f8cacb57 2039 int delete_unused;
5924de0b 2040{
19cb6b50 2041 rtx olabel = JUMP_LABEL (jump);
5924de0b 2042
2043 if (nlabel == olabel)
2044 return 1;
2045
ba08b7e7 2046 if (! redirect_exp (olabel, nlabel, jump))
5924de0b 2047 return 0;
2048
5924de0b 2049 JUMP_LABEL (jump) = nlabel;
2050 if (nlabel)
2051 ++LABEL_NUSES (nlabel);
2052
9cf49039 2053 /* If we're eliding the jump over exception cleanups at the end of a
2054 function, move the function end note so that -Wreturn-type works. */
4476207f 2055 if (olabel && nlabel
2056 && NEXT_INSN (olabel)
9cf49039 2057 && GET_CODE (NEXT_INSN (olabel)) == NOTE
2058 && NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END)
2059 emit_note_after (NOTE_INSN_FUNCTION_END, nlabel);
2060
7f8c3466 2061 if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused
2062 /* Undefined labels will remain outside the insn stream. */
2063 && INSN_UID (olabel))
e4bf866d 2064 delete_related_insns (olabel);
5924de0b 2065
2066 return 1;
2067}
2068
7113a566 2069/* Invert the jump condition of rtx X contained in jump insn, INSN.
a8b5d014 2070 Accrue the modifications into the change group. */
2071
2072static void
ba08b7e7 2073invert_exp_1 (insn)
a8b5d014 2074 rtx insn;
2075{
19cb6b50 2076 RTX_CODE code;
ba08b7e7 2077 rtx x = pc_set (insn);
2078
2079 if (!x)
7113a566 2080 abort ();
ba08b7e7 2081 x = SET_SRC (x);
a8b5d014 2082
2083 code = GET_CODE (x);
2084
2085 if (code == IF_THEN_ELSE)
2086 {
19cb6b50 2087 rtx comp = XEXP (x, 0);
2088 rtx tem;
7da6ea0c 2089 enum rtx_code reversed_code;
a8b5d014 2090
2091 /* We can do this in two ways: The preferable way, which can only
2092 be done if this is not an integer comparison, is to reverse
2093 the comparison code. Otherwise, swap the THEN-part and ELSE-part
2094 of the IF_THEN_ELSE. If we can't do either, fail. */
2095
7da6ea0c 2096 reversed_code = reversed_comparison_code (comp, insn);
2097
2098 if (reversed_code != UNKNOWN)
a8b5d014 2099 {
2100 validate_change (insn, &XEXP (x, 0),
7da6ea0c 2101 gen_rtx_fmt_ee (reversed_code,
a8b5d014 2102 GET_MODE (comp), XEXP (comp, 0),
2103 XEXP (comp, 1)),
2104 1);
2105 return;
2106 }
7113a566 2107
a8b5d014 2108 tem = XEXP (x, 1);
2109 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
2110 validate_change (insn, &XEXP (x, 2), tem, 1);
a8b5d014 2111 }
ba08b7e7 2112 else
2113 abort ();
a8b5d014 2114}
2115
7113a566 2116/* Invert the jump condition of conditional jump insn, INSN.
a8b5d014 2117
2118 Return 1 if we can do so, 0 if we cannot find a way to do so that
2119 matches a pattern. */
2120
ba08b7e7 2121static int
2122invert_exp (insn)
a8b5d014 2123 rtx insn;
2124{
ba08b7e7 2125 invert_exp_1 (insn);
a8b5d014 2126 if (num_validated_changes () == 0)
2127 return 0;
2128
2129 return apply_change_group ();
2130}
2131
2132/* Invert the condition of the jump JUMP, and make it jump to label
2133 NLABEL instead of where it jumps now. Accrue changes into the
2134 change group. Return false if we didn't see how to perform the
2135 inversion and redirection. */
2136
2137int
2138invert_jump_1 (jump, nlabel)
2139 rtx jump, nlabel;
2140{
2141 int ochanges;
2142
2143 ochanges = num_validated_changes ();
ba08b7e7 2144 invert_exp_1 (jump);
a8b5d014 2145 if (num_validated_changes () == ochanges)
2146 return 0;
2147
2148 return redirect_jump_1 (jump, nlabel);
2149}
2150
2151/* Invert the condition of the jump JUMP, and make it jump to label
2152 NLABEL instead of where it jumps now. Return true if successful. */
2153
2154int
f8cacb57 2155invert_jump (jump, nlabel, delete_unused)
a8b5d014 2156 rtx jump, nlabel;
f8cacb57 2157 int delete_unused;
a8b5d014 2158{
2159 /* We have to either invert the condition and change the label or
2160 do neither. Either operation could fail. We first try to invert
2161 the jump. If that succeeds, we try changing the label. If that fails,
2162 we invert the jump back to what it was. */
2163
ba08b7e7 2164 if (! invert_exp (jump))
a8b5d014 2165 return 0;
2166
f8cacb57 2167 if (redirect_jump (jump, nlabel, delete_unused))
a8b5d014 2168 {
13488c51 2169 invert_br_probabilities (jump);
a8b5d014 2170
2171 return 1;
2172 }
2173
ba08b7e7 2174 if (! invert_exp (jump))
a8b5d014 2175 /* This should just be putting it back the way it was. */
2176 abort ();
2177
2178 return 0;
2179}
2180
5924de0b 2181\f
2182/* Like rtx_equal_p except that it considers two REGs as equal
6c60c295 2183 if they renumber to the same value and considers two commutative
2184 operations to be the same if the order of the operands has been
2207ad6a 2185 reversed.
2186
2187 ??? Addition is not commutative on the PA due to the weird implicit
2188 space register selection rules for memory addresses. Therefore, we
2189 don't consider a + b == b + a.
2190
2191 We could/should make this test a little tighter. Possibly only
2192 disabling it on the PA via some backend macro or only disabling this
2193 case when the PLUS is inside a MEM. */
5924de0b 2194
2195int
2196rtx_renumbered_equal_p (x, y)
2197 rtx x, y;
2198{
19cb6b50 2199 int i;
2200 RTX_CODE code = GET_CODE (x);
2201 const char *fmt;
7113a566 2202
5924de0b 2203 if (x == y)
2204 return 1;
6c60c295 2205
5924de0b 2206 if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
2207 && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
2208 && GET_CODE (SUBREG_REG (y)) == REG)))
2209 {
6c60c295 2210 int reg_x = -1, reg_y = -1;
701e46d0 2211 int byte_x = 0, byte_y = 0;
5924de0b 2212
2213 if (GET_MODE (x) != GET_MODE (y))
2214 return 0;
2215
2216 /* If we haven't done any renumbering, don't
2217 make any assumptions. */
2218 if (reg_renumber == 0)
2219 return rtx_equal_p (x, y);
2220
2221 if (code == SUBREG)
2222 {
6c60c295 2223 reg_x = REGNO (SUBREG_REG (x));
701e46d0 2224 byte_x = SUBREG_BYTE (x);
6c60c295 2225
2226 if (reg_renumber[reg_x] >= 0)
2227 {
701e46d0 2228 reg_x = subreg_regno_offset (reg_renumber[reg_x],
2229 GET_MODE (SUBREG_REG (x)),
2230 byte_x,
2231 GET_MODE (x));
2232 byte_x = 0;
6c60c295 2233 }
5924de0b 2234 }
2235 else
2236 {
6c60c295 2237 reg_x = REGNO (x);
2238 if (reg_renumber[reg_x] >= 0)
2239 reg_x = reg_renumber[reg_x];
5924de0b 2240 }
6c60c295 2241
5924de0b 2242 if (GET_CODE (y) == SUBREG)
2243 {
6c60c295 2244 reg_y = REGNO (SUBREG_REG (y));
701e46d0 2245 byte_y = SUBREG_BYTE (y);
6c60c295 2246
2247 if (reg_renumber[reg_y] >= 0)
2248 {
701e46d0 2249 reg_y = subreg_regno_offset (reg_renumber[reg_y],
2250 GET_MODE (SUBREG_REG (y)),
2251 byte_y,
2252 GET_MODE (y));
2253 byte_y = 0;
6c60c295 2254 }
5924de0b 2255 }
2256 else
2257 {
6c60c295 2258 reg_y = REGNO (y);
2259 if (reg_renumber[reg_y] >= 0)
2260 reg_y = reg_renumber[reg_y];
5924de0b 2261 }
6c60c295 2262
701e46d0 2263 return reg_x >= 0 && reg_x == reg_y && byte_x == byte_y;
5924de0b 2264 }
6c60c295 2265
7113a566 2266 /* Now we have disposed of all the cases
5924de0b 2267 in which different rtx codes can match. */
2268 if (code != GET_CODE (y))
2269 return 0;
6c60c295 2270
5924de0b 2271 switch (code)
2272 {
2273 case PC:
2274 case CC0:
2275 case ADDR_VEC:
2276 case ADDR_DIFF_VEC:
2277 return 0;
2278
2279 case CONST_INT:
5fbd420b 2280 return INTVAL (x) == INTVAL (y);
5924de0b 2281
2282 case LABEL_REF:
f08cae9d 2283 /* We can't assume nonlocal labels have their following insns yet. */
2284 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
2285 return XEXP (x, 0) == XEXP (y, 0);
6c60c295 2286
5924de0b 2287 /* Two label-refs are equivalent if they point at labels
2288 in the same position in the instruction stream. */
2289 return (next_real_insn (XEXP (x, 0))
2290 == next_real_insn (XEXP (y, 0)));
2291
2292 case SYMBOL_REF:
2293 return XSTR (x, 0) == XSTR (y, 0);
0dbd1c74 2294
fc41ccae 2295 case CODE_LABEL:
2296 /* If we didn't match EQ equality above, they aren't the same. */
2297 return 0;
2298
0dbd1c74 2299 default:
2300 break;
5924de0b 2301 }
2302
2303 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
2304
2305 if (GET_MODE (x) != GET_MODE (y))
2306 return 0;
2307
6c60c295 2308 /* For commutative operations, the RTX match if the operand match in any
2207ad6a 2309 order. Also handle the simple binary and unary cases without a loop.
2310
2311 ??? Don't consider PLUS a commutative operator; see comments above. */
2312 if ((code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
2313 && code != PLUS)
6c60c295 2314 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
2315 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
2316 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
2317 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
2318 else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
2319 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
2320 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
2321 else if (GET_RTX_CLASS (code) == '1')
2322 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
2323
5924de0b 2324 /* Compare the elements. If any pair of corresponding elements
2325 fail to match, return 0 for the whole things. */
2326
2327 fmt = GET_RTX_FORMAT (code);
2328 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2329 {
19cb6b50 2330 int j;
5924de0b 2331 switch (fmt[i])
2332 {
1bb04728 2333 case 'w':
2334 if (XWINT (x, i) != XWINT (y, i))
2335 return 0;
2336 break;
2337
5924de0b 2338 case 'i':
2339 if (XINT (x, i) != XINT (y, i))
2340 return 0;
2341 break;
2342
a0d79d69 2343 case 't':
2344 if (XTREE (x, i) != XTREE (y, i))
2345 return 0;
2346 break;
2347
5924de0b 2348 case 's':
2349 if (strcmp (XSTR (x, i), XSTR (y, i)))
2350 return 0;
2351 break;
2352
2353 case 'e':
2354 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
2355 return 0;
2356 break;
2357
2358 case 'u':
2359 if (XEXP (x, i) != XEXP (y, i))
2360 return 0;
2361 /* fall through. */
2362 case '0':
2363 break;
2364
2365 case 'E':
2366 if (XVECLEN (x, i) != XVECLEN (y, i))
2367 return 0;
2368 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2369 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
2370 return 0;
2371 break;
2372
2373 default:
2374 abort ();
2375 }
2376 }
2377 return 1;
2378}
2379\f
2380/* If X is a hard register or equivalent to one or a subregister of one,
2381 return the hard register number. If X is a pseudo register that was not
2382 assigned a hard register, return the pseudo register number. Otherwise,
2383 return -1. Any rtx is valid for X. */
2384
2385int
2386true_regnum (x)
2387 rtx x;
2388{
2389 if (GET_CODE (x) == REG)
2390 {
2391 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
2392 return reg_renumber[REGNO (x)];
2393 return REGNO (x);
2394 }
2395 if (GET_CODE (x) == SUBREG)
2396 {
2397 int base = true_regnum (SUBREG_REG (x));
2398 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
701e46d0 2399 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
2400 GET_MODE (SUBREG_REG (x)),
2401 SUBREG_BYTE (x), GET_MODE (x));
5924de0b 2402 }
2403 return -1;
2404}
b627bae7 2405
2406/* Return regno of the register REG and handle subregs too. */
2407unsigned int
2408reg_or_subregno (reg)
2409 rtx reg;
2410{
2411 if (REG_P (reg))
2412 return REGNO (reg);
2413 if (GET_CODE (reg) == SUBREG)
2414 return REGNO (SUBREG_REG (reg));
2415 abort ();
2416}