]> gcc.gnu.org Git - gcc.git/blame - gcc/jump.c
Initial revision
[gcc.git] / gcc / jump.c
CommitLineData
15a63be1
RK
1/* Optimize jump instructions, for GNU compiler.
2 Copyright (C) 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21/* This is the jump-optimization pass of the compiler.
22 It is run two or three times: once before cse, sometimes once after cse,
23 and once after reload (before final).
24
25 jump_optimize deletes unreachable code and labels that are not used.
26 It also deletes jumps that jump to the following insn,
27 and simplifies jumps around unconditional jumps and jumps
28 to unconditional jumps.
29
30 Each CODE_LABEL has a count of the times it is used
31 stored in the LABEL_NUSES internal field, and each JUMP_INSN
32 has one label that it refers to stored in the
33 JUMP_LABEL internal field. With this we can detect labels that
34 become unused because of the deletion of all the jumps that
35 formerly used them. The JUMP_LABEL info is sometimes looked
36 at by later passes.
37
38 Optionally, cross-jumping can be done. Currently it is done
39 only the last time (when after reload and before final).
40 In fact, the code for cross-jumping now assumes that register
41 allocation has been done, since it uses `rtx_renumbered_equal_p'.
42
43 Jump optimization is done after cse when cse's constant-propagation
44 causes jumps to become unconditional or to be deleted.
45
46 Unreachable loops are not detected here, because the labels
47 have references and the insns appear reachable from the labels.
48 find_basic_blocks in flow.c finds and deletes such loops.
49
50 The subroutines delete_insn, redirect_jump, and invert_jump are used
51 from other passes as well. */
52
53#include "config.h"
54#include "rtl.h"
55#include "flags.h"
56#include "hard-reg-set.h"
57#include "regs.h"
58#include "expr.h"
59#include "insn-config.h"
60#include "insn-flags.h"
61#include "real.h"
62
63/* ??? Eventually must record somehow the labels used by jumps
64 from nested functions. */
65/* Pre-record the next or previous real insn for each label?
66 No, this pass is very fast anyway. */
67/* Condense consecutive labels?
68 This would make life analysis faster, maybe. */
69/* Optimize jump y; x: ... y: jumpif... x?
70 Don't know if it is worth bothering with. */
71/* Optimize two cases of conditional jump to conditional jump?
72 This can never delete any instruction or make anything dead,
73 or even change what is live at any point.
74 So perhaps let combiner do it. */
75
76/* Vector indexed by uid.
77 For each CODE_LABEL, index by its uid to get first unconditional jump
78 that jumps to the label.
79 For each JUMP_INSN, index by its uid to get the next unconditional jump
80 that jumps to the same label.
81 Element 0 is the start of a chain of all return insns.
82 (It is safe to use element 0 because insn uid 0 is not used. */
83
84static rtx *jump_chain;
85
86/* List of labels referred to from initializers.
87 These can never be deleted. */
88rtx forced_labels;
89
90/* Maximum index in jump_chain. */
91
92static int max_jump_chain;
93
94/* Set nonzero by jump_optimize if control can fall through
95 to the end of the function. */
96int can_reach_end;
97
98/* Indicates whether death notes are significant in cross jump analysis.
99 Normally they are not significant, because of A and B jump to C,
100 and R dies in A, it must die in B. But this might not be true after
101 stack register conversion, and we must compare death notes in that
102 case. */
103
104static int cross_jump_death_matters = 0;
105
106static int duplicate_loop_exit_test ();
107rtx delete_insn ();
108int redirect_jump ();
109static int redirect_exp ();
110void redirect_tablejump ();
111static int delete_labelref_insn ();
112int invert_jump ();
113static int invert_exp ();
114int condjump_p ();
115int simplejump_p ();
116
117extern rtx gen_jump ();
118
119void squeeze_notes ();
120static void mark_jump_label ();
121void delete_jump ();
122static void delete_from_jump_chain ();
123static int tension_vector_labels ();
124static void find_cross_jump ();
125static void do_cross_jump ();
126static int jump_back_p ();
127\f
128/* Delete no-op jumps and optimize jumps to jumps
129 and jumps around jumps.
130 Delete unused labels and unreachable code.
131
132 If CROSS_JUMP is 1, detect matching code
133 before a jump and its destination and unify them.
134 If CROSS_JUMP is 2, do cross-jumping, but pay attention to death notes.
135
136 If NOOP_MOVES is nonzero, delete no-op move insns.
137
138 If AFTER_REGSCAN is nonzero, then this jump pass is being run immediately
139 after regscan, and it is safe to use regno_first_uid and regno_last_uid.
140
141 If `optimize' is zero, don't change any code,
142 just determine whether control drops off the end of the function.
143 This case occurs when we have -W and not -O.
144 It works because `delete_insn' checks the value of `optimize'
145 and refrains from actually deleting when that is 0. */
146
147void
148jump_optimize (f, cross_jump, noop_moves, after_regscan)
149 rtx f;
150 int cross_jump;
151 int noop_moves;
152 int after_regscan;
153{
154 register rtx insn;
155 int changed;
156 int first = 1;
157 int max_uid = 0;
158 rtx last_insn;
159
160 cross_jump_death_matters = (cross_jump == 2);
161
162 /* Initialize LABEL_NUSES and JUMP_LABEL fields. */
163
164 for (insn = f; insn; insn = NEXT_INSN (insn))
165 {
166 if (GET_CODE (insn) == CODE_LABEL)
167 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
168 else if (GET_CODE (insn) == JUMP_INSN)
169 JUMP_LABEL (insn) = 0;
170 if (INSN_UID (insn) > max_uid)
171 max_uid = INSN_UID (insn);
172 }
173
174 max_uid++;
175
176 /* Delete insns following barriers, up to next label. */
177
178 for (insn = f; insn;)
179 {
180 if (GET_CODE (insn) == BARRIER)
181 {
182 insn = NEXT_INSN (insn);
183 while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
184 {
185 if (GET_CODE (insn) == NOTE
186 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
187 insn = NEXT_INSN (insn);
188 else
189 insn = delete_insn (insn);
190 }
191 /* INSN is now the code_label. */
192 }
193 else
194 insn = NEXT_INSN (insn);
195 }
196
197 /* Leave some extra room for labels and duplicate exit test insns
198 we make. */
199 max_jump_chain = max_uid * 14 / 10;
200 jump_chain = (rtx *) alloca (max_jump_chain * sizeof (rtx));
201 bzero (jump_chain, max_jump_chain * sizeof (rtx));
202
203 /* Mark the label each jump jumps to.
204 Combine consecutive labels, and count uses of labels.
205
206 For each label, make a chain (using `jump_chain')
207 of all the *unconditional* jumps that jump to it;
208 also make a chain of all returns. */
209
210 for (insn = f; insn; insn = NEXT_INSN (insn))
211 if ((GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == INSN
212 || GET_CODE (insn) == CALL_INSN)
213 && ! INSN_DELETED_P (insn))
214 {
215 mark_jump_label (PATTERN (insn), insn, cross_jump);
216 if (GET_CODE (insn) == JUMP_INSN)
217 {
218 if (JUMP_LABEL (insn) != 0 && simplejump_p (insn))
219 {
220 jump_chain[INSN_UID (insn)]
221 = jump_chain[INSN_UID (JUMP_LABEL (insn))];
222 jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn;
223 }
224 if (GET_CODE (PATTERN (insn)) == RETURN)
225 {
226 jump_chain[INSN_UID (insn)] = jump_chain[0];
227 jump_chain[0] = insn;
228 }
229 }
230 }
231
232 /* Keep track of labels used from static data;
233 they cannot ever be deleted. */
234
235 for (insn = forced_labels; insn; insn = XEXP (insn, 1))
236 LABEL_NUSES (XEXP (insn, 0))++;
237
238 /* Delete all labels already not referenced.
239 Also find the last insn. */
240
241 last_insn = 0;
242 for (insn = f; insn; )
243 {
244 if (GET_CODE (insn) == CODE_LABEL && LABEL_NUSES (insn) == 0)
245 insn = delete_insn (insn);
246 else
247 {
248 last_insn = insn;
249 insn = NEXT_INSN (insn);
250 }
251 }
252
253 if (!optimize)
254 {
255 /* See if there is still a NOTE_INSN_FUNCTION_END in this function.
256 If so record that this function can drop off the end. */
257
258 insn = last_insn;
259 {
260 int n_labels = 1;
261 while (insn
262 /* One label can follow the end-note: the return label. */
263 && ((GET_CODE (insn) == CODE_LABEL && n_labels-- > 0)
264 /* Ordinary insns can follow it if returning a structure. */
265 || GET_CODE (insn) == INSN
266 /* If machine uses explicit RETURN insns, no epilogue,
267 then one of them follows the note. */
268 || (GET_CODE (insn) == JUMP_INSN
269 && GET_CODE (PATTERN (insn)) == RETURN)
270 /* Other kinds of notes can follow also. */
271 || (GET_CODE (insn) == NOTE
272 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)))
273 insn = PREV_INSN (insn);
274 }
275
276 /* Report if control can fall through at the end of the function. */
277 if (insn && GET_CODE (insn) == NOTE
278 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END
279 && ! INSN_DELETED_P (insn))
280 can_reach_end = 1;
281
282 /* Zero the "deleted" flag of all the "deleted" insns. */
283 for (insn = f; insn; insn = NEXT_INSN (insn))
284 INSN_DELETED_P (insn) = 0;
285 return;
286 }
287
288#ifdef HAVE_return
289 if (HAVE_return)
290 {
291 /* If we fall through to the epilogue, see if we can insert a RETURN insn
292 in front of it. If the machine allows it at this point (we might be
293 after reload for a leaf routine), it will improve optimization for it
294 to be there. */
295 insn = get_last_insn ();
296 while (insn && GET_CODE (insn) == NOTE)
297 insn = PREV_INSN (insn);
298
299 if (insn && GET_CODE (insn) != BARRIER)
300 {
301 emit_jump_insn (gen_return ());
302 emit_barrier ();
303 }
304 }
305#endif
306
307 if (noop_moves)
308 for (insn = f; insn; )
309 {
310 register rtx next = NEXT_INSN (insn);
311
312 if (GET_CODE (insn) == INSN)
313 {
314 register rtx body = PATTERN (insn);
315
316/* Combine stack_adjusts with following push_insns. */
317#ifdef PUSH_ROUNDING
318 if (GET_CODE (body) == SET
319 && SET_DEST (body) == stack_pointer_rtx
320 && GET_CODE (SET_SRC (body)) == PLUS
321 && XEXP (SET_SRC (body), 0) == stack_pointer_rtx
322 && GET_CODE (XEXP (SET_SRC (body), 1)) == CONST_INT
323 && INTVAL (XEXP (SET_SRC (body), 1)) > 0)
324 {
325 rtx p;
326 rtx stack_adjust_insn = insn;
327 int stack_adjust_amount = INTVAL (XEXP (SET_SRC (body), 1));
328 int total_pushed = 0;
329 int pushes = 0;
330
331 /* Find all successive push insns. */
332 p = insn;
333 /* Don't convert more than three pushes;
334 that starts adding too many displaced addresses
335 and the whole thing starts becoming a losing
336 proposition. */
337 while (pushes < 3)
338 {
339 rtx pbody, dest;
340 p = next_nonnote_insn (p);
341 if (p == 0 || GET_CODE (p) != INSN)
342 break;
343 pbody = PATTERN (p);
344 if (GET_CODE (pbody) != SET)
345 break;
346 dest = SET_DEST (pbody);
347 /* Allow a no-op move between the adjust and the push. */
348 if (GET_CODE (dest) == REG
349 && GET_CODE (SET_SRC (pbody)) == REG
350 && REGNO (dest) == REGNO (SET_SRC (pbody)))
351 continue;
352 if (! (GET_CODE (dest) == MEM
353 && GET_CODE (XEXP (dest, 0)) == POST_INC
354 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
355 break;
356 pushes++;
357 if (total_pushed + GET_MODE_SIZE (SET_DEST (pbody))
358 > stack_adjust_amount)
359 break;
360 total_pushed += GET_MODE_SIZE (SET_DEST (pbody));
361 }
362
363 /* Discard the amount pushed from the stack adjust;
364 maybe eliminate it entirely. */
365 if (total_pushed >= stack_adjust_amount)
366 {
367 delete_insn (stack_adjust_insn);
368 total_pushed = stack_adjust_amount;
369 }
370 else
371 XEXP (SET_SRC (PATTERN (stack_adjust_insn)), 1)
372 = gen_rtx (CONST_INT, VOIDmode,
373 stack_adjust_amount - total_pushed);
374
375 /* Change the appropriate push insns to ordinary stores. */
376 p = insn;
377 while (total_pushed > 0)
378 {
379 rtx pbody, dest;
380 p = next_nonnote_insn (p);
381 if (GET_CODE (p) != INSN)
382 break;
383 pbody = PATTERN (p);
384 if (GET_CODE (pbody) == SET)
385 break;
386 dest = SET_DEST (pbody);
387 if (! (GET_CODE (dest) == MEM
388 && GET_CODE (XEXP (dest, 0)) == POST_INC
389 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
390 break;
391 total_pushed -= GET_MODE_SIZE (SET_DEST (pbody));
392 /* If this push doesn't fully fit in the space
393 of the stack adjust that we deleted,
394 make another stack adjust here for what we
395 didn't use up. There should be peepholes
396 to recognize the resulting sequence of insns. */
397 if (total_pushed < 0)
398 {
399 emit_insn_before (gen_add2_insn (stack_pointer_rtx,
400 gen_rtx (CONST_INT, VOIDmode, - total_pushed)),
401 p);
402 break;
403 }
404 XEXP (dest, 0)
405 = plus_constant (stack_pointer_rtx, total_pushed);
406 }
407 }
408#endif
409
410 /* Detect and delete no-op move instructions
411 resulting from not allocating a parameter in a register. */
412
413 if (GET_CODE (body) == SET
414 && (SET_DEST (body) == SET_SRC (body)
415 || (GET_CODE (SET_DEST (body)) == MEM
416 && GET_CODE (SET_SRC (body)) == MEM
417 && rtx_equal_p (SET_SRC (body), SET_DEST (body))))
418 && ! (GET_CODE (SET_DEST (body)) == MEM
419 && MEM_VOLATILE_P (SET_DEST (body)))
420 && ! (GET_CODE (SET_SRC (body)) == MEM
421 && MEM_VOLATILE_P (SET_SRC (body))))
422 delete_insn (insn);
423
424 /* Detect and ignore no-op move instructions
425 resulting from smart or fortuitous register allocation. */
426
427 else if (GET_CODE (body) == SET)
428 {
429 int sreg = true_regnum (SET_SRC (body));
430 int dreg = true_regnum (SET_DEST (body));
431
432 if (sreg == dreg && sreg >= 0)
433 delete_insn (insn);
434 else if (sreg >= 0 && dreg >= 0)
435 {
436 rtx trial;
437 rtx tem = find_equiv_reg (0, insn, 0,
438 sreg, 0, dreg,
439 GET_MODE (SET_SRC (body)));
440
441#ifdef PRESERVE_DEATH_INFO_REGNO_P
442 /* Deleting insn could lose a death-note for SREG or DREG
443 so don't do it if final needs accurate death-notes. */
444 if (! PRESERVE_DEATH_INFO_REGNO_P (sreg)
445 && ! PRESERVE_DEATH_INFO_REGNO_P (dreg))
446#endif
447 {
448 /* DREG may have been the target of a REG_DEAD note in
449 the insn which makes INSN redundant. If so, reorg
450 would still think it is dead. So search for such a
451 note and delete it if we find it. */
452 for (trial = prev_nonnote_insn (insn);
453 trial && GET_CODE (trial) != CODE_LABEL;
454 trial = prev_nonnote_insn (trial))
455 if (find_regno_note (trial, REG_DEAD, dreg))
456 {
457 remove_death (dreg, trial);
458 break;
459 }
460
461 if (tem != 0
462 && GET_MODE (tem) == GET_MODE (SET_DEST (body)))
463 delete_insn (insn);
464 }
465 }
466 else if (dreg >= 0 && CONSTANT_P (SET_SRC (body))
467 && find_equiv_reg (SET_SRC (body), insn, 0, dreg, 0,
468 0, GET_MODE (SET_DEST (body))))
469 {
470 /* This handles the case where we have two consecutive
471 assignments of the same constant to pseudos that didn't
472 get a hard reg. Each SET from the constant will be
473 converted into a SET of the spill register and an
474 output reload will be made following it. This produces
475 two loads of the same constant into the same spill
476 register. */
477
478 rtx in_insn = insn;
479
480 /* Look back for a death note for the first reg.
481 If there is one, it is no longer accurate. */
482 while (in_insn && GET_CODE (in_insn) != CODE_LABEL)
483 {
484 if ((GET_CODE (in_insn) == INSN
485 || GET_CODE (in_insn) == JUMP_INSN)
486 && find_regno_note (in_insn, REG_DEAD, dreg))
487 {
488 remove_death (dreg, in_insn);
489 break;
490 }
491 in_insn = PREV_INSN (in_insn);
492 }
493
494 /* Delete the second load of the value. */
495 delete_insn (insn);
496 }
497 }
498 else if (GET_CODE (body) == PARALLEL)
499 {
500 /* If each part is a set between two identical registers or
501 a USE or CLOBBER, delete the insn. */
502 int i, sreg, dreg;
503 rtx tem;
504
505 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
506 {
507 tem = XVECEXP (body, 0, i);
508 if (GET_CODE (tem) == USE || GET_CODE (tem) == CLOBBER)
509 continue;
510
511 if (GET_CODE (tem) != SET
512 || (sreg = true_regnum (SET_SRC (tem))) < 0
513 || (dreg = true_regnum (SET_DEST (tem))) < 0
514 || dreg != sreg)
515 break;
516 }
517
518 if (i < 0)
519 delete_insn (insn);
520 }
521#if !BYTES_BIG_ENDIAN /* Not worth the hair to detect this
522 in the big-endian case. */
523 /* Also delete insns to store bit fields if they are no-ops. */
524 else if (GET_CODE (body) == SET
525 && GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
526 && XEXP (SET_DEST (body), 2) == const0_rtx
527 && XEXP (SET_DEST (body), 0) == SET_SRC (body)
528 && ! (GET_CODE (SET_SRC (body)) == MEM
529 && MEM_VOLATILE_P (SET_SRC (body))))
530 delete_insn (insn);
531#endif /* not BYTES_BIG_ENDIAN */
532 }
533 insn = next;
534 }
535
536 /* Now iterate optimizing jumps until nothing changes over one pass. */
537 changed = 1;
538 while (changed)
539 {
540 register rtx next;
541 changed = 0;
542
543 for (insn = f; insn; insn = next)
544 {
545 rtx reallabelprev;
546 rtx temp, temp1, temp2, temp3, temp4, temp5;
547 rtx nlabel;
548 int this_is_simplejump, this_is_condjump;
549#if 0
550 /* If NOT the first iteration, if this is the last jump pass
551 (just before final), do the special peephole optimizations.
552 Avoiding the first iteration gives ordinary jump opts
553 a chance to work before peephole opts. */
554
555 if (reload_completed && !first && !flag_no_peephole)
556 if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
557 peephole (insn);
558#endif
559
560 /* That could have deleted some insns after INSN, so check now
561 what the following insn is. */
562
563 next = NEXT_INSN (insn);
564
565 /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional
566 jump. Try to optimize by duplicating the loop exit test if so.
567 This is only safe immediately after regscan, because it uses
568 the values of regno_first_uid and regno_last_uid. */
569 if (after_regscan && GET_CODE (insn) == NOTE
570 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
571 && (temp1 = next_nonnote_insn (insn)) != 0
572 && simplejump_p (temp1))
573 {
574 temp = PREV_INSN (insn);
575 if (duplicate_loop_exit_test (insn))
576 {
577 changed = 1;
578 next = NEXT_INSN (temp);
579 continue;
580 }
581 }
582
583 if (GET_CODE (insn) != JUMP_INSN)
584 continue;
585
586 this_is_simplejump = simplejump_p (insn);
587 this_is_condjump = condjump_p (insn);
588
589 /* Tension the labels in dispatch tables. */
590
591 if (GET_CODE (PATTERN (insn)) == ADDR_VEC)
592 changed |= tension_vector_labels (PATTERN (insn), 0);
593 if (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
594 changed |= tension_vector_labels (PATTERN (insn), 1);
595
596 /* If a dispatch table always goes to the same place,
597 get rid of it and replace the insn that uses it. */
598
599 if (GET_CODE (PATTERN (insn)) == ADDR_VEC
600 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
601 {
602 int i;
603 rtx pat = PATTERN (insn);
604 int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC;
605 int len = XVECLEN (pat, diff_vec_p);
606 rtx dispatch = prev_real_insn (insn);
607
608 for (i = 0; i < len; i++)
609 if (XEXP (XVECEXP (pat, diff_vec_p, i), 0)
610 != XEXP (XVECEXP (pat, diff_vec_p, 0), 0))
611 break;
612 if (i == len
613 && GET_CODE (dispatch) == JUMP_INSN
614 && JUMP_LABEL (dispatch) != 0
615 /* Don't mess with a casesi insn. */
616 && !(GET_CODE (PATTERN (dispatch)) == SET
617 && (GET_CODE (SET_SRC (PATTERN (dispatch)))
618 == IF_THEN_ELSE))
619 && next_real_insn (JUMP_LABEL (dispatch)) == insn)
620 {
621 redirect_tablejump (dispatch,
622 XEXP (XVECEXP (pat, diff_vec_p, 0), 0));
623 changed = 1;
624 }
625 }
626
627 reallabelprev = prev_active_insn (JUMP_LABEL (insn));
628
629 /* If a jump references the end of the function, try to turn
630 it into a RETURN insn, possibly a conditional one. */
631 if (JUMP_LABEL (insn)
632 && next_active_insn (JUMP_LABEL (insn)) == 0)
633 changed |= redirect_jump (insn, 0);
634
635 /* Detect jump to following insn. */
636 if (reallabelprev == insn && condjump_p (insn))
637 {
638 delete_jump (insn);
639 changed = 1;
640 continue;
641 }
642
643 /* If we have an unconditional jump preceeded by a USE, try to put
644 the USE before the target and jump there. This simplifies many
645 of the optimizations below since we don't have to worry about
646 dealing with these USE insns. We only do this if the label
647 being branch to already has the identical USE or if code
648 never falls through to that label. */
649
650 if (this_is_simplejump
651 && (temp = prev_nonnote_insn (insn)) != 0
652 && GET_CODE (temp) == INSN && GET_CODE (PATTERN (temp)) == USE
653 && (temp1 = prev_nonnote_insn (JUMP_LABEL (insn))) != 0
654 && (GET_CODE (temp1) == BARRIER
655 || (GET_CODE (temp1) == INSN
656 && rtx_equal_p (PATTERN (temp), PATTERN (temp1)))))
657 {
658 if (GET_CODE (temp1) == BARRIER)
659 {
660 reorder_insns (temp, temp, temp1);
661 temp1 = NEXT_INSN (temp1);
662 }
663 else
664 delete_insn (temp);
665
666 redirect_jump (insn, get_label_before (temp1));
667 reallabelprev = prev_real_insn (temp1);
668 changed = 1;
669 }
670
671 /* Simplify if (...) x = a; else x = b; by converting it
672 to x = b; if (...) x = a;
673 if B is sufficiently simple, the test doesn't involve X,
674 and nothing in the test modifies B or X.
675
676 If we have small register classes, we also can't do this if X
677 is a hard register.
678
679 If the "x = b;" insn has any REG_NOTES, we don't do this because
680 of the possibility that we are running after CSE and there is a
681 REG_EQUAL note that is only valid if the branch has already been
682 taken. If we move the insn with the REG_EQUAL note, we may
683 fold the comparison to always be false in a later CSE pass.
684 (We could also delete the REG_NOTES when moving the insn, but it
685 seems simpler to not move it.) An exception is that we can move
686 the insn if the only note is a REG_EQUAL or REG_EQUIV whose
687 value is the same as "b".
688
689 INSN is the branch over the `else' part.
690
691 We set:
692
693 TEMP to the jump insn preceeding "x = a;"
694 TEMP1 to X
695 TEMP2 to the insn that sets "x = b;"
696 TEMP3 to the insn that sets "x = a;" */
697
698 if (this_is_simplejump
699 && (temp3 = prev_active_insn (insn)) != 0
700 && GET_CODE (temp3) == INSN
701 && GET_CODE (PATTERN (temp3)) == SET
702 && GET_CODE (temp1 = SET_DEST (PATTERN (temp3))) == REG
703#ifdef SMALL_REGISTER_CLASSES
704 && REGNO (temp1) >= FIRST_PSEUDO_REGISTER
705#endif
706 && (temp2 = next_active_insn (insn)) != 0
707 && GET_CODE (temp2) == INSN
708 && GET_CODE (PATTERN (temp2)) == SET
709 && rtx_equal_p (SET_DEST (PATTERN (temp2)), temp1)
710 && (GET_CODE (SET_SRC (PATTERN (temp2))) == REG
711 || CONSTANT_P (SET_SRC (PATTERN (temp2))))
712 && (REG_NOTES (temp2) == 0
713 || ((REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUAL
714 || REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUIV)
715 && XEXP (REG_NOTES (temp2), 1) == 0
716 && rtx_equal_p (XEXP (REG_NOTES (temp2), 0),
717 SET_SRC (PATTERN (temp2)))))
718 && (temp = prev_active_insn (temp3)) != 0
719 && condjump_p (temp) && ! simplejump_p (temp)
720 /* TEMP must skip over the "x = a;" insn */
721 && prev_real_insn (JUMP_LABEL (temp)) == insn
722 && no_labels_between_p (insn, JUMP_LABEL (temp))
723 /* There must be no other entries to the "x = b;" insn. */
724 && no_labels_between_p (JUMP_LABEL (temp), temp2)
725 /* INSN must either branch to the insn after TEMP2 or the insn
726 after TEMP2 must branch to the same place as INSN. */
727 && (reallabelprev == temp2
728 || ((temp4 = next_active_insn (temp2)) != 0
729 && simplejump_p (temp4)
730 && JUMP_LABEL (temp4) == JUMP_LABEL (insn))))
731 {
732 /* The test expression, X, may be a complicated test with
733 multiple branches. See if we can find all the uses of
734 the label that TEMP branches to without hitting a CALL_INSN
735 or a jump to somewhere else. */
736 rtx target = JUMP_LABEL (temp);
737 int nuses = LABEL_NUSES (target);
738 rtx p, q;
739
740 /* Set P to the first jump insn that goes around "x = a;". */
741 for (p = temp; nuses && p; p = prev_nonnote_insn (p))
742 {
743 if (GET_CODE (p) == JUMP_INSN)
744 {
745 if (condjump_p (p) && ! simplejump_p (p)
746 && JUMP_LABEL (p) == target)
747 {
748 nuses--;
749 if (nuses == 0)
750 break;
751 }
752 else
753 break;
754 }
755 else if (GET_CODE (p) == CALL_INSN)
756 break;
757 }
758
759#ifdef HAVE_cc0
760 /* We cannot insert anything between a set of cc and its use
761 so if P uses cc0, we must back up to the previous insn. */
762 q = prev_nonnote_insn (p);
763 if (q && GET_RTX_CLASS (GET_CODE (q)) == 'i'
764 && sets_cc0_p (PATTERN (q)))
765 p = q;
766#endif
767
768 if (p)
769 p = PREV_INSN (p);
770
771 /* If we found all the uses and there was no data conflict, we
772 can move the assignment unless we can branch into the middle
773 from somewhere. */
774 if (nuses == 0 && p
775 && no_labels_between_p (p, insn)
776 && ! reg_referenced_between_p (temp1, p, NEXT_INSN (temp3))
777 && ! reg_set_between_p (temp1, p, temp3)
778 && (GET_CODE (SET_SRC (PATTERN (temp2))) == CONST_INT
779 || ! reg_set_between_p (SET_SRC (PATTERN (temp2)),
780 p, temp2)))
781 {
782 reorder_insns_with_line_notes (temp2, temp2, p);
783
784 /* Set NEXT to an insn that we know won't go away. */
785 next = next_active_insn (insn);
786
787 /* Delete the jump around the set. Note that we must do
788 this before we redirect the test jumps so that it won't
789 delete the code immediately following the assignment
790 we moved (which might be a jump). */
791
792 delete_insn (insn);
793
794 /* We either have two consecutive labels or a jump to
795 a jump, so adjust all the JUMP_INSNs to branch to where
796 INSN branches to. */
797 for (p = NEXT_INSN (p); p != next; p = NEXT_INSN (p))
798 if (GET_CODE (p) == JUMP_INSN)
799 redirect_jump (p, target);
800
801 changed = 1;
802 continue;
803 }
804 }
805
806 /* If we have x = a; if (...) x = b;
807 and either A or B is zero, or if we have if (...) x = 0;
808 and jumps are expensive, try to use a store-flag insn to
809 avoid the jump. (If the jump would be faster, the machine
810 should not have defined the scc insns!). These cases are often
811 made by the previous optimization.
812
813 INSN here is the jump around the store. We set:
814
815 TEMP to the "x = b;" insn.
816 TEMP1 to X.
817 TEMP2 to B (const0_rtx in the second case).
818 TEMP3 to A (X in the second case).
819 TEMP4 to the condition being tested.
820 TEMP5 to the earliest insn used to find the condition. */
821
822 if (/* We can't do this after reload has completed. */
823 ! reload_completed
824 && this_is_condjump && ! this_is_simplejump
825 /* Set TEMP to the "x = b;" insn. */
826 && (temp = next_nonnote_insn (insn)) != 0
827 && GET_CODE (temp) == INSN
828 && GET_CODE (PATTERN (temp)) == SET
829 && GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG
830#ifdef SMALL_REGISTER_CLASSES
831 && REGNO (temp1) >= FIRST_PSEUDO_REGISTER
832#endif
833 && GET_MODE_CLASS (GET_MODE (temp1)) == MODE_INT
834 && (GET_CODE (temp2 = SET_SRC (PATTERN (temp))) == REG
835 || GET_CODE (temp2) == CONST_INT)
836 /* Allow either form, but prefer the former if both apply. */
837 && (((temp3 = reg_set_last (temp1, insn)) != 0
838 && ((GET_CODE (temp3) == REG
839#ifdef SMALL_REGISTER_CLASSES
840 && REGNO (temp3) >= FIRST_PSEUDO_REGISTER
841#endif
842 )
843 || GET_CODE (temp3) == CONST_INT))
844 /* Make the latter case look like x = x; if (...) x = 0; */
845 || ((temp3 = temp1, BRANCH_COST > 1)
846 && temp2 == const0_rtx))
847 /* INSN must either branch to the insn after TEMP or the insn
848 after TEMP must branch to the same place as INSN. */
849 && (reallabelprev == temp
850 || ((temp4 = next_active_insn (temp)) != 0
851 && simplejump_p (temp4)
852 && JUMP_LABEL (temp4) == JUMP_LABEL (insn)))
853 && (temp4 = get_condition (insn, &temp5)) != 0
854
855 /* If B is zero, OK; if A is zero, can only do this if we
856 can reverse the condition. */
857 && (temp2 == const0_rtx
858 || (temp3 == const0_rtx
859 && (can_reverse_comparison_p (temp4, insn)))))
860 {
861 enum rtx_code code = GET_CODE (temp4);
862 rtx yes = temp3, var = temp1;
863 int normalizep;
864 rtx target;
865
866 /* If necessary, reverse the condition. */
867 if (temp3 == const0_rtx)
868 code = reverse_condition (code), yes = temp2;
869
870 /* See if we can do this with a store-flag insn. */
871 start_sequence ();
872
873 /* If YES is the constant 1, it is best to just compute
874 the result directly. If YES is constant and STORE_FLAG_VALUE
875 includes all of its bits, it is best to compute the flag
876 value unnormalized and `and' it with YES. Otherwise,
877 normalize to -1 and `and' with YES. */
878 normalizep = (yes == const1_rtx ? 1
879 : (GET_CODE (yes) == CONST_INT
880 && (INTVAL (yes) & ~ STORE_FLAG_VALUE) == 0) ? 0
881 : -1);
882
883 /* We will be putting the store-flag insn immediately in
884 front of the comparison that was originally being done,
885 so we know all the variables in TEMP4 will be valid.
886 However, this might be in front of the assignment of
887 A to VAR. If it is, it would clobber the store-flag
888 we will be emitting.
889
890 Therefore, emit into a temporary which will be copied to
891 VAR immediately after TEMP. */
892
893 target = emit_store_flag (gen_reg_rtx (GET_MODE (var)), code,
894 XEXP (temp4, 0), XEXP (temp4, 1),
895 VOIDmode,
896 (code == LTU || code == LEU
897 || code == GEU || code == GTU),
898 normalizep);
899 if (target)
900 {
901 rtx seq;
902
903 if (normalizep != 1)
904 target = expand_and (yes, target,
905 (GET_CODE (target) == REG
906 ? target : 0));
907 seq = gen_sequence ();
908 end_sequence ();
909 emit_insn_before (seq, temp5);
910 emit_insn_after (gen_move_insn (var, target), insn);
911 delete_insn (temp);
912 next = NEXT_INSN (insn);
913#ifdef HAVE_cc0
914 delete_insn (prev_nonnote_insn (insn));
915#endif
916 delete_insn (insn);
917 changed = 1;
918 continue;
919 }
920 else
921 end_sequence ();
922 }
923
924 /* If branches are expensive, convert
925 if (foo) bar++; to bar += (foo != 0);
926 and similarly for "bar--;"
927
928 INSN is the conditional branch around the arithmetic. We set:
929
930 TEMP is the arithmetic insn.
931 TEMP1 is the SET doing the arthmetic.
932 TEMP2 is the operand being incremented or decremented.
933 TEMP3 to the condition being tested.
934 TEMP4 to the earliest insn used to find the condition. */
935
936 if (BRANCH_COST >= 2
937 && ! reload_completed
938 && this_is_condjump && ! this_is_simplejump
939 && (temp = next_nonnote_insn (insn)) != 0
940 && (temp1 = single_set (temp)) != 0
941 && (temp2 = SET_DEST (temp1),
942 GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT)
943 && GET_CODE (SET_SRC (temp1)) == PLUS
944 && (XEXP (SET_SRC (temp1), 1) == const1_rtx
945 || XEXP (SET_SRC (temp1), 1) == constm1_rtx)
946 && rtx_equal_p (temp2, XEXP (SET_SRC (temp1), 0))
947 /* INSN must either branch to the insn after TEMP or the insn
948 after TEMP must branch to the same place as INSN. */
949 && (reallabelprev == temp
950 || ((temp3 = next_active_insn (temp)) != 0
951 && simplejump_p (temp3)
952 && JUMP_LABEL (temp3) == JUMP_LABEL (insn)))
953 && (temp3 = get_condition (insn, &temp4)) != 0
954 && can_reverse_comparison_p (temp3, insn))
955 {
956 rtx target, seq;
957 enum rtx_code code = reverse_condition (GET_CODE (temp3));
958
959 start_sequence ();
960
961 target = emit_store_flag (gen_reg_rtx (GET_MODE (temp2)), code,
962 XEXP (temp3, 0), XEXP (temp3, 1),
963 VOIDmode,
964 (code == LTU || code == LEU
965 || code == GTU || code == GEU), 1);
966
967 /* If we can do the store-flag, do the addition or
968 subtraction. */
969
970 if (target)
971 target = expand_binop (GET_MODE (temp2),
972 (XEXP (SET_SRC (temp1), 1) == const1_rtx
973 ? add_optab : sub_optab),
974 temp2, target, temp2, OPTAB_WIDEN);
975
976 if (target != 0)
977 {
978 /* Put the result back in temp2 in case it isn't already.
979 Then replace the jump, possible a CC0-setting insn in
980 front of the jump, and TEMP, with the sequence we have
981 made. */
982
983 if (target != temp2)
984 emit_move_insn (temp2, target);
985
986 seq = get_insns ();
987 end_sequence ();
988
989 emit_insns_before (seq, temp4);
990 delete_insn (temp);
991 next = NEXT_INSN (insn);
992#ifdef HAVE_cc0
993 delete_insn (prev_nonnote_insn (insn));
994#endif
995 delete_insn (insn);
996 changed = 1;
997 continue;
998 }
999 else
1000 end_sequence ();
1001 }
1002
1003 /* Simplify if (...) x = 1; else {...} if (x) ...
1004 We recognize this case scanning backwards as well.
1005
1006 TEMP is the assignment to x;
1007 TEMP1 is the label at the head of the second if. */
1008 /* ?? This should call get_condition to find the values being
1009 compared, instead of looking for a COMPARE insn when HAVE_cc0
1010 is not defined. This would allow it to work on the m88k. */
1011 /* ?? This optimization is only safe before cse is run if HAVE_cc0
1012 is not defined and the condition is tested by a separate compare
1013 insn. This is because the code below assumes that the result
1014 of the compare dies in the following branch.
1015
1016 Not only that, but there might be other insns between the
1017 compare and branch whose results are live. Those insns need
1018 to be executed.
1019
1020 A way to fix this is to move the insns at JUMP_LABEL (insn)
1021 to before INSN. If we are running before flow, they will
1022 be deleted if they aren't needed. But this doesn't work
1023 well after flow.
1024
1025 This is really a special-case of jump threading, anyway. The
1026 right thing to do is to replace this and jump threading with
1027 much simpler code in cse.
1028
1029 This code has been turned off in the non-cc0 case in the
1030 meantime. */
1031
1032#ifdef HAVE_cc0
1033 else if (this_is_simplejump
1034 /* Safe to skip USE and CLOBBER insns here
1035 since they will not be deleted. */
1036 && (temp = prev_active_insn (insn))
1037 && no_labels_between_p (temp, insn)
1038 && GET_CODE (temp) == INSN
1039 && GET_CODE (PATTERN (temp)) == SET
1040 && GET_CODE (SET_DEST (PATTERN (temp))) == REG
1041 && CONSTANT_P (SET_SRC (PATTERN (temp)))
1042 && (temp1 = next_active_insn (JUMP_LABEL (insn)))
1043 /* If we find that the next value tested is `x'
1044 (TEMP1 is the insn where this happens), win. */
1045 && GET_CODE (temp1) == INSN
1046 && GET_CODE (PATTERN (temp1)) == SET
1047#ifdef HAVE_cc0
1048 /* Does temp1 `tst' the value of x? */
1049 && SET_SRC (PATTERN (temp1)) == SET_DEST (PATTERN (temp))
1050 && SET_DEST (PATTERN (temp1)) == cc0_rtx
1051 && (temp1 = next_nonnote_insn (temp1))
1052#else
1053 /* Does temp1 compare the value of x against zero? */
1054 && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE
1055 && XEXP (SET_SRC (PATTERN (temp1)), 1) == const0_rtx
1056 && (XEXP (SET_SRC (PATTERN (temp1)), 0)
1057 == SET_DEST (PATTERN (temp)))
1058 && GET_CODE (SET_DEST (PATTERN (temp1))) == REG
1059 && (temp1 = find_next_ref (SET_DEST (PATTERN (temp1)), temp1))
1060#endif
1061 && condjump_p (temp1))
1062 {
1063 /* Get the if_then_else from the condjump. */
1064 rtx choice = SET_SRC (PATTERN (temp1));
1065 if (GET_CODE (choice) == IF_THEN_ELSE)
1066 {
1067 enum rtx_code code = GET_CODE (XEXP (choice, 0));
1068 rtx val = SET_SRC (PATTERN (temp));
1069 rtx cond
1070 = simplify_relational_operation (code, GET_MODE (SET_DEST (PATTERN (temp))),
1071 val, const0_rtx);
1072 rtx ultimate;
1073
1074 if (cond == const_true_rtx)
1075 ultimate = XEXP (choice, 1);
1076 else if (cond == const0_rtx)
1077 ultimate = XEXP (choice, 2);
1078 else
1079 ultimate = 0;
1080
1081 if (ultimate == pc_rtx)
1082 ultimate = get_label_after (temp1);
1083 else if (ultimate && GET_CODE (ultimate) != RETURN)
1084 ultimate = XEXP (ultimate, 0);
1085
1086 if (ultimate)
1087 changed |= redirect_jump (insn, ultimate);
1088 }
1089 }
1090#endif
1091
1092#if 0
1093 /* @@ This needs a bit of work before it will be right.
1094
1095 Any type of comparison can be accepted for the first and
1096 second compare. When rewriting the first jump, we must
1097 compute the what conditions can reach label3, and use the
1098 appropriate code. We can not simply reverse/swap the code
1099 of the first jump. In some cases, the second jump must be
1100 rewritten also.
1101
1102 For example,
1103 < == converts to > ==
1104 < != converts to == >
1105 etc.
1106
1107 If the code is written to only accept an '==' test for the second
1108 compare, then all that needs to be done is to swap the condition
1109 of the first branch.
1110
1111 It is questionable whether we want this optimization anyways,
1112 since if the user wrote code like this because he/she knew that
1113 the jump to label1 is taken most of the time, then rewritting
1114 this gives slower code. */
1115 /* @@ This should call get_condition to find the values being
1116 compared, instead of looking for a COMPARE insn when HAVE_cc0
1117 is not defined. This would allow it to work on the m88k. */
1118 /* @@ This optimization is only safe before cse is run if HAVE_cc0
1119 is not defined and the condition is tested by a separate compare
1120 insn. This is because the code below assumes that the result
1121 of the compare dies in the following branch. */
1122
1123 /* Simplify test a ~= b
1124 condjump label1;
1125 test a == b
1126 condjump label2;
1127 jump label3;
1128 label1:
1129
1130 rewriting as
1131 test a ~~= b
1132 condjump label3
1133 test a == b
1134 condjump label2
1135 label1:
1136
1137 where ~= is an inequality, e.g. >, and ~~= is the swapped
1138 inequality, e.g. <.
1139
1140 We recognize this case scanning backwards.
1141
1142 TEMP is the conditional jump to `label2';
1143 TEMP1 is the test for `a == b';
1144 TEMP2 is the conditional jump to `label1';
1145 TEMP3 is the test for `a ~= b'. */
1146 else if (this_is_simplejump
1147 && (temp = prev_active_insn (insn))
1148 && no_labels_between_p (temp, insn)
1149 && condjump_p (temp)
1150 && (temp1 = prev_active_insn (temp))
1151 && no_labels_between_p (temp1, temp)
1152 && GET_CODE (temp1) == INSN
1153 && GET_CODE (PATTERN (temp1)) == SET
1154#ifdef HAVE_cc0
1155 && sets_cc0_p (PATTERN (temp1)) == 1
1156#else
1157 && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE
1158 && GET_CODE (SET_DEST (PATTERN (temp1))) == REG
1159 && (temp == find_next_ref (SET_DEST (PATTERN (temp1)), temp1))
1160#endif
1161 && (temp2 = prev_active_insn (temp1))
1162 && no_labels_between_p (temp2, temp1)
1163 && condjump_p (temp2)
1164 && JUMP_LABEL (temp2) == next_nonnote_insn (NEXT_INSN (insn))
1165 && (temp3 = prev_active_insn (temp2))
1166 && no_labels_between_p (temp3, temp2)
1167 && GET_CODE (PATTERN (temp3)) == SET
1168 && rtx_equal_p (SET_DEST (PATTERN (temp3)),
1169 SET_DEST (PATTERN (temp1)))
1170 && rtx_equal_p (SET_SRC (PATTERN (temp1)),
1171 SET_SRC (PATTERN (temp3)))
1172 && ! inequality_comparisons_p (PATTERN (temp))
1173 && inequality_comparisons_p (PATTERN (temp2)))
1174 {
1175 rtx fallthrough_label = JUMP_LABEL (temp2);
1176
1177 ++LABEL_NUSES (fallthrough_label);
1178 if (swap_jump (temp2, JUMP_LABEL (insn)))
1179 {
1180 delete_insn (insn);
1181 changed = 1;
1182 }
1183
1184 if (--LABEL_NUSES (fallthrough_label) == 0)
1185 delete_insn (fallthrough_label);
1186 }
1187#endif
1188 /* Simplify if (...) {... x = 1;} if (x) ...
1189
1190 We recognize this case backwards.
1191
1192 TEMP is the test of `x';
1193 TEMP1 is the assignment to `x' at the end of the
1194 previous statement. */
1195 /* @@ This should call get_condition to find the values being
1196 compared, instead of looking for a COMPARE insn when HAVE_cc0
1197 is not defined. This would allow it to work on the m88k. */
1198 /* @@ This optimization is only safe before cse is run if HAVE_cc0
1199 is not defined and the condition is tested by a separate compare
1200 insn. This is because the code below assumes that the result
1201 of the compare dies in the following branch. */
2d20b9df
RS
1202
1203 /* ??? This has to be turned off. The problem is that the
1204 unconditional jump might indirectly end up branching to the
1205 label between TEMP1 and TEMP. We can't detect this, in general,
1206 since it may become a jump to there after further optimizations.
1207 If that jump is done, it will be deleted, so we will retry
1208 this optimization in the next pass, thus an infinite loop.
1209
1210 The present code prevents this by putting the jump after the
1211 label, but this is not logically correct. */
1212#if 0
15a63be1
RK
1213 else if (this_is_condjump
1214 /* Safe to skip USE and CLOBBER insns here
1215 since they will not be deleted. */
1216 && (temp = prev_active_insn (insn))
1217 && no_labels_between_p (temp, insn)
1218 && GET_CODE (temp) == INSN
1219 && GET_CODE (PATTERN (temp)) == SET
1220#ifdef HAVE_cc0
1221 && sets_cc0_p (PATTERN (temp)) == 1
1222 && GET_CODE (SET_SRC (PATTERN (temp))) == REG
1223#else
1224 /* Temp must be a compare insn, we can not accept a register
1225 to register move here, since it may not be simply a
1226 tst insn. */
1227 && GET_CODE (SET_SRC (PATTERN (temp))) == COMPARE
1228 && XEXP (SET_SRC (PATTERN (temp)), 1) == const0_rtx
1229 && GET_CODE (XEXP (SET_SRC (PATTERN (temp)), 0)) == REG
1230 && GET_CODE (SET_DEST (PATTERN (temp))) == REG
1231 && insn == find_next_ref (SET_DEST (PATTERN (temp)), temp)
1232#endif
1233 /* May skip USE or CLOBBER insns here
1234 for checking for opportunity, since we
1235 take care of them later. */
1236 && (temp1 = prev_active_insn (temp))
1237 && GET_CODE (temp1) == INSN
1238 && GET_CODE (PATTERN (temp1)) == SET
1239#ifdef HAVE_cc0
1240 && SET_SRC (PATTERN (temp)) == SET_DEST (PATTERN (temp1))
1241#else
1242 && (XEXP (SET_SRC (PATTERN (temp)), 0)
1243 == SET_DEST (PATTERN (temp1)))
1244#endif
1245 && CONSTANT_P (SET_SRC (PATTERN (temp1)))
1246 /* If this isn't true, cse will do the job. */
1247 && ! no_labels_between_p (temp1, temp))
1248 {
1249 /* Get the if_then_else from the condjump. */
1250 rtx choice = SET_SRC (PATTERN (insn));
1251 if (GET_CODE (choice) == IF_THEN_ELSE
1252 && (GET_CODE (XEXP (choice, 0)) == EQ
1253 || GET_CODE (XEXP (choice, 0)) == NE))
1254 {
1255 int want_nonzero = (GET_CODE (XEXP (choice, 0)) == NE);
1256 rtx last_insn;
1257 rtx ultimate;
1258 rtx p;
1259
1260 /* Get the place that condjump will jump to
1261 if it is reached from here. */
1262 if ((SET_SRC (PATTERN (temp1)) != const0_rtx)
1263 == want_nonzero)
1264 ultimate = XEXP (choice, 1);
1265 else
1266 ultimate = XEXP (choice, 2);
1267 /* Get it as a CODE_LABEL. */
1268 if (ultimate == pc_rtx)
1269 ultimate = get_label_after (insn);
1270 else
1271 /* Get the label out of the LABEL_REF. */
1272 ultimate = XEXP (ultimate, 0);
1273
2d20b9df
RS
1274 /* Insert the jump immediately before TEMP, specifically
1275 after the label that is between TEMP1 and TEMP. */
1276 last_insn = PREV_INSN (temp);
15a63be1
RK
1277
1278 /* If we would be branching to the next insn, the jump
1279 would immediately be deleted and the re-inserted in
1280 a subsequent pass over the code. So don't do anything
1281 in that case. */
1282 if (next_active_insn (last_insn)
1283 != next_active_insn (ultimate))
1284 {
1285 emit_barrier_after (last_insn);
1286 p = emit_jump_insn_after (gen_jump (ultimate),
1287 last_insn);
1288 JUMP_LABEL (p) = ultimate;
1289 ++LABEL_NUSES (ultimate);
1290 if (INSN_UID (ultimate) < max_jump_chain
1291 && INSN_CODE (p) < max_jump_chain)
1292 {
1293 jump_chain[INSN_UID (p)]
1294 = jump_chain[INSN_UID (ultimate)];
1295 jump_chain[INSN_UID (ultimate)] = p;
1296 }
1297 changed = 1;
1298 continue;
1299 }
1300 }
1301 }
2d20b9df 1302#endif
15a63be1
RK
1303 /* Detect a conditional jump going to the same place
1304 as an immediately following unconditional jump. */
1305 else if (this_is_condjump
1306 && (temp = next_active_insn (insn)) != 0
1307 && simplejump_p (temp)
1308 && (next_active_insn (JUMP_LABEL (insn))
1309 == next_active_insn (JUMP_LABEL (temp))))
1310 {
1311 delete_jump (insn);
1312 changed = 1;
1313 continue;
1314 }
1315 /* Detect a conditional jump jumping over an unconditional jump. */
1316
1317 else if (this_is_condjump && ! this_is_simplejump
1318 && reallabelprev != 0
1319 && GET_CODE (reallabelprev) == JUMP_INSN
1320 && prev_active_insn (reallabelprev) == insn
1321 && no_labels_between_p (insn, reallabelprev)
1322 && simplejump_p (reallabelprev))
1323 {
1324 /* When we invert the unconditional jump, we will be
1325 decrementing the usage count of its old label.
1326 Make sure that we don't delete it now because that
1327 might cause the following code to be deleted. */
1328 rtx prev_uses = prev_nonnote_insn (reallabelprev);
1329 rtx prev_label = JUMP_LABEL (insn);
1330
1331 ++LABEL_NUSES (prev_label);
1332
1333 if (invert_jump (insn, JUMP_LABEL (reallabelprev)))
1334 {
1335 /* It is very likely that if there are USE insns before
1336 this jump, they hold REG_DEAD notes. These REG_DEAD
1337 notes are no longer valid due to this optimization,
1338 and will cause the life-analysis that following passes
1339 (notably delayed-branch scheduling) to think that
1340 these registers are dead when they are not.
1341
1342 To prevent this trouble, we just remove the USE insns
1343 from the insn chain. */
1344
1345 while (prev_uses && GET_CODE (prev_uses) == INSN
1346 && GET_CODE (PATTERN (prev_uses)) == USE)
1347 {
1348 rtx useless = prev_uses;
1349 prev_uses = prev_nonnote_insn (prev_uses);
1350 delete_insn (useless);
1351 }
1352
1353 delete_insn (reallabelprev);
1354 next = insn;
1355 changed = 1;
1356 }
1357
1358 /* We can now safely delete the label if it is unreferenced
1359 since the delete_insn above has deleted the BARRIER. */
1360 if (--LABEL_NUSES (prev_label) == 0)
1361 delete_insn (prev_label);
1362 continue;
1363 }
1364 else
1365 {
1366 /* Detect a jump to a jump. */
1367
1368 nlabel = follow_jumps (JUMP_LABEL (insn));
1369 if (nlabel != JUMP_LABEL (insn)
1370 && redirect_jump (insn, nlabel))
1371 {
1372 changed = 1;
1373 next = insn;
1374 }
1375
1376 /* Look for if (foo) bar; else break; */
1377 /* The insns look like this:
1378 insn = condjump label1;
1379 ...range1 (some insns)...
1380 jump label2;
1381 label1:
1382 ...range2 (some insns)...
1383 jump somewhere unconditionally
1384 label2: */
1385 {
1386 rtx label1 = next_label (insn);
1387 rtx range1end = label1 ? prev_active_insn (label1) : 0;
1388 /* Don't do this optimization on the first round, so that
1389 jump-around-a-jump gets simplified before we ask here
1390 whether a jump is unconditional.
1391
1392 Also don't do it when we are called after reload since
1393 it will confuse reorg. */
1394 if (! first
1395 && (reload_completed ? ! flag_delayed_branch : 1)
1396 /* Make sure INSN is something we can invert. */
1397 && condjump_p (insn)
1398 && label1 != 0
1399 && JUMP_LABEL (insn) == label1
1400 && LABEL_NUSES (label1) == 1
1401 && GET_CODE (range1end) == JUMP_INSN
1402 && simplejump_p (range1end))
1403 {
1404 rtx label2 = next_label (label1);
1405 rtx range2end = label2 ? prev_active_insn (label2) : 0;
1406 if (range1end != range2end
1407 && JUMP_LABEL (range1end) == label2
1408 && GET_CODE (range2end) == JUMP_INSN
1409 && GET_CODE (NEXT_INSN (range2end)) == BARRIER
1410 /* Invert the jump condition, so we
1411 still execute the same insns in each case. */
1412 && invert_jump (insn, label1))
1413 {
1414 rtx range1beg = next_active_insn (insn);
1415 rtx range2beg = next_active_insn (label1);
1416 rtx range1after, range2after;
1417 rtx range1before, range2before;
1418
0e690bdb
RS
1419 /* Include in each range any line number before it. */
1420 while (PREV_INSN (range1beg)
1421 && GET_CODE (PREV_INSN (range1beg)) == NOTE)
1422 range1beg = PREV_INSN (range1beg);
1423
1424 while (PREV_INSN (range2beg)
1425 && GET_CODE (PREV_INSN (range2beg)) == NOTE)
1426 range2beg = PREV_INSN (range2beg);
1427
15a63be1
RK
1428 /* Don't move NOTEs for blocks or loops; shift them
1429 outside the ranges, where they'll stay put. */
1430 squeeze_notes (range1beg, range1end);
1431 squeeze_notes (range2beg, range2end);
1432
1433 /* Get current surrounds of the 2 ranges. */
1434 range1before = PREV_INSN (range1beg);
1435 range2before = PREV_INSN (range2beg);
1436 range1after = NEXT_INSN (range1end);
1437 range2after = NEXT_INSN (range2end);
1438
1439 /* Splice range2 where range1 was. */
1440 NEXT_INSN (range1before) = range2beg;
1441 PREV_INSN (range2beg) = range1before;
1442 NEXT_INSN (range2end) = range1after;
1443 PREV_INSN (range1after) = range2end;
1444 /* Splice range1 where range2 was. */
1445 NEXT_INSN (range2before) = range1beg;
1446 PREV_INSN (range1beg) = range2before;
1447 NEXT_INSN (range1end) = range2after;
1448 PREV_INSN (range2after) = range1end;
1449 changed = 1;
1450 continue;
1451 }
1452 }
1453 }
1454
1455 /* Now that the jump has been tensioned,
1456 try cross jumping: check for identical code
1457 before the jump and before its target label. */
1458
1459 /* First, cross jumping of conditional jumps: */
1460
1461 if (cross_jump && condjump_p (insn))
1462 {
1463 rtx newjpos, newlpos;
1464 rtx x = prev_real_insn (JUMP_LABEL (insn));
1465
1466 /* A conditional jump may be crossjumped
1467 only if the place it jumps to follows
1468 an opposing jump that comes back here. */
1469
1470 if (x != 0 && ! jump_back_p (x, insn))
1471 /* We have no opposing jump;
1472 cannot cross jump this insn. */
1473 x = 0;
1474
1475 newjpos = 0;
1476 /* TARGET is nonzero if it is ok to cross jump
1477 to code before TARGET. If so, see if matches. */
1478 if (x != 0)
1479 find_cross_jump (insn, x, 2,
1480 &newjpos, &newlpos);
1481
1482 if (newjpos != 0)
1483 {
1484 do_cross_jump (insn, newjpos, newlpos);
1485 /* Make the old conditional jump
1486 into an unconditional one. */
1487 SET_SRC (PATTERN (insn))
1488 = gen_rtx (LABEL_REF, VOIDmode, JUMP_LABEL (insn));
1489 INSN_CODE (insn) = -1;
1490 emit_barrier_after (insn);
1491 /* Add to jump_chain unless this is a new label
1492 whose UID is too large. */
1493 if (INSN_UID (JUMP_LABEL (insn)) < max_jump_chain)
1494 {
1495 jump_chain[INSN_UID (insn)]
1496 = jump_chain[INSN_UID (JUMP_LABEL (insn))];
1497 jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn;
1498 }
1499 changed = 1;
1500 next = insn;
1501 }
1502 }
1503
1504 /* Cross jumping of unconditional jumps:
1505 a few differences. */
1506
1507 if (cross_jump && simplejump_p (insn))
1508 {
1509 rtx newjpos, newlpos;
1510 rtx target;
1511
1512 newjpos = 0;
1513
1514 /* TARGET is nonzero if it is ok to cross jump
1515 to code before TARGET. If so, see if matches. */
1516 find_cross_jump (insn, JUMP_LABEL (insn), 1,
1517 &newjpos, &newlpos);
1518
1519 /* If cannot cross jump to code before the label,
1520 see if we can cross jump to another jump to
1521 the same label. */
1522 /* Try each other jump to this label. */
1523 if (INSN_UID (JUMP_LABEL (insn)) < max_uid)
1524 for (target = jump_chain[INSN_UID (JUMP_LABEL (insn))];
1525 target != 0 && newjpos == 0;
1526 target = jump_chain[INSN_UID (target)])
1527 if (target != insn
1528 && JUMP_LABEL (target) == JUMP_LABEL (insn)
1529 /* Ignore TARGET if it's deleted. */
1530 && ! INSN_DELETED_P (target))
1531 find_cross_jump (insn, target, 2,
1532 &newjpos, &newlpos);
1533
1534 if (newjpos != 0)
1535 {
1536 do_cross_jump (insn, newjpos, newlpos);
1537 changed = 1;
1538 next = insn;
1539 }
1540 }
1541
1542 /* This code was dead in the previous jump.c! */
1543 if (cross_jump && GET_CODE (PATTERN (insn)) == RETURN)
1544 {
1545 /* Return insns all "jump to the same place"
1546 so we can cross-jump between any two of them. */
1547
1548 rtx newjpos, newlpos, target;
1549
1550 newjpos = 0;
1551
1552 /* If cannot cross jump to code before the label,
1553 see if we can cross jump to another jump to
1554 the same label. */
1555 /* Try each other jump to this label. */
1556 for (target = jump_chain[0];
1557 target != 0 && newjpos == 0;
1558 target = jump_chain[INSN_UID (target)])
1559 if (target != insn
1560 && ! INSN_DELETED_P (target)
1561 && GET_CODE (PATTERN (target)) == RETURN)
1562 find_cross_jump (insn, target, 2,
1563 &newjpos, &newlpos);
1564
1565 if (newjpos != 0)
1566 {
1567 do_cross_jump (insn, newjpos, newlpos);
1568 changed = 1;
1569 next = insn;
1570 }
1571 }
1572 }
1573 }
1574
1575 first = 0;
1576 }
1577
1578 /* Delete extraneous line number notes.
1579 Note that two consecutive notes for different lines are not really
1580 extraneous. There should be some indication where that line belonged,
1581 even if it became empty. */
1582
1583 {
1584 rtx last_note = 0;
1585
1586 for (insn = f; insn; insn = NEXT_INSN (insn))
1587 if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0)
1588 {
1589 /* Delete this note if it is identical to previous note. */
1590 if (last_note
1591 && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
1592 && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
1593 {
1594 delete_insn (insn);
1595 continue;
1596 }
1597
1598 last_note = insn;
1599 }
1600 }
1601
1602 /* See if there is still a NOTE_INSN_FUNCTION_END in this function.
1603 If so, delete it, and record that this function can drop off the end. */
1604
1605 insn = last_insn;
1606 {
1607 int n_labels = 1;
1608 while (insn
1609 /* One label can follow the end-note: the return label. */
1610 && ((GET_CODE (insn) == CODE_LABEL && n_labels-- > 0)
1611 /* Ordinary insns can follow it if returning a structure. */
1612 || GET_CODE (insn) == INSN
1613 /* If machine uses explicit RETURN insns, no epilogue,
1614 then one of them follows the note. */
1615 || (GET_CODE (insn) == JUMP_INSN
1616 && GET_CODE (PATTERN (insn)) == RETURN)
1617 /* Other kinds of notes can follow also. */
1618 || (GET_CODE (insn) == NOTE
1619 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)))
1620 insn = PREV_INSN (insn);
1621 }
1622
1623 /* Report if control can fall through at the end of the function. */
1624 if (insn && GET_CODE (insn) == NOTE
1625 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END)
1626 {
1627 can_reach_end = 1;
1628 delete_insn (insn);
1629 }
1630
1631 /* Show JUMP_CHAIN no longer valid. */
1632 jump_chain = 0;
1633}
1634\f
1635/* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional
1636 jump. Assume that this unconditional jump is to the exit test code. If
1637 the code is sufficiently simple, make a copy of it before INSN,
1638 followed by a jump to the exit of the loop. Then delete the unconditional
1639 jump after INSN.
1640
1641 Note that it is possible we can get confused here if the jump immediately
1642 after the loop start branches outside the loop but within an outer loop.
1643 If we are near the exit of that loop, we will copy its exit test. This
1644 will not generate incorrect code, but could suppress some optimizations.
1645 However, such cases are degenerate loops anyway.
1646
1647 Return 1 if we made the change, else 0.
1648
1649 This is only safe immediately after a regscan pass because it uses the
1650 values of regno_first_uid and regno_last_uid. */
1651
1652static int
1653duplicate_loop_exit_test (loop_start)
1654 rtx loop_start;
1655{
1656 rtx insn, set, p;
1657 rtx copy, link;
1658 int num_insns = 0;
1659 rtx exitcode = NEXT_INSN (JUMP_LABEL (next_nonnote_insn (loop_start)));
1660 rtx lastexit;
1661 int max_reg = max_reg_num ();
1662 rtx *reg_map = 0;
1663
1664 /* Scan the exit code. We do not perform this optimization if any insn:
1665
1666 is a CALL_INSN
1667 is a CODE_LABEL
1668 has a REG_RETVAL or REG_LIBCALL note (hard to adjust)
1669 is a NOTE_INSN_LOOP_BEG because this means we have a nested loop
1670 is a NOTE_INSN_BLOCK_{BEG,END} because duplicating these notes
1671 are not valid
1672
1673 Also, don't do this if the exit code is more than 20 insns. */
1674
1675 for (insn = exitcode;
1676 insn
1677 && ! (GET_CODE (insn) == NOTE
1678 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
1679 insn = NEXT_INSN (insn))
1680 {
1681 switch (GET_CODE (insn))
1682 {
1683 case CODE_LABEL:
1684 case CALL_INSN:
1685 return 0;
1686 case NOTE:
1687 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
1688 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
1689 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
1690 return 0;
1691 break;
1692 case JUMP_INSN:
1693 case INSN:
1694 if (++num_insns > 20
1695 || find_reg_note (insn, REG_RETVAL, 0)
1696 || find_reg_note (insn, REG_LIBCALL, 0))
1697 return 0;
1698 break;
1699 }
1700 }
1701
1702 /* Unless INSN is zero, we can do the optimization. */
1703 if (insn == 0)
1704 return 0;
1705
1706 lastexit = insn;
1707
1708 /* See if any insn sets a register only used in the loop exit code and
1709 not a user variable. If so, replace it with a new register. */
1710 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
1711 if (GET_CODE (insn) == INSN
1712 && (set = single_set (insn)) != 0
1713 && GET_CODE (SET_DEST (set)) == REG
1714 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1715 && regno_first_uid[REGNO (SET_DEST (set))] == INSN_UID (insn))
1716 {
1717 for (p = NEXT_INSN (insn); p != lastexit; p = NEXT_INSN (p))
1718 if (regno_last_uid[REGNO (SET_DEST (set))] == INSN_UID (p))
1719 break;
1720
1721 if (p != lastexit)
1722 {
1723 /* We can do the replacement. Allocate reg_map if this is the
1724 first replacement we found. */
1725 if (reg_map == 0)
1726 {
1727 reg_map = (rtx *) alloca (max_reg * sizeof (rtx));
1728 bzero (reg_map, max_reg * sizeof (rtx));
1729 }
1730
1731 REG_LOOP_TEST_P (SET_DEST (set)) = 1;
1732
1733 reg_map[REGNO (SET_DEST (set))]
1734 = gen_reg_rtx (GET_MODE (SET_DEST (set)));
1735 }
1736 }
1737
1738 /* Now copy each insn. */
1739 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
1740 switch (GET_CODE (insn))
1741 {
1742 case BARRIER:
1743 copy = emit_barrier_before (loop_start);
1744 break;
1745 case NOTE:
1746 /* Only copy line-number notes. */
1747 if (NOTE_LINE_NUMBER (insn) >= 0)
1748 {
1749 copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
1750 NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
1751 }
1752 break;
1753
1754 case INSN:
1755 copy = emit_insn_before (copy_rtx (PATTERN (insn)), loop_start);
1756 if (reg_map)
1757 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
1758
1759 mark_jump_label (PATTERN (copy), copy, 0);
1760
1761 /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
1762 make them. */
1763 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1764 if (REG_NOTE_KIND (link) != REG_LABEL)
1765 REG_NOTES (copy)
1766 = copy_rtx (gen_rtx (EXPR_LIST, REG_NOTE_KIND (link),
1767 XEXP (link, 0), REG_NOTES (copy)));
1768 if (reg_map && REG_NOTES (copy))
1769 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
1770 break;
1771
1772 case JUMP_INSN:
1773 copy = emit_jump_insn_before (copy_rtx (PATTERN (insn)), loop_start);
1774 if (reg_map)
1775 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
1776 mark_jump_label (PATTERN (copy), copy, 0);
1777 if (REG_NOTES (insn))
1778 {
1779 REG_NOTES (copy) = copy_rtx (REG_NOTES (insn));
1780 if (reg_map)
1781 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
1782 }
1783
1784 /* If this is a simple jump, add it to the jump chain. */
1785
1786 if (INSN_UID (copy) < max_jump_chain && JUMP_LABEL (copy)
1787 && simplejump_p (copy))
1788 {
1789 jump_chain[INSN_UID (copy)]
1790 = jump_chain[INSN_UID (JUMP_LABEL (copy))];
1791 jump_chain[INSN_UID (JUMP_LABEL (copy))] = copy;
1792 }
1793 break;
1794
1795 default:
1796 abort ();
1797 }
1798
1799 /* Now clean up by emitting a jump to the end label and deleting the jump
1800 at the start of the loop. */
1801 if (GET_CODE (copy) != BARRIER)
1802 {
1803 copy = emit_jump_insn_before (gen_jump (get_label_after (insn)),
1804 loop_start);
1805 mark_jump_label (PATTERN (copy), copy, 0);
1806 if (INSN_UID (copy) < max_jump_chain
1807 && INSN_UID (JUMP_LABEL (copy)) < max_jump_chain)
1808 {
1809 jump_chain[INSN_UID (copy)]
1810 = jump_chain[INSN_UID (JUMP_LABEL (copy))];
1811 jump_chain[INSN_UID (JUMP_LABEL (copy))] = copy;
1812 }
1813 emit_barrier_before (loop_start);
1814 }
1815
1816 delete_insn (next_nonnote_insn (loop_start));
1817
1818 /* Mark the exit code as the virtual top of the converted loop. */
1819 emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode);
1820
1821 return 1;
1822}
1823\f
1824/* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, and
1825 loop-end notes between START and END out before START. Assume neither
1826 START nor END is such a note. */
1827
1828void
1829squeeze_notes (start, end)
1830 rtx start, end;
1831{
1832 rtx insn;
1833 rtx next;
1834
1835 for (insn = start; insn != end; insn = next)
1836 {
1837 next = NEXT_INSN (insn);
1838 if (GET_CODE (insn) == NOTE
1839 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
1840 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
1841 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
1842 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
1843 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
1844 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
1845 {
1846 rtx prev = PREV_INSN (insn);
1847 PREV_INSN (insn) = PREV_INSN (start);
1848 NEXT_INSN (insn) = start;
1849 NEXT_INSN (PREV_INSN (insn)) = insn;
1850 PREV_INSN (NEXT_INSN (insn)) = insn;
1851 NEXT_INSN (prev) = next;
1852 PREV_INSN (next) = prev;
1853 }
1854 }
1855}
1856\f
1857/* Compare the instructions before insn E1 with those before E2
1858 to find an opportunity for cross jumping.
1859 (This means detecting identical sequences of insns followed by
1860 jumps to the same place, or followed by a label and a jump
1861 to that label, and replacing one with a jump to the other.)
1862
1863 Assume E1 is a jump that jumps to label E2
1864 (that is not always true but it might as well be).
1865 Find the longest possible equivalent sequences
1866 and store the first insns of those sequences into *F1 and *F2.
1867 Store zero there if no equivalent preceding instructions are found.
1868
1869 We give up if we find a label in stream 1.
1870 Actually we could transfer that label into stream 2. */
1871
1872static void
1873find_cross_jump (e1, e2, minimum, f1, f2)
1874 rtx e1, e2;
1875 int minimum;
1876 rtx *f1, *f2;
1877{
1878 register rtx i1 = e1, i2 = e2;
1879 register rtx p1, p2;
1880 int lose = 0;
1881
1882 rtx last1 = 0, last2 = 0;
1883 rtx afterlast1 = 0, afterlast2 = 0;
1884 rtx prev1;
1885
1886 *f1 = 0;
1887 *f2 = 0;
1888
1889 while (1)
1890 {
1891 i1 = prev_nonnote_insn (i1);
1892
1893 i2 = PREV_INSN (i2);
1894 while (i2 && (GET_CODE (i2) == NOTE || GET_CODE (i2) == CODE_LABEL))
1895 i2 = PREV_INSN (i2);
1896
1897 if (i1 == 0)
1898 break;
1899
1900 /* Don't allow the range of insns preceding E1 or E2
1901 to include the other (E2 or E1). */
1902 if (i2 == e1 || i1 == e2)
1903 break;
1904
1905 /* If we will get to this code by jumping, those jumps will be
1906 tensioned to go directly to the new label (before I2),
1907 so this cross-jumping won't cost extra. So reduce the minimum. */
1908 if (GET_CODE (i1) == CODE_LABEL)
1909 {
1910 --minimum;
1911 break;
1912 }
1913
1914 if (i2 == 0 || GET_CODE (i1) != GET_CODE (i2))
1915 break;
1916
1917 p1 = PATTERN (i1);
1918 p2 = PATTERN (i2);
1919
1920#ifdef STACK_REGS
1921 /* If cross_jump_death_matters is not 0, the insn's mode
1922 indicates whether or not the insn contains any stack-like
1923 regs. */
1924
1925 if (cross_jump_death_matters && GET_MODE (i1) == QImode)
1926 {
1927 /* If register stack conversion has already been done, then
1928 death notes must also be compared before it is certain that
1929 the two instruction streams match. */
1930
1931 rtx note;
1932 HARD_REG_SET i1_regset, i2_regset;
1933
1934 CLEAR_HARD_REG_SET (i1_regset);
1935 CLEAR_HARD_REG_SET (i2_regset);
1936
1937 for (note = REG_NOTES (i1); note; note = XEXP (note, 1))
1938 if (REG_NOTE_KIND (note) == REG_DEAD
1939 && STACK_REG_P (XEXP (note, 0)))
1940 SET_HARD_REG_BIT (i1_regset, REGNO (XEXP (note, 0)));
1941
1942 for (note = REG_NOTES (i2); note; note = XEXP (note, 1))
1943 if (REG_NOTE_KIND (note) == REG_DEAD
1944 && STACK_REG_P (XEXP (note, 0)))
1945 SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0)));
1946
1947 GO_IF_HARD_REG_EQUAL (i1_regset, i2_regset, done);
1948
1949 lose = 1;
1950
1951 done:
1952 ;
1953 }
1954#endif
1955
1956 if (lose || GET_CODE (p1) != GET_CODE (p2)
1957 || ! rtx_renumbered_equal_p (p1, p2))
1958 {
1959 /* The following code helps take care of G++ cleanups. */
1960 rtx equiv1;
1961 rtx equiv2;
1962
1963 if (!lose && GET_CODE (p1) == GET_CODE (p2)
1964 && ((equiv1 = find_reg_note (i1, REG_EQUAL, 0)) != 0
1965 || (equiv1 = find_reg_note (i1, REG_EQUIV, 0)) != 0)
1966 && ((equiv2 = find_reg_note (i2, REG_EQUAL, 0)) != 0
1967 || (equiv2 = find_reg_note (i2, REG_EQUIV, 0)) != 0)
1968 /* If the equivalences are not to a constant, they may
1969 reference pseudos that no longer exist, so we can't
1970 use them. */
1971 && CONSTANT_P (XEXP (equiv1, 0))
1972 && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))
1973 {
1974 rtx s1 = single_set (i1);
1975 rtx s2 = single_set (i2);
1976 if (s1 != 0 && s2 != 0
1977 && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2)))
1978 {
1979 validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1);
1980 validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1);
1981 if (! rtx_renumbered_equal_p (p1, p2))
1982 cancel_changes (0);
1983 else if (apply_change_group ())
1984 goto win;
1985 }
1986 }
1987
1988 /* Insns fail to match; cross jumping is limited to the following
1989 insns. */
1990
1991#ifdef HAVE_cc0
1992 /* Don't allow the insn after a compare to be shared by
1993 cross-jumping unless the compare is also shared.
1994 Here, if either of these non-matching insns is a compare,
1995 exclude the following insn from possible cross-jumping. */
1996 if (sets_cc0_p (p1) || sets_cc0_p (p2))
1997 last1 = afterlast1, last2 = afterlast2, ++minimum;
1998#endif
1999
2000 /* If cross-jumping here will feed a jump-around-jump
2001 optimization, this jump won't cost extra, so reduce
2002 the minimum. */
2003 if (GET_CODE (i1) == JUMP_INSN
2004 && JUMP_LABEL (i1)
2005 && prev_real_insn (JUMP_LABEL (i1)) == e1)
2006 --minimum;
2007 break;
2008 }
2009
2010 win:
2011 if (GET_CODE (p1) != USE && GET_CODE (p1) != CLOBBER)
2012 {
2013 /* Ok, this insn is potentially includable in a cross-jump here. */
2014 afterlast1 = last1, afterlast2 = last2;
2015 last1 = i1, last2 = i2, --minimum;
2016 }
2017 }
2018
2019 /* We have to be careful that we do not cross-jump into the middle of
2020 USE-CALL_INSN-CLOBBER sequence. This sequence is used instead of
2021 putting the USE and CLOBBERs inside the CALL_INSN. The delay slot
2022 scheduler needs to know what registers are used and modified by the
2023 CALL_INSN and needs the adjacent USE and CLOBBERs to do so.
2024
2025 ??? At some point we should probably change this so that these are
2026 part of the CALL_INSN. The way we are doing it now is a kludge that
2027 is now causing trouble. */
2028
2029 if (last1 != 0 && GET_CODE (last1) == CALL_INSN
2030 && (prev1 = prev_nonnote_insn (last1))
2031 && GET_CODE (prev1) == INSN
2032 && GET_CODE (PATTERN (prev1)) == USE)
2033 {
2034 /* Remove this CALL_INSN from the range we can cross-jump. */
2035 last1 = next_real_insn (last1);
2036 last2 = next_real_insn (last2);
2037
2038 minimum++;
2039 }
2040
2041 /* Skip past CLOBBERS since they may be right after a CALL_INSN. It
2042 isn't worth checking for the CALL_INSN. */
2043 while (last1 != 0 && GET_CODE (PATTERN (last1)) == CLOBBER)
2044 last1 = next_real_insn (last1), last2 = next_real_insn (last2);
2045
2046 if (minimum <= 0 && last1 != 0 && last1 != e1)
2047 *f1 = last1, *f2 = last2;
2048}
2049
2050static void
2051do_cross_jump (insn, newjpos, newlpos)
2052 rtx insn, newjpos, newlpos;
2053{
2054 /* Find an existing label at this point
2055 or make a new one if there is none. */
2056 register rtx label = get_label_before (newlpos);
2057
2058 /* Make the same jump insn jump to the new point. */
2059 if (GET_CODE (PATTERN (insn)) == RETURN)
2060 {
2061 /* Remove from jump chain of returns. */
2062 delete_from_jump_chain (insn);
2063 /* Change the insn. */
2064 PATTERN (insn) = gen_jump (label);
2065 INSN_CODE (insn) = -1;
2066 JUMP_LABEL (insn) = label;
2067 LABEL_NUSES (label)++;
2068 /* Add to new the jump chain. */
2069 if (INSN_UID (label) < max_jump_chain
2070 && INSN_UID (insn) < max_jump_chain)
2071 {
2072 jump_chain[INSN_UID (insn)] = jump_chain[INSN_UID (label)];
2073 jump_chain[INSN_UID (label)] = insn;
2074 }
2075 }
2076 else
2077 redirect_jump (insn, label);
2078
2079 /* Delete the matching insns before the jump. Also, remove any REG_EQUAL
2080 or REG_EQUIV note in the NEWLPOS stream that isn't also present in
2081 the NEWJPOS stream. */
2082
2083 while (newjpos != insn)
2084 {
2085 rtx lnote;
2086
2087 for (lnote = REG_NOTES (newlpos); lnote; lnote = XEXP (lnote, 1))
2088 if ((REG_NOTE_KIND (lnote) == REG_EQUAL
2089 || REG_NOTE_KIND (lnote) == REG_EQUIV)
2090 && ! find_reg_note (newjpos, REG_EQUAL, XEXP (lnote, 0))
2091 && ! find_reg_note (newjpos, REG_EQUIV, XEXP (lnote, 0)))
2092 remove_note (newlpos, lnote);
2093
2094 delete_insn (newjpos);
2095 newjpos = next_real_insn (newjpos);
2096 newlpos = next_real_insn (newlpos);
2097 }
2098}
2099\f
2100/* Return the label before INSN, or put a new label there. */
2101
2102rtx
2103get_label_before (insn)
2104 rtx insn;
2105{
2106 rtx label;
2107
2108 /* Find an existing label at this point
2109 or make a new one if there is none. */
2110 label = prev_nonnote_insn (insn);
2111
2112 if (label == 0 || GET_CODE (label) != CODE_LABEL)
2113 {
2114 rtx prev = PREV_INSN (insn);
2115
2116 /* Don't put a label between a CALL_INSN and USE insns that preceed
2117 it. */
2118
2119 if (GET_CODE (insn) == CALL_INSN
2120 || (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE
2121 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN))
2122 while (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == USE)
2123 prev = PREV_INSN (prev);
2124
2125 label = gen_label_rtx ();
2126 emit_label_after (label, prev);
2127 LABEL_NUSES (label) = 0;
2128 }
2129 return label;
2130}
2131
2132/* Return the label after INSN, or put a new label there. */
2133
2134rtx
2135get_label_after (insn)
2136 rtx insn;
2137{
2138 rtx label;
2139
2140 /* Find an existing label at this point
2141 or make a new one if there is none. */
2142 label = next_nonnote_insn (insn);
2143
2144 if (label == 0 || GET_CODE (label) != CODE_LABEL)
2145 {
2146 /* Don't put a label between a CALL_INSN and CLOBBER insns
2147 following it. */
2148
2149 if (GET_CODE (insn) == CALL_INSN
2150 || (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE
2151 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN))
2152 while (GET_CODE (NEXT_INSN (insn)) == INSN
2153 && GET_CODE (PATTERN (NEXT_INSN (insn))) == CLOBBER)
2154 insn = NEXT_INSN (insn);
2155
2156 label = gen_label_rtx ();
2157 emit_label_after (label, insn);
2158 LABEL_NUSES (label) = 0;
2159 }
2160 return label;
2161}
2162\f
2163/* Return 1 if INSN is a jump that jumps to right after TARGET
2164 only on the condition that TARGET itself would drop through.
2165 Assumes that TARGET is a conditional jump. */
2166
2167static int
2168jump_back_p (insn, target)
2169 rtx insn, target;
2170{
2171 rtx cinsn, ctarget;
2172 enum rtx_code codei, codet;
2173
2174 if (simplejump_p (insn) || ! condjump_p (insn)
2175 || simplejump_p (target)
2176 || target != prev_real_insn (JUMP_LABEL (insn)))
2177 return 0;
2178
2179 cinsn = XEXP (SET_SRC (PATTERN (insn)), 0);
2180 ctarget = XEXP (SET_SRC (PATTERN (target)), 0);
2181
2182 codei = GET_CODE (cinsn);
2183 codet = GET_CODE (ctarget);
2184
2185 if (XEXP (SET_SRC (PATTERN (insn)), 1) == pc_rtx)
2186 {
2187 if (! can_reverse_comparison_p (cinsn, insn))
2188 return 0;
2189 codei = reverse_condition (codei);
2190 }
2191
2192 if (XEXP (SET_SRC (PATTERN (target)), 2) == pc_rtx)
2193 {
2194 if (! can_reverse_comparison_p (ctarget, target))
2195 return 0;
2196 codet = reverse_condition (codet);
2197 }
2198
2199 return (codei == codet
2200 && rtx_renumbered_equal_p (XEXP (cinsn, 0), XEXP (ctarget, 0))
2201 && rtx_renumbered_equal_p (XEXP (cinsn, 1), XEXP (ctarget, 1)));
2202}
2203\f
2204/* Given a comparison, COMPARISON, inside a conditional jump insn, INSN,
2205 return non-zero if it is safe to reverse this comparison. It is if our
2206 floating-point is not IEEE, if this is an NE or EQ comparison, or if
2207 this is known to be an integer comparison. */
2208
2209int
2210can_reverse_comparison_p (comparison, insn)
2211 rtx comparison;
2212 rtx insn;
2213{
2214 rtx arg0;
2215
2216 /* If this is not actually a comparison, we can't reverse it. */
2217 if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
2218 return 0;
2219
2220 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
2221 /* If this is an NE comparison, it is safe to reverse it to an EQ
2222 comparison and vice versa, even for floating point. If no operands
2223 are NaNs, the reversal is valid. If some operand is a NaN, EQ is
2224 always false and NE is always true, so the reversal is also valid. */
2225 || GET_CODE (comparison) == NE
2226 || GET_CODE (comparison) == EQ)
2227 return 1;
2228
2229 arg0 = XEXP (comparison, 0);
2230
2231 /* Make sure ARG0 is one of the actual objects being compared. If we
2232 can't do this, we can't be sure the comparison can be reversed.
2233
2234 Handle cc0 and a MODE_CC register. */
2235 if ((GET_CODE (arg0) == REG && GET_MODE_CLASS (GET_MODE (arg0)) == MODE_CC)
2236#ifdef HAVE_cc0
2237 || arg0 == cc0_rtx
2238#endif
2239 )
2240 {
2241 rtx prev = prev_nonnote_insn (insn);
2242 rtx set = single_set (prev);
2243
2244 if (set == 0 || SET_DEST (set) != arg0)
2245 return 0;
2246
2247 arg0 = SET_SRC (set);
2248
2249 if (GET_CODE (arg0) == COMPARE)
2250 arg0 = XEXP (arg0, 0);
2251 }
2252
2253 /* We can reverse this if ARG0 is a CONST_INT or if its mode is
2254 not VOIDmode and neither a MODE_CC nor MODE_FLOAT type. */
2255 return (GET_CODE (arg0) == CONST_INT
2256 || (GET_MODE (arg0) != VOIDmode
2257 && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_CC
2258 && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_FLOAT));
2259}
2260
2261/* Given an rtx-code for a comparison, return the code
2262 for the negated comparison.
2263 WATCH OUT! reverse_condition is not safe to use on a jump
2264 that might be acting on the results of an IEEE floating point comparison,
2265 because of the special treatment of non-signaling nans in comparisons.
2266 Use can_reverse_comparison_p to be sure. */
2267
2268enum rtx_code
2269reverse_condition (code)
2270 enum rtx_code code;
2271{
2272 switch (code)
2273 {
2274 case EQ:
2275 return NE;
2276
2277 case NE:
2278 return EQ;
2279
2280 case GT:
2281 return LE;
2282
2283 case GE:
2284 return LT;
2285
2286 case LT:
2287 return GE;
2288
2289 case LE:
2290 return GT;
2291
2292 case GTU:
2293 return LEU;
2294
2295 case GEU:
2296 return LTU;
2297
2298 case LTU:
2299 return GEU;
2300
2301 case LEU:
2302 return GTU;
2303
2304 default:
2305 abort ();
2306 return UNKNOWN;
2307 }
2308}
2309
2310/* Similar, but return the code when two operands of a comparison are swapped.
2311 This IS safe for IEEE floating-point. */
2312
2313enum rtx_code
2314swap_condition (code)
2315 enum rtx_code code;
2316{
2317 switch (code)
2318 {
2319 case EQ:
2320 case NE:
2321 return code;
2322
2323 case GT:
2324 return LT;
2325
2326 case GE:
2327 return LE;
2328
2329 case LT:
2330 return GT;
2331
2332 case LE:
2333 return GE;
2334
2335 case GTU:
2336 return LTU;
2337
2338 case GEU:
2339 return LEU;
2340
2341 case LTU:
2342 return GTU;
2343
2344 case LEU:
2345 return GEU;
2346
2347 default:
2348 abort ();
2349 return UNKNOWN;
2350 }
2351}
2352
2353/* Given a comparison CODE, return the corresponding unsigned comparison.
2354 If CODE is an equality comparison or already an unsigned comparison,
2355 CODE is returned. */
2356
2357enum rtx_code
2358unsigned_condition (code)
2359 enum rtx_code code;
2360{
2361 switch (code)
2362 {
2363 case EQ:
2364 case NE:
2365 case GTU:
2366 case GEU:
2367 case LTU:
2368 case LEU:
2369 return code;
2370
2371 case GT:
2372 return GTU;
2373
2374 case GE:
2375 return GEU;
2376
2377 case LT:
2378 return LTU;
2379
2380 case LE:
2381 return LEU;
2382
2383 default:
2384 abort ();
2385 }
2386}
2387
2388/* Similarly, return the signed version of a comparison. */
2389
2390enum rtx_code
2391signed_condition (code)
2392 enum rtx_code code;
2393{
2394 switch (code)
2395 {
2396 case EQ:
2397 case NE:
2398 case GT:
2399 case GE:
2400 case LT:
2401 case LE:
2402 return code;
2403
2404 case GTU:
2405 return GT;
2406
2407 case GEU:
2408 return GE;
2409
2410 case LTU:
2411 return LT;
2412
2413 case LEU:
2414 return LE;
2415
2416 default:
2417 abort ();
2418 }
2419}
2420\f
2421/* Return non-zero if CODE1 is more strict than CODE2, i.e., if the
2422 truth of CODE1 implies the truth of CODE2. */
2423
2424int
2425comparison_dominates_p (code1, code2)
2426 enum rtx_code code1, code2;
2427{
2428 if (code1 == code2)
2429 return 1;
2430
2431 switch (code1)
2432 {
2433 case EQ:
2434 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU)
2435 return 1;
2436 break;
2437
2438 case LT:
2439 if (code2 == LE)
2440 return 1;
2441 break;
2442
2443 case GT:
2444 if (code2 == GE)
2445 return 1;
2446 break;
2447
2448 case LTU:
2449 if (code2 == LEU)
2450 return 1;
2451 break;
2452
2453 case GTU:
2454 if (code2 == GEU)
2455 return 1;
2456 break;
2457 }
2458
2459 return 0;
2460}
2461\f
2462/* Return 1 if INSN is an unconditional jump and nothing else. */
2463
2464int
2465simplejump_p (insn)
2466 rtx insn;
2467{
2468 return (GET_CODE (insn) == JUMP_INSN
2469 && GET_CODE (PATTERN (insn)) == SET
2470 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
2471 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
2472}
2473
2474/* Return nonzero if INSN is a (possibly) conditional jump
2475 and nothing more. */
2476
2477int
2478condjump_p (insn)
2479 rtx insn;
2480{
2481 register rtx x = PATTERN (insn);
2482 if (GET_CODE (x) != SET)
2483 return 0;
2484 if (GET_CODE (SET_DEST (x)) != PC)
2485 return 0;
2486 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
2487 return 1;
2488 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
2489 return 0;
2490 if (XEXP (SET_SRC (x), 2) == pc_rtx
2491 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
2492 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
2493 return 1;
2494 if (XEXP (SET_SRC (x), 1) == pc_rtx
2495 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
2496 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
2497 return 1;
2498 return 0;
2499}
2500
2501/* Return 1 if X is an RTX that does nothing but set the condition codes
2502 and CLOBBER or USE registers.
2503 Return -1 if X does explicitly set the condition codes,
2504 but also does other things. */
2505
2506int
2507sets_cc0_p (x)
2508 rtx x;
2509{
2510#ifdef HAVE_cc0
2511 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
2512 return 1;
2513 if (GET_CODE (x) == PARALLEL)
2514 {
2515 int i;
2516 int sets_cc0 = 0;
2517 int other_things = 0;
2518 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
2519 {
2520 if (GET_CODE (XVECEXP (x, 0, i)) == SET
2521 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
2522 sets_cc0 = 1;
2523 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
2524 other_things = 1;
2525 }
2526 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
2527 }
2528 return 0;
2529#else
2530 abort ();
2531#endif
2532}
2533\f
2534/* Follow any unconditional jump at LABEL;
2535 return the ultimate label reached by any such chain of jumps.
2536 If LABEL is not followed by a jump, return LABEL.
2d20b9df
RS
2537 If the chain loops or we can't find end, return LABEL,
2538 since that tells caller to avoid changing the insn.
15a63be1
RK
2539
2540 If RELOAD_COMPLETED is 0, we do not chain across a NOTE_INSN_LOOP_BEG or
2541 a USE or CLOBBER. */
2542
2543rtx
2544follow_jumps (label)
2545 rtx label;
2546{
2547 register rtx insn;
2548 register rtx next;
2549 register rtx value = label;
2550 register int depth;
2551
2552 for (depth = 0;
2553 (depth < 10
2554 && (insn = next_active_insn (value)) != 0
2555 && GET_CODE (insn) == JUMP_INSN
2556 && (JUMP_LABEL (insn) != 0 || GET_CODE (PATTERN (insn)) == RETURN)
2557 && (next = NEXT_INSN (insn))
2558 && GET_CODE (next) == BARRIER);
2559 depth++)
2560 {
2561 /* Don't chain through the insn that jumps into a loop
2562 from outside the loop,
2563 since that would create multiple loop entry jumps
2564 and prevent loop optimization. */
2565 rtx tem;
2566 if (!reload_completed)
2567 for (tem = value; tem != insn; tem = NEXT_INSN (tem))
2568 if (GET_CODE (tem) == NOTE
2569 && NOTE_LINE_NUMBER (tem) == NOTE_INSN_LOOP_BEG)
2570 return value;
2571
2572 /* If we have found a cycle, make the insn jump to itself. */
2573 if (JUMP_LABEL (insn) == label)
2d20b9df 2574 return label;
15a63be1
RK
2575 value = JUMP_LABEL (insn);
2576 }
2d20b9df
RS
2577 if (depth == 10)
2578 return label;
15a63be1
RK
2579 return value;
2580}
2581
2582/* Assuming that field IDX of X is a vector of label_refs,
2583 replace each of them by the ultimate label reached by it.
2584 Return nonzero if a change is made.
2585 If IGNORE_LOOPS is 0, we do not chain across a NOTE_INSN_LOOP_BEG. */
2586
2587static int
2588tension_vector_labels (x, idx)
2589 register rtx x;
2590 register int idx;
2591{
2592 int changed = 0;
2593 register int i;
2594 for (i = XVECLEN (x, idx) - 1; i >= 0; i--)
2595 {
2596 register rtx olabel = XEXP (XVECEXP (x, idx, i), 0);
2597 register rtx nlabel = follow_jumps (olabel);
2598 if (nlabel && nlabel != olabel)
2599 {
2600 XEXP (XVECEXP (x, idx, i), 0) = nlabel;
2601 ++LABEL_NUSES (nlabel);
2602 if (--LABEL_NUSES (olabel) == 0)
2603 delete_insn (olabel);
2604 changed = 1;
2605 }
2606 }
2607 return changed;
2608}
2609\f
2610/* Find all CODE_LABELs referred to in X, and increment their use counts.
2611 If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced
2612 in INSN, then store one of them in JUMP_LABEL (INSN).
2613 If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL
2614 referenced in INSN, add a REG_LABEL note containing that label to INSN.
2615 Also, when there are consecutive labels, canonicalize on the last of them.
2616
2617 Note that two labels separated by a loop-beginning note
2618 must be kept distinct if we have not yet done loop-optimization,
2619 because the gap between them is where loop-optimize
2620 will want to move invariant code to. CROSS_JUMP tells us
2621 that loop-optimization is done with.
2622
2623 Once reload has completed (CROSS_JUMP non-zero), we need not consider
2624 two labels distinct if they are separated by only USE or CLOBBER insns. */
2625
2626static void
2627mark_jump_label (x, insn, cross_jump)
2628 register rtx x;
2629 rtx insn;
2630 int cross_jump;
2631{
2632 register RTX_CODE code = GET_CODE (x);
2633 register int i;
2634 register char *fmt;
2635
2636 switch (code)
2637 {
2638 case PC:
2639 case CC0:
2640 case REG:
2641 case SUBREG:
2642 case CONST_INT:
2643 case SYMBOL_REF:
2644 case CONST_DOUBLE:
2645 case CLOBBER:
2646 case CALL:
2647 return;
2648
2649 case LABEL_REF:
2650 {
2651 register rtx label = XEXP (x, 0);
2652 register rtx next;
2653 if (GET_CODE (label) != CODE_LABEL)
2654 abort ();
2655 /* If there are other labels following this one,
2656 replace it with the last of the consecutive labels. */
2657 for (next = NEXT_INSN (label); next; next = NEXT_INSN (next))
2658 {
2659 if (GET_CODE (next) == CODE_LABEL)
2660 label = next;
2661 else if (cross_jump && GET_CODE (next) == INSN
2662 && (GET_CODE (PATTERN (next)) == USE
2663 || GET_CODE (PATTERN (next)) == CLOBBER))
2664 continue;
2665 else if (GET_CODE (next) != NOTE)
2666 break;
2667 else if (! cross_jump
2668 && (NOTE_LINE_NUMBER (next) == NOTE_INSN_LOOP_BEG
2669 || NOTE_LINE_NUMBER (next) == NOTE_INSN_FUNCTION_END))
2670 break;
2671 }
2672 XEXP (x, 0) = label;
2673 ++LABEL_NUSES (label);
2674 if (insn)
2675 {
2676 if (GET_CODE (insn) == JUMP_INSN)
2677 JUMP_LABEL (insn) = label;
0e690bdb 2678 else if (! find_reg_note (insn, REG_LABEL, label))
15a63be1
RK
2679 {
2680 rtx next = next_real_insn (label);
2681 /* Don't record labels that refer to dispatch tables.
2682 This is not necessary, since the tablejump
2683 references the same label.
2684 And if we did record them, flow.c would make worse code. */
2685 if (next == 0
2686 || ! (GET_CODE (next) == JUMP_INSN
2687 && (GET_CODE (PATTERN (next)) == ADDR_VEC
2688 || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC)))
2689 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_LABEL, label,
2690 REG_NOTES (insn));
2691 }
2692 }
2693 return;
2694 }
2695
2696 /* Do walk the labels in a vector, but not the first operand of an
2697 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
2698 case ADDR_VEC:
2699 case ADDR_DIFF_VEC:
2700 {
2701 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
2702
2703 for (i = 0; i < XVECLEN (x, eltnum); i++)
2704 mark_jump_label (XVECEXP (x, eltnum, i), 0, cross_jump);
2705 return;
2706 }
2707 }
2708
2709 fmt = GET_RTX_FORMAT (code);
2710 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2711 {
2712 if (fmt[i] == 'e')
2713 mark_jump_label (XEXP (x, i), insn, cross_jump);
2714 else if (fmt[i] == 'E')
2715 {
2716 register int j;
2717 for (j = 0; j < XVECLEN (x, i); j++)
2718 mark_jump_label (XVECEXP (x, i, j), insn, cross_jump);
2719 }
2720 }
2721}
2722
2723/* If all INSN does is set the pc, delete it,
2724 and delete the insn that set the condition codes for it
2725 if that's what the previous thing was. */
2726
2727void
2728delete_jump (insn)
2729 rtx insn;
2730{
2731 register rtx x = PATTERN (insn);
2732 register rtx prev;
2733
2734 if (GET_CODE (x) == SET
2735 && GET_CODE (SET_DEST (x)) == PC)
2736 {
2737 prev = prev_nonnote_insn (insn);
2738#ifdef HAVE_cc0
2739 /* We assume that at this stage
2740 CC's are always set explicitly
2741 and always immediately before the jump that
2742 will use them. So if the previous insn
2743 exists to set the CC's, delete it
2744 (unless it performs auto-increments, etc.). */
2745 if (prev && GET_CODE (prev) == INSN
2746 && sets_cc0_p (PATTERN (prev)))
2747 {
2748 if (sets_cc0_p (PATTERN (prev)) > 0
2749 && !FIND_REG_INC_NOTE (prev, 0))
2750 delete_insn (prev);
2751 else
2752 /* Otherwise, show that cc0 won't be used. */
2753 REG_NOTES (prev) = gen_rtx (EXPR_LIST, REG_UNUSED,
2754 cc0_rtx, REG_NOTES (prev));
2755 }
2756#else
2757 {
2758 rtx note;
2759
2760 /* If we are running before flow.c, we need do nothing since flow.c
2761 will delete the set of the condition code if it is dead. We also
2762 can't know if the register being used as the condition code is
2763 dead or not at this point.
2764
2765 Otherwise, look at all our REG_DEAD notes. If a previous insn
2766 does nothing other than set a register that dies in this jump,
2767 we can delete the insn. */
2768
2769 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
2770 {
2771 rtx our_prev;
2772
2773 if (REG_NOTE_KIND (note) != REG_DEAD
2774 /* Verify that the REG_NOTE has a legal value. */
2775 || GET_CODE (XEXP (note, 0)) != REG)
2776 continue;
2777
2778 for (our_prev = prev_nonnote_insn (insn);
2779 our_prev && GET_CODE (our_prev) == INSN;
2780 our_prev = prev_nonnote_insn (our_prev))
2781 {
2782 /* If we reach a SEQUENCE, it is too complex to try to
2783 do anything with it, so give up. */
2784 if (GET_CODE (PATTERN (our_prev)) == SEQUENCE)
2785 break;
2786
2787 if (GET_CODE (PATTERN (our_prev)) == USE
2788 && GET_CODE (XEXP (PATTERN (our_prev), 0)) == INSN)
2789 /* reorg creates USEs that look like this. We leave them
2790 alone because reorg needs them for its own purposes. */
2791 break;
2792
2793 if (reg_set_p (XEXP (note, 0), PATTERN (our_prev)))
2794 {
2795 if (FIND_REG_INC_NOTE (our_prev, 0))
2796 break;
2797
2798 if (GET_CODE (PATTERN (our_prev)) == PARALLEL)
2799 {
2800 /* If we find a SET of something else, we can't
2801 delete the insn. */
2802
2803 int i;
2804
2805 for (i = 0; i < XVECLEN (PATTERN (our_prev), 0); i++)
2806 {
2807 rtx part = XVECEXP (PATTERN (our_prev), 0, i);
2808
2809 if (GET_CODE (part) == SET
2810 && SET_DEST (part) != XEXP (note, 0))
2811 break;
2812 }
2813
2814 if (i == XVECLEN (PATTERN (our_prev), 0))
2815 delete_insn (our_prev);
2816 }
2817 else if (GET_CODE (PATTERN (our_prev)) == SET
2818 && SET_DEST (PATTERN (our_prev)) == XEXP (note, 0))
2819 delete_insn (our_prev);
2820
2821 break;
2822 }
2823
2824 /* If OUR_PREV references the register that dies here,
2825 it is an additional use. Hence any prior SET isn't
2826 dead. */
2827 if (reg_overlap_mentioned_p (XEXP (note, 0),
2828 PATTERN (our_prev)))
2829 break;
2830 }
2831 }
2832 }
2833#endif
2834 /* Now delete the jump insn itself. */
2835 delete_insn (insn);
2836 }
2837}
2838\f
2839/* Delete insn INSN from the chain of insns and update label ref counts.
2840 May delete some following insns as a consequence; may even delete
2841 a label elsewhere and insns that follow it.
2842
2843 Returns the first insn after INSN that was not deleted. */
2844
2845rtx
2846delete_insn (insn)
2847 register rtx insn;
2848{
2849 register rtx next = NEXT_INSN (insn);
2850 register rtx prev = PREV_INSN (insn);
2851
2852 while (next && INSN_DELETED_P (next))
2853 next = NEXT_INSN (next);
2854
2855 /* This insn is already deleted => return first following nondeleted. */
2856 if (INSN_DELETED_P (insn))
2857 return next;
2858
2859 /* Mark this insn as deleted. */
2860
2861 INSN_DELETED_P (insn) = 1;
2862
2863 /* If this is an unconditional jump, delete it from the jump chain. */
2864 if (simplejump_p (insn))
2865 delete_from_jump_chain (insn);
2866
2867 /* If instruction is followed by a barrier,
2868 delete the barrier too. */
2869
2870 if (next != 0 && GET_CODE (next) == BARRIER)
2871 {
2872 INSN_DELETED_P (next) = 1;
2873 next = NEXT_INSN (next);
2874 }
2875
2876 /* Patch out INSN (and the barrier if any) */
2877
2878 if (optimize)
2879 {
2880 if (prev)
2881 {
2882 NEXT_INSN (prev) = next;
2883 if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SEQUENCE)
2884 NEXT_INSN (XVECEXP (PATTERN (prev), 0,
2885 XVECLEN (PATTERN (prev), 0) - 1)) = next;
2886 }
2887
2888 if (next)
2889 {
2890 PREV_INSN (next) = prev;
2891 if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE)
2892 PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
2893 }
2894
2895 if (prev && NEXT_INSN (prev) == 0)
2896 set_last_insn (prev);
2897 }
2898
2899 /* If deleting a jump, decrement the count of the label,
2900 and delete the label if it is now unused. */
2901
2902 if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
2903 if (--LABEL_NUSES (JUMP_LABEL (insn)) == 0)
2904 {
2905 /* This can delete NEXT or PREV,
2906 either directly if NEXT is JUMP_LABEL (INSN),
2907 or indirectly through more levels of jumps. */
2908 delete_insn (JUMP_LABEL (insn));
2909 /* I feel a little doubtful about this loop,
2910 but I see no clean and sure alternative way
2911 to find the first insn after INSN that is not now deleted.
2912 I hope this works. */
2913 while (next && INSN_DELETED_P (next))
2914 next = NEXT_INSN (next);
2915 return next;
2916 }
2917
2918 while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
2919 prev = PREV_INSN (prev);
2920
2921 /* If INSN was a label and a dispatch table follows it,
2922 delete the dispatch table. The tablejump must have gone already.
2923 It isn't useful to fall through into a table. */
2924
2925 if (GET_CODE (insn) == CODE_LABEL
2926 && NEXT_INSN (insn) != 0
2927 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
2928 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
2929 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
2930 next = delete_insn (NEXT_INSN (insn));
2931
2932 /* If INSN was a label, delete insns following it if now unreachable. */
2933
2934 if (GET_CODE (insn) == CODE_LABEL && prev
2935 && GET_CODE (prev) == BARRIER)
2936 {
2937 register RTX_CODE code;
2938 while (next != 0
2939 && ((code = GET_CODE (next)) == INSN
2940 || code == JUMP_INSN || code == CALL_INSN
2941 || code == NOTE))
2942 {
2943 if (code == NOTE
2944 && NOTE_LINE_NUMBER (next) != NOTE_INSN_FUNCTION_END)
2945 next = NEXT_INSN (next);
2946 else
2947 /* Note: if this deletes a jump, it can cause more
2948 deletion of unreachable code, after a different label.
2949 As long as the value from this recursive call is correct,
2950 this invocation functions correctly. */
2951 next = delete_insn (next);
2952 }
2953 }
2954
2955 return next;
2956}
2957
2958/* Advance from INSN till reaching something not deleted
2959 then return that. May return INSN itself. */
2960
2961rtx
2962next_nondeleted_insn (insn)
2963 rtx insn;
2964{
2965 while (INSN_DELETED_P (insn))
2966 insn = NEXT_INSN (insn);
2967 return insn;
2968}
2969\f
2970/* Delete a range of insns from FROM to TO, inclusive.
2971 This is for the sake of peephole optimization, so assume
2972 that whatever these insns do will still be done by a new
2973 peephole insn that will replace them. */
2974
2975void
2976delete_for_peephole (from, to)
2977 register rtx from, to;
2978{
2979 register rtx insn = from;
2980
2981 while (1)
2982 {
2983 register rtx next = NEXT_INSN (insn);
2984 register rtx prev = PREV_INSN (insn);
2985
2986 if (GET_CODE (insn) != NOTE)
2987 {
2988 INSN_DELETED_P (insn) = 1;
2989
2990 /* Patch this insn out of the chain. */
2991 /* We don't do this all at once, because we
2992 must preserve all NOTEs. */
2993 if (prev)
2994 NEXT_INSN (prev) = next;
2995
2996 if (next)
2997 PREV_INSN (next) = prev;
2998 }
2999
3000 if (insn == to)
3001 break;
3002 insn = next;
3003 }
3004
3005 /* Note that if TO is an unconditional jump
3006 we *do not* delete the BARRIER that follows,
3007 since the peephole that replaces this sequence
3008 is also an unconditional jump in that case. */
3009}
3010\f
3011/* Invert the condition of the jump JUMP, and make it jump
3012 to label NLABEL instead of where it jumps now. */
3013
3014int
3015invert_jump (jump, nlabel)
3016 rtx jump, nlabel;
3017{
3018 register rtx olabel = JUMP_LABEL (jump);
3019
3020 /* We have to either invert the condition and change the label or
3021 do neither. Either operation could fail. We first try to invert
3022 the jump. If that succeeds, we try changing the label. If that fails,
3023 we invert the jump back to what it was. */
3024
3025 if (! invert_exp (PATTERN (jump), jump))
3026 return 0;
3027
3028 if (redirect_jump (jump, nlabel))
3029 return 1;
3030
3031 if (! invert_exp (PATTERN (jump), jump))
3032 /* This should just be putting it back the way it was. */
3033 abort ();
3034
3035 return 0;
3036}
3037
3038/* Invert the jump condition of rtx X contained in jump insn, INSN.
3039
3040 Return 1 if we can do so, 0 if we cannot find a way to do so that
3041 matches a pattern. */
3042
3043static int
3044invert_exp (x, insn)
3045 rtx x;
3046 rtx insn;
3047{
3048 register RTX_CODE code;
3049 register int i;
3050 register char *fmt;
3051
3052 code = GET_CODE (x);
3053
3054 if (code == IF_THEN_ELSE)
3055 {
3056 register rtx comp = XEXP (x, 0);
3057 register rtx tem;
3058
3059 /* We can do this in two ways: The preferable way, which can only
3060 be done if this is not an integer comparison, is to reverse
3061 the comparison code. Otherwise, swap the THEN-part and ELSE-part
3062 of the IF_THEN_ELSE. If we can't do either, fail. */
3063
3064 if (can_reverse_comparison_p (comp, insn)
3065 && validate_change (insn, &XEXP (x, 0),
3066 gen_rtx (reverse_condition (GET_CODE (comp)),
3067 GET_MODE (comp), XEXP (comp, 0),
3068 XEXP (comp, 1)), 0))
3069 return 1;
3070
3071 tem = XEXP (x, 1);
3072 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
3073 validate_change (insn, &XEXP (x, 2), tem, 1);
3074 return apply_change_group ();
3075 }
3076
3077 fmt = GET_RTX_FORMAT (code);
3078 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3079 {
3080 if (fmt[i] == 'e')
3081 if (! invert_exp (XEXP (x, i), insn))
3082 return 0;
3083 if (fmt[i] == 'E')
3084 {
3085 register int j;
3086 for (j = 0; j < XVECLEN (x, i); j++)
3087 if (!invert_exp (XVECEXP (x, i, j), insn))
3088 return 0;
3089 }
3090 }
3091
3092 return 1;
3093}
3094\f
3095/* Make jump JUMP jump to label NLABEL instead of where it jumps now.
3096 If the old jump target label is unused as a result,
3097 it and the code following it may be deleted.
3098
3099 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
3100 RETURN insn.
3101
3102 The return value will be 1 if the change was made, 0 if it wasn't (this
3103 can only occur for NLABEL == 0). */
3104
3105int
3106redirect_jump (jump, nlabel)
3107 rtx jump, nlabel;
3108{
3109 register rtx olabel = JUMP_LABEL (jump);
3110
3111 if (nlabel == olabel)
3112 return 1;
3113
3114 if (! redirect_exp (&PATTERN (jump), olabel, nlabel, jump))
3115 return 0;
3116
3117 /* If this is an unconditional branch, delete it from the jump_chain of
3118 OLABEL and add it to the jump_chain of NLABEL (assuming both labels
3119 have UID's in range and JUMP_CHAIN is valid). */
3120 if (jump_chain && (simplejump_p (jump)
3121 || GET_CODE (PATTERN (jump)) == RETURN))
3122 {
3123 int label_index = nlabel ? INSN_UID (nlabel) : 0;
3124
3125 delete_from_jump_chain (jump);
2d20b9df
RS
3126 if (label_index < max_jump_chain
3127 && INSN_UID (jump) < max_jump_chain)
15a63be1
RK
3128 {
3129 jump_chain[INSN_UID (jump)] = jump_chain[label_index];
3130 jump_chain[label_index] = jump;
3131 }
3132 }
3133
3134 JUMP_LABEL (jump) = nlabel;
3135 if (nlabel)
3136 ++LABEL_NUSES (nlabel);
3137
3138 if (olabel && --LABEL_NUSES (olabel) == 0)
3139 delete_insn (olabel);
3140
3141 return 1;
3142}
3143
3144/* Delete the instruction JUMP from any jump chain it might be on. */
3145
3146static void
3147delete_from_jump_chain (jump)
3148 rtx jump;
3149{
3150 int index;
3151 rtx olabel = JUMP_LABEL (jump);
3152
3153 /* Handle unconditional jumps. */
3154 if (jump_chain && olabel != 0
3155 && INSN_UID (olabel) < max_jump_chain
3156 && simplejump_p (jump))
3157 index = INSN_UID (olabel);
3158 /* Handle return insns. */
3159 else if (jump_chain && GET_CODE (PATTERN (jump)) == RETURN)
3160 index = 0;
3161 else return;
3162
3163 if (jump_chain[index] == jump)
3164 jump_chain[index] = jump_chain[INSN_UID (jump)];
3165 else
3166 {
3167 rtx insn;
3168
3169 for (insn = jump_chain[index];
3170 insn != 0;
3171 insn = jump_chain[INSN_UID (insn)])
3172 if (jump_chain[INSN_UID (insn)] == jump)
3173 {
3174 jump_chain[INSN_UID (insn)] = jump_chain[INSN_UID (jump)];
3175 break;
3176 }
3177 }
3178}
3179
3180/* If NLABEL is nonzero, throughout the rtx at LOC,
3181 alter (LABEL_REF OLABEL) to (LABEL_REF NLABEL). If OLABEL is
3182 zero, alter (RETURN) to (LABEL_REF NLABEL).
3183
3184 If NLABEL is zero, alter (LABEL_REF OLABEL) to (RETURN) and check
3185 validity with validate_change. Convert (set (pc) (label_ref olabel))
3186 to (return).
3187
3188 Return 0 if we found a change we would like to make but it is invalid.
3189 Otherwise, return 1. */
3190
3191static int
3192redirect_exp (loc, olabel, nlabel, insn)
3193 rtx *loc;
3194 rtx olabel, nlabel;
3195 rtx insn;
3196{
3197 register rtx x = *loc;
3198 register RTX_CODE code = GET_CODE (x);
3199 register int i;
3200 register char *fmt;
3201
3202 if (code == LABEL_REF)
3203 {
3204 if (XEXP (x, 0) == olabel)
3205 {
3206 if (nlabel)
3207 XEXP (x, 0) = nlabel;
3208 else
3209 return validate_change (insn, loc, gen_rtx (RETURN, VOIDmode), 0);
3210 return 1;
3211 }
3212 }
3213 else if (code == RETURN && olabel == 0)
3214 {
3215 x = gen_rtx (LABEL_REF, VOIDmode, nlabel);
3216 if (loc == &PATTERN (insn))
3217 x = gen_rtx (SET, VOIDmode, pc_rtx, x);
3218 return validate_change (insn, loc, x, 0);
3219 }
3220
3221 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
3222 && GET_CODE (SET_SRC (x)) == LABEL_REF
3223 && XEXP (SET_SRC (x), 0) == olabel)
3224 return validate_change (insn, loc, gen_rtx (RETURN, VOIDmode), 0);
3225
3226 fmt = GET_RTX_FORMAT (code);
3227 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3228 {
3229 if (fmt[i] == 'e')
3230 if (! redirect_exp (&XEXP (x, i), olabel, nlabel, insn))
3231 return 0;
3232 if (fmt[i] == 'E')
3233 {
3234 register int j;
3235 for (j = 0; j < XVECLEN (x, i); j++)
3236 if (! redirect_exp (&XVECEXP (x, i, j), olabel, nlabel, insn))
3237 return 0;
3238 }
3239 }
3240
3241 return 1;
3242}
3243\f
3244/* Make jump JUMP jump to label NLABEL, assuming it used to be a tablejump.
3245
3246 If the old jump target label (before the dispatch table) becomes unused,
3247 it and the dispatch table may be deleted. In that case, find the insn
3248 before the jump references that label and delete it and logical sucessors
3249 too. */
3250
3251void
3252redirect_tablejump (jump, nlabel)
3253 rtx jump, nlabel;
3254{
3255 register rtx olabel = JUMP_LABEL (jump);
3256
3257 /* Add this jump to the jump_chain of NLABEL. */
3258 if (jump_chain && INSN_UID (nlabel) < max_jump_chain
3259 && INSN_UID (jump) < max_jump_chain)
3260 {
3261 jump_chain[INSN_UID (jump)] = jump_chain[INSN_UID (nlabel)];
3262 jump_chain[INSN_UID (nlabel)] = jump;
3263 }
3264
3265 PATTERN (jump) = gen_jump (nlabel);
3266 JUMP_LABEL (jump) = nlabel;
3267 ++LABEL_NUSES (nlabel);
3268 INSN_CODE (jump) = -1;
3269
3270 if (--LABEL_NUSES (olabel) == 0)
3271 {
3272 delete_labelref_insn (jump, olabel, 0);
3273 delete_insn (olabel);
3274 }
3275}
3276
3277/* Find the insn referencing LABEL that is a logical predecessor of INSN.
3278 If we found one, delete it and then delete this insn if DELETE_THIS is
3279 non-zero. Return non-zero if INSN or a predecessor references LABEL. */
3280
3281static int
3282delete_labelref_insn (insn, label, delete_this)
3283 rtx insn, label;
3284 int delete_this;
3285{
3286 int deleted = 0;
3287 rtx link;
3288
3289 if (GET_CODE (insn) != NOTE
3290 && reg_mentioned_p (label, PATTERN (insn)))
3291 {
3292 if (delete_this)
3293 {
3294 delete_insn (insn);
3295 deleted = 1;
3296 }
3297 else
3298 return 1;
3299 }
3300
3301 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
3302 if (delete_labelref_insn (XEXP (link, 0), label, 1))
3303 {
3304 if (delete_this)
3305 {
3306 delete_insn (insn);
3307 deleted = 1;
3308 }
3309 else
3310 return 1;
3311 }
3312
3313 return deleted;
3314}
3315\f
3316/* Like rtx_equal_p except that it considers two REGs as equal
3317 if they renumber to the same value. */
3318
3319int
3320rtx_renumbered_equal_p (x, y)
3321 rtx x, y;
3322{
3323 register int i;
3324 register RTX_CODE code = GET_CODE (x);
3325 register char *fmt;
3326
3327 if (x == y)
3328 return 1;
3329 if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
3330 && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
3331 && GET_CODE (SUBREG_REG (y)) == REG)))
3332 {
3333 register int j;
3334
3335 if (GET_MODE (x) != GET_MODE (y))
3336 return 0;
3337
3338 /* If we haven't done any renumbering, don't
3339 make any assumptions. */
3340 if (reg_renumber == 0)
3341 return rtx_equal_p (x, y);
3342
3343 if (code == SUBREG)
3344 {
3345 i = REGNO (SUBREG_REG (x));
3346 if (reg_renumber[i] >= 0)
3347 i = reg_renumber[i];
3348 i += SUBREG_WORD (x);
3349 }
3350 else
3351 {
3352 i = REGNO (x);
3353 if (reg_renumber[i] >= 0)
3354 i = reg_renumber[i];
3355 }
3356 if (GET_CODE (y) == SUBREG)
3357 {
3358 j = REGNO (SUBREG_REG (y));
3359 if (reg_renumber[j] >= 0)
3360 j = reg_renumber[j];
3361 j += SUBREG_WORD (y);
3362 }
3363 else
3364 {
3365 j = REGNO (y);
3366 if (reg_renumber[j] >= 0)
3367 j = reg_renumber[j];
3368 }
3369 return i == j;
3370 }
3371 /* Now we have disposed of all the cases
3372 in which different rtx codes can match. */
3373 if (code != GET_CODE (y))
3374 return 0;
3375 switch (code)
3376 {
3377 case PC:
3378 case CC0:
3379 case ADDR_VEC:
3380 case ADDR_DIFF_VEC:
3381 return 0;
3382
3383 case CONST_INT:
3384 return XINT (x, 0) == XINT (y, 0);
3385
3386 case LABEL_REF:
3387 /* Two label-refs are equivalent if they point at labels
3388 in the same position in the instruction stream. */
3389 return (next_real_insn (XEXP (x, 0))
3390 == next_real_insn (XEXP (y, 0)));
3391
3392 case SYMBOL_REF:
3393 return XSTR (x, 0) == XSTR (y, 0);
3394 }
3395
3396 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
3397
3398 if (GET_MODE (x) != GET_MODE (y))
3399 return 0;
3400
3401 /* Compare the elements. If any pair of corresponding elements
3402 fail to match, return 0 for the whole things. */
3403
3404 fmt = GET_RTX_FORMAT (code);
3405 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3406 {
3407 register int j;
3408 switch (fmt[i])
3409 {
3410 case 'i':
3411 if (XINT (x, i) != XINT (y, i))
3412 return 0;
3413 break;
3414
3415 case 's':
3416 if (strcmp (XSTR (x, i), XSTR (y, i)))
3417 return 0;
3418 break;
3419
3420 case 'e':
3421 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
3422 return 0;
3423 break;
3424
3425 case 'u':
3426 if (XEXP (x, i) != XEXP (y, i))
3427 return 0;
3428 /* fall through. */
3429 case '0':
3430 break;
3431
3432 case 'E':
3433 if (XVECLEN (x, i) != XVECLEN (y, i))
3434 return 0;
3435 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3436 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
3437 return 0;
3438 break;
3439
3440 default:
3441 abort ();
3442 }
3443 }
3444 return 1;
3445}
3446\f
3447/* If X is a hard register or equivalent to one or a subregister of one,
3448 return the hard register number. If X is a pseudo register that was not
3449 assigned a hard register, return the pseudo register number. Otherwise,
3450 return -1. Any rtx is valid for X. */
3451
3452int
3453true_regnum (x)
3454 rtx x;
3455{
3456 if (GET_CODE (x) == REG)
3457 {
3458 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
3459 return reg_renumber[REGNO (x)];
3460 return REGNO (x);
3461 }
3462 if (GET_CODE (x) == SUBREG)
3463 {
3464 int base = true_regnum (SUBREG_REG (x));
3465 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
3466 return SUBREG_WORD (x) + base;
3467 }
3468 return -1;
3469}
3470\f
3471/* Optimize code of the form:
3472
3473 for (x = a[i]; x; ...)
3474 ...
3475 for (x = a[i]; x; ...)
3476 ...
3477 foo:
3478
3479 Loop optimize will change the above code into
3480
3481 if (x = a[i])
3482 for (;;)
3483 { ...; if (! (x = ...)) break; }
3484 if (x = a[i])
3485 for (;;)
3486 { ...; if (! (x = ...)) break; }
3487 foo:
3488
3489 In general, if the first test fails, the program can branch
3490 directly to `foo' and skip the second try which is doomed to fail.
3491 We run this after loop optimization and before flow analysis. */
3492
3493/* When comparing the insn patterns, we track the fact that different
3494 pseudo-register numbers may have been used in each computation.
3495 The following array stores an equivalence -- same_regs[I] == J means
3496 that pseudo register I was used in the first set of tests in a context
3497 where J was used in the second set. We also count the number of such
3498 pending equivalences. If nonzero, the expressions really aren't the
3499 same. */
3500
3501static short *same_regs;
3502
3503static int num_same_regs;
3504
3505/* Track any registers modified between the target of the first jump and
3506 the second jump. They never compare equal. */
3507
3508static char *modified_regs;
3509
3510/* Record if memory was modified. */
3511
3512static int modified_mem;
3513
3514/* Called via note_stores on each insn between the target of the first
3515 branch and the second branch. It marks any changed registers. */
3516
3517static void
3518mark_modified_reg (dest, x)
3519 rtx dest;
3520 rtx x;
3521{
3522 int regno, i;
3523
3524 if (GET_CODE (dest) == SUBREG)
3525 dest = SUBREG_REG (dest);
3526
3527 if (GET_CODE (dest) == MEM)
3528 modified_mem = 1;
3529
3530 if (GET_CODE (dest) != REG)
3531 return;
3532
3533 regno = REGNO (dest);
3534 if (regno >= FIRST_PSEUDO_REGISTER)
3535 modified_regs[regno] = 1;
3536 else
3537 for (i = 0; i < HARD_REGNO_NREGS (regno, GET_MODE (dest)); i++)
3538 modified_regs[regno + i] = 1;
3539}
3540
3541/* F is the first insn in the chain of insns. */
3542
3543void
3544thread_jumps (f, max_reg, verbose)
3545 rtx f;
3546 int max_reg;
3547 int verbose;
3548{
3549 /* Basic algorithm is to find a conditional branch,
3550 the label it may branch to, and the branch after
3551 that label. If the two branches test the same condition,
3552 walk back from both branch paths until the insn patterns
3553 differ, or code labels are hit. If we make it back to
3554 the target of the first branch, then we know that the first branch
3555 will either always succeed or always fail depending on the relative
3556 senses of the two branches. So adjust the first branch accordingly
3557 in this case. */
3558
3559 rtx label, b1, b2, t1, t2;
3560 enum rtx_code code1, code2;
3561 rtx b1op0, b1op1, b2op0, b2op1;
3562 int changed = 1;
3563 int i;
3564 short *all_reset;
3565
3566 /* Allocate register tables and quick-reset table. */
3567 modified_regs = (char *) alloca (max_reg * sizeof (char));
3568 same_regs = (short *) alloca (max_reg * sizeof (short));
3569 all_reset = (short *) alloca (max_reg * sizeof (short));
3570 for (i = 0; i < max_reg; i++)
3571 all_reset[i] = -1;
3572
3573 while (changed)
3574 {
3575 changed = 0;
3576
3577 for (b1 = f; b1; b1 = NEXT_INSN (b1))
3578 {
3579 /* Get to a candidate branch insn. */
3580 if (GET_CODE (b1) != JUMP_INSN
3581 || ! condjump_p (b1) || simplejump_p (b1)
3582 || JUMP_LABEL (b1) == 0)
3583 continue;
3584
3585 bzero (modified_regs, max_reg * sizeof (char));
3586 modified_mem = 0;
3587
3588 bcopy (all_reset, same_regs, max_reg * sizeof (short));
3589 num_same_regs = 0;
3590
3591 label = JUMP_LABEL (b1);
3592
3593 /* Look for a branch after the target. Record any registers and
3594 memory modified between the target and the branch. Stop when we
3595 get to a label since we can't know what was changed there. */
3596 for (b2 = NEXT_INSN (label); b2; b2 = NEXT_INSN (b2))
3597 {
3598 if (GET_CODE (b2) == CODE_LABEL)
3599 break;
3600
3601 else if (GET_CODE (b2) == JUMP_INSN)
3602 {
3603 /* If this is an unconditional jump and is the only use of
3604 its target label, we can follow it. */
3605 if (simplejump_p (b2)
3606 && JUMP_LABEL (b2) != 0
3607 && LABEL_NUSES (JUMP_LABEL (b2)) == 1)
3608 {
3609 b2 = JUMP_LABEL (b2);
3610 continue;
3611 }
3612 else
3613 break;
3614 }
3615
3616 if (GET_CODE (b2) != CALL_INSN && GET_CODE (b2) != INSN)
3617 continue;
3618
3619 if (GET_CODE (b2) == CALL_INSN)
3620 {
3621 modified_mem = 1;
3622 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3623 if (call_used_regs[i] && ! fixed_regs[i]
3624 && i != STACK_POINTER_REGNUM
3625 && i != FRAME_POINTER_REGNUM
3626 && i != ARG_POINTER_REGNUM)
3627 modified_regs[i] = 1;
3628 }
3629
3630 note_stores (PATTERN (b2), mark_modified_reg);
3631 }
3632
3633 /* Check the next candidate branch insn from the label
3634 of the first. */
3635 if (b2 == 0
3636 || GET_CODE (b2) != JUMP_INSN
3637 || b2 == b1
3638 || ! condjump_p (b2)
3639 || simplejump_p (b2))
3640 continue;
3641
3642 /* Get the comparison codes and operands, reversing the
3643 codes if appropriate. If we don't have comparison codes,
3644 we can't do anything. */
3645 b1op0 = XEXP (XEXP (SET_SRC (PATTERN (b1)), 0), 0);
3646 b1op1 = XEXP (XEXP (SET_SRC (PATTERN (b1)), 0), 1);
3647 code1 = GET_CODE (XEXP (SET_SRC (PATTERN (b1)), 0));
3648 if (XEXP (SET_SRC (PATTERN (b1)), 1) == pc_rtx)
3649 code1 = reverse_condition (code1);
3650
3651 b2op0 = XEXP (XEXP (SET_SRC (PATTERN (b2)), 0), 0);
3652 b2op1 = XEXP (XEXP (SET_SRC (PATTERN (b2)), 0), 1);
3653 code2 = GET_CODE (XEXP (SET_SRC (PATTERN (b2)), 0));
3654 if (XEXP (SET_SRC (PATTERN (b2)), 1) == pc_rtx)
3655 code2 = reverse_condition (code2);
3656
3657 /* If they test the same things and knowing that B1 branches
3658 tells us whether or not B2 branches, check if we
3659 can thread the branch. */
3660 if (rtx_equal_for_thread_p (b1op0, b2op0, b2)
3661 && rtx_equal_for_thread_p (b1op1, b2op1, b2)
3662 && (comparison_dominates_p (code1, code2)
3663 || comparison_dominates_p (code1, reverse_condition (code2))))
3664 {
3665 t1 = prev_nonnote_insn (b1);
3666 t2 = prev_nonnote_insn (b2);
3667
3668 while (t1 != 0 && t2 != 0)
3669 {
3670 if (t1 == 0 || t2 == 0)
3671 break;
3672
3673 if (t2 == label)
3674 {
3675 /* We have reached the target of the first branch.
3676 If there are no pending register equivalents,
3677 we know that this branch will either always
3678 succeed (if the senses of the two branches are
3679 the same) or always fail (if not). */
3680 rtx new_label;
3681
3682 if (num_same_regs != 0)
3683 break;
3684
3685 if (comparison_dominates_p (code1, code2))
3686 new_label = JUMP_LABEL (b2);
3687 else
3688 new_label = get_label_after (b2);
3689
3690 if (JUMP_LABEL (b1) != new_label
3691 && redirect_jump (b1, new_label))
3692 changed = 1;
3693 break;
3694 }
3695
3696 /* If either of these is not a normal insn (it might be
3697 a JUMP_INSN, CALL_INSN, or CODE_LABEL) we fail. (NOTEs
3698 have already been skipped above.) Similarly, fail
3699 if the insns are different. */
3700 if (GET_CODE (t1) != INSN || GET_CODE (t2) != INSN
3701 || recog_memoized (t1) != recog_memoized (t2)
3702 || ! rtx_equal_for_thread_p (PATTERN (t1),
3703 PATTERN (t2), t2))
3704 break;
3705
3706 t1 = prev_nonnote_insn (t1);
3707 t2 = prev_nonnote_insn (t2);
3708 }
3709 }
3710 }
3711 }
3712}
3713\f
3714/* This is like RTX_EQUAL_P except that it knows about our handling of
3715 possibly equivalent registers and knows to consider volatile and
3716 modified objects as not equal.
3717
3718 YINSN is the insn containing Y. */
3719
3720int
3721rtx_equal_for_thread_p (x, y, yinsn)
3722 rtx x, y;
3723 rtx yinsn;
3724{
3725 register int i;
3726 register int j;
3727 register enum rtx_code code;
3728 register char *fmt;
3729
3730 code = GET_CODE (x);
3731 /* Rtx's of different codes cannot be equal. */
3732 if (code != GET_CODE (y))
3733 return 0;
3734
3735 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
3736 (REG:SI x) and (REG:HI x) are NOT equivalent. */
3737
3738 if (GET_MODE (x) != GET_MODE (y))
3739 return 0;
3740
3741 /* Handle special-cases first. */
3742 switch (code)
3743 {
3744 case REG:
3745 if (REGNO (x) == REGNO (y) && ! modified_regs[REGNO (x)])
3746 return 1;
3747
3748 /* If neither is user variable or hard register, check for possible
3749 equivalence. */
3750 if (REG_USERVAR_P (x) || REG_USERVAR_P (y)
3751 || REGNO (x) < FIRST_PSEUDO_REGISTER
3752 || REGNO (y) < FIRST_PSEUDO_REGISTER)
3753 return 0;
3754
3755 if (same_regs[REGNO (x)] == -1)
3756 {
3757 same_regs[REGNO (x)] = REGNO (y);
3758 num_same_regs++;
3759
3760 /* If this is the first time we are seeing a register on the `Y'
3761 side, see if it is the last use. If not, we can't thread the
3762 jump, so mark it as not equivalent. */
3763 if (regno_last_uid[REGNO (y)] != INSN_UID (yinsn))
3764 return 0;
3765
3766 return 1;
3767 }
3768 else
3769 return (same_regs[REGNO (x)] == REGNO (y));
3770
3771 break;
3772
3773 case MEM:
3774 /* If memory modified or either volatile, not eqivalent.
3775 Else, check address. */
3776 if (modified_mem || MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
3777 return 0;
3778
3779 return rtx_equal_for_thread_p (XEXP (x, 0), XEXP (y, 0), yinsn);
3780
3781 case ASM_INPUT:
3782 if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
3783 return 0;
3784
3785 break;
3786
3787 case SET:
3788 /* Cancel a pending `same_regs' if setting equivalenced registers.
3789 Then process source. */
3790 if (GET_CODE (SET_DEST (x)) == REG
3791 && GET_CODE (SET_DEST (y)) == REG)
3792 {
3793 if (same_regs[REGNO (SET_DEST (x))] == REGNO (SET_DEST (y)))
3794 {
3795 same_regs[REGNO (SET_DEST (x))] = -1;
3796 num_same_regs--;
3797 }
3798 else if (REGNO (SET_DEST (x)) != REGNO (SET_DEST (y)))
3799 return 0;
3800 }
3801 else
3802 if (rtx_equal_for_thread_p (SET_DEST (x), SET_DEST (y), yinsn) == 0)
3803 return 0;
3804
3805 return rtx_equal_for_thread_p (SET_SRC (x), SET_SRC (y), yinsn);
3806
3807 case LABEL_REF:
3808 return XEXP (x, 0) == XEXP (y, 0);
3809
3810 case SYMBOL_REF:
3811 return XSTR (x, 0) == XSTR (y, 0);
3812 }
3813
3814 if (x == y)
3815 return 1;
3816
3817 fmt = GET_RTX_FORMAT (code);
3818 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3819 {
3820 switch (fmt[i])
3821 {
3822 case 'n':
3823 case 'i':
3824 if (XINT (x, i) != XINT (y, i))
3825 return 0;
3826 break;
3827
3828 case 'V':
3829 case 'E':
3830 /* Two vectors must have the same length. */
3831 if (XVECLEN (x, i) != XVECLEN (y, i))
3832 return 0;
3833
3834 /* And the corresponding elements must match. */
3835 for (j = 0; j < XVECLEN (x, i); j++)
3836 if (rtx_equal_for_thread_p (XVECEXP (x, i, j),
3837 XVECEXP (y, i, j), yinsn) == 0)
3838 return 0;
3839 break;
3840
3841 case 'e':
3842 if (rtx_equal_for_thread_p (XEXP (x, i), XEXP (y, i), yinsn) == 0)
3843 return 0;
3844 break;
3845
3846 case 'S':
3847 case 's':
3848 if (strcmp (XSTR (x, i), XSTR (y, i)))
3849 return 0;
3850 break;
3851
3852 case 'u':
3853 /* These are just backpointers, so they don't matter. */
3854 break;
3855
3856 case '0':
3857 break;
3858
3859 /* It is believed that rtx's at this level will never
3860 contain anything but integers and other rtx's,
3861 except for within LABEL_REFs and SYMBOL_REFs. */
3862 default:
3863 abort ();
3864 }
3865 }
3866 return 1;
3867}
This page took 0.375593 seconds and 5 git commands to generate.