]> gcc.gnu.org Git - gcc.git/blob - gcc/jump.c
rtl.h (rtx_format): Constify a char*.
[gcc.git] / gcc / jump.c
1 /* Optimize jump instructions, for GNU compiler.
2 Copyright (C) 1987, 88, 89, 91-98, 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 /* This is the jump-optimization pass of the compiler.
23 It is run two or three times: once before cse, sometimes once after cse,
24 and once after reload (before final).
25
26 jump_optimize deletes unreachable code and labels that are not used.
27 It also deletes jumps that jump to the following insn,
28 and simplifies jumps around unconditional jumps and jumps
29 to unconditional jumps.
30
31 Each CODE_LABEL has a count of the times it is used
32 stored in the LABEL_NUSES internal field, and each JUMP_INSN
33 has one label that it refers to stored in the
34 JUMP_LABEL internal field. With this we can detect labels that
35 become unused because of the deletion of all the jumps that
36 formerly used them. The JUMP_LABEL info is sometimes looked
37 at by later passes.
38
39 Optionally, cross-jumping can be done. Currently it is done
40 only the last time (when after reload and before final).
41 In fact, the code for cross-jumping now assumes that register
42 allocation has been done, since it uses `rtx_renumbered_equal_p'.
43
44 Jump optimization is done after cse when cse's constant-propagation
45 causes jumps to become unconditional or to be deleted.
46
47 Unreachable loops are not detected here, because the labels
48 have references and the insns appear reachable from the labels.
49 find_basic_blocks in flow.c finds and deletes such loops.
50
51 The subroutines delete_insn, redirect_jump, and invert_jump are used
52 from other passes as well. */
53
54 #include "config.h"
55 #include "system.h"
56 #include "rtl.h"
57 #include "flags.h"
58 #include "hard-reg-set.h"
59 #include "regs.h"
60 #include "insn-config.h"
61 #include "insn-flags.h"
62 #include "insn-attr.h"
63 #include "recog.h"
64 #include "function.h"
65 #include "expr.h"
66 #include "real.h"
67 #include "except.h"
68 #include "toplev.h"
69
70 /* ??? Eventually must record somehow the labels used by jumps
71 from nested functions. */
72 /* Pre-record the next or previous real insn for each label?
73 No, this pass is very fast anyway. */
74 /* Condense consecutive labels?
75 This would make life analysis faster, maybe. */
76 /* Optimize jump y; x: ... y: jumpif... x?
77 Don't know if it is worth bothering with. */
78 /* Optimize two cases of conditional jump to conditional jump?
79 This can never delete any instruction or make anything dead,
80 or even change what is live at any point.
81 So perhaps let combiner do it. */
82
83 /* Vector indexed by uid.
84 For each CODE_LABEL, index by its uid to get first unconditional jump
85 that jumps to the label.
86 For each JUMP_INSN, index by its uid to get the next unconditional jump
87 that jumps to the same label.
88 Element 0 is the start of a chain of all return insns.
89 (It is safe to use element 0 because insn uid 0 is not used. */
90
91 static rtx *jump_chain;
92
93 /* Maximum index in jump_chain. */
94
95 static int max_jump_chain;
96
97 /* Set nonzero by jump_optimize if control can fall through
98 to the end of the function. */
99 int can_reach_end;
100
101 /* Indicates whether death notes are significant in cross jump analysis.
102 Normally they are not significant, because of A and B jump to C,
103 and R dies in A, it must die in B. But this might not be true after
104 stack register conversion, and we must compare death notes in that
105 case. */
106
107 static int cross_jump_death_matters = 0;
108
109 static int init_label_info PROTO((rtx));
110 static void delete_barrier_successors PROTO((rtx));
111 static void mark_all_labels PROTO((rtx, int));
112 static rtx delete_unreferenced_labels PROTO((rtx));
113 static void delete_noop_moves PROTO((rtx));
114 static int calculate_can_reach_end PROTO((rtx, int, int));
115 static int duplicate_loop_exit_test PROTO((rtx));
116 static void find_cross_jump PROTO((rtx, rtx, int, rtx *, rtx *));
117 static void do_cross_jump PROTO((rtx, rtx, rtx));
118 static int jump_back_p PROTO((rtx, rtx));
119 static int tension_vector_labels PROTO((rtx, int));
120 static void mark_jump_label PROTO((rtx, rtx, int));
121 static void delete_computation PROTO((rtx));
122 static void delete_from_jump_chain PROTO((rtx));
123 static int delete_labelref_insn PROTO((rtx, rtx, int));
124 static void mark_modified_reg PROTO((rtx, rtx));
125 static void redirect_tablejump PROTO((rtx, rtx));
126 static void jump_optimize_1 PROTO ((rtx, int, int, int, int));
127 #ifndef HAVE_cc0
128 static rtx find_insert_position PROTO((rtx, rtx));
129 #endif
130
131 /* Main external entry point into the jump optimizer. See comments before
132 jump_optimize_1 for descriptions of the arguments. */
133 void
134 jump_optimize (f, cross_jump, noop_moves, after_regscan)
135 rtx f;
136 int cross_jump;
137 int noop_moves;
138 int after_regscan;
139 {
140 jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, 0);
141 }
142
143 /* Alternate entry into the jump optimizer. This entry point only rebuilds
144 the JUMP_LABEL field in jumping insns and REG_LABEL notes in non-jumping
145 instructions. */
146 void
147 rebuild_jump_labels (f)
148 rtx f;
149 {
150 jump_optimize_1 (f, 0, 0, 0, 1);
151 }
152
153 \f
154 /* Delete no-op jumps and optimize jumps to jumps
155 and jumps around jumps.
156 Delete unused labels and unreachable code.
157
158 If CROSS_JUMP is 1, detect matching code
159 before a jump and its destination and unify them.
160 If CROSS_JUMP is 2, do cross-jumping, but pay attention to death notes.
161
162 If NOOP_MOVES is nonzero, delete no-op move insns.
163
164 If AFTER_REGSCAN is nonzero, then this jump pass is being run immediately
165 after regscan, and it is safe to use regno_first_uid and regno_last_uid.
166
167 If MARK_LABELS_ONLY is nonzero, then we only rebuild the jump chain
168 and JUMP_LABEL field for jumping insns.
169
170 If `optimize' is zero, don't change any code,
171 just determine whether control drops off the end of the function.
172 This case occurs when we have -W and not -O.
173 It works because `delete_insn' checks the value of `optimize'
174 and refrains from actually deleting when that is 0. */
175
176 static void
177 jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
178 rtx f;
179 int cross_jump;
180 int noop_moves;
181 int after_regscan;
182 int mark_labels_only;
183 {
184 register rtx insn, next;
185 int changed;
186 int old_max_reg;
187 int first = 1;
188 int max_uid = 0;
189 rtx last_insn;
190
191 cross_jump_death_matters = (cross_jump == 2);
192 max_uid = init_label_info (f) + 1;
193
194 /* If we are performing cross jump optimizations, then initialize
195 tables mapping UIDs to EH regions to avoid incorrect movement
196 of insns from one EH region to another. */
197 if (flag_exceptions && cross_jump)
198 init_insn_eh_region (f, max_uid);
199
200 delete_barrier_successors (f);
201
202 /* Leave some extra room for labels and duplicate exit test insns
203 we make. */
204 max_jump_chain = max_uid * 14 / 10;
205 jump_chain = (rtx *) alloca (max_jump_chain * sizeof (rtx));
206 bzero ((char *) jump_chain, max_jump_chain * sizeof (rtx));
207
208 mark_all_labels (f, cross_jump);
209
210 /* Keep track of labels used from static data;
211 they cannot ever be deleted. */
212
213 for (insn = forced_labels; insn; insn = XEXP (insn, 1))
214 LABEL_NUSES (XEXP (insn, 0))++;
215
216 check_exception_handler_labels ();
217
218 /* Keep track of labels used for marking handlers for exception
219 regions; they cannot usually be deleted. */
220
221 for (insn = exception_handler_labels; insn; insn = XEXP (insn, 1))
222 LABEL_NUSES (XEXP (insn, 0))++;
223
224 /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
225 notes and recompute LABEL_NUSES. */
226 if (mark_labels_only)
227 return;
228
229 exception_optimize ();
230
231 last_insn = delete_unreferenced_labels (f);
232
233 if (!optimize)
234 {
235 /* CAN_REACH_END is persistent for each function. Once set it should
236 not be cleared. This is especially true for the case where we
237 delete the NOTE_FUNCTION_END note. CAN_REACH_END is cleared by
238 the front-end before compiling each function. */
239 if (calculate_can_reach_end (last_insn, 1, 0))
240 can_reach_end = 1;
241
242 /* Zero the "deleted" flag of all the "deleted" insns. */
243 for (insn = f; insn; insn = NEXT_INSN (insn))
244 INSN_DELETED_P (insn) = 0;
245
246 /* Show that the jump chain is not valid. */
247 jump_chain = 0;
248 return;
249 }
250
251 #ifdef HAVE_return
252 if (HAVE_return)
253 {
254 /* If we fall through to the epilogue, see if we can insert a RETURN insn
255 in front of it. If the machine allows it at this point (we might be
256 after reload for a leaf routine), it will improve optimization for it
257 to be there. */
258 insn = get_last_insn ();
259 while (insn && GET_CODE (insn) == NOTE)
260 insn = PREV_INSN (insn);
261
262 if (insn && GET_CODE (insn) != BARRIER)
263 {
264 emit_jump_insn (gen_return ());
265 emit_barrier ();
266 }
267 }
268 #endif
269
270 if (noop_moves)
271 delete_noop_moves (f);
272
273 /* If we haven't yet gotten to reload and we have just run regscan,
274 delete any insn that sets a register that isn't used elsewhere.
275 This helps some of the optimizations below by having less insns
276 being jumped around. */
277
278 if (! reload_completed && after_regscan)
279 for (insn = f; insn; insn = next)
280 {
281 rtx set = single_set (insn);
282
283 next = NEXT_INSN (insn);
284
285 if (set && GET_CODE (SET_DEST (set)) == REG
286 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
287 && REGNO_FIRST_UID (REGNO (SET_DEST (set))) == INSN_UID (insn)
288 /* We use regno_last_note_uid so as not to delete the setting
289 of a reg that's used in notes. A subsequent optimization
290 might arrange to use that reg for real. */
291 && REGNO_LAST_NOTE_UID (REGNO (SET_DEST (set))) == INSN_UID (insn)
292 && ! side_effects_p (SET_SRC (set))
293 && ! find_reg_note (insn, REG_RETVAL, 0))
294 delete_insn (insn);
295 }
296
297 /* Now iterate optimizing jumps until nothing changes over one pass. */
298 changed = 1;
299 old_max_reg = max_reg_num ();
300 while (changed)
301 {
302 changed = 0;
303
304 for (insn = f; insn; insn = next)
305 {
306 rtx reallabelprev;
307 rtx temp, temp1, temp2, temp3, temp4, temp5, temp6;
308 rtx nlabel;
309 int this_is_simplejump, this_is_condjump, reversep = 0;
310 int this_is_condjump_in_parallel;
311
312 #if 0
313 /* If NOT the first iteration, if this is the last jump pass
314 (just before final), do the special peephole optimizations.
315 Avoiding the first iteration gives ordinary jump opts
316 a chance to work before peephole opts. */
317
318 if (reload_completed && !first && !flag_no_peephole)
319 if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
320 peephole (insn);
321 #endif
322
323 /* That could have deleted some insns after INSN, so check now
324 what the following insn is. */
325
326 next = NEXT_INSN (insn);
327
328 /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional
329 jump. Try to optimize by duplicating the loop exit test if so.
330 This is only safe immediately after regscan, because it uses
331 the values of regno_first_uid and regno_last_uid. */
332 if (after_regscan && GET_CODE (insn) == NOTE
333 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
334 && (temp1 = next_nonnote_insn (insn)) != 0
335 && simplejump_p (temp1))
336 {
337 temp = PREV_INSN (insn);
338 if (duplicate_loop_exit_test (insn))
339 {
340 changed = 1;
341 next = NEXT_INSN (temp);
342 continue;
343 }
344 }
345
346 if (GET_CODE (insn) != JUMP_INSN)
347 continue;
348
349 this_is_simplejump = simplejump_p (insn);
350 this_is_condjump = condjump_p (insn);
351 this_is_condjump_in_parallel = condjump_in_parallel_p (insn);
352
353 /* Tension the labels in dispatch tables. */
354
355 if (GET_CODE (PATTERN (insn)) == ADDR_VEC)
356 changed |= tension_vector_labels (PATTERN (insn), 0);
357 if (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
358 changed |= tension_vector_labels (PATTERN (insn), 1);
359
360 /* If a dispatch table always goes to the same place,
361 get rid of it and replace the insn that uses it. */
362
363 if (GET_CODE (PATTERN (insn)) == ADDR_VEC
364 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
365 {
366 int i;
367 rtx pat = PATTERN (insn);
368 int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC;
369 int len = XVECLEN (pat, diff_vec_p);
370 rtx dispatch = prev_real_insn (insn);
371
372 for (i = 0; i < len; i++)
373 if (XEXP (XVECEXP (pat, diff_vec_p, i), 0)
374 != XEXP (XVECEXP (pat, diff_vec_p, 0), 0))
375 break;
376 if (i == len
377 && dispatch != 0
378 && GET_CODE (dispatch) == JUMP_INSN
379 && JUMP_LABEL (dispatch) != 0
380 /* Don't mess with a casesi insn. */
381 && !(GET_CODE (PATTERN (dispatch)) == SET
382 && (GET_CODE (SET_SRC (PATTERN (dispatch)))
383 == IF_THEN_ELSE))
384 && next_real_insn (JUMP_LABEL (dispatch)) == insn)
385 {
386 redirect_tablejump (dispatch,
387 XEXP (XVECEXP (pat, diff_vec_p, 0), 0));
388 changed = 1;
389 }
390 }
391
392 reallabelprev = prev_active_insn (JUMP_LABEL (insn));
393
394 /* If a jump references the end of the function, try to turn
395 it into a RETURN insn, possibly a conditional one. */
396 if (JUMP_LABEL (insn)
397 && (next_active_insn (JUMP_LABEL (insn)) == 0
398 || GET_CODE (PATTERN (next_active_insn (JUMP_LABEL (insn))))
399 == RETURN))
400 changed |= redirect_jump (insn, NULL_RTX);
401
402 /* Detect jump to following insn. */
403 if (reallabelprev == insn && condjump_p (insn))
404 {
405 next = next_real_insn (JUMP_LABEL (insn));
406 delete_jump (insn);
407 changed = 1;
408 continue;
409 }
410
411 /* If we have an unconditional jump preceded by a USE, try to put
412 the USE before the target and jump there. This simplifies many
413 of the optimizations below since we don't have to worry about
414 dealing with these USE insns. We only do this if the label
415 being branch to already has the identical USE or if code
416 never falls through to that label. */
417
418 if (this_is_simplejump
419 && (temp = prev_nonnote_insn (insn)) != 0
420 && GET_CODE (temp) == INSN && GET_CODE (PATTERN (temp)) == USE
421 && (temp1 = prev_nonnote_insn (JUMP_LABEL (insn))) != 0
422 && (GET_CODE (temp1) == BARRIER
423 || (GET_CODE (temp1) == INSN
424 && rtx_equal_p (PATTERN (temp), PATTERN (temp1))))
425 /* Don't do this optimization if we have a loop containing only
426 the USE instruction, and the loop start label has a usage
427 count of 1. This is because we will redo this optimization
428 everytime through the outer loop, and jump opt will never
429 exit. */
430 && ! ((temp2 = prev_nonnote_insn (temp)) != 0
431 && temp2 == JUMP_LABEL (insn)
432 && LABEL_NUSES (temp2) == 1))
433 {
434 if (GET_CODE (temp1) == BARRIER)
435 {
436 emit_insn_after (PATTERN (temp), temp1);
437 temp1 = NEXT_INSN (temp1);
438 }
439
440 delete_insn (temp);
441 redirect_jump (insn, get_label_before (temp1));
442 reallabelprev = prev_real_insn (temp1);
443 changed = 1;
444 }
445
446 /* Simplify if (...) x = a; else x = b; by converting it
447 to x = b; if (...) x = a;
448 if B is sufficiently simple, the test doesn't involve X,
449 and nothing in the test modifies B or X.
450
451 If we have small register classes, we also can't do this if X
452 is a hard register.
453
454 If the "x = b;" insn has any REG_NOTES, we don't do this because
455 of the possibility that we are running after CSE and there is a
456 REG_EQUAL note that is only valid if the branch has already been
457 taken. If we move the insn with the REG_EQUAL note, we may
458 fold the comparison to always be false in a later CSE pass.
459 (We could also delete the REG_NOTES when moving the insn, but it
460 seems simpler to not move it.) An exception is that we can move
461 the insn if the only note is a REG_EQUAL or REG_EQUIV whose
462 value is the same as "b".
463
464 INSN is the branch over the `else' part.
465
466 We set:
467
468 TEMP to the jump insn preceding "x = a;"
469 TEMP1 to X
470 TEMP2 to the insn that sets "x = b;"
471 TEMP3 to the insn that sets "x = a;"
472 TEMP4 to the set of "x = b"; */
473
474 if (this_is_simplejump
475 && (temp3 = prev_active_insn (insn)) != 0
476 && GET_CODE (temp3) == INSN
477 && (temp4 = single_set (temp3)) != 0
478 && GET_CODE (temp1 = SET_DEST (temp4)) == REG
479 && (! SMALL_REGISTER_CLASSES
480 || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)
481 && (temp2 = next_active_insn (insn)) != 0
482 && GET_CODE (temp2) == INSN
483 && (temp4 = single_set (temp2)) != 0
484 && rtx_equal_p (SET_DEST (temp4), temp1)
485 && ! side_effects_p (SET_SRC (temp4))
486 && ! may_trap_p (SET_SRC (temp4))
487 && (REG_NOTES (temp2) == 0
488 || ((REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUAL
489 || REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUIV)
490 && XEXP (REG_NOTES (temp2), 1) == 0
491 && rtx_equal_p (XEXP (REG_NOTES (temp2), 0),
492 SET_SRC (temp4))))
493 && (temp = prev_active_insn (temp3)) != 0
494 && condjump_p (temp) && ! simplejump_p (temp)
495 /* TEMP must skip over the "x = a;" insn */
496 && prev_real_insn (JUMP_LABEL (temp)) == insn
497 && no_labels_between_p (insn, JUMP_LABEL (temp))
498 /* There must be no other entries to the "x = b;" insn. */
499 && no_labels_between_p (JUMP_LABEL (temp), temp2)
500 /* INSN must either branch to the insn after TEMP2 or the insn
501 after TEMP2 must branch to the same place as INSN. */
502 && (reallabelprev == temp2
503 || ((temp5 = next_active_insn (temp2)) != 0
504 && simplejump_p (temp5)
505 && JUMP_LABEL (temp5) == JUMP_LABEL (insn))))
506 {
507 /* The test expression, X, may be a complicated test with
508 multiple branches. See if we can find all the uses of
509 the label that TEMP branches to without hitting a CALL_INSN
510 or a jump to somewhere else. */
511 rtx target = JUMP_LABEL (temp);
512 int nuses = LABEL_NUSES (target);
513 rtx p;
514 #ifdef HAVE_cc0
515 rtx q;
516 #endif
517
518 /* Set P to the first jump insn that goes around "x = a;". */
519 for (p = temp; nuses && p; p = prev_nonnote_insn (p))
520 {
521 if (GET_CODE (p) == JUMP_INSN)
522 {
523 if (condjump_p (p) && ! simplejump_p (p)
524 && JUMP_LABEL (p) == target)
525 {
526 nuses--;
527 if (nuses == 0)
528 break;
529 }
530 else
531 break;
532 }
533 else if (GET_CODE (p) == CALL_INSN)
534 break;
535 }
536
537 #ifdef HAVE_cc0
538 /* We cannot insert anything between a set of cc and its use
539 so if P uses cc0, we must back up to the previous insn. */
540 q = prev_nonnote_insn (p);
541 if (q && GET_RTX_CLASS (GET_CODE (q)) == 'i'
542 && sets_cc0_p (PATTERN (q)))
543 p = q;
544 #endif
545
546 if (p)
547 p = PREV_INSN (p);
548
549 /* If we found all the uses and there was no data conflict, we
550 can move the assignment unless we can branch into the middle
551 from somewhere. */
552 if (nuses == 0 && p
553 && no_labels_between_p (p, insn)
554 && ! reg_referenced_between_p (temp1, p, NEXT_INSN (temp3))
555 && ! reg_set_between_p (temp1, p, temp3)
556 && (GET_CODE (SET_SRC (temp4)) == CONST_INT
557 || ! modified_between_p (SET_SRC (temp4), p, temp2))
558 /* Verify that registers used by the jump are not clobbered
559 by the instruction being moved. */
560 && ! regs_set_between_p (PATTERN (temp),
561 PREV_INSN (temp2),
562 NEXT_INSN (temp2)))
563 {
564 emit_insn_after_with_line_notes (PATTERN (temp2), p, temp2);
565 delete_insn (temp2);
566
567 /* Set NEXT to an insn that we know won't go away. */
568 next = next_active_insn (insn);
569
570 /* Delete the jump around the set. Note that we must do
571 this before we redirect the test jumps so that it won't
572 delete the code immediately following the assignment
573 we moved (which might be a jump). */
574
575 delete_insn (insn);
576
577 /* We either have two consecutive labels or a jump to
578 a jump, so adjust all the JUMP_INSNs to branch to where
579 INSN branches to. */
580 for (p = NEXT_INSN (p); p != next; p = NEXT_INSN (p))
581 if (GET_CODE (p) == JUMP_INSN)
582 redirect_jump (p, target);
583
584 changed = 1;
585 continue;
586 }
587 }
588
589 /* Simplify if (...) { x = a; goto l; } x = b; by converting it
590 to x = a; if (...) goto l; x = b;
591 if A is sufficiently simple, the test doesn't involve X,
592 and nothing in the test modifies A or X.
593
594 If we have small register classes, we also can't do this if X
595 is a hard register.
596
597 If the "x = a;" insn has any REG_NOTES, we don't do this because
598 of the possibility that we are running after CSE and there is a
599 REG_EQUAL note that is only valid if the branch has already been
600 taken. If we move the insn with the REG_EQUAL note, we may
601 fold the comparison to always be false in a later CSE pass.
602 (We could also delete the REG_NOTES when moving the insn, but it
603 seems simpler to not move it.) An exception is that we can move
604 the insn if the only note is a REG_EQUAL or REG_EQUIV whose
605 value is the same as "a".
606
607 INSN is the goto.
608
609 We set:
610
611 TEMP to the jump insn preceding "x = a;"
612 TEMP1 to X
613 TEMP2 to the insn that sets "x = b;"
614 TEMP3 to the insn that sets "x = a;"
615 TEMP4 to the set of "x = a"; */
616
617 if (this_is_simplejump
618 && (temp2 = next_active_insn (insn)) != 0
619 && GET_CODE (temp2) == INSN
620 && (temp4 = single_set (temp2)) != 0
621 && GET_CODE (temp1 = SET_DEST (temp4)) == REG
622 && (! SMALL_REGISTER_CLASSES
623 || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)
624 && (temp3 = prev_active_insn (insn)) != 0
625 && GET_CODE (temp3) == INSN
626 && (temp4 = single_set (temp3)) != 0
627 && rtx_equal_p (SET_DEST (temp4), temp1)
628 && ! side_effects_p (SET_SRC (temp4))
629 && ! may_trap_p (SET_SRC (temp4))
630 && (REG_NOTES (temp3) == 0
631 || ((REG_NOTE_KIND (REG_NOTES (temp3)) == REG_EQUAL
632 || REG_NOTE_KIND (REG_NOTES (temp3)) == REG_EQUIV)
633 && XEXP (REG_NOTES (temp3), 1) == 0
634 && rtx_equal_p (XEXP (REG_NOTES (temp3), 0),
635 SET_SRC (temp4))))
636 && (temp = prev_active_insn (temp3)) != 0
637 && condjump_p (temp) && ! simplejump_p (temp)
638 /* TEMP must skip over the "x = a;" insn */
639 && prev_real_insn (JUMP_LABEL (temp)) == insn
640 && no_labels_between_p (temp, insn))
641 {
642 rtx prev_label = JUMP_LABEL (temp);
643 rtx insert_after = prev_nonnote_insn (temp);
644
645 #ifdef HAVE_cc0
646 /* We cannot insert anything between a set of cc and its use. */
647 if (insert_after && GET_RTX_CLASS (GET_CODE (insert_after)) == 'i'
648 && sets_cc0_p (PATTERN (insert_after)))
649 insert_after = prev_nonnote_insn (insert_after);
650 #endif
651 ++LABEL_NUSES (prev_label);
652
653 if (insert_after
654 && no_labels_between_p (insert_after, temp)
655 && ! reg_referenced_between_p (temp1, insert_after, temp3)
656 && ! reg_referenced_between_p (temp1, temp3,
657 NEXT_INSN (temp2))
658 && ! reg_set_between_p (temp1, insert_after, temp)
659 && ! modified_between_p (SET_SRC (temp4), insert_after, temp)
660 /* Verify that registers used by the jump are not clobbered
661 by the instruction being moved. */
662 && ! regs_set_between_p (PATTERN (temp),
663 PREV_INSN (temp3),
664 NEXT_INSN (temp3))
665 && invert_jump (temp, JUMP_LABEL (insn)))
666 {
667 emit_insn_after_with_line_notes (PATTERN (temp3),
668 insert_after, temp3);
669 delete_insn (temp3);
670 delete_insn (insn);
671 /* Set NEXT to an insn that we know won't go away. */
672 next = temp2;
673 changed = 1;
674 }
675 if (prev_label && --LABEL_NUSES (prev_label) == 0)
676 delete_insn (prev_label);
677 if (changed)
678 continue;
679 }
680
681 #ifndef HAVE_cc0
682 /* If we have if (...) x = exp; and branches are expensive,
683 EXP is a single insn, does not have any side effects, cannot
684 trap, and is not too costly, convert this to
685 t = exp; if (...) x = t;
686
687 Don't do this when we have CC0 because it is unlikely to help
688 and we'd need to worry about where to place the new insn and
689 the potential for conflicts. We also can't do this when we have
690 notes on the insn for the same reason as above.
691
692 We set:
693
694 TEMP to the "x = exp;" insn.
695 TEMP1 to the single set in the "x = exp;" insn.
696 TEMP2 to "x". */
697
698 if (! reload_completed
699 && this_is_condjump && ! this_is_simplejump
700 && BRANCH_COST >= 3
701 && (temp = next_nonnote_insn (insn)) != 0
702 && GET_CODE (temp) == INSN
703 && REG_NOTES (temp) == 0
704 && (reallabelprev == temp
705 || ((temp2 = next_active_insn (temp)) != 0
706 && simplejump_p (temp2)
707 && JUMP_LABEL (temp2) == JUMP_LABEL (insn)))
708 && (temp1 = single_set (temp)) != 0
709 && (temp2 = SET_DEST (temp1), GET_CODE (temp2) == REG)
710 && (! SMALL_REGISTER_CLASSES
711 || REGNO (temp2) >= FIRST_PSEUDO_REGISTER)
712 && GET_CODE (SET_SRC (temp1)) != REG
713 && GET_CODE (SET_SRC (temp1)) != SUBREG
714 && GET_CODE (SET_SRC (temp1)) != CONST_INT
715 && ! side_effects_p (SET_SRC (temp1))
716 && ! may_trap_p (SET_SRC (temp1))
717 && rtx_cost (SET_SRC (temp1), SET) < 10)
718 {
719 rtx new = gen_reg_rtx (GET_MODE (temp2));
720
721 if ((temp3 = find_insert_position (insn, temp))
722 && validate_change (temp, &SET_DEST (temp1), new, 0))
723 {
724 next = emit_insn_after (gen_move_insn (temp2, new), insn);
725 emit_insn_after_with_line_notes (PATTERN (temp),
726 PREV_INSN (temp3), temp);
727 delete_insn (temp);
728 reallabelprev = prev_active_insn (JUMP_LABEL (insn));
729
730 if (after_regscan)
731 {
732 reg_scan_update (temp3, NEXT_INSN (next), old_max_reg);
733 old_max_reg = max_reg_num ();
734 }
735 }
736 }
737
738 /* Similarly, if it takes two insns to compute EXP but they
739 have the same destination. Here TEMP3 will be the second
740 insn and TEMP4 the SET from that insn. */
741
742 if (! reload_completed
743 && this_is_condjump && ! this_is_simplejump
744 && BRANCH_COST >= 4
745 && (temp = next_nonnote_insn (insn)) != 0
746 && GET_CODE (temp) == INSN
747 && REG_NOTES (temp) == 0
748 && (temp3 = next_nonnote_insn (temp)) != 0
749 && GET_CODE (temp3) == INSN
750 && REG_NOTES (temp3) == 0
751 && (reallabelprev == temp3
752 || ((temp2 = next_active_insn (temp3)) != 0
753 && simplejump_p (temp2)
754 && JUMP_LABEL (temp2) == JUMP_LABEL (insn)))
755 && (temp1 = single_set (temp)) != 0
756 && (temp2 = SET_DEST (temp1), GET_CODE (temp2) == REG)
757 && GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT
758 && (! SMALL_REGISTER_CLASSES
759 || REGNO (temp2) >= FIRST_PSEUDO_REGISTER)
760 && ! side_effects_p (SET_SRC (temp1))
761 && ! may_trap_p (SET_SRC (temp1))
762 && rtx_cost (SET_SRC (temp1), SET) < 10
763 && (temp4 = single_set (temp3)) != 0
764 && rtx_equal_p (SET_DEST (temp4), temp2)
765 && ! side_effects_p (SET_SRC (temp4))
766 && ! may_trap_p (SET_SRC (temp4))
767 && rtx_cost (SET_SRC (temp4), SET) < 10)
768 {
769 rtx new = gen_reg_rtx (GET_MODE (temp2));
770
771 if ((temp5 = find_insert_position (insn, temp))
772 && (temp6 = find_insert_position (insn, temp3))
773 && validate_change (temp, &SET_DEST (temp1), new, 0))
774 {
775 /* Use the earliest of temp5 and temp6. */
776 if (temp5 != insn)
777 temp6 = temp5;
778 next = emit_insn_after (gen_move_insn (temp2, new), insn);
779 emit_insn_after_with_line_notes (PATTERN (temp),
780 PREV_INSN (temp6), temp);
781 emit_insn_after_with_line_notes
782 (replace_rtx (PATTERN (temp3), temp2, new),
783 PREV_INSN (temp6), temp3);
784 delete_insn (temp);
785 delete_insn (temp3);
786 reallabelprev = prev_active_insn (JUMP_LABEL (insn));
787
788 if (after_regscan)
789 {
790 reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);
791 old_max_reg = max_reg_num ();
792 }
793 }
794 }
795
796 /* Finally, handle the case where two insns are used to
797 compute EXP but a temporary register is used. Here we must
798 ensure that the temporary register is not used anywhere else. */
799
800 if (! reload_completed
801 && after_regscan
802 && this_is_condjump && ! this_is_simplejump
803 && BRANCH_COST >= 4
804 && (temp = next_nonnote_insn (insn)) != 0
805 && GET_CODE (temp) == INSN
806 && REG_NOTES (temp) == 0
807 && (temp3 = next_nonnote_insn (temp)) != 0
808 && GET_CODE (temp3) == INSN
809 && REG_NOTES (temp3) == 0
810 && (reallabelprev == temp3
811 || ((temp2 = next_active_insn (temp3)) != 0
812 && simplejump_p (temp2)
813 && JUMP_LABEL (temp2) == JUMP_LABEL (insn)))
814 && (temp1 = single_set (temp)) != 0
815 && (temp5 = SET_DEST (temp1),
816 (GET_CODE (temp5) == REG
817 || (GET_CODE (temp5) == SUBREG
818 && (temp5 = SUBREG_REG (temp5),
819 GET_CODE (temp5) == REG))))
820 && REGNO (temp5) >= FIRST_PSEUDO_REGISTER
821 && REGNO_FIRST_UID (REGNO (temp5)) == INSN_UID (temp)
822 && REGNO_LAST_UID (REGNO (temp5)) == INSN_UID (temp3)
823 && ! side_effects_p (SET_SRC (temp1))
824 && ! may_trap_p (SET_SRC (temp1))
825 && rtx_cost (SET_SRC (temp1), SET) < 10
826 && (temp4 = single_set (temp3)) != 0
827 && (temp2 = SET_DEST (temp4), GET_CODE (temp2) == REG)
828 && GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT
829 && (! SMALL_REGISTER_CLASSES
830 || REGNO (temp2) >= FIRST_PSEUDO_REGISTER)
831 && rtx_equal_p (SET_DEST (temp4), temp2)
832 && ! side_effects_p (SET_SRC (temp4))
833 && ! may_trap_p (SET_SRC (temp4))
834 && rtx_cost (SET_SRC (temp4), SET) < 10)
835 {
836 rtx new = gen_reg_rtx (GET_MODE (temp2));
837
838 if ((temp5 = find_insert_position (insn, temp))
839 && (temp6 = find_insert_position (insn, temp3))
840 && validate_change (temp3, &SET_DEST (temp4), new, 0))
841 {
842 /* Use the earliest of temp5 and temp6. */
843 if (temp5 != insn)
844 temp6 = temp5;
845 next = emit_insn_after (gen_move_insn (temp2, new), insn);
846 emit_insn_after_with_line_notes (PATTERN (temp),
847 PREV_INSN (temp6), temp);
848 emit_insn_after_with_line_notes (PATTERN (temp3),
849 PREV_INSN (temp6), temp3);
850 delete_insn (temp);
851 delete_insn (temp3);
852 reallabelprev = prev_active_insn (JUMP_LABEL (insn));
853
854 if (after_regscan)
855 {
856 reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);
857 old_max_reg = max_reg_num ();
858 }
859 }
860 }
861 #endif /* HAVE_cc0 */
862
863 /* Try to use a conditional move (if the target has them), or a
864 store-flag insn. The general case is:
865
866 1) x = a; if (...) x = b; and
867 2) if (...) x = b;
868
869 If the jump would be faster, the machine should not have defined
870 the movcc or scc insns!. These cases are often made by the
871 previous optimization.
872
873 The second case is treated as x = x; if (...) x = b;.
874
875 INSN here is the jump around the store. We set:
876
877 TEMP to the "x = b;" insn.
878 TEMP1 to X.
879 TEMP2 to B.
880 TEMP3 to A (X in the second case).
881 TEMP4 to the condition being tested.
882 TEMP5 to the earliest insn used to find the condition. */
883
884 if (/* We can't do this after reload has completed. */
885 ! reload_completed
886 && this_is_condjump && ! this_is_simplejump
887 /* Set TEMP to the "x = b;" insn. */
888 && (temp = next_nonnote_insn (insn)) != 0
889 && GET_CODE (temp) == INSN
890 && GET_CODE (PATTERN (temp)) == SET
891 && GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG
892 && (! SMALL_REGISTER_CLASSES
893 || REGNO (temp1) >= FIRST_PSEUDO_REGISTER)
894 && ! side_effects_p (temp2 = SET_SRC (PATTERN (temp)))
895 && ! may_trap_p (temp2)
896 /* Allow either form, but prefer the former if both apply.
897 There is no point in using the old value of TEMP1 if
898 it is a register, since cse will alias them. It can
899 lose if the old value were a hard register since CSE
900 won't replace hard registers. Avoid using TEMP3 if
901 small register classes and it is a hard register. */
902 && (((temp3 = reg_set_last (temp1, insn)) != 0
903 && ! (SMALL_REGISTER_CLASSES && GET_CODE (temp3) == REG
904 && REGNO (temp3) < FIRST_PSEUDO_REGISTER))
905 /* Make the latter case look like x = x; if (...) x = b; */
906 || (temp3 = temp1, 1))
907 /* INSN must either branch to the insn after TEMP or the insn
908 after TEMP must branch to the same place as INSN. */
909 && (reallabelprev == temp
910 || ((temp4 = next_active_insn (temp)) != 0
911 && simplejump_p (temp4)
912 && JUMP_LABEL (temp4) == JUMP_LABEL (insn)))
913 && (temp4 = get_condition (insn, &temp5)) != 0
914 /* We must be comparing objects whose modes imply the size.
915 We could handle BLKmode if (1) emit_store_flag could
916 and (2) we could find the size reliably. */
917 && GET_MODE (XEXP (temp4, 0)) != BLKmode
918 /* Even if branches are cheap, the store_flag optimization
919 can win when the operation to be performed can be
920 expressed directly. */
921 #ifdef HAVE_cc0
922 /* If the previous insn sets CC0 and something else, we can't
923 do this since we are going to delete that insn. */
924
925 && ! ((temp6 = prev_nonnote_insn (insn)) != 0
926 && GET_CODE (temp6) == INSN
927 && (sets_cc0_p (PATTERN (temp6)) == -1
928 || (sets_cc0_p (PATTERN (temp6)) == 1
929 && FIND_REG_INC_NOTE (temp6, NULL_RTX))))
930 #endif
931 )
932 {
933 #ifdef HAVE_conditional_move
934 /* First try a conditional move. */
935 {
936 enum rtx_code code = GET_CODE (temp4);
937 rtx var = temp1;
938 rtx cond0, cond1, aval, bval;
939 rtx target;
940
941 /* Copy the compared variables into cond0 and cond1, so that
942 any side effects performed in or after the old comparison,
943 will not affect our compare which will come later. */
944 /* ??? Is it possible to just use the comparison in the jump
945 insn? After all, we're going to delete it. We'd have
946 to modify emit_conditional_move to take a comparison rtx
947 instead or write a new function. */
948 cond0 = gen_reg_rtx (GET_MODE (XEXP (temp4, 0)));
949 /* We want the target to be able to simplify comparisons with
950 zero (and maybe other constants as well), so don't create
951 pseudos for them. There's no need to either. */
952 if (GET_CODE (XEXP (temp4, 1)) == CONST_INT
953 || GET_CODE (XEXP (temp4, 1)) == CONST_DOUBLE)
954 cond1 = XEXP (temp4, 1);
955 else
956 cond1 = gen_reg_rtx (GET_MODE (XEXP (temp4, 1)));
957
958 aval = temp3;
959 bval = temp2;
960
961 start_sequence ();
962 target = emit_conditional_move (var, code,
963 cond0, cond1, VOIDmode,
964 aval, bval, GET_MODE (var),
965 (code == LTU || code == GEU
966 || code == LEU || code == GTU));
967
968 if (target)
969 {
970 rtx seq1, seq2, last;
971 int copy_ok;
972
973 /* Save the conditional move sequence but don't emit it
974 yet. On some machines, like the alpha, it is possible
975 that temp5 == insn, so next generate the sequence that
976 saves the compared values and then emit both
977 sequences ensuring seq1 occurs before seq2. */
978 seq2 = get_insns ();
979 end_sequence ();
980
981 /* "Now that we can't fail..." Famous last words.
982 Generate the copy insns that preserve the compared
983 values. */
984 start_sequence ();
985 emit_move_insn (cond0, XEXP (temp4, 0));
986 if (cond1 != XEXP (temp4, 1))
987 emit_move_insn (cond1, XEXP (temp4, 1));
988 seq1 = get_insns ();
989 end_sequence ();
990
991 /* Validate the sequence -- this may be some weird
992 bit-extract-and-test instruction for which there
993 exists no complimentary bit-extract insn. */
994 copy_ok = 1;
995 for (last = seq1; last ; last = NEXT_INSN (last))
996 if (recog_memoized (last) < 0)
997 {
998 copy_ok = 0;
999 break;
1000 }
1001
1002 if (copy_ok)
1003 {
1004 emit_insns_before (seq1, temp5);
1005
1006 /* Insert conditional move after insn, to be sure
1007 that the jump and a possible compare won't be
1008 separated. */
1009 last = emit_insns_after (seq2, insn);
1010
1011 /* ??? We can also delete the insn that sets X to A.
1012 Flow will do it too though. */
1013 delete_insn (temp);
1014 next = NEXT_INSN (insn);
1015 delete_jump (insn);
1016
1017 if (after_regscan)
1018 {
1019 reg_scan_update (seq1, NEXT_INSN (last),
1020 old_max_reg);
1021 old_max_reg = max_reg_num ();
1022 }
1023
1024 changed = 1;
1025 continue;
1026 }
1027 }
1028 else
1029 end_sequence ();
1030 }
1031 #endif
1032
1033 /* That didn't work, try a store-flag insn.
1034
1035 We further divide the cases into:
1036
1037 1) x = a; if (...) x = b; and either A or B is zero,
1038 2) if (...) x = 0; and jumps are expensive,
1039 3) x = a; if (...) x = b; and A and B are constants where all
1040 the set bits in A are also set in B and jumps are expensive,
1041 4) x = a; if (...) x = b; and A and B non-zero, and jumps are
1042 more expensive, and
1043 5) if (...) x = b; if jumps are even more expensive. */
1044
1045 if (GET_MODE_CLASS (GET_MODE (temp1)) == MODE_INT
1046 && ((GET_CODE (temp3) == CONST_INT)
1047 /* Make the latter case look like
1048 x = x; if (...) x = 0; */
1049 || (temp3 = temp1,
1050 ((BRANCH_COST >= 2
1051 && temp2 == const0_rtx)
1052 || BRANCH_COST >= 3)))
1053 /* If B is zero, OK; if A is zero, can only do (1) if we
1054 can reverse the condition. See if (3) applies possibly
1055 by reversing the condition. Prefer reversing to (4) when
1056 branches are very expensive. */
1057 && (((BRANCH_COST >= 2
1058 || STORE_FLAG_VALUE == -1
1059 || (STORE_FLAG_VALUE == 1
1060 /* Check that the mask is a power of two,
1061 so that it can probably be generated
1062 with a shift. */
1063 && GET_CODE (temp3) == CONST_INT
1064 && exact_log2 (INTVAL (temp3)) >= 0))
1065 && (reversep = 0, temp2 == const0_rtx))
1066 || ((BRANCH_COST >= 2
1067 || STORE_FLAG_VALUE == -1
1068 || (STORE_FLAG_VALUE == 1
1069 && GET_CODE (temp2) == CONST_INT
1070 && exact_log2 (INTVAL (temp2)) >= 0))
1071 && temp3 == const0_rtx
1072 && (reversep = can_reverse_comparison_p (temp4, insn)))
1073 || (BRANCH_COST >= 2
1074 && GET_CODE (temp2) == CONST_INT
1075 && GET_CODE (temp3) == CONST_INT
1076 && ((INTVAL (temp2) & INTVAL (temp3)) == INTVAL (temp2)
1077 || ((INTVAL (temp2) & INTVAL (temp3)) == INTVAL (temp3)
1078 && (reversep = can_reverse_comparison_p (temp4,
1079 insn)))))
1080 || BRANCH_COST >= 3)
1081 )
1082 {
1083 enum rtx_code code = GET_CODE (temp4);
1084 rtx uval, cval, var = temp1;
1085 int normalizep;
1086 rtx target;
1087
1088 /* If necessary, reverse the condition. */
1089 if (reversep)
1090 code = reverse_condition (code), uval = temp2, cval = temp3;
1091 else
1092 uval = temp3, cval = temp2;
1093
1094 /* If CVAL is non-zero, normalize to -1. Otherwise, if UVAL
1095 is the constant 1, it is best to just compute the result
1096 directly. If UVAL is constant and STORE_FLAG_VALUE
1097 includes all of its bits, it is best to compute the flag
1098 value unnormalized and `and' it with UVAL. Otherwise,
1099 normalize to -1 and `and' with UVAL. */
1100 normalizep = (cval != const0_rtx ? -1
1101 : (uval == const1_rtx ? 1
1102 : (GET_CODE (uval) == CONST_INT
1103 && (INTVAL (uval) & ~STORE_FLAG_VALUE) == 0)
1104 ? 0 : -1));
1105
1106 /* We will be putting the store-flag insn immediately in
1107 front of the comparison that was originally being done,
1108 so we know all the variables in TEMP4 will be valid.
1109 However, this might be in front of the assignment of
1110 A to VAR. If it is, it would clobber the store-flag
1111 we will be emitting.
1112
1113 Therefore, emit into a temporary which will be copied to
1114 VAR immediately after TEMP. */
1115
1116 start_sequence ();
1117 target = emit_store_flag (gen_reg_rtx (GET_MODE (var)), code,
1118 XEXP (temp4, 0), XEXP (temp4, 1),
1119 VOIDmode,
1120 (code == LTU || code == LEU
1121 || code == GEU || code == GTU),
1122 normalizep);
1123 if (target)
1124 {
1125 rtx seq;
1126 rtx before = insn;
1127
1128 seq = get_insns ();
1129 end_sequence ();
1130
1131 /* Put the store-flag insns in front of the first insn
1132 used to compute the condition to ensure that we
1133 use the same values of them as the current
1134 comparison. However, the remainder of the insns we
1135 generate will be placed directly in front of the
1136 jump insn, in case any of the pseudos we use
1137 are modified earlier. */
1138
1139 emit_insns_before (seq, temp5);
1140
1141 start_sequence ();
1142
1143 /* Both CVAL and UVAL are non-zero. */
1144 if (cval != const0_rtx && uval != const0_rtx)
1145 {
1146 rtx tem1, tem2;
1147
1148 tem1 = expand_and (uval, target, NULL_RTX);
1149 if (GET_CODE (cval) == CONST_INT
1150 && GET_CODE (uval) == CONST_INT
1151 && (INTVAL (cval) & INTVAL (uval)) == INTVAL (cval))
1152 tem2 = cval;
1153 else
1154 {
1155 tem2 = expand_unop (GET_MODE (var), one_cmpl_optab,
1156 target, NULL_RTX, 0);
1157 tem2 = expand_and (cval, tem2,
1158 (GET_CODE (tem2) == REG
1159 ? tem2 : 0));
1160 }
1161
1162 /* If we usually make new pseudos, do so here. This
1163 turns out to help machines that have conditional
1164 move insns. */
1165 /* ??? Conditional moves have already been handled.
1166 This may be obsolete. */
1167
1168 if (flag_expensive_optimizations)
1169 target = 0;
1170
1171 target = expand_binop (GET_MODE (var), ior_optab,
1172 tem1, tem2, target,
1173 1, OPTAB_WIDEN);
1174 }
1175 else if (normalizep != 1)
1176 {
1177 /* We know that either CVAL or UVAL is zero. If
1178 UVAL is zero, negate TARGET and `and' with CVAL.
1179 Otherwise, `and' with UVAL. */
1180 if (uval == const0_rtx)
1181 {
1182 target = expand_unop (GET_MODE (var), one_cmpl_optab,
1183 target, NULL_RTX, 0);
1184 uval = cval;
1185 }
1186
1187 target = expand_and (uval, target,
1188 (GET_CODE (target) == REG
1189 && ! preserve_subexpressions_p ()
1190 ? target : NULL_RTX));
1191 }
1192
1193 emit_move_insn (var, target);
1194 seq = get_insns ();
1195 end_sequence ();
1196 #ifdef HAVE_cc0
1197 /* If INSN uses CC0, we must not separate it from the
1198 insn that sets cc0. */
1199 if (reg_mentioned_p (cc0_rtx, PATTERN (before)))
1200 before = prev_nonnote_insn (before);
1201 #endif
1202 emit_insns_before (seq, before);
1203
1204 delete_insn (temp);
1205 next = NEXT_INSN (insn);
1206 delete_jump (insn);
1207
1208 if (after_regscan)
1209 {
1210 reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
1211 old_max_reg = max_reg_num ();
1212 }
1213
1214 changed = 1;
1215 continue;
1216 }
1217 else
1218 end_sequence ();
1219 }
1220 }
1221
1222 /* If branches are expensive, convert
1223 if (foo) bar++; to bar += (foo != 0);
1224 and similarly for "bar--;"
1225
1226 INSN is the conditional branch around the arithmetic. We set:
1227
1228 TEMP is the arithmetic insn.
1229 TEMP1 is the SET doing the arithmetic.
1230 TEMP2 is the operand being incremented or decremented.
1231 TEMP3 to the condition being tested.
1232 TEMP4 to the earliest insn used to find the condition. */
1233
1234 if ((BRANCH_COST >= 2
1235 #ifdef HAVE_incscc
1236 || HAVE_incscc
1237 #endif
1238 #ifdef HAVE_decscc
1239 || HAVE_decscc
1240 #endif
1241 )
1242 && ! reload_completed
1243 && this_is_condjump && ! this_is_simplejump
1244 && (temp = next_nonnote_insn (insn)) != 0
1245 && (temp1 = single_set (temp)) != 0
1246 && (temp2 = SET_DEST (temp1),
1247 GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT)
1248 && GET_CODE (SET_SRC (temp1)) == PLUS
1249 && (XEXP (SET_SRC (temp1), 1) == const1_rtx
1250 || XEXP (SET_SRC (temp1), 1) == constm1_rtx)
1251 && rtx_equal_p (temp2, XEXP (SET_SRC (temp1), 0))
1252 && ! side_effects_p (temp2)
1253 && ! may_trap_p (temp2)
1254 /* INSN must either branch to the insn after TEMP or the insn
1255 after TEMP must branch to the same place as INSN. */
1256 && (reallabelprev == temp
1257 || ((temp3 = next_active_insn (temp)) != 0
1258 && simplejump_p (temp3)
1259 && JUMP_LABEL (temp3) == JUMP_LABEL (insn)))
1260 && (temp3 = get_condition (insn, &temp4)) != 0
1261 /* We must be comparing objects whose modes imply the size.
1262 We could handle BLKmode if (1) emit_store_flag could
1263 and (2) we could find the size reliably. */
1264 && GET_MODE (XEXP (temp3, 0)) != BLKmode
1265 && can_reverse_comparison_p (temp3, insn))
1266 {
1267 rtx temp6, target = 0, seq, init_insn = 0, init = temp2;
1268 enum rtx_code code = reverse_condition (GET_CODE (temp3));
1269
1270 start_sequence ();
1271
1272 /* It must be the case that TEMP2 is not modified in the range
1273 [TEMP4, INSN). The one exception we make is if the insn
1274 before INSN sets TEMP2 to something which is also unchanged
1275 in that range. In that case, we can move the initialization
1276 into our sequence. */
1277
1278 if ((temp5 = prev_active_insn (insn)) != 0
1279 && no_labels_between_p (temp5, insn)
1280 && GET_CODE (temp5) == INSN
1281 && (temp6 = single_set (temp5)) != 0
1282 && rtx_equal_p (temp2, SET_DEST (temp6))
1283 && (CONSTANT_P (SET_SRC (temp6))
1284 || GET_CODE (SET_SRC (temp6)) == REG
1285 || GET_CODE (SET_SRC (temp6)) == SUBREG))
1286 {
1287 emit_insn (PATTERN (temp5));
1288 init_insn = temp5;
1289 init = SET_SRC (temp6);
1290 }
1291
1292 if (CONSTANT_P (init)
1293 || ! reg_set_between_p (init, PREV_INSN (temp4), insn))
1294 target = emit_store_flag (gen_reg_rtx (GET_MODE (temp2)), code,
1295 XEXP (temp3, 0), XEXP (temp3, 1),
1296 VOIDmode,
1297 (code == LTU || code == LEU
1298 || code == GTU || code == GEU), 1);
1299
1300 /* If we can do the store-flag, do the addition or
1301 subtraction. */
1302
1303 if (target)
1304 target = expand_binop (GET_MODE (temp2),
1305 (XEXP (SET_SRC (temp1), 1) == const1_rtx
1306 ? add_optab : sub_optab),
1307 temp2, target, temp2, 0, OPTAB_WIDEN);
1308
1309 if (target != 0)
1310 {
1311 /* Put the result back in temp2 in case it isn't already.
1312 Then replace the jump, possible a CC0-setting insn in
1313 front of the jump, and TEMP, with the sequence we have
1314 made. */
1315
1316 if (target != temp2)
1317 emit_move_insn (temp2, target);
1318
1319 seq = get_insns ();
1320 end_sequence ();
1321
1322 emit_insns_before (seq, temp4);
1323 delete_insn (temp);
1324
1325 if (init_insn)
1326 delete_insn (init_insn);
1327
1328 next = NEXT_INSN (insn);
1329 #ifdef HAVE_cc0
1330 delete_insn (prev_nonnote_insn (insn));
1331 #endif
1332 delete_insn (insn);
1333
1334 if (after_regscan)
1335 {
1336 reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
1337 old_max_reg = max_reg_num ();
1338 }
1339
1340 changed = 1;
1341 continue;
1342 }
1343 else
1344 end_sequence ();
1345 }
1346
1347 /* Simplify if (...) x = 1; else {...} if (x) ...
1348 We recognize this case scanning backwards as well.
1349
1350 TEMP is the assignment to x;
1351 TEMP1 is the label at the head of the second if. */
1352 /* ?? This should call get_condition to find the values being
1353 compared, instead of looking for a COMPARE insn when HAVE_cc0
1354 is not defined. This would allow it to work on the m88k. */
1355 /* ?? This optimization is only safe before cse is run if HAVE_cc0
1356 is not defined and the condition is tested by a separate compare
1357 insn. This is because the code below assumes that the result
1358 of the compare dies in the following branch.
1359
1360 Not only that, but there might be other insns between the
1361 compare and branch whose results are live. Those insns need
1362 to be executed.
1363
1364 A way to fix this is to move the insns at JUMP_LABEL (insn)
1365 to before INSN. If we are running before flow, they will
1366 be deleted if they aren't needed. But this doesn't work
1367 well after flow.
1368
1369 This is really a special-case of jump threading, anyway. The
1370 right thing to do is to replace this and jump threading with
1371 much simpler code in cse.
1372
1373 This code has been turned off in the non-cc0 case in the
1374 meantime. */
1375
1376 #ifdef HAVE_cc0
1377 else if (this_is_simplejump
1378 /* Safe to skip USE and CLOBBER insns here
1379 since they will not be deleted. */
1380 && (temp = prev_active_insn (insn))
1381 && no_labels_between_p (temp, insn)
1382 && GET_CODE (temp) == INSN
1383 && GET_CODE (PATTERN (temp)) == SET
1384 && GET_CODE (SET_DEST (PATTERN (temp))) == REG
1385 && CONSTANT_P (SET_SRC (PATTERN (temp)))
1386 && (temp1 = next_active_insn (JUMP_LABEL (insn)))
1387 /* If we find that the next value tested is `x'
1388 (TEMP1 is the insn where this happens), win. */
1389 && GET_CODE (temp1) == INSN
1390 && GET_CODE (PATTERN (temp1)) == SET
1391 #ifdef HAVE_cc0
1392 /* Does temp1 `tst' the value of x? */
1393 && SET_SRC (PATTERN (temp1)) == SET_DEST (PATTERN (temp))
1394 && SET_DEST (PATTERN (temp1)) == cc0_rtx
1395 && (temp1 = next_nonnote_insn (temp1))
1396 #else
1397 /* Does temp1 compare the value of x against zero? */
1398 && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE
1399 && XEXP (SET_SRC (PATTERN (temp1)), 1) == const0_rtx
1400 && (XEXP (SET_SRC (PATTERN (temp1)), 0)
1401 == SET_DEST (PATTERN (temp)))
1402 && GET_CODE (SET_DEST (PATTERN (temp1))) == REG
1403 && (temp1 = find_next_ref (SET_DEST (PATTERN (temp1)), temp1))
1404 #endif
1405 && condjump_p (temp1))
1406 {
1407 /* Get the if_then_else from the condjump. */
1408 rtx choice = SET_SRC (PATTERN (temp1));
1409 if (GET_CODE (choice) == IF_THEN_ELSE)
1410 {
1411 enum rtx_code code = GET_CODE (XEXP (choice, 0));
1412 rtx val = SET_SRC (PATTERN (temp));
1413 rtx cond
1414 = simplify_relational_operation (code, GET_MODE (SET_DEST (PATTERN (temp))),
1415 val, const0_rtx);
1416 rtx ultimate;
1417
1418 if (cond == const_true_rtx)
1419 ultimate = XEXP (choice, 1);
1420 else if (cond == const0_rtx)
1421 ultimate = XEXP (choice, 2);
1422 else
1423 ultimate = 0;
1424
1425 if (ultimate == pc_rtx)
1426 ultimate = get_label_after (temp1);
1427 else if (ultimate && GET_CODE (ultimate) != RETURN)
1428 ultimate = XEXP (ultimate, 0);
1429
1430 if (ultimate && JUMP_LABEL(insn) != ultimate)
1431 changed |= redirect_jump (insn, ultimate);
1432 }
1433 }
1434 #endif
1435
1436 #if 0
1437 /* @@ This needs a bit of work before it will be right.
1438
1439 Any type of comparison can be accepted for the first and
1440 second compare. When rewriting the first jump, we must
1441 compute the what conditions can reach label3, and use the
1442 appropriate code. We can not simply reverse/swap the code
1443 of the first jump. In some cases, the second jump must be
1444 rewritten also.
1445
1446 For example,
1447 < == converts to > ==
1448 < != converts to == >
1449 etc.
1450
1451 If the code is written to only accept an '==' test for the second
1452 compare, then all that needs to be done is to swap the condition
1453 of the first branch.
1454
1455 It is questionable whether we want this optimization anyways,
1456 since if the user wrote code like this because he/she knew that
1457 the jump to label1 is taken most of the time, then rewriting
1458 this gives slower code. */
1459 /* @@ This should call get_condition to find the values being
1460 compared, instead of looking for a COMPARE insn when HAVE_cc0
1461 is not defined. This would allow it to work on the m88k. */
1462 /* @@ This optimization is only safe before cse is run if HAVE_cc0
1463 is not defined and the condition is tested by a separate compare
1464 insn. This is because the code below assumes that the result
1465 of the compare dies in the following branch. */
1466
1467 /* Simplify test a ~= b
1468 condjump label1;
1469 test a == b
1470 condjump label2;
1471 jump label3;
1472 label1:
1473
1474 rewriting as
1475 test a ~~= b
1476 condjump label3
1477 test a == b
1478 condjump label2
1479 label1:
1480
1481 where ~= is an inequality, e.g. >, and ~~= is the swapped
1482 inequality, e.g. <.
1483
1484 We recognize this case scanning backwards.
1485
1486 TEMP is the conditional jump to `label2';
1487 TEMP1 is the test for `a == b';
1488 TEMP2 is the conditional jump to `label1';
1489 TEMP3 is the test for `a ~= b'. */
1490 else if (this_is_simplejump
1491 && (temp = prev_active_insn (insn))
1492 && no_labels_between_p (temp, insn)
1493 && condjump_p (temp)
1494 && (temp1 = prev_active_insn (temp))
1495 && no_labels_between_p (temp1, temp)
1496 && GET_CODE (temp1) == INSN
1497 && GET_CODE (PATTERN (temp1)) == SET
1498 #ifdef HAVE_cc0
1499 && sets_cc0_p (PATTERN (temp1)) == 1
1500 #else
1501 && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE
1502 && GET_CODE (SET_DEST (PATTERN (temp1))) == REG
1503 && (temp == find_next_ref (SET_DEST (PATTERN (temp1)), temp1))
1504 #endif
1505 && (temp2 = prev_active_insn (temp1))
1506 && no_labels_between_p (temp2, temp1)
1507 && condjump_p (temp2)
1508 && JUMP_LABEL (temp2) == next_nonnote_insn (NEXT_INSN (insn))
1509 && (temp3 = prev_active_insn (temp2))
1510 && no_labels_between_p (temp3, temp2)
1511 && GET_CODE (PATTERN (temp3)) == SET
1512 && rtx_equal_p (SET_DEST (PATTERN (temp3)),
1513 SET_DEST (PATTERN (temp1)))
1514 && rtx_equal_p (SET_SRC (PATTERN (temp1)),
1515 SET_SRC (PATTERN (temp3)))
1516 && ! inequality_comparisons_p (PATTERN (temp))
1517 && inequality_comparisons_p (PATTERN (temp2)))
1518 {
1519 rtx fallthrough_label = JUMP_LABEL (temp2);
1520
1521 ++LABEL_NUSES (fallthrough_label);
1522 if (swap_jump (temp2, JUMP_LABEL (insn)))
1523 {
1524 delete_insn (insn);
1525 changed = 1;
1526 }
1527
1528 if (--LABEL_NUSES (fallthrough_label) == 0)
1529 delete_insn (fallthrough_label);
1530 }
1531 #endif
1532 /* Simplify if (...) {... x = 1;} if (x) ...
1533
1534 We recognize this case backwards.
1535
1536 TEMP is the test of `x';
1537 TEMP1 is the assignment to `x' at the end of the
1538 previous statement. */
1539 /* @@ This should call get_condition to find the values being
1540 compared, instead of looking for a COMPARE insn when HAVE_cc0
1541 is not defined. This would allow it to work on the m88k. */
1542 /* @@ This optimization is only safe before cse is run if HAVE_cc0
1543 is not defined and the condition is tested by a separate compare
1544 insn. This is because the code below assumes that the result
1545 of the compare dies in the following branch. */
1546
1547 /* ??? This has to be turned off. The problem is that the
1548 unconditional jump might indirectly end up branching to the
1549 label between TEMP1 and TEMP. We can't detect this, in general,
1550 since it may become a jump to there after further optimizations.
1551 If that jump is done, it will be deleted, so we will retry
1552 this optimization in the next pass, thus an infinite loop.
1553
1554 The present code prevents this by putting the jump after the
1555 label, but this is not logically correct. */
1556 #if 0
1557 else if (this_is_condjump
1558 /* Safe to skip USE and CLOBBER insns here
1559 since they will not be deleted. */
1560 && (temp = prev_active_insn (insn))
1561 && no_labels_between_p (temp, insn)
1562 && GET_CODE (temp) == INSN
1563 && GET_CODE (PATTERN (temp)) == SET
1564 #ifdef HAVE_cc0
1565 && sets_cc0_p (PATTERN (temp)) == 1
1566 && GET_CODE (SET_SRC (PATTERN (temp))) == REG
1567 #else
1568 /* Temp must be a compare insn, we can not accept a register
1569 to register move here, since it may not be simply a
1570 tst insn. */
1571 && GET_CODE (SET_SRC (PATTERN (temp))) == COMPARE
1572 && XEXP (SET_SRC (PATTERN (temp)), 1) == const0_rtx
1573 && GET_CODE (XEXP (SET_SRC (PATTERN (temp)), 0)) == REG
1574 && GET_CODE (SET_DEST (PATTERN (temp))) == REG
1575 && insn == find_next_ref (SET_DEST (PATTERN (temp)), temp)
1576 #endif
1577 /* May skip USE or CLOBBER insns here
1578 for checking for opportunity, since we
1579 take care of them later. */
1580 && (temp1 = prev_active_insn (temp))
1581 && GET_CODE (temp1) == INSN
1582 && GET_CODE (PATTERN (temp1)) == SET
1583 #ifdef HAVE_cc0
1584 && SET_SRC (PATTERN (temp)) == SET_DEST (PATTERN (temp1))
1585 #else
1586 && (XEXP (SET_SRC (PATTERN (temp)), 0)
1587 == SET_DEST (PATTERN (temp1)))
1588 #endif
1589 && CONSTANT_P (SET_SRC (PATTERN (temp1)))
1590 /* If this isn't true, cse will do the job. */
1591 && ! no_labels_between_p (temp1, temp))
1592 {
1593 /* Get the if_then_else from the condjump. */
1594 rtx choice = SET_SRC (PATTERN (insn));
1595 if (GET_CODE (choice) == IF_THEN_ELSE
1596 && (GET_CODE (XEXP (choice, 0)) == EQ
1597 || GET_CODE (XEXP (choice, 0)) == NE))
1598 {
1599 int want_nonzero = (GET_CODE (XEXP (choice, 0)) == NE);
1600 rtx last_insn;
1601 rtx ultimate;
1602 rtx p;
1603
1604 /* Get the place that condjump will jump to
1605 if it is reached from here. */
1606 if ((SET_SRC (PATTERN (temp1)) != const0_rtx)
1607 == want_nonzero)
1608 ultimate = XEXP (choice, 1);
1609 else
1610 ultimate = XEXP (choice, 2);
1611 /* Get it as a CODE_LABEL. */
1612 if (ultimate == pc_rtx)
1613 ultimate = get_label_after (insn);
1614 else
1615 /* Get the label out of the LABEL_REF. */
1616 ultimate = XEXP (ultimate, 0);
1617
1618 /* Insert the jump immediately before TEMP, specifically
1619 after the label that is between TEMP1 and TEMP. */
1620 last_insn = PREV_INSN (temp);
1621
1622 /* If we would be branching to the next insn, the jump
1623 would immediately be deleted and the re-inserted in
1624 a subsequent pass over the code. So don't do anything
1625 in that case. */
1626 if (next_active_insn (last_insn)
1627 != next_active_insn (ultimate))
1628 {
1629 emit_barrier_after (last_insn);
1630 p = emit_jump_insn_after (gen_jump (ultimate),
1631 last_insn);
1632 JUMP_LABEL (p) = ultimate;
1633 ++LABEL_NUSES (ultimate);
1634 if (INSN_UID (ultimate) < max_jump_chain
1635 && INSN_CODE (p) < max_jump_chain)
1636 {
1637 jump_chain[INSN_UID (p)]
1638 = jump_chain[INSN_UID (ultimate)];
1639 jump_chain[INSN_UID (ultimate)] = p;
1640 }
1641 changed = 1;
1642 continue;
1643 }
1644 }
1645 }
1646 #endif
1647 /* Detect a conditional jump going to the same place
1648 as an immediately following unconditional jump. */
1649 else if (this_is_condjump
1650 && (temp = next_active_insn (insn)) != 0
1651 && simplejump_p (temp)
1652 && (next_active_insn (JUMP_LABEL (insn))
1653 == next_active_insn (JUMP_LABEL (temp))))
1654 {
1655 rtx tem = temp;
1656
1657 /* ??? Optional. Disables some optimizations, but makes
1658 gcov output more accurate with -O. */
1659 if (flag_test_coverage && !reload_completed)
1660 for (tem = insn; tem != temp; tem = NEXT_INSN (tem))
1661 if (GET_CODE (tem) == NOTE && NOTE_LINE_NUMBER (tem) > 0)
1662 break;
1663
1664 if (tem == temp)
1665 {
1666 delete_jump (insn);
1667 changed = 1;
1668 continue;
1669 }
1670 }
1671 #ifdef HAVE_trap
1672 /* Detect a conditional jump jumping over an unconditional trap. */
1673 else if (HAVE_trap
1674 && this_is_condjump && ! this_is_simplejump
1675 && reallabelprev != 0
1676 && GET_CODE (reallabelprev) == INSN
1677 && GET_CODE (PATTERN (reallabelprev)) == TRAP_IF
1678 && TRAP_CONDITION (PATTERN (reallabelprev)) == const_true_rtx
1679 && prev_active_insn (reallabelprev) == insn
1680 && no_labels_between_p (insn, reallabelprev)
1681 && (temp2 = get_condition (insn, &temp4))
1682 && can_reverse_comparison_p (temp2, insn))
1683 {
1684 rtx new = gen_cond_trap (reverse_condition (GET_CODE (temp2)),
1685 XEXP (temp2, 0), XEXP (temp2, 1),
1686 TRAP_CODE (PATTERN (reallabelprev)));
1687
1688 if (new)
1689 {
1690 emit_insn_before (new, temp4);
1691 delete_insn (reallabelprev);
1692 delete_jump (insn);
1693 changed = 1;
1694 continue;
1695 }
1696 }
1697 /* Detect a jump jumping to an unconditional trap. */
1698 else if (HAVE_trap && this_is_condjump
1699 && (temp = next_active_insn (JUMP_LABEL (insn)))
1700 && GET_CODE (temp) == INSN
1701 && GET_CODE (PATTERN (temp)) == TRAP_IF
1702 && (this_is_simplejump
1703 || (temp2 = get_condition (insn, &temp4))))
1704 {
1705 rtx tc = TRAP_CONDITION (PATTERN (temp));
1706
1707 if (tc == const_true_rtx
1708 || (! this_is_simplejump && rtx_equal_p (temp2, tc)))
1709 {
1710 rtx new;
1711 /* Replace an unconditional jump to a trap with a trap. */
1712 if (this_is_simplejump)
1713 {
1714 emit_barrier_after (emit_insn_before (gen_trap (), insn));
1715 delete_jump (insn);
1716 changed = 1;
1717 continue;
1718 }
1719 new = gen_cond_trap (GET_CODE (temp2), XEXP (temp2, 0),
1720 XEXP (temp2, 1),
1721 TRAP_CODE (PATTERN (temp)));
1722 if (new)
1723 {
1724 emit_insn_before (new, temp4);
1725 delete_jump (insn);
1726 changed = 1;
1727 continue;
1728 }
1729 }
1730 /* If the trap condition and jump condition are mutually
1731 exclusive, redirect the jump to the following insn. */
1732 else if (GET_RTX_CLASS (GET_CODE (tc)) == '<'
1733 && ! this_is_simplejump
1734 && swap_condition (GET_CODE (temp2)) == GET_CODE (tc)
1735 && rtx_equal_p (XEXP (tc, 0), XEXP (temp2, 0))
1736 && rtx_equal_p (XEXP (tc, 1), XEXP (temp2, 1))
1737 && redirect_jump (insn, get_label_after (temp)))
1738 {
1739 changed = 1;
1740 continue;
1741 }
1742 }
1743 #endif
1744
1745 /* Detect a conditional jump jumping over an unconditional jump. */
1746
1747 else if ((this_is_condjump || this_is_condjump_in_parallel)
1748 && ! this_is_simplejump
1749 && reallabelprev != 0
1750 && GET_CODE (reallabelprev) == JUMP_INSN
1751 && prev_active_insn (reallabelprev) == insn
1752 && no_labels_between_p (insn, reallabelprev)
1753 && simplejump_p (reallabelprev))
1754 {
1755 /* When we invert the unconditional jump, we will be
1756 decrementing the usage count of its old label.
1757 Make sure that we don't delete it now because that
1758 might cause the following code to be deleted. */
1759 rtx prev_uses = prev_nonnote_insn (reallabelprev);
1760 rtx prev_label = JUMP_LABEL (insn);
1761
1762 if (prev_label)
1763 ++LABEL_NUSES (prev_label);
1764
1765 if (invert_jump (insn, JUMP_LABEL (reallabelprev)))
1766 {
1767 /* It is very likely that if there are USE insns before
1768 this jump, they hold REG_DEAD notes. These REG_DEAD
1769 notes are no longer valid due to this optimization,
1770 and will cause the life-analysis that following passes
1771 (notably delayed-branch scheduling) to think that
1772 these registers are dead when they are not.
1773
1774 To prevent this trouble, we just remove the USE insns
1775 from the insn chain. */
1776
1777 while (prev_uses && GET_CODE (prev_uses) == INSN
1778 && GET_CODE (PATTERN (prev_uses)) == USE)
1779 {
1780 rtx useless = prev_uses;
1781 prev_uses = prev_nonnote_insn (prev_uses);
1782 delete_insn (useless);
1783 }
1784
1785 delete_insn (reallabelprev);
1786 next = insn;
1787 changed = 1;
1788 }
1789
1790 /* We can now safely delete the label if it is unreferenced
1791 since the delete_insn above has deleted the BARRIER. */
1792 if (prev_label && --LABEL_NUSES (prev_label) == 0)
1793 delete_insn (prev_label);
1794 continue;
1795 }
1796 else
1797 {
1798 /* Detect a jump to a jump. */
1799
1800 nlabel = follow_jumps (JUMP_LABEL (insn));
1801 if (nlabel != JUMP_LABEL (insn)
1802 && redirect_jump (insn, nlabel))
1803 {
1804 changed = 1;
1805 next = insn;
1806 }
1807
1808 /* Look for if (foo) bar; else break; */
1809 /* The insns look like this:
1810 insn = condjump label1;
1811 ...range1 (some insns)...
1812 jump label2;
1813 label1:
1814 ...range2 (some insns)...
1815 jump somewhere unconditionally
1816 label2: */
1817 {
1818 rtx label1 = next_label (insn);
1819 rtx range1end = label1 ? prev_active_insn (label1) : 0;
1820 /* Don't do this optimization on the first round, so that
1821 jump-around-a-jump gets simplified before we ask here
1822 whether a jump is unconditional.
1823
1824 Also don't do it when we are called after reload since
1825 it will confuse reorg. */
1826 if (! first
1827 && (reload_completed ? ! flag_delayed_branch : 1)
1828 /* Make sure INSN is something we can invert. */
1829 && condjump_p (insn)
1830 && label1 != 0
1831 && JUMP_LABEL (insn) == label1
1832 && LABEL_NUSES (label1) == 1
1833 && GET_CODE (range1end) == JUMP_INSN
1834 && simplejump_p (range1end))
1835 {
1836 rtx label2 = next_label (label1);
1837 rtx range2end = label2 ? prev_active_insn (label2) : 0;
1838 if (range1end != range2end
1839 && JUMP_LABEL (range1end) == label2
1840 && GET_CODE (range2end) == JUMP_INSN
1841 && GET_CODE (NEXT_INSN (range2end)) == BARRIER
1842 /* Invert the jump condition, so we
1843 still execute the same insns in each case. */
1844 && invert_jump (insn, label1))
1845 {
1846 rtx range1beg = next_active_insn (insn);
1847 rtx range2beg = next_active_insn (label1);
1848 rtx range1after, range2after;
1849 rtx range1before, range2before;
1850 rtx rangenext;
1851
1852 /* Include in each range any notes before it, to be
1853 sure that we get the line number note if any, even
1854 if there are other notes here. */
1855 while (PREV_INSN (range1beg)
1856 && GET_CODE (PREV_INSN (range1beg)) == NOTE)
1857 range1beg = PREV_INSN (range1beg);
1858
1859 while (PREV_INSN (range2beg)
1860 && GET_CODE (PREV_INSN (range2beg)) == NOTE)
1861 range2beg = PREV_INSN (range2beg);
1862
1863 /* Don't move NOTEs for blocks or loops; shift them
1864 outside the ranges, where they'll stay put. */
1865 range1beg = squeeze_notes (range1beg, range1end);
1866 range2beg = squeeze_notes (range2beg, range2end);
1867
1868 /* Get current surrounds of the 2 ranges. */
1869 range1before = PREV_INSN (range1beg);
1870 range2before = PREV_INSN (range2beg);
1871 range1after = NEXT_INSN (range1end);
1872 range2after = NEXT_INSN (range2end);
1873
1874 /* Splice range2 where range1 was. */
1875 NEXT_INSN (range1before) = range2beg;
1876 PREV_INSN (range2beg) = range1before;
1877 NEXT_INSN (range2end) = range1after;
1878 PREV_INSN (range1after) = range2end;
1879 /* Splice range1 where range2 was. */
1880 NEXT_INSN (range2before) = range1beg;
1881 PREV_INSN (range1beg) = range2before;
1882 NEXT_INSN (range1end) = range2after;
1883 PREV_INSN (range2after) = range1end;
1884
1885 /* Check for a loop end note between the end of
1886 range2, and the next code label. If there is one,
1887 then what we have really seen is
1888 if (foo) break; end_of_loop;
1889 and moved the break sequence outside the loop.
1890 We must move the LOOP_END note to where the
1891 loop really ends now, or we will confuse loop
1892 optimization. Stop if we find a LOOP_BEG note
1893 first, since we don't want to move the LOOP_END
1894 note in that case. */
1895 for (;range2after != label2; range2after = rangenext)
1896 {
1897 rangenext = NEXT_INSN (range2after);
1898 if (GET_CODE (range2after) == NOTE)
1899 {
1900 if (NOTE_LINE_NUMBER (range2after)
1901 == NOTE_INSN_LOOP_END)
1902 {
1903 NEXT_INSN (PREV_INSN (range2after))
1904 = rangenext;
1905 PREV_INSN (rangenext)
1906 = PREV_INSN (range2after);
1907 PREV_INSN (range2after)
1908 = PREV_INSN (range1beg);
1909 NEXT_INSN (range2after) = range1beg;
1910 NEXT_INSN (PREV_INSN (range1beg))
1911 = range2after;
1912 PREV_INSN (range1beg) = range2after;
1913 }
1914 else if (NOTE_LINE_NUMBER (range2after)
1915 == NOTE_INSN_LOOP_BEG)
1916 break;
1917 }
1918 }
1919 changed = 1;
1920 continue;
1921 }
1922 }
1923 }
1924
1925 /* Now that the jump has been tensioned,
1926 try cross jumping: check for identical code
1927 before the jump and before its target label. */
1928
1929 /* First, cross jumping of conditional jumps: */
1930
1931 if (cross_jump && condjump_p (insn))
1932 {
1933 rtx newjpos, newlpos;
1934 rtx x = prev_real_insn (JUMP_LABEL (insn));
1935
1936 /* A conditional jump may be crossjumped
1937 only if the place it jumps to follows
1938 an opposing jump that comes back here. */
1939
1940 if (x != 0 && ! jump_back_p (x, insn))
1941 /* We have no opposing jump;
1942 cannot cross jump this insn. */
1943 x = 0;
1944
1945 newjpos = 0;
1946 /* TARGET is nonzero if it is ok to cross jump
1947 to code before TARGET. If so, see if matches. */
1948 if (x != 0)
1949 find_cross_jump (insn, x, 2,
1950 &newjpos, &newlpos);
1951
1952 if (newjpos != 0)
1953 {
1954 do_cross_jump (insn, newjpos, newlpos);
1955 /* Make the old conditional jump
1956 into an unconditional one. */
1957 SET_SRC (PATTERN (insn))
1958 = gen_rtx_LABEL_REF (VOIDmode, JUMP_LABEL (insn));
1959 INSN_CODE (insn) = -1;
1960 emit_barrier_after (insn);
1961 /* Add to jump_chain unless this is a new label
1962 whose UID is too large. */
1963 if (INSN_UID (JUMP_LABEL (insn)) < max_jump_chain)
1964 {
1965 jump_chain[INSN_UID (insn)]
1966 = jump_chain[INSN_UID (JUMP_LABEL (insn))];
1967 jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn;
1968 }
1969 changed = 1;
1970 next = insn;
1971 }
1972 }
1973
1974 /* Cross jumping of unconditional jumps:
1975 a few differences. */
1976
1977 if (cross_jump && simplejump_p (insn))
1978 {
1979 rtx newjpos, newlpos;
1980 rtx target;
1981
1982 newjpos = 0;
1983
1984 /* TARGET is nonzero if it is ok to cross jump
1985 to code before TARGET. If so, see if matches. */
1986 find_cross_jump (insn, JUMP_LABEL (insn), 1,
1987 &newjpos, &newlpos);
1988
1989 /* If cannot cross jump to code before the label,
1990 see if we can cross jump to another jump to
1991 the same label. */
1992 /* Try each other jump to this label. */
1993 if (INSN_UID (JUMP_LABEL (insn)) < max_uid)
1994 for (target = jump_chain[INSN_UID (JUMP_LABEL (insn))];
1995 target != 0 && newjpos == 0;
1996 target = jump_chain[INSN_UID (target)])
1997 if (target != insn
1998 && JUMP_LABEL (target) == JUMP_LABEL (insn)
1999 /* Ignore TARGET if it's deleted. */
2000 && ! INSN_DELETED_P (target))
2001 find_cross_jump (insn, target, 2,
2002 &newjpos, &newlpos);
2003
2004 if (newjpos != 0)
2005 {
2006 do_cross_jump (insn, newjpos, newlpos);
2007 changed = 1;
2008 next = insn;
2009 }
2010 }
2011
2012 /* This code was dead in the previous jump.c! */
2013 if (cross_jump && GET_CODE (PATTERN (insn)) == RETURN)
2014 {
2015 /* Return insns all "jump to the same place"
2016 so we can cross-jump between any two of them. */
2017
2018 rtx newjpos, newlpos, target;
2019
2020 newjpos = 0;
2021
2022 /* If cannot cross jump to code before the label,
2023 see if we can cross jump to another jump to
2024 the same label. */
2025 /* Try each other jump to this label. */
2026 for (target = jump_chain[0];
2027 target != 0 && newjpos == 0;
2028 target = jump_chain[INSN_UID (target)])
2029 if (target != insn
2030 && ! INSN_DELETED_P (target)
2031 && GET_CODE (PATTERN (target)) == RETURN)
2032 find_cross_jump (insn, target, 2,
2033 &newjpos, &newlpos);
2034
2035 if (newjpos != 0)
2036 {
2037 do_cross_jump (insn, newjpos, newlpos);
2038 changed = 1;
2039 next = insn;
2040 }
2041 }
2042 }
2043 }
2044
2045 first = 0;
2046 }
2047
2048 /* Delete extraneous line number notes.
2049 Note that two consecutive notes for different lines are not really
2050 extraneous. There should be some indication where that line belonged,
2051 even if it became empty. */
2052
2053 {
2054 rtx last_note = 0;
2055
2056 for (insn = f; insn; insn = NEXT_INSN (insn))
2057 if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0)
2058 {
2059 /* Delete this note if it is identical to previous note. */
2060 if (last_note
2061 && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note)
2062 && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note))
2063 {
2064 delete_insn (insn);
2065 continue;
2066 }
2067
2068 last_note = insn;
2069 }
2070 }
2071
2072 #ifdef HAVE_return
2073 if (HAVE_return)
2074 {
2075 /* If we fall through to the epilogue, see if we can insert a RETURN insn
2076 in front of it. If the machine allows it at this point (we might be
2077 after reload for a leaf routine), it will improve optimization for it
2078 to be there. We do this both here and at the start of this pass since
2079 the RETURN might have been deleted by some of our optimizations. */
2080 insn = get_last_insn ();
2081 while (insn && GET_CODE (insn) == NOTE)
2082 insn = PREV_INSN (insn);
2083
2084 if (insn && GET_CODE (insn) != BARRIER)
2085 {
2086 emit_jump_insn (gen_return ());
2087 emit_barrier ();
2088 }
2089 }
2090 #endif
2091
2092 /* CAN_REACH_END is persistent for each function. Once set it should
2093 not be cleared. This is especially true for the case where we
2094 delete the NOTE_FUNCTION_END note. CAN_REACH_END is cleared by
2095 the front-end before compiling each function. */
2096 if (calculate_can_reach_end (last_insn, 0, 1))
2097 can_reach_end = 1;
2098
2099 /* Show JUMP_CHAIN no longer valid. */
2100 jump_chain = 0;
2101 }
2102 \f
2103 /* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
2104 notes whose labels don't occur in the insn any more. Returns the
2105 largest INSN_UID found. */
2106 static int
2107 init_label_info (f)
2108 rtx f;
2109 {
2110 int largest_uid = 0;
2111 rtx insn;
2112
2113 for (insn = f; insn; insn = NEXT_INSN (insn))
2114 {
2115 if (GET_CODE (insn) == CODE_LABEL)
2116 LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
2117 else if (GET_CODE (insn) == JUMP_INSN)
2118 JUMP_LABEL (insn) = 0;
2119 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
2120 {
2121 rtx note, next;
2122
2123 for (note = REG_NOTES (insn); note; note = next)
2124 {
2125 next = XEXP (note, 1);
2126 if (REG_NOTE_KIND (note) == REG_LABEL
2127 && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
2128 remove_note (insn, note);
2129 }
2130 }
2131 if (INSN_UID (insn) > largest_uid)
2132 largest_uid = INSN_UID (insn);
2133 }
2134
2135 return largest_uid;
2136 }
2137
2138 /* Delete insns following barriers, up to next label.
2139
2140 Also delete no-op jumps created by gcse. */
2141 static void
2142 delete_barrier_successors (f)
2143 rtx f;
2144 {
2145 rtx insn;
2146
2147 for (insn = f; insn;)
2148 {
2149 if (GET_CODE (insn) == BARRIER)
2150 {
2151 insn = NEXT_INSN (insn);
2152
2153 never_reached_warning (insn);
2154
2155 while (insn != 0 && GET_CODE (insn) != CODE_LABEL)
2156 {
2157 if (GET_CODE (insn) == NOTE
2158 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
2159 insn = NEXT_INSN (insn);
2160 else
2161 insn = delete_insn (insn);
2162 }
2163 /* INSN is now the code_label. */
2164 }
2165 /* Also remove (set (pc) (pc)) insns which can be created by
2166 gcse. We eliminate such insns now to avoid having them
2167 cause problems later. */
2168 else if (GET_CODE (insn) == JUMP_INSN
2169 && SET_SRC (PATTERN (insn)) == pc_rtx
2170 && SET_DEST (PATTERN (insn)) == pc_rtx)
2171 insn = delete_insn (insn);
2172
2173 else
2174 insn = NEXT_INSN (insn);
2175 }
2176 }
2177
2178 /* Mark the label each jump jumps to.
2179 Combine consecutive labels, and count uses of labels.
2180
2181 For each label, make a chain (using `jump_chain')
2182 of all the *unconditional* jumps that jump to it;
2183 also make a chain of all returns.
2184
2185 CROSS_JUMP indicates whether we are doing cross jumping
2186 and if we are whether we will be paying attention to
2187 death notes or not. */
2188
2189 static void
2190 mark_all_labels (f, cross_jump)
2191 rtx f;
2192 int cross_jump;
2193 {
2194 rtx insn;
2195
2196 for (insn = f; insn; insn = NEXT_INSN (insn))
2197 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
2198 {
2199 mark_jump_label (PATTERN (insn), insn, cross_jump);
2200 if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
2201 {
2202 if (JUMP_LABEL (insn) != 0 && simplejump_p (insn))
2203 {
2204 jump_chain[INSN_UID (insn)]
2205 = jump_chain[INSN_UID (JUMP_LABEL (insn))];
2206 jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn;
2207 }
2208 if (GET_CODE (PATTERN (insn)) == RETURN)
2209 {
2210 jump_chain[INSN_UID (insn)] = jump_chain[0];
2211 jump_chain[0] = insn;
2212 }
2213 }
2214 }
2215 }
2216
2217 /* Delete all labels already not referenced.
2218 Also find and return the last insn. */
2219
2220 static rtx
2221 delete_unreferenced_labels (f)
2222 rtx f;
2223 {
2224 rtx final = NULL_RTX;
2225 rtx insn;
2226
2227 for (insn = f; insn; )
2228 {
2229 if (GET_CODE (insn) == CODE_LABEL && LABEL_NUSES (insn) == 0)
2230 insn = delete_insn (insn);
2231 else
2232 {
2233 final = insn;
2234 insn = NEXT_INSN (insn);
2235 }
2236 }
2237
2238 return final;
2239 }
2240
2241 /* Delete various simple forms of moves which have no necessary
2242 side effect. */
2243
2244 static void
2245 delete_noop_moves (f)
2246 rtx f;
2247 {
2248 rtx insn, next;
2249
2250 for (insn = f; insn; )
2251 {
2252 next = NEXT_INSN (insn);
2253
2254 if (GET_CODE (insn) == INSN)
2255 {
2256 register rtx body = PATTERN (insn);
2257
2258 /* Combine stack_adjusts with following push_insns. */
2259 #ifdef PUSH_ROUNDING
2260 if (GET_CODE (body) == SET
2261 && SET_DEST (body) == stack_pointer_rtx
2262 && GET_CODE (SET_SRC (body)) == PLUS
2263 && XEXP (SET_SRC (body), 0) == stack_pointer_rtx
2264 && GET_CODE (XEXP (SET_SRC (body), 1)) == CONST_INT
2265 && INTVAL (XEXP (SET_SRC (body), 1)) > 0)
2266 {
2267 rtx p;
2268 rtx stack_adjust_insn = insn;
2269 int stack_adjust_amount = INTVAL (XEXP (SET_SRC (body), 1));
2270 int total_pushed = 0;
2271 int pushes = 0;
2272
2273 /* Find all successive push insns. */
2274 p = insn;
2275 /* Don't convert more than three pushes;
2276 that starts adding too many displaced addresses
2277 and the whole thing starts becoming a losing
2278 proposition. */
2279 while (pushes < 3)
2280 {
2281 rtx pbody, dest;
2282 p = next_nonnote_insn (p);
2283 if (p == 0 || GET_CODE (p) != INSN)
2284 break;
2285 pbody = PATTERN (p);
2286 if (GET_CODE (pbody) != SET)
2287 break;
2288 dest = SET_DEST (pbody);
2289 /* Allow a no-op move between the adjust and the push. */
2290 if (GET_CODE (dest) == REG
2291 && GET_CODE (SET_SRC (pbody)) == REG
2292 && REGNO (dest) == REGNO (SET_SRC (pbody)))
2293 continue;
2294 if (! (GET_CODE (dest) == MEM
2295 && GET_CODE (XEXP (dest, 0)) == POST_INC
2296 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
2297 break;
2298 pushes++;
2299 if (total_pushed + GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)))
2300 > stack_adjust_amount)
2301 break;
2302 total_pushed += GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)));
2303 }
2304
2305 /* Discard the amount pushed from the stack adjust;
2306 maybe eliminate it entirely. */
2307 if (total_pushed >= stack_adjust_amount)
2308 {
2309 delete_computation (stack_adjust_insn);
2310 total_pushed = stack_adjust_amount;
2311 }
2312 else
2313 XEXP (SET_SRC (PATTERN (stack_adjust_insn)), 1)
2314 = GEN_INT (stack_adjust_amount - total_pushed);
2315
2316 /* Change the appropriate push insns to ordinary stores. */
2317 p = insn;
2318 while (total_pushed > 0)
2319 {
2320 rtx pbody, dest;
2321 p = next_nonnote_insn (p);
2322 if (GET_CODE (p) != INSN)
2323 break;
2324 pbody = PATTERN (p);
2325 if (GET_CODE (pbody) != SET)
2326 break;
2327 dest = SET_DEST (pbody);
2328 /* Allow a no-op move between the adjust and the push. */
2329 if (GET_CODE (dest) == REG
2330 && GET_CODE (SET_SRC (pbody)) == REG
2331 && REGNO (dest) == REGNO (SET_SRC (pbody)))
2332 continue;
2333 if (! (GET_CODE (dest) == MEM
2334 && GET_CODE (XEXP (dest, 0)) == POST_INC
2335 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx))
2336 break;
2337 total_pushed -= GET_MODE_SIZE (GET_MODE (SET_DEST (pbody)));
2338 /* If this push doesn't fully fit in the space
2339 of the stack adjust that we deleted,
2340 make another stack adjust here for what we
2341 didn't use up. There should be peepholes
2342 to recognize the resulting sequence of insns. */
2343 if (total_pushed < 0)
2344 {
2345 emit_insn_before (gen_add2_insn (stack_pointer_rtx,
2346 GEN_INT (- total_pushed)),
2347 p);
2348 break;
2349 }
2350 XEXP (dest, 0)
2351 = plus_constant (stack_pointer_rtx, total_pushed);
2352 }
2353 }
2354 #endif
2355
2356 /* Detect and delete no-op move instructions
2357 resulting from not allocating a parameter in a register. */
2358
2359 if (GET_CODE (body) == SET
2360 && (SET_DEST (body) == SET_SRC (body)
2361 || (GET_CODE (SET_DEST (body)) == MEM
2362 && GET_CODE (SET_SRC (body)) == MEM
2363 && rtx_equal_p (SET_SRC (body), SET_DEST (body))))
2364 && ! (GET_CODE (SET_DEST (body)) == MEM
2365 && MEM_VOLATILE_P (SET_DEST (body)))
2366 && ! (GET_CODE (SET_SRC (body)) == MEM
2367 && MEM_VOLATILE_P (SET_SRC (body))))
2368 delete_computation (insn);
2369
2370 /* Detect and ignore no-op move instructions
2371 resulting from smart or fortuitous register allocation. */
2372
2373 else if (GET_CODE (body) == SET)
2374 {
2375 int sreg = true_regnum (SET_SRC (body));
2376 int dreg = true_regnum (SET_DEST (body));
2377
2378 if (sreg == dreg && sreg >= 0)
2379 delete_insn (insn);
2380 else if (sreg >= 0 && dreg >= 0)
2381 {
2382 rtx trial;
2383 rtx tem = find_equiv_reg (NULL_RTX, insn, 0,
2384 sreg, NULL_PTR, dreg,
2385 GET_MODE (SET_SRC (body)));
2386
2387 if (tem != 0
2388 && GET_MODE (tem) == GET_MODE (SET_DEST (body)))
2389 {
2390 /* DREG may have been the target of a REG_DEAD note in
2391 the insn which makes INSN redundant. If so, reorg
2392 would still think it is dead. So search for such a
2393 note and delete it if we find it. */
2394 if (! find_regno_note (insn, REG_UNUSED, dreg))
2395 for (trial = prev_nonnote_insn (insn);
2396 trial && GET_CODE (trial) != CODE_LABEL;
2397 trial = prev_nonnote_insn (trial))
2398 if (find_regno_note (trial, REG_DEAD, dreg))
2399 {
2400 remove_death (dreg, trial);
2401 break;
2402 }
2403
2404 /* Deleting insn could lose a death-note for SREG. */
2405 if ((trial = find_regno_note (insn, REG_DEAD, sreg)))
2406 {
2407 /* Change this into a USE so that we won't emit
2408 code for it, but still can keep the note. */
2409 PATTERN (insn)
2410 = gen_rtx_USE (VOIDmode, XEXP (trial, 0));
2411 INSN_CODE (insn) = -1;
2412 /* Remove all reg notes but the REG_DEAD one. */
2413 REG_NOTES (insn) = trial;
2414 XEXP (trial, 1) = NULL_RTX;
2415 }
2416 else
2417 delete_insn (insn);
2418 }
2419 }
2420 else if (dreg >= 0 && CONSTANT_P (SET_SRC (body))
2421 && find_equiv_reg (SET_SRC (body), insn, 0, dreg,
2422 NULL_PTR, 0,
2423 GET_MODE (SET_DEST (body))))
2424 {
2425 /* This handles the case where we have two consecutive
2426 assignments of the same constant to pseudos that didn't
2427 get a hard reg. Each SET from the constant will be
2428 converted into a SET of the spill register and an
2429 output reload will be made following it. This produces
2430 two loads of the same constant into the same spill
2431 register. */
2432
2433 rtx in_insn = insn;
2434
2435 /* Look back for a death note for the first reg.
2436 If there is one, it is no longer accurate. */
2437 while (in_insn && GET_CODE (in_insn) != CODE_LABEL)
2438 {
2439 if ((GET_CODE (in_insn) == INSN
2440 || GET_CODE (in_insn) == JUMP_INSN)
2441 && find_regno_note (in_insn, REG_DEAD, dreg))
2442 {
2443 remove_death (dreg, in_insn);
2444 break;
2445 }
2446 in_insn = PREV_INSN (in_insn);
2447 }
2448
2449 /* Delete the second load of the value. */
2450 delete_insn (insn);
2451 }
2452 }
2453 else if (GET_CODE (body) == PARALLEL)
2454 {
2455 /* If each part is a set between two identical registers or
2456 a USE or CLOBBER, delete the insn. */
2457 int i, sreg, dreg;
2458 rtx tem;
2459
2460 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
2461 {
2462 tem = XVECEXP (body, 0, i);
2463 if (GET_CODE (tem) == USE || GET_CODE (tem) == CLOBBER)
2464 continue;
2465
2466 if (GET_CODE (tem) != SET
2467 || (sreg = true_regnum (SET_SRC (tem))) < 0
2468 || (dreg = true_regnum (SET_DEST (tem))) < 0
2469 || dreg != sreg)
2470 break;
2471 }
2472
2473 if (i < 0)
2474 delete_insn (insn);
2475 }
2476 /* Also delete insns to store bit fields if they are no-ops. */
2477 /* Not worth the hair to detect this in the big-endian case. */
2478 else if (! BYTES_BIG_ENDIAN
2479 && GET_CODE (body) == SET
2480 && GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
2481 && XEXP (SET_DEST (body), 2) == const0_rtx
2482 && XEXP (SET_DEST (body), 0) == SET_SRC (body)
2483 && ! (GET_CODE (SET_SRC (body)) == MEM
2484 && MEM_VOLATILE_P (SET_SRC (body))))
2485 delete_insn (insn);
2486 }
2487 insn = next;
2488 }
2489 }
2490
2491 /* See if there is still a NOTE_INSN_FUNCTION_END in this function.
2492 If so indicate that this function can drop off the end by returning
2493 1, else return 0.
2494
2495 CHECK_DELETED indicates whether we must check if the note being
2496 searched for has the deleted flag set.
2497
2498 DELETE_FINAL_NOTE indicates whether we should delete the note
2499 if we find it. */
2500
2501 static int
2502 calculate_can_reach_end (last, check_deleted, delete_final_note)
2503 rtx last;
2504 int check_deleted;
2505 int delete_final_note;
2506 {
2507 rtx insn = last;
2508 int n_labels = 1;
2509
2510 while (insn != NULL_RTX)
2511 {
2512 int ok = 0;
2513
2514 /* One label can follow the end-note: the return label. */
2515 if (GET_CODE (insn) == CODE_LABEL && n_labels-- > 0)
2516 ok = 1;
2517 /* Ordinary insns can follow it if returning a structure. */
2518 else if (GET_CODE (insn) == INSN)
2519 ok = 1;
2520 /* If machine uses explicit RETURN insns, no epilogue,
2521 then one of them follows the note. */
2522 else if (GET_CODE (insn) == JUMP_INSN
2523 && GET_CODE (PATTERN (insn)) == RETURN)
2524 ok = 1;
2525 /* A barrier can follow the return insn. */
2526 else if (GET_CODE (insn) == BARRIER)
2527 ok = 1;
2528 /* Other kinds of notes can follow also. */
2529 else if (GET_CODE (insn) == NOTE
2530 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END)
2531 ok = 1;
2532
2533 if (ok != 1)
2534 break;
2535
2536 insn = PREV_INSN (insn);
2537 }
2538
2539 /* See if we backed up to the appropriate type of note. */
2540 if (insn != NULL_RTX
2541 && GET_CODE (insn) == NOTE
2542 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END
2543 && (check_deleted == 0
2544 || ! INSN_DELETED_P (insn)))
2545 {
2546 if (delete_final_note)
2547 delete_insn (insn);
2548 return 1;
2549 }
2550
2551 return 0;
2552 }
2553
2554 /* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional
2555 jump. Assume that this unconditional jump is to the exit test code. If
2556 the code is sufficiently simple, make a copy of it before INSN,
2557 followed by a jump to the exit of the loop. Then delete the unconditional
2558 jump after INSN.
2559
2560 Return 1 if we made the change, else 0.
2561
2562 This is only safe immediately after a regscan pass because it uses the
2563 values of regno_first_uid and regno_last_uid. */
2564
2565 static int
2566 duplicate_loop_exit_test (loop_start)
2567 rtx loop_start;
2568 {
2569 rtx insn, set, reg, p, link;
2570 rtx copy = 0;
2571 int num_insns = 0;
2572 rtx exitcode = NEXT_INSN (JUMP_LABEL (next_nonnote_insn (loop_start)));
2573 rtx lastexit;
2574 int max_reg = max_reg_num ();
2575 rtx *reg_map = 0;
2576
2577 /* Scan the exit code. We do not perform this optimization if any insn:
2578
2579 is a CALL_INSN
2580 is a CODE_LABEL
2581 has a REG_RETVAL or REG_LIBCALL note (hard to adjust)
2582 is a NOTE_INSN_LOOP_BEG because this means we have a nested loop
2583 is a NOTE_INSN_BLOCK_{BEG,END} because duplicating these notes
2584 is not valid.
2585
2586 We also do not do this if we find an insn with ASM_OPERANDS. While
2587 this restriction should not be necessary, copying an insn with
2588 ASM_OPERANDS can confuse asm_noperands in some cases.
2589
2590 Also, don't do this if the exit code is more than 20 insns. */
2591
2592 for (insn = exitcode;
2593 insn
2594 && ! (GET_CODE (insn) == NOTE
2595 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
2596 insn = NEXT_INSN (insn))
2597 {
2598 switch (GET_CODE (insn))
2599 {
2600 case CODE_LABEL:
2601 case CALL_INSN:
2602 return 0;
2603 case NOTE:
2604 /* We could be in front of the wrong NOTE_INSN_LOOP_END if there is
2605 a jump immediately after the loop start that branches outside
2606 the loop but within an outer loop, near the exit test.
2607 If we copied this exit test and created a phony
2608 NOTE_INSN_LOOP_VTOP, this could make instructions immediately
2609 before the exit test look like these could be safely moved
2610 out of the loop even if they actually may be never executed.
2611 This can be avoided by checking here for NOTE_INSN_LOOP_CONT. */
2612
2613 if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
2614 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT)
2615 return 0;
2616
2617 if (optimize < 2
2618 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
2619 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
2620 /* If we were to duplicate this code, we would not move
2621 the BLOCK notes, and so debugging the moved code would
2622 be difficult. Thus, we only move the code with -O2 or
2623 higher. */
2624 return 0;
2625
2626 break;
2627 case JUMP_INSN:
2628 case INSN:
2629 /* The code below would grossly mishandle REG_WAS_0 notes,
2630 so get rid of them here. */
2631 while ((p = find_reg_note (insn, REG_WAS_0, NULL_RTX)) != 0)
2632 remove_note (insn, p);
2633 if (++num_insns > 20
2634 || find_reg_note (insn, REG_RETVAL, NULL_RTX)
2635 || find_reg_note (insn, REG_LIBCALL, NULL_RTX)
2636 || asm_noperands (PATTERN (insn)) > 0)
2637 return 0;
2638 break;
2639 default:
2640 break;
2641 }
2642 }
2643
2644 /* Unless INSN is zero, we can do the optimization. */
2645 if (insn == 0)
2646 return 0;
2647
2648 lastexit = insn;
2649
2650 /* See if any insn sets a register only used in the loop exit code and
2651 not a user variable. If so, replace it with a new register. */
2652 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
2653 if (GET_CODE (insn) == INSN
2654 && (set = single_set (insn)) != 0
2655 && ((reg = SET_DEST (set), GET_CODE (reg) == REG)
2656 || (GET_CODE (reg) == SUBREG
2657 && (reg = SUBREG_REG (reg), GET_CODE (reg) == REG)))
2658 && REGNO (reg) >= FIRST_PSEUDO_REGISTER
2659 && REGNO_FIRST_UID (REGNO (reg)) == INSN_UID (insn))
2660 {
2661 for (p = NEXT_INSN (insn); p != lastexit; p = NEXT_INSN (p))
2662 if (REGNO_LAST_UID (REGNO (reg)) == INSN_UID (p))
2663 break;
2664
2665 if (p != lastexit)
2666 {
2667 /* We can do the replacement. Allocate reg_map if this is the
2668 first replacement we found. */
2669 if (reg_map == 0)
2670 {
2671 reg_map = (rtx *) alloca (max_reg * sizeof (rtx));
2672 bzero ((char *) reg_map, max_reg * sizeof (rtx));
2673 }
2674
2675 REG_LOOP_TEST_P (reg) = 1;
2676
2677 reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg));
2678 }
2679 }
2680
2681 /* Now copy each insn. */
2682 for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
2683 switch (GET_CODE (insn))
2684 {
2685 case BARRIER:
2686 copy = emit_barrier_before (loop_start);
2687 break;
2688 case NOTE:
2689 /* Only copy line-number notes. */
2690 if (NOTE_LINE_NUMBER (insn) >= 0)
2691 {
2692 copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start);
2693 NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
2694 }
2695 break;
2696
2697 case INSN:
2698 copy = emit_insn_before (copy_rtx (PATTERN (insn)), loop_start);
2699 if (reg_map)
2700 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
2701
2702 mark_jump_label (PATTERN (copy), copy, 0);
2703
2704 /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
2705 make them. */
2706 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
2707 if (REG_NOTE_KIND (link) != REG_LABEL)
2708 REG_NOTES (copy)
2709 = copy_rtx (gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
2710 XEXP (link, 0),
2711 REG_NOTES (copy)));
2712 if (reg_map && REG_NOTES (copy))
2713 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
2714 break;
2715
2716 case JUMP_INSN:
2717 copy = emit_jump_insn_before (copy_rtx (PATTERN (insn)), loop_start);
2718 if (reg_map)
2719 replace_regs (PATTERN (copy), reg_map, max_reg, 1);
2720 mark_jump_label (PATTERN (copy), copy, 0);
2721 if (REG_NOTES (insn))
2722 {
2723 REG_NOTES (copy) = copy_rtx (REG_NOTES (insn));
2724 if (reg_map)
2725 replace_regs (REG_NOTES (copy), reg_map, max_reg, 1);
2726 }
2727
2728 /* If this is a simple jump, add it to the jump chain. */
2729
2730 if (INSN_UID (copy) < max_jump_chain && JUMP_LABEL (copy)
2731 && simplejump_p (copy))
2732 {
2733 jump_chain[INSN_UID (copy)]
2734 = jump_chain[INSN_UID (JUMP_LABEL (copy))];
2735 jump_chain[INSN_UID (JUMP_LABEL (copy))] = copy;
2736 }
2737 break;
2738
2739 default:
2740 abort ();
2741 }
2742
2743 /* Now clean up by emitting a jump to the end label and deleting the jump
2744 at the start of the loop. */
2745 if (! copy || GET_CODE (copy) != BARRIER)
2746 {
2747 copy = emit_jump_insn_before (gen_jump (get_label_after (insn)),
2748 loop_start);
2749 mark_jump_label (PATTERN (copy), copy, 0);
2750 if (INSN_UID (copy) < max_jump_chain
2751 && INSN_UID (JUMP_LABEL (copy)) < max_jump_chain)
2752 {
2753 jump_chain[INSN_UID (copy)]
2754 = jump_chain[INSN_UID (JUMP_LABEL (copy))];
2755 jump_chain[INSN_UID (JUMP_LABEL (copy))] = copy;
2756 }
2757 emit_barrier_before (loop_start);
2758 }
2759
2760 /* Mark the exit code as the virtual top of the converted loop. */
2761 emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode);
2762
2763 delete_insn (next_nonnote_insn (loop_start));
2764
2765 return 1;
2766 }
2767 \f
2768 /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, and
2769 loop-end notes between START and END out before START. Assume that
2770 END is not such a note. START may be such a note. Returns the value
2771 of the new starting insn, which may be different if the original start
2772 was such a note. */
2773
2774 rtx
2775 squeeze_notes (start, end)
2776 rtx start, end;
2777 {
2778 rtx insn;
2779 rtx next;
2780
2781 for (insn = start; insn != end; insn = next)
2782 {
2783 next = NEXT_INSN (insn);
2784 if (GET_CODE (insn) == NOTE
2785 && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
2786 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
2787 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
2788 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
2789 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
2790 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
2791 {
2792 if (insn == start)
2793 start = next;
2794 else
2795 {
2796 rtx prev = PREV_INSN (insn);
2797 PREV_INSN (insn) = PREV_INSN (start);
2798 NEXT_INSN (insn) = start;
2799 NEXT_INSN (PREV_INSN (insn)) = insn;
2800 PREV_INSN (NEXT_INSN (insn)) = insn;
2801 NEXT_INSN (prev) = next;
2802 PREV_INSN (next) = prev;
2803 }
2804 }
2805 }
2806
2807 return start;
2808 }
2809 \f
2810 /* Compare the instructions before insn E1 with those before E2
2811 to find an opportunity for cross jumping.
2812 (This means detecting identical sequences of insns followed by
2813 jumps to the same place, or followed by a label and a jump
2814 to that label, and replacing one with a jump to the other.)
2815
2816 Assume E1 is a jump that jumps to label E2
2817 (that is not always true but it might as well be).
2818 Find the longest possible equivalent sequences
2819 and store the first insns of those sequences into *F1 and *F2.
2820 Store zero there if no equivalent preceding instructions are found.
2821
2822 We give up if we find a label in stream 1.
2823 Actually we could transfer that label into stream 2. */
2824
2825 static void
2826 find_cross_jump (e1, e2, minimum, f1, f2)
2827 rtx e1, e2;
2828 int minimum;
2829 rtx *f1, *f2;
2830 {
2831 register rtx i1 = e1, i2 = e2;
2832 register rtx p1, p2;
2833 int lose = 0;
2834
2835 rtx last1 = 0, last2 = 0;
2836 rtx afterlast1 = 0, afterlast2 = 0;
2837
2838 *f1 = 0;
2839 *f2 = 0;
2840
2841 while (1)
2842 {
2843 i1 = prev_nonnote_insn (i1);
2844
2845 i2 = PREV_INSN (i2);
2846 while (i2 && (GET_CODE (i2) == NOTE || GET_CODE (i2) == CODE_LABEL))
2847 i2 = PREV_INSN (i2);
2848
2849 if (i1 == 0)
2850 break;
2851
2852 /* Don't allow the range of insns preceding E1 or E2
2853 to include the other (E2 or E1). */
2854 if (i2 == e1 || i1 == e2)
2855 break;
2856
2857 /* If we will get to this code by jumping, those jumps will be
2858 tensioned to go directly to the new label (before I2),
2859 so this cross-jumping won't cost extra. So reduce the minimum. */
2860 if (GET_CODE (i1) == CODE_LABEL)
2861 {
2862 --minimum;
2863 break;
2864 }
2865
2866 if (i2 == 0 || GET_CODE (i1) != GET_CODE (i2))
2867 break;
2868
2869 /* Avoid moving insns across EH regions if either of the insns
2870 can throw. */
2871 if (flag_exceptions
2872 && (asynchronous_exceptions || GET_CODE (i1) == CALL_INSN)
2873 && !in_same_eh_region (i1, i2))
2874 break;
2875
2876 p1 = PATTERN (i1);
2877 p2 = PATTERN (i2);
2878
2879 /* If this is a CALL_INSN, compare register usage information.
2880 If we don't check this on stack register machines, the two
2881 CALL_INSNs might be merged leaving reg-stack.c with mismatching
2882 numbers of stack registers in the same basic block.
2883 If we don't check this on machines with delay slots, a delay slot may
2884 be filled that clobbers a parameter expected by the subroutine.
2885
2886 ??? We take the simple route for now and assume that if they're
2887 equal, they were constructed identically. */
2888
2889 if (GET_CODE (i1) == CALL_INSN
2890 && ! rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
2891 CALL_INSN_FUNCTION_USAGE (i2)))
2892 lose = 1;
2893
2894 #ifdef STACK_REGS
2895 /* If cross_jump_death_matters is not 0, the insn's mode
2896 indicates whether or not the insn contains any stack-like
2897 regs. */
2898
2899 if (!lose && cross_jump_death_matters && stack_regs_mentioned (i1))
2900 {
2901 /* If register stack conversion has already been done, then
2902 death notes must also be compared before it is certain that
2903 the two instruction streams match. */
2904
2905 rtx note;
2906 HARD_REG_SET i1_regset, i2_regset;
2907
2908 CLEAR_HARD_REG_SET (i1_regset);
2909 CLEAR_HARD_REG_SET (i2_regset);
2910
2911 for (note = REG_NOTES (i1); note; note = XEXP (note, 1))
2912 if (REG_NOTE_KIND (note) == REG_DEAD
2913 && STACK_REG_P (XEXP (note, 0)))
2914 SET_HARD_REG_BIT (i1_regset, REGNO (XEXP (note, 0)));
2915
2916 for (note = REG_NOTES (i2); note; note = XEXP (note, 1))
2917 if (REG_NOTE_KIND (note) == REG_DEAD
2918 && STACK_REG_P (XEXP (note, 0)))
2919 SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0)));
2920
2921 GO_IF_HARD_REG_EQUAL (i1_regset, i2_regset, done);
2922
2923 lose = 1;
2924
2925 done:
2926 ;
2927 }
2928 #endif
2929
2930 /* Don't allow old-style asm or volatile extended asms to be accepted
2931 for cross jumping purposes. It is conceptually correct to allow
2932 them, since cross-jumping preserves the dynamic instruction order
2933 even though it is changing the static instruction order. However,
2934 if an asm is being used to emit an assembler pseudo-op, such as
2935 the MIPS `.set reorder' pseudo-op, then the static instruction order
2936 matters and it must be preserved. */
2937 if (GET_CODE (p1) == ASM_INPUT || GET_CODE (p2) == ASM_INPUT
2938 || (GET_CODE (p1) == ASM_OPERANDS && MEM_VOLATILE_P (p1))
2939 || (GET_CODE (p2) == ASM_OPERANDS && MEM_VOLATILE_P (p2)))
2940 lose = 1;
2941
2942 if (lose || GET_CODE (p1) != GET_CODE (p2)
2943 || ! rtx_renumbered_equal_p (p1, p2))
2944 {
2945 /* The following code helps take care of G++ cleanups. */
2946 rtx equiv1;
2947 rtx equiv2;
2948
2949 if (!lose && GET_CODE (p1) == GET_CODE (p2)
2950 && ((equiv1 = find_reg_note (i1, REG_EQUAL, NULL_RTX)) != 0
2951 || (equiv1 = find_reg_note (i1, REG_EQUIV, NULL_RTX)) != 0)
2952 && ((equiv2 = find_reg_note (i2, REG_EQUAL, NULL_RTX)) != 0
2953 || (equiv2 = find_reg_note (i2, REG_EQUIV, NULL_RTX)) != 0)
2954 /* If the equivalences are not to a constant, they may
2955 reference pseudos that no longer exist, so we can't
2956 use them. */
2957 && CONSTANT_P (XEXP (equiv1, 0))
2958 && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))
2959 {
2960 rtx s1 = single_set (i1);
2961 rtx s2 = single_set (i2);
2962 if (s1 != 0 && s2 != 0
2963 && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2)))
2964 {
2965 validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1);
2966 validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1);
2967 if (! rtx_renumbered_equal_p (p1, p2))
2968 cancel_changes (0);
2969 else if (apply_change_group ())
2970 goto win;
2971 }
2972 }
2973
2974 /* Insns fail to match; cross jumping is limited to the following
2975 insns. */
2976
2977 #ifdef HAVE_cc0
2978 /* Don't allow the insn after a compare to be shared by
2979 cross-jumping unless the compare is also shared.
2980 Here, if either of these non-matching insns is a compare,
2981 exclude the following insn from possible cross-jumping. */
2982 if (sets_cc0_p (p1) || sets_cc0_p (p2))
2983 last1 = afterlast1, last2 = afterlast2, ++minimum;
2984 #endif
2985
2986 /* If cross-jumping here will feed a jump-around-jump
2987 optimization, this jump won't cost extra, so reduce
2988 the minimum. */
2989 if (GET_CODE (i1) == JUMP_INSN
2990 && JUMP_LABEL (i1)
2991 && prev_real_insn (JUMP_LABEL (i1)) == e1)
2992 --minimum;
2993 break;
2994 }
2995
2996 win:
2997 if (GET_CODE (p1) != USE && GET_CODE (p1) != CLOBBER)
2998 {
2999 /* Ok, this insn is potentially includable in a cross-jump here. */
3000 afterlast1 = last1, afterlast2 = last2;
3001 last1 = i1, last2 = i2, --minimum;
3002 }
3003 }
3004
3005 if (minimum <= 0 && last1 != 0 && last1 != e1)
3006 *f1 = last1, *f2 = last2;
3007 }
3008
3009 static void
3010 do_cross_jump (insn, newjpos, newlpos)
3011 rtx insn, newjpos, newlpos;
3012 {
3013 /* Find an existing label at this point
3014 or make a new one if there is none. */
3015 register rtx label = get_label_before (newlpos);
3016
3017 /* Make the same jump insn jump to the new point. */
3018 if (GET_CODE (PATTERN (insn)) == RETURN)
3019 {
3020 /* Remove from jump chain of returns. */
3021 delete_from_jump_chain (insn);
3022 /* Change the insn. */
3023 PATTERN (insn) = gen_jump (label);
3024 INSN_CODE (insn) = -1;
3025 JUMP_LABEL (insn) = label;
3026 LABEL_NUSES (label)++;
3027 /* Add to new the jump chain. */
3028 if (INSN_UID (label) < max_jump_chain
3029 && INSN_UID (insn) < max_jump_chain)
3030 {
3031 jump_chain[INSN_UID (insn)] = jump_chain[INSN_UID (label)];
3032 jump_chain[INSN_UID (label)] = insn;
3033 }
3034 }
3035 else
3036 redirect_jump (insn, label);
3037
3038 /* Delete the matching insns before the jump. Also, remove any REG_EQUAL
3039 or REG_EQUIV note in the NEWLPOS stream that isn't also present in
3040 the NEWJPOS stream. */
3041
3042 while (newjpos != insn)
3043 {
3044 rtx lnote;
3045
3046 for (lnote = REG_NOTES (newlpos); lnote; lnote = XEXP (lnote, 1))
3047 if ((REG_NOTE_KIND (lnote) == REG_EQUAL
3048 || REG_NOTE_KIND (lnote) == REG_EQUIV)
3049 && ! find_reg_note (newjpos, REG_EQUAL, XEXP (lnote, 0))
3050 && ! find_reg_note (newjpos, REG_EQUIV, XEXP (lnote, 0)))
3051 remove_note (newlpos, lnote);
3052
3053 delete_insn (newjpos);
3054 newjpos = next_real_insn (newjpos);
3055 newlpos = next_real_insn (newlpos);
3056 }
3057 }
3058 \f
3059 /* Return the label before INSN, or put a new label there. */
3060
3061 rtx
3062 get_label_before (insn)
3063 rtx insn;
3064 {
3065 rtx label;
3066
3067 /* Find an existing label at this point
3068 or make a new one if there is none. */
3069 label = prev_nonnote_insn (insn);
3070
3071 if (label == 0 || GET_CODE (label) != CODE_LABEL)
3072 {
3073 rtx prev = PREV_INSN (insn);
3074
3075 label = gen_label_rtx ();
3076 emit_label_after (label, prev);
3077 LABEL_NUSES (label) = 0;
3078 }
3079 return label;
3080 }
3081
3082 /* Return the label after INSN, or put a new label there. */
3083
3084 rtx
3085 get_label_after (insn)
3086 rtx insn;
3087 {
3088 rtx label;
3089
3090 /* Find an existing label at this point
3091 or make a new one if there is none. */
3092 label = next_nonnote_insn (insn);
3093
3094 if (label == 0 || GET_CODE (label) != CODE_LABEL)
3095 {
3096 label = gen_label_rtx ();
3097 emit_label_after (label, insn);
3098 LABEL_NUSES (label) = 0;
3099 }
3100 return label;
3101 }
3102 \f
3103 /* Return 1 if INSN is a jump that jumps to right after TARGET
3104 only on the condition that TARGET itself would drop through.
3105 Assumes that TARGET is a conditional jump. */
3106
3107 static int
3108 jump_back_p (insn, target)
3109 rtx insn, target;
3110 {
3111 rtx cinsn, ctarget;
3112 enum rtx_code codei, codet;
3113
3114 if (simplejump_p (insn) || ! condjump_p (insn)
3115 || simplejump_p (target)
3116 || target != prev_real_insn (JUMP_LABEL (insn)))
3117 return 0;
3118
3119 cinsn = XEXP (SET_SRC (PATTERN (insn)), 0);
3120 ctarget = XEXP (SET_SRC (PATTERN (target)), 0);
3121
3122 codei = GET_CODE (cinsn);
3123 codet = GET_CODE (ctarget);
3124
3125 if (XEXP (SET_SRC (PATTERN (insn)), 1) == pc_rtx)
3126 {
3127 if (! can_reverse_comparison_p (cinsn, insn))
3128 return 0;
3129 codei = reverse_condition (codei);
3130 }
3131
3132 if (XEXP (SET_SRC (PATTERN (target)), 2) == pc_rtx)
3133 {
3134 if (! can_reverse_comparison_p (ctarget, target))
3135 return 0;
3136 codet = reverse_condition (codet);
3137 }
3138
3139 return (codei == codet
3140 && rtx_renumbered_equal_p (XEXP (cinsn, 0), XEXP (ctarget, 0))
3141 && rtx_renumbered_equal_p (XEXP (cinsn, 1), XEXP (ctarget, 1)));
3142 }
3143 \f
3144 /* Given a comparison, COMPARISON, inside a conditional jump insn, INSN,
3145 return non-zero if it is safe to reverse this comparison. It is if our
3146 floating-point is not IEEE, if this is an NE or EQ comparison, or if
3147 this is known to be an integer comparison. */
3148
3149 int
3150 can_reverse_comparison_p (comparison, insn)
3151 rtx comparison;
3152 rtx insn;
3153 {
3154 rtx arg0;
3155
3156 /* If this is not actually a comparison, we can't reverse it. */
3157 if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
3158 return 0;
3159
3160 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
3161 /* If this is an NE comparison, it is safe to reverse it to an EQ
3162 comparison and vice versa, even for floating point. If no operands
3163 are NaNs, the reversal is valid. If some operand is a NaN, EQ is
3164 always false and NE is always true, so the reversal is also valid. */
3165 || flag_fast_math
3166 || GET_CODE (comparison) == NE
3167 || GET_CODE (comparison) == EQ)
3168 return 1;
3169
3170 arg0 = XEXP (comparison, 0);
3171
3172 /* Make sure ARG0 is one of the actual objects being compared. If we
3173 can't do this, we can't be sure the comparison can be reversed.
3174
3175 Handle cc0 and a MODE_CC register. */
3176 if ((GET_CODE (arg0) == REG && GET_MODE_CLASS (GET_MODE (arg0)) == MODE_CC)
3177 #ifdef HAVE_cc0
3178 || arg0 == cc0_rtx
3179 #endif
3180 )
3181 {
3182 rtx prev = prev_nonnote_insn (insn);
3183 rtx set;
3184
3185 /* If the comparison itself was a loop invariant, it could have been
3186 hoisted out of the loop. If we proceed to unroll such a loop, then
3187 we may not be able to find the comparison when copying the loop.
3188
3189 Returning zero in that case is the safe thing to do. */
3190 if (prev == 0)
3191 return 0;
3192
3193 set = single_set (prev);
3194 if (set == 0 || SET_DEST (set) != arg0)
3195 return 0;
3196
3197 arg0 = SET_SRC (set);
3198
3199 if (GET_CODE (arg0) == COMPARE)
3200 arg0 = XEXP (arg0, 0);
3201 }
3202
3203 /* We can reverse this if ARG0 is a CONST_INT or if its mode is
3204 not VOIDmode and neither a MODE_CC nor MODE_FLOAT type. */
3205 return (GET_CODE (arg0) == CONST_INT
3206 || (GET_MODE (arg0) != VOIDmode
3207 && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_CC
3208 && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_FLOAT));
3209 }
3210
3211 /* Given an rtx-code for a comparison, return the code
3212 for the negated comparison.
3213 WATCH OUT! reverse_condition is not safe to use on a jump
3214 that might be acting on the results of an IEEE floating point comparison,
3215 because of the special treatment of non-signaling nans in comparisons.
3216 Use can_reverse_comparison_p to be sure. */
3217
3218 enum rtx_code
3219 reverse_condition (code)
3220 enum rtx_code code;
3221 {
3222 switch (code)
3223 {
3224 case EQ:
3225 return NE;
3226
3227 case NE:
3228 return EQ;
3229
3230 case GT:
3231 return LE;
3232
3233 case GE:
3234 return LT;
3235
3236 case LT:
3237 return GE;
3238
3239 case LE:
3240 return GT;
3241
3242 case GTU:
3243 return LEU;
3244
3245 case GEU:
3246 return LTU;
3247
3248 case LTU:
3249 return GEU;
3250
3251 case LEU:
3252 return GTU;
3253
3254 default:
3255 abort ();
3256 return UNKNOWN;
3257 }
3258 }
3259
3260 /* Similar, but return the code when two operands of a comparison are swapped.
3261 This IS safe for IEEE floating-point. */
3262
3263 enum rtx_code
3264 swap_condition (code)
3265 enum rtx_code code;
3266 {
3267 switch (code)
3268 {
3269 case EQ:
3270 case NE:
3271 return code;
3272
3273 case GT:
3274 return LT;
3275
3276 case GE:
3277 return LE;
3278
3279 case LT:
3280 return GT;
3281
3282 case LE:
3283 return GE;
3284
3285 case GTU:
3286 return LTU;
3287
3288 case GEU:
3289 return LEU;
3290
3291 case LTU:
3292 return GTU;
3293
3294 case LEU:
3295 return GEU;
3296
3297 default:
3298 abort ();
3299 return UNKNOWN;
3300 }
3301 }
3302
3303 /* Given a comparison CODE, return the corresponding unsigned comparison.
3304 If CODE is an equality comparison or already an unsigned comparison,
3305 CODE is returned. */
3306
3307 enum rtx_code
3308 unsigned_condition (code)
3309 enum rtx_code code;
3310 {
3311 switch (code)
3312 {
3313 case EQ:
3314 case NE:
3315 case GTU:
3316 case GEU:
3317 case LTU:
3318 case LEU:
3319 return code;
3320
3321 case GT:
3322 return GTU;
3323
3324 case GE:
3325 return GEU;
3326
3327 case LT:
3328 return LTU;
3329
3330 case LE:
3331 return LEU;
3332
3333 default:
3334 abort ();
3335 }
3336 }
3337
3338 /* Similarly, return the signed version of a comparison. */
3339
3340 enum rtx_code
3341 signed_condition (code)
3342 enum rtx_code code;
3343 {
3344 switch (code)
3345 {
3346 case EQ:
3347 case NE:
3348 case GT:
3349 case GE:
3350 case LT:
3351 case LE:
3352 return code;
3353
3354 case GTU:
3355 return GT;
3356
3357 case GEU:
3358 return GE;
3359
3360 case LTU:
3361 return LT;
3362
3363 case LEU:
3364 return LE;
3365
3366 default:
3367 abort ();
3368 }
3369 }
3370 \f
3371 /* Return non-zero if CODE1 is more strict than CODE2, i.e., if the
3372 truth of CODE1 implies the truth of CODE2. */
3373
3374 int
3375 comparison_dominates_p (code1, code2)
3376 enum rtx_code code1, code2;
3377 {
3378 if (code1 == code2)
3379 return 1;
3380
3381 switch (code1)
3382 {
3383 case EQ:
3384 if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU)
3385 return 1;
3386 break;
3387
3388 case LT:
3389 if (code2 == LE || code2 == NE)
3390 return 1;
3391 break;
3392
3393 case GT:
3394 if (code2 == GE || code2 == NE)
3395 return 1;
3396 break;
3397
3398 case LTU:
3399 if (code2 == LEU || code2 == NE)
3400 return 1;
3401 break;
3402
3403 case GTU:
3404 if (code2 == GEU || code2 == NE)
3405 return 1;
3406 break;
3407
3408 default:
3409 break;
3410 }
3411
3412 return 0;
3413 }
3414 \f
3415 /* Return 1 if INSN is an unconditional jump and nothing else. */
3416
3417 int
3418 simplejump_p (insn)
3419 rtx insn;
3420 {
3421 return (GET_CODE (insn) == JUMP_INSN
3422 && GET_CODE (PATTERN (insn)) == SET
3423 && GET_CODE (SET_DEST (PATTERN (insn))) == PC
3424 && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
3425 }
3426
3427 /* Return nonzero if INSN is a (possibly) conditional jump
3428 and nothing more. */
3429
3430 int
3431 condjump_p (insn)
3432 rtx insn;
3433 {
3434 register rtx x = PATTERN (insn);
3435 if (GET_CODE (x) != SET)
3436 return 0;
3437 if (GET_CODE (SET_DEST (x)) != PC)
3438 return 0;
3439 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
3440 return 1;
3441 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
3442 return 0;
3443 if (XEXP (SET_SRC (x), 2) == pc_rtx
3444 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
3445 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
3446 return 1;
3447 if (XEXP (SET_SRC (x), 1) == pc_rtx
3448 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
3449 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
3450 return 1;
3451 return 0;
3452 }
3453
3454 /* Return nonzero if INSN is a (possibly) conditional jump
3455 and nothing more. */
3456
3457 int
3458 condjump_in_parallel_p (insn)
3459 rtx insn;
3460 {
3461 register rtx x = PATTERN (insn);
3462
3463 if (GET_CODE (x) != PARALLEL)
3464 return 0;
3465 else
3466 x = XVECEXP (x, 0, 0);
3467
3468 if (GET_CODE (x) != SET)
3469 return 0;
3470 if (GET_CODE (SET_DEST (x)) != PC)
3471 return 0;
3472 if (GET_CODE (SET_SRC (x)) == LABEL_REF)
3473 return 1;
3474 if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
3475 return 0;
3476 if (XEXP (SET_SRC (x), 2) == pc_rtx
3477 && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
3478 || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
3479 return 1;
3480 if (XEXP (SET_SRC (x), 1) == pc_rtx
3481 && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
3482 || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
3483 return 1;
3484 return 0;
3485 }
3486
3487 /* Return the label of a conditional jump. */
3488
3489 rtx
3490 condjump_label (insn)
3491 rtx insn;
3492 {
3493 register rtx x = PATTERN (insn);
3494
3495 if (GET_CODE (x) == PARALLEL)
3496 x = XVECEXP (x, 0, 0);
3497 if (GET_CODE (x) != SET)
3498 return NULL_RTX;
3499 if (GET_CODE (SET_DEST (x)) != PC)
3500 return NULL_RTX;
3501 x = SET_SRC (x);
3502 if (GET_CODE (x) == LABEL_REF)
3503 return x;
3504 if (GET_CODE (x) != IF_THEN_ELSE)
3505 return NULL_RTX;
3506 if (XEXP (x, 2) == pc_rtx && GET_CODE (XEXP (x, 1)) == LABEL_REF)
3507 return XEXP (x, 1);
3508 if (XEXP (x, 1) == pc_rtx && GET_CODE (XEXP (x, 2)) == LABEL_REF)
3509 return XEXP (x, 2);
3510 return NULL_RTX;
3511 }
3512
3513 /* Return true if INSN is a (possibly conditional) return insn. */
3514
3515 static int
3516 returnjump_p_1 (loc, data)
3517 rtx *loc;
3518 void *data ATTRIBUTE_UNUSED;
3519 {
3520 rtx x = *loc;
3521 return GET_CODE (x) == RETURN;
3522 }
3523
3524 int
3525 returnjump_p (insn)
3526 rtx insn;
3527 {
3528 return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
3529 }
3530
3531 /* Return true if INSN is a jump that only transfers control and
3532 nothing more. */
3533
3534 int
3535 onlyjump_p (insn)
3536 rtx insn;
3537 {
3538 rtx set;
3539
3540 if (GET_CODE (insn) != JUMP_INSN)
3541 return 0;
3542
3543 set = single_set (insn);
3544 if (set == NULL)
3545 return 0;
3546 if (GET_CODE (SET_DEST (set)) != PC)
3547 return 0;
3548 if (side_effects_p (SET_SRC (set)))
3549 return 0;
3550
3551 return 1;
3552 }
3553
3554 #ifdef HAVE_cc0
3555
3556 /* Return 1 if X is an RTX that does nothing but set the condition codes
3557 and CLOBBER or USE registers.
3558 Return -1 if X does explicitly set the condition codes,
3559 but also does other things. */
3560
3561 int
3562 sets_cc0_p (x)
3563 rtx x ATTRIBUTE_UNUSED;
3564 {
3565 if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx)
3566 return 1;
3567 if (GET_CODE (x) == PARALLEL)
3568 {
3569 int i;
3570 int sets_cc0 = 0;
3571 int other_things = 0;
3572 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3573 {
3574 if (GET_CODE (XVECEXP (x, 0, i)) == SET
3575 && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx)
3576 sets_cc0 = 1;
3577 else if (GET_CODE (XVECEXP (x, 0, i)) == SET)
3578 other_things = 1;
3579 }
3580 return ! sets_cc0 ? 0 : other_things ? -1 : 1;
3581 }
3582 return 0;
3583 }
3584 #endif
3585 \f
3586 /* Follow any unconditional jump at LABEL;
3587 return the ultimate label reached by any such chain of jumps.
3588 If LABEL is not followed by a jump, return LABEL.
3589 If the chain loops or we can't find end, return LABEL,
3590 since that tells caller to avoid changing the insn.
3591
3592 If RELOAD_COMPLETED is 0, we do not chain across a NOTE_INSN_LOOP_BEG or
3593 a USE or CLOBBER. */
3594
3595 rtx
3596 follow_jumps (label)
3597 rtx label;
3598 {
3599 register rtx insn;
3600 register rtx next;
3601 register rtx value = label;
3602 register int depth;
3603
3604 for (depth = 0;
3605 (depth < 10
3606 && (insn = next_active_insn (value)) != 0
3607 && GET_CODE (insn) == JUMP_INSN
3608 && ((JUMP_LABEL (insn) != 0 && simplejump_p (insn))
3609 || GET_CODE (PATTERN (insn)) == RETURN)
3610 && (next = NEXT_INSN (insn))
3611 && GET_CODE (next) == BARRIER);
3612 depth++)
3613 {
3614 /* Don't chain through the insn that jumps into a loop
3615 from outside the loop,
3616 since that would create multiple loop entry jumps
3617 and prevent loop optimization. */
3618 rtx tem;
3619 if (!reload_completed)
3620 for (tem = value; tem != insn; tem = NEXT_INSN (tem))
3621 if (GET_CODE (tem) == NOTE
3622 && (NOTE_LINE_NUMBER (tem) == NOTE_INSN_LOOP_BEG
3623 /* ??? Optional. Disables some optimizations, but makes
3624 gcov output more accurate with -O. */
3625 || (flag_test_coverage && NOTE_LINE_NUMBER (tem) > 0)))
3626 return value;
3627
3628 /* If we have found a cycle, make the insn jump to itself. */
3629 if (JUMP_LABEL (insn) == label)
3630 return label;
3631
3632 tem = next_active_insn (JUMP_LABEL (insn));
3633 if (tem && (GET_CODE (PATTERN (tem)) == ADDR_VEC
3634 || GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
3635 break;
3636
3637 value = JUMP_LABEL (insn);
3638 }
3639 if (depth == 10)
3640 return label;
3641 return value;
3642 }
3643
3644 /* Assuming that field IDX of X is a vector of label_refs,
3645 replace each of them by the ultimate label reached by it.
3646 Return nonzero if a change is made.
3647 If IGNORE_LOOPS is 0, we do not chain across a NOTE_INSN_LOOP_BEG. */
3648
3649 static int
3650 tension_vector_labels (x, idx)
3651 register rtx x;
3652 register int idx;
3653 {
3654 int changed = 0;
3655 register int i;
3656 for (i = XVECLEN (x, idx) - 1; i >= 0; i--)
3657 {
3658 register rtx olabel = XEXP (XVECEXP (x, idx, i), 0);
3659 register rtx nlabel = follow_jumps (olabel);
3660 if (nlabel && nlabel != olabel)
3661 {
3662 XEXP (XVECEXP (x, idx, i), 0) = nlabel;
3663 ++LABEL_NUSES (nlabel);
3664 if (--LABEL_NUSES (olabel) == 0)
3665 delete_insn (olabel);
3666 changed = 1;
3667 }
3668 }
3669 return changed;
3670 }
3671 \f
3672 /* Find all CODE_LABELs referred to in X, and increment their use counts.
3673 If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced
3674 in INSN, then store one of them in JUMP_LABEL (INSN).
3675 If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL
3676 referenced in INSN, add a REG_LABEL note containing that label to INSN.
3677 Also, when there are consecutive labels, canonicalize on the last of them.
3678
3679 Note that two labels separated by a loop-beginning note
3680 must be kept distinct if we have not yet done loop-optimization,
3681 because the gap between them is where loop-optimize
3682 will want to move invariant code to. CROSS_JUMP tells us
3683 that loop-optimization is done with.
3684
3685 Once reload has completed (CROSS_JUMP non-zero), we need not consider
3686 two labels distinct if they are separated by only USE or CLOBBER insns. */
3687
3688 static void
3689 mark_jump_label (x, insn, cross_jump)
3690 register rtx x;
3691 rtx insn;
3692 int cross_jump;
3693 {
3694 register RTX_CODE code = GET_CODE (x);
3695 register int i;
3696 register const char *fmt;
3697
3698 switch (code)
3699 {
3700 case PC:
3701 case CC0:
3702 case REG:
3703 case SUBREG:
3704 case CONST_INT:
3705 case SYMBOL_REF:
3706 case CONST_DOUBLE:
3707 case CLOBBER:
3708 case CALL:
3709 return;
3710
3711 case MEM:
3712 /* If this is a constant-pool reference, see if it is a label. */
3713 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
3714 && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
3715 mark_jump_label (get_pool_constant (XEXP (x, 0)), insn, cross_jump);
3716 break;
3717
3718 case LABEL_REF:
3719 {
3720 rtx label = XEXP (x, 0);
3721 rtx olabel = label;
3722 rtx note;
3723 rtx next;
3724
3725 if (GET_CODE (label) != CODE_LABEL)
3726 abort ();
3727
3728 /* Ignore references to labels of containing functions. */
3729 if (LABEL_REF_NONLOCAL_P (x))
3730 break;
3731
3732 /* If there are other labels following this one,
3733 replace it with the last of the consecutive labels. */
3734 for (next = NEXT_INSN (label); next; next = NEXT_INSN (next))
3735 {
3736 if (GET_CODE (next) == CODE_LABEL)
3737 label = next;
3738 else if (cross_jump && GET_CODE (next) == INSN
3739 && (GET_CODE (PATTERN (next)) == USE
3740 || GET_CODE (PATTERN (next)) == CLOBBER))
3741 continue;
3742 else if (GET_CODE (next) != NOTE)
3743 break;
3744 else if (! cross_jump
3745 && (NOTE_LINE_NUMBER (next) == NOTE_INSN_LOOP_BEG
3746 || NOTE_LINE_NUMBER (next) == NOTE_INSN_FUNCTION_END
3747 /* ??? Optional. Disables some optimizations, but
3748 makes gcov output more accurate with -O. */
3749 || (flag_test_coverage && NOTE_LINE_NUMBER (next) > 0)))
3750 break;
3751 }
3752
3753 XEXP (x, 0) = label;
3754 if (! insn || ! INSN_DELETED_P (insn))
3755 ++LABEL_NUSES (label);
3756
3757 if (insn)
3758 {
3759 if (GET_CODE (insn) == JUMP_INSN)
3760 JUMP_LABEL (insn) = label;
3761
3762 /* If we've changed OLABEL and we had a REG_LABEL note
3763 for it, update it as well. */
3764 else if (label != olabel
3765 && (note = find_reg_note (insn, REG_LABEL, olabel)) != 0)
3766 XEXP (note, 0) = label;
3767
3768 /* Otherwise, add a REG_LABEL note for LABEL unless there already
3769 is one. */
3770 else if (! find_reg_note (insn, REG_LABEL, label))
3771 {
3772 /* This code used to ignore labels which refered to dispatch
3773 tables to avoid flow.c generating worse code.
3774
3775 However, in the presense of global optimizations like
3776 gcse which call find_basic_blocks without calling
3777 life_analysis, not recording such labels will lead
3778 to compiler aborts because of inconsistencies in the
3779 flow graph. So we go ahead and record the label.
3780
3781 It may also be the case that the optimization argument
3782 is no longer valid because of the more accurate cfg
3783 we build in find_basic_blocks -- it no longer pessimizes
3784 code when it finds a REG_LABEL note. */
3785 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL, label,
3786 REG_NOTES (insn));
3787 }
3788 }
3789 return;
3790 }
3791
3792 /* Do walk the labels in a vector, but not the first operand of an
3793 ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */
3794 case ADDR_VEC:
3795 case ADDR_DIFF_VEC:
3796 if (! INSN_DELETED_P (insn))
3797 {
3798 int eltnum = code == ADDR_DIFF_VEC ? 1 : 0;
3799
3800 for (i = 0; i < XVECLEN (x, eltnum); i++)
3801 mark_jump_label (XVECEXP (x, eltnum, i), NULL_RTX, cross_jump);
3802 }
3803 return;
3804
3805 default:
3806 break;
3807 }
3808
3809 fmt = GET_RTX_FORMAT (code);
3810 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3811 {
3812 if (fmt[i] == 'e')
3813 mark_jump_label (XEXP (x, i), insn, cross_jump);
3814 else if (fmt[i] == 'E')
3815 {
3816 register int j;
3817 for (j = 0; j < XVECLEN (x, i); j++)
3818 mark_jump_label (XVECEXP (x, i, j), insn, cross_jump);
3819 }
3820 }
3821 }
3822
3823 /* If all INSN does is set the pc, delete it,
3824 and delete the insn that set the condition codes for it
3825 if that's what the previous thing was. */
3826
3827 void
3828 delete_jump (insn)
3829 rtx insn;
3830 {
3831 register rtx set = single_set (insn);
3832
3833 if (set && GET_CODE (SET_DEST (set)) == PC)
3834 delete_computation (insn);
3835 }
3836
3837 /* Recursively delete prior insns that compute the value (used only by INSN
3838 which the caller is deleting) stored in the register mentioned by NOTE
3839 which is a REG_DEAD note associated with INSN. */
3840
3841 static void
3842 delete_prior_computation (note, insn)
3843 rtx note;
3844 rtx insn;
3845 {
3846 rtx our_prev;
3847 rtx reg = XEXP (note, 0);
3848
3849 for (our_prev = prev_nonnote_insn (insn);
3850 our_prev && GET_CODE (our_prev) == INSN;
3851 our_prev = prev_nonnote_insn (our_prev))
3852 {
3853 rtx pat = PATTERN (our_prev);
3854
3855 /* If we reach a SEQUENCE, it is too complex to try to
3856 do anything with it, so give up. */
3857 if (GET_CODE (pat) == SEQUENCE)
3858 break;
3859
3860 if (GET_CODE (pat) == USE
3861 && GET_CODE (XEXP (pat, 0)) == INSN)
3862 /* reorg creates USEs that look like this. We leave them
3863 alone because reorg needs them for its own purposes. */
3864 break;
3865
3866 if (reg_set_p (reg, pat))
3867 {
3868 if (side_effects_p (pat))
3869 break;
3870
3871 if (GET_CODE (pat) == PARALLEL)
3872 {
3873 /* If we find a SET of something else, we can't
3874 delete the insn. */
3875
3876 int i;
3877
3878 for (i = 0; i < XVECLEN (pat, 0); i++)
3879 {
3880 rtx part = XVECEXP (pat, 0, i);
3881
3882 if (GET_CODE (part) == SET
3883 && SET_DEST (part) != reg)
3884 break;
3885 }
3886
3887 if (i == XVECLEN (pat, 0))
3888 delete_computation (our_prev);
3889 }
3890 else if (GET_CODE (pat) == SET
3891 && GET_CODE (SET_DEST (pat)) == REG)
3892 {
3893 int dest_regno = REGNO (SET_DEST (pat));
3894 int dest_endregno
3895 = dest_regno + (dest_regno < FIRST_PSEUDO_REGISTER
3896 ? HARD_REGNO_NREGS (dest_regno,
3897 GET_MODE (SET_DEST (pat))) : 1);
3898 int regno = REGNO (reg);
3899 int endregno = regno + (regno < FIRST_PSEUDO_REGISTER
3900 ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1);
3901
3902 if (dest_regno >= regno
3903 && dest_endregno <= endregno)
3904 delete_computation (our_prev);
3905
3906 /* We may have a multi-word hard register and some, but not
3907 all, of the words of the register are needed in subsequent
3908 insns. Write REG_UNUSED notes for those parts that were not
3909 needed. */
3910 else if (dest_regno <= regno
3911 && dest_endregno >= endregno
3912 && ! find_regno_note (our_prev, REG_UNUSED, REGNO(reg)))
3913 {
3914 int i;
3915
3916 REG_NOTES (our_prev)
3917 = gen_rtx_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (our_prev));
3918
3919 for (i = dest_regno; i < dest_endregno; i++)
3920 if (! find_regno_note (our_prev, REG_UNUSED, i))
3921 break;
3922
3923 if (i == dest_endregno)
3924 delete_computation (our_prev);
3925 }
3926 }
3927
3928 break;
3929 }
3930
3931 /* If PAT references the register that dies here, it is an
3932 additional use. Hence any prior SET isn't dead. However, this
3933 insn becomes the new place for the REG_DEAD note. */
3934 if (reg_overlap_mentioned_p (reg, pat))
3935 {
3936 XEXP (note, 1) = REG_NOTES (our_prev);
3937 REG_NOTES (our_prev) = note;
3938 break;
3939 }
3940 }
3941 }
3942
3943 /* Delete INSN and recursively delete insns that compute values used only
3944 by INSN. This uses the REG_DEAD notes computed during flow analysis.
3945 If we are running before flow.c, we need do nothing since flow.c will
3946 delete dead code. We also can't know if the registers being used are
3947 dead or not at this point.
3948
3949 Otherwise, look at all our REG_DEAD notes. If a previous insn does
3950 nothing other than set a register that dies in this insn, we can delete
3951 that insn as well.
3952
3953 On machines with CC0, if CC0 is used in this insn, we may be able to
3954 delete the insn that set it. */
3955
3956 static void
3957 delete_computation (insn)
3958 rtx insn;
3959 {
3960 rtx note, next;
3961 rtx set;
3962
3963 #ifdef HAVE_cc0
3964 if (reg_referenced_p (cc0_rtx, PATTERN (insn)))
3965 {
3966 rtx prev = prev_nonnote_insn (insn);
3967 /* We assume that at this stage
3968 CC's are always set explicitly
3969 and always immediately before the jump that
3970 will use them. So if the previous insn
3971 exists to set the CC's, delete it
3972 (unless it performs auto-increments, etc.). */
3973 if (prev && GET_CODE (prev) == INSN
3974 && sets_cc0_p (PATTERN (prev)))
3975 {
3976 if (sets_cc0_p (PATTERN (prev)) > 0
3977 && ! side_effects_p (PATTERN (prev)))
3978 delete_computation (prev);
3979 else
3980 /* Otherwise, show that cc0 won't be used. */
3981 REG_NOTES (prev) = gen_rtx_EXPR_LIST (REG_UNUSED,
3982 cc0_rtx, REG_NOTES (prev));
3983 }
3984 }
3985 #endif
3986
3987 #ifdef INSN_SCHEDULING
3988 /* ?!? The schedulers do not keep REG_DEAD notes accurate after
3989 reload has completed. The schedulers need to be fixed. Until
3990 they are, we must not rely on the death notes here. */
3991 if (reload_completed && flag_schedule_insns_after_reload)
3992 {
3993 delete_insn (insn);
3994 return;
3995 }
3996 #endif
3997
3998 set = single_set (insn);
3999
4000 for (note = REG_NOTES (insn); note; note = next)
4001 {
4002 next = XEXP (note, 1);
4003
4004 if (REG_NOTE_KIND (note) != REG_DEAD
4005 /* Verify that the REG_NOTE is legitimate. */
4006 || GET_CODE (XEXP (note, 0)) != REG)
4007 continue;
4008
4009 if (set && reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
4010 set = NULL_RTX;
4011
4012 delete_prior_computation (note, insn);
4013 }
4014
4015 /* The REG_DEAD note may have been omitted for a register
4016 which is both set and used by the insn. */
4017 if (set
4018 && GET_CODE (SET_DEST (set)) == REG
4019 && reg_mentioned_p (SET_DEST (set), SET_SRC (set)))
4020 {
4021 note = gen_rtx_EXPR_LIST (REG_DEAD, SET_DEST (set), NULL_RTX);
4022 delete_prior_computation (note, insn);
4023 }
4024
4025 delete_insn (insn);
4026 }
4027 \f
4028 /* Delete insn INSN from the chain of insns and update label ref counts.
4029 May delete some following insns as a consequence; may even delete
4030 a label elsewhere and insns that follow it.
4031
4032 Returns the first insn after INSN that was not deleted. */
4033
4034 rtx
4035 delete_insn (insn)
4036 register rtx insn;
4037 {
4038 register rtx next = NEXT_INSN (insn);
4039 register rtx prev = PREV_INSN (insn);
4040 register int was_code_label = (GET_CODE (insn) == CODE_LABEL);
4041 register int dont_really_delete = 0;
4042
4043 while (next && INSN_DELETED_P (next))
4044 next = NEXT_INSN (next);
4045
4046 /* This insn is already deleted => return first following nondeleted. */
4047 if (INSN_DELETED_P (insn))
4048 return next;
4049
4050 if (was_code_label)
4051 remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
4052
4053 /* Don't delete user-declared labels. Convert them to special NOTEs
4054 instead. */
4055 if (was_code_label && LABEL_NAME (insn) != 0
4056 && optimize && ! dont_really_delete)
4057 {
4058 PUT_CODE (insn, NOTE);
4059 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL;
4060 NOTE_SOURCE_FILE (insn) = 0;
4061 dont_really_delete = 1;
4062 }
4063 else
4064 /* Mark this insn as deleted. */
4065 INSN_DELETED_P (insn) = 1;
4066
4067 /* If this is an unconditional jump, delete it from the jump chain. */
4068 if (simplejump_p (insn))
4069 delete_from_jump_chain (insn);
4070
4071 /* If instruction is followed by a barrier,
4072 delete the barrier too. */
4073
4074 if (next != 0 && GET_CODE (next) == BARRIER)
4075 {
4076 INSN_DELETED_P (next) = 1;
4077 next = NEXT_INSN (next);
4078 }
4079
4080 /* Patch out INSN (and the barrier if any) */
4081
4082 if (optimize && ! dont_really_delete)
4083 {
4084 if (prev)
4085 {
4086 NEXT_INSN (prev) = next;
4087 if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SEQUENCE)
4088 NEXT_INSN (XVECEXP (PATTERN (prev), 0,
4089 XVECLEN (PATTERN (prev), 0) - 1)) = next;
4090 }
4091
4092 if (next)
4093 {
4094 PREV_INSN (next) = prev;
4095 if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE)
4096 PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
4097 }
4098
4099 if (prev && NEXT_INSN (prev) == 0)
4100 set_last_insn (prev);
4101 }
4102
4103 /* If deleting a jump, decrement the count of the label,
4104 and delete the label if it is now unused. */
4105
4106 if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn))
4107 {
4108 rtx lab = JUMP_LABEL (insn), lab_next;
4109
4110 if (--LABEL_NUSES (lab) == 0)
4111 {
4112 /* This can delete NEXT or PREV,
4113 either directly if NEXT is JUMP_LABEL (INSN),
4114 or indirectly through more levels of jumps. */
4115 delete_insn (lab);
4116
4117 /* I feel a little doubtful about this loop,
4118 but I see no clean and sure alternative way
4119 to find the first insn after INSN that is not now deleted.
4120 I hope this works. */
4121 while (next && INSN_DELETED_P (next))
4122 next = NEXT_INSN (next);
4123 return next;
4124 }
4125 else if ((lab_next = next_nonnote_insn (lab)) != NULL
4126 && GET_CODE (lab_next) == JUMP_INSN
4127 && (GET_CODE (PATTERN (lab_next)) == ADDR_VEC
4128 || GET_CODE (PATTERN (lab_next)) == ADDR_DIFF_VEC))
4129 {
4130 /* If we're deleting the tablejump, delete the dispatch table.
4131 We may not be able to kill the label immediately preceeding
4132 just yet, as it might be referenced in code leading up to
4133 the tablejump. */
4134 delete_insn (lab_next);
4135 }
4136 }
4137
4138 /* Likewise if we're deleting a dispatch table. */
4139
4140 if (GET_CODE (insn) == JUMP_INSN
4141 && (GET_CODE (PATTERN (insn)) == ADDR_VEC
4142 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
4143 {
4144 rtx pat = PATTERN (insn);
4145 int i, diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
4146 int len = XVECLEN (pat, diff_vec_p);
4147
4148 for (i = 0; i < len; i++)
4149 if (--LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0)) == 0)
4150 delete_insn (XEXP (XVECEXP (pat, diff_vec_p, i), 0));
4151 while (next && INSN_DELETED_P (next))
4152 next = NEXT_INSN (next);
4153 return next;
4154 }
4155
4156 while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE))
4157 prev = PREV_INSN (prev);
4158
4159 /* If INSN was a label and a dispatch table follows it,
4160 delete the dispatch table. The tablejump must have gone already.
4161 It isn't useful to fall through into a table. */
4162
4163 if (was_code_label
4164 && NEXT_INSN (insn) != 0
4165 && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
4166 && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
4167 || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
4168 next = delete_insn (NEXT_INSN (insn));
4169
4170 /* If INSN was a label, delete insns following it if now unreachable. */
4171
4172 if (was_code_label && prev && GET_CODE (prev) == BARRIER)
4173 {
4174 register RTX_CODE code;
4175 while (next != 0
4176 && (GET_RTX_CLASS (code = GET_CODE (next)) == 'i'
4177 || code == NOTE || code == BARRIER
4178 || (code == CODE_LABEL && INSN_DELETED_P (next))))
4179 {
4180 if (code == NOTE
4181 && NOTE_LINE_NUMBER (next) != NOTE_INSN_FUNCTION_END)
4182 next = NEXT_INSN (next);
4183 /* Keep going past other deleted labels to delete what follows. */
4184 else if (code == CODE_LABEL && INSN_DELETED_P (next))
4185 next = NEXT_INSN (next);
4186 else
4187 /* Note: if this deletes a jump, it can cause more
4188 deletion of unreachable code, after a different label.
4189 As long as the value from this recursive call is correct,
4190 this invocation functions correctly. */
4191 next = delete_insn (next);
4192 }
4193 }
4194
4195 return next;
4196 }
4197
4198 /* Advance from INSN till reaching something not deleted
4199 then return that. May return INSN itself. */
4200
4201 rtx
4202 next_nondeleted_insn (insn)
4203 rtx insn;
4204 {
4205 while (INSN_DELETED_P (insn))
4206 insn = NEXT_INSN (insn);
4207 return insn;
4208 }
4209 \f
4210 /* Delete a range of insns from FROM to TO, inclusive.
4211 This is for the sake of peephole optimization, so assume
4212 that whatever these insns do will still be done by a new
4213 peephole insn that will replace them. */
4214
4215 void
4216 delete_for_peephole (from, to)
4217 register rtx from, to;
4218 {
4219 register rtx insn = from;
4220
4221 while (1)
4222 {
4223 register rtx next = NEXT_INSN (insn);
4224 register rtx prev = PREV_INSN (insn);
4225
4226 if (GET_CODE (insn) != NOTE)
4227 {
4228 INSN_DELETED_P (insn) = 1;
4229
4230 /* Patch this insn out of the chain. */
4231 /* We don't do this all at once, because we
4232 must preserve all NOTEs. */
4233 if (prev)
4234 NEXT_INSN (prev) = next;
4235
4236 if (next)
4237 PREV_INSN (next) = prev;
4238 }
4239
4240 if (insn == to)
4241 break;
4242 insn = next;
4243 }
4244
4245 /* Note that if TO is an unconditional jump
4246 we *do not* delete the BARRIER that follows,
4247 since the peephole that replaces this sequence
4248 is also an unconditional jump in that case. */
4249 }
4250 \f
4251 /* We have determined that INSN is never reached, and are about to
4252 delete it. Print a warning if the user asked for one.
4253
4254 To try to make this warning more useful, this should only be called
4255 once per basic block not reached, and it only warns when the basic
4256 block contains more than one line from the current function, and
4257 contains at least one operation. CSE and inlining can duplicate insns,
4258 so it's possible to get spurious warnings from this. */
4259
4260 void
4261 never_reached_warning (avoided_insn)
4262 rtx avoided_insn;
4263 {
4264 rtx insn;
4265 rtx a_line_note = NULL;
4266 int two_avoided_lines = 0;
4267 int contains_insn = 0;
4268
4269 if (! warn_notreached)
4270 return;
4271
4272 /* Scan forwards, looking at LINE_NUMBER notes, until
4273 we hit a LABEL or we run out of insns. */
4274
4275 for (insn = avoided_insn; insn != NULL; insn = NEXT_INSN (insn))
4276 {
4277 if (GET_CODE (insn) == CODE_LABEL)
4278 break;
4279 else if (GET_CODE (insn) == NOTE /* A line number note? */
4280 && NOTE_LINE_NUMBER (insn) >= 0)
4281 {
4282 if (a_line_note == NULL)
4283 a_line_note = insn;
4284 else
4285 two_avoided_lines |= (NOTE_LINE_NUMBER (a_line_note)
4286 != NOTE_LINE_NUMBER (insn));
4287 }
4288 else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
4289 contains_insn = 1;
4290 }
4291 if (two_avoided_lines && contains_insn)
4292 warning_with_file_and_line (NOTE_SOURCE_FILE (a_line_note),
4293 NOTE_LINE_NUMBER (a_line_note),
4294 "will never be executed");
4295 }
4296 \f
4297 /* Invert the condition of the jump JUMP, and make it jump
4298 to label NLABEL instead of where it jumps now. */
4299
4300 int
4301 invert_jump (jump, nlabel)
4302 rtx jump, nlabel;
4303 {
4304 /* We have to either invert the condition and change the label or
4305 do neither. Either operation could fail. We first try to invert
4306 the jump. If that succeeds, we try changing the label. If that fails,
4307 we invert the jump back to what it was. */
4308
4309 if (! invert_exp (PATTERN (jump), jump))
4310 return 0;
4311
4312 if (redirect_jump (jump, nlabel))
4313 {
4314 if (flag_branch_probabilities)
4315 {
4316 rtx note = find_reg_note (jump, REG_BR_PROB, 0);
4317
4318 /* An inverted jump means that a probability taken becomes a
4319 probability not taken. Subtract the branch probability from the
4320 probability base to convert it back to a taken probability.
4321 (We don't flip the probability on a branch that's never taken. */
4322 if (note && XINT (XEXP (note, 0), 0) >= 0)
4323 XINT (XEXP (note, 0), 0) = REG_BR_PROB_BASE - XINT (XEXP (note, 0), 0);
4324 }
4325
4326 return 1;
4327 }
4328
4329 if (! invert_exp (PATTERN (jump), jump))
4330 /* This should just be putting it back the way it was. */
4331 abort ();
4332
4333 return 0;
4334 }
4335
4336 /* Invert the jump condition of rtx X contained in jump insn, INSN.
4337
4338 Return 1 if we can do so, 0 if we cannot find a way to do so that
4339 matches a pattern. */
4340
4341 int
4342 invert_exp (x, insn)
4343 rtx x;
4344 rtx insn;
4345 {
4346 register RTX_CODE code;
4347 register int i;
4348 register const char *fmt;
4349
4350 code = GET_CODE (x);
4351
4352 if (code == IF_THEN_ELSE)
4353 {
4354 register rtx comp = XEXP (x, 0);
4355 register rtx tem;
4356
4357 /* We can do this in two ways: The preferable way, which can only
4358 be done if this is not an integer comparison, is to reverse
4359 the comparison code. Otherwise, swap the THEN-part and ELSE-part
4360 of the IF_THEN_ELSE. If we can't do either, fail. */
4361
4362 if (can_reverse_comparison_p (comp, insn)
4363 && validate_change (insn, &XEXP (x, 0),
4364 gen_rtx_fmt_ee (reverse_condition (GET_CODE (comp)),
4365 GET_MODE (comp), XEXP (comp, 0),
4366 XEXP (comp, 1)), 0))
4367 return 1;
4368
4369 tem = XEXP (x, 1);
4370 validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1);
4371 validate_change (insn, &XEXP (x, 2), tem, 1);
4372 return apply_change_group ();
4373 }
4374
4375 fmt = GET_RTX_FORMAT (code);
4376 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4377 {
4378 if (fmt[i] == 'e')
4379 if (! invert_exp (XEXP (x, i), insn))
4380 return 0;
4381 if (fmt[i] == 'E')
4382 {
4383 register int j;
4384 for (j = 0; j < XVECLEN (x, i); j++)
4385 if (!invert_exp (XVECEXP (x, i, j), insn))
4386 return 0;
4387 }
4388 }
4389
4390 return 1;
4391 }
4392 \f
4393 /* Make jump JUMP jump to label NLABEL instead of where it jumps now.
4394 If the old jump target label is unused as a result,
4395 it and the code following it may be deleted.
4396
4397 If NLABEL is zero, we are to turn the jump into a (possibly conditional)
4398 RETURN insn.
4399
4400 The return value will be 1 if the change was made, 0 if it wasn't (this
4401 can only occur for NLABEL == 0). */
4402
4403 int
4404 redirect_jump (jump, nlabel)
4405 rtx jump, nlabel;
4406 {
4407 register rtx olabel = JUMP_LABEL (jump);
4408
4409 if (nlabel == olabel)
4410 return 1;
4411
4412 if (! redirect_exp (&PATTERN (jump), olabel, nlabel, jump))
4413 return 0;
4414
4415 /* If this is an unconditional branch, delete it from the jump_chain of
4416 OLABEL and add it to the jump_chain of NLABEL (assuming both labels
4417 have UID's in range and JUMP_CHAIN is valid). */
4418 if (jump_chain && (simplejump_p (jump)
4419 || GET_CODE (PATTERN (jump)) == RETURN))
4420 {
4421 int label_index = nlabel ? INSN_UID (nlabel) : 0;
4422
4423 delete_from_jump_chain (jump);
4424 if (label_index < max_jump_chain
4425 && INSN_UID (jump) < max_jump_chain)
4426 {
4427 jump_chain[INSN_UID (jump)] = jump_chain[label_index];
4428 jump_chain[label_index] = jump;
4429 }
4430 }
4431
4432 JUMP_LABEL (jump) = nlabel;
4433 if (nlabel)
4434 ++LABEL_NUSES (nlabel);
4435
4436 if (olabel && --LABEL_NUSES (olabel) == 0)
4437 delete_insn (olabel);
4438
4439 return 1;
4440 }
4441
4442 /* Delete the instruction JUMP from any jump chain it might be on. */
4443
4444 static void
4445 delete_from_jump_chain (jump)
4446 rtx jump;
4447 {
4448 int index;
4449 rtx olabel = JUMP_LABEL (jump);
4450
4451 /* Handle unconditional jumps. */
4452 if (jump_chain && olabel != 0
4453 && INSN_UID (olabel) < max_jump_chain
4454 && simplejump_p (jump))
4455 index = INSN_UID (olabel);
4456 /* Handle return insns. */
4457 else if (jump_chain && GET_CODE (PATTERN (jump)) == RETURN)
4458 index = 0;
4459 else return;
4460
4461 if (jump_chain[index] == jump)
4462 jump_chain[index] = jump_chain[INSN_UID (jump)];
4463 else
4464 {
4465 rtx insn;
4466
4467 for (insn = jump_chain[index];
4468 insn != 0;
4469 insn = jump_chain[INSN_UID (insn)])
4470 if (jump_chain[INSN_UID (insn)] == jump)
4471 {
4472 jump_chain[INSN_UID (insn)] = jump_chain[INSN_UID (jump)];
4473 break;
4474 }
4475 }
4476 }
4477
4478 /* If NLABEL is nonzero, throughout the rtx at LOC,
4479 alter (LABEL_REF OLABEL) to (LABEL_REF NLABEL). If OLABEL is
4480 zero, alter (RETURN) to (LABEL_REF NLABEL).
4481
4482 If NLABEL is zero, alter (LABEL_REF OLABEL) to (RETURN) and check
4483 validity with validate_change. Convert (set (pc) (label_ref olabel))
4484 to (return).
4485
4486 Return 0 if we found a change we would like to make but it is invalid.
4487 Otherwise, return 1. */
4488
4489 int
4490 redirect_exp (loc, olabel, nlabel, insn)
4491 rtx *loc;
4492 rtx olabel, nlabel;
4493 rtx insn;
4494 {
4495 register rtx x = *loc;
4496 register RTX_CODE code = GET_CODE (x);
4497 register int i;
4498 register const char *fmt;
4499
4500 if (code == LABEL_REF)
4501 {
4502 if (XEXP (x, 0) == olabel)
4503 {
4504 if (nlabel)
4505 XEXP (x, 0) = nlabel;
4506 else
4507 return validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 0);
4508 return 1;
4509 }
4510 }
4511 else if (code == RETURN && olabel == 0)
4512 {
4513 x = gen_rtx_LABEL_REF (VOIDmode, nlabel);
4514 if (loc == &PATTERN (insn))
4515 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
4516 return validate_change (insn, loc, x, 0);
4517 }
4518
4519 if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx
4520 && GET_CODE (SET_SRC (x)) == LABEL_REF
4521 && XEXP (SET_SRC (x), 0) == olabel)
4522 return validate_change (insn, loc, gen_rtx_RETURN (VOIDmode), 0);
4523
4524 fmt = GET_RTX_FORMAT (code);
4525 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4526 {
4527 if (fmt[i] == 'e')
4528 if (! redirect_exp (&XEXP (x, i), olabel, nlabel, insn))
4529 return 0;
4530 if (fmt[i] == 'E')
4531 {
4532 register int j;
4533 for (j = 0; j < XVECLEN (x, i); j++)
4534 if (! redirect_exp (&XVECEXP (x, i, j), olabel, nlabel, insn))
4535 return 0;
4536 }
4537 }
4538
4539 return 1;
4540 }
4541 \f
4542 /* Make jump JUMP jump to label NLABEL, assuming it used to be a tablejump.
4543
4544 If the old jump target label (before the dispatch table) becomes unused,
4545 it and the dispatch table may be deleted. In that case, find the insn
4546 before the jump references that label and delete it and logical successors
4547 too. */
4548
4549 static void
4550 redirect_tablejump (jump, nlabel)
4551 rtx jump, nlabel;
4552 {
4553 register rtx olabel = JUMP_LABEL (jump);
4554
4555 /* Add this jump to the jump_chain of NLABEL. */
4556 if (jump_chain && INSN_UID (nlabel) < max_jump_chain
4557 && INSN_UID (jump) < max_jump_chain)
4558 {
4559 jump_chain[INSN_UID (jump)] = jump_chain[INSN_UID (nlabel)];
4560 jump_chain[INSN_UID (nlabel)] = jump;
4561 }
4562
4563 PATTERN (jump) = gen_jump (nlabel);
4564 JUMP_LABEL (jump) = nlabel;
4565 ++LABEL_NUSES (nlabel);
4566 INSN_CODE (jump) = -1;
4567
4568 if (--LABEL_NUSES (olabel) == 0)
4569 {
4570 delete_labelref_insn (jump, olabel, 0);
4571 delete_insn (olabel);
4572 }
4573 }
4574
4575 /* Find the insn referencing LABEL that is a logical predecessor of INSN.
4576 If we found one, delete it and then delete this insn if DELETE_THIS is
4577 non-zero. Return non-zero if INSN or a predecessor references LABEL. */
4578
4579 static int
4580 delete_labelref_insn (insn, label, delete_this)
4581 rtx insn, label;
4582 int delete_this;
4583 {
4584 int deleted = 0;
4585 rtx link;
4586
4587 if (GET_CODE (insn) != NOTE
4588 && reg_mentioned_p (label, PATTERN (insn)))
4589 {
4590 if (delete_this)
4591 {
4592 delete_insn (insn);
4593 deleted = 1;
4594 }
4595 else
4596 return 1;
4597 }
4598
4599 for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
4600 if (delete_labelref_insn (XEXP (link, 0), label, 1))
4601 {
4602 if (delete_this)
4603 {
4604 delete_insn (insn);
4605 deleted = 1;
4606 }
4607 else
4608 return 1;
4609 }
4610
4611 return deleted;
4612 }
4613 \f
4614 /* Like rtx_equal_p except that it considers two REGs as equal
4615 if they renumber to the same value and considers two commutative
4616 operations to be the same if the order of the operands has been
4617 reversed.
4618
4619 ??? Addition is not commutative on the PA due to the weird implicit
4620 space register selection rules for memory addresses. Therefore, we
4621 don't consider a + b == b + a.
4622
4623 We could/should make this test a little tighter. Possibly only
4624 disabling it on the PA via some backend macro or only disabling this
4625 case when the PLUS is inside a MEM. */
4626
4627 int
4628 rtx_renumbered_equal_p (x, y)
4629 rtx x, y;
4630 {
4631 register int i;
4632 register RTX_CODE code = GET_CODE (x);
4633 register const char *fmt;
4634
4635 if (x == y)
4636 return 1;
4637
4638 if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG))
4639 && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG
4640 && GET_CODE (SUBREG_REG (y)) == REG)))
4641 {
4642 int reg_x = -1, reg_y = -1;
4643 int word_x = 0, word_y = 0;
4644
4645 if (GET_MODE (x) != GET_MODE (y))
4646 return 0;
4647
4648 /* If we haven't done any renumbering, don't
4649 make any assumptions. */
4650 if (reg_renumber == 0)
4651 return rtx_equal_p (x, y);
4652
4653 if (code == SUBREG)
4654 {
4655 reg_x = REGNO (SUBREG_REG (x));
4656 word_x = SUBREG_WORD (x);
4657
4658 if (reg_renumber[reg_x] >= 0)
4659 {
4660 reg_x = reg_renumber[reg_x] + word_x;
4661 word_x = 0;
4662 }
4663 }
4664
4665 else
4666 {
4667 reg_x = REGNO (x);
4668 if (reg_renumber[reg_x] >= 0)
4669 reg_x = reg_renumber[reg_x];
4670 }
4671
4672 if (GET_CODE (y) == SUBREG)
4673 {
4674 reg_y = REGNO (SUBREG_REG (y));
4675 word_y = SUBREG_WORD (y);
4676
4677 if (reg_renumber[reg_y] >= 0)
4678 {
4679 reg_y = reg_renumber[reg_y];
4680 word_y = 0;
4681 }
4682 }
4683
4684 else
4685 {
4686 reg_y = REGNO (y);
4687 if (reg_renumber[reg_y] >= 0)
4688 reg_y = reg_renumber[reg_y];
4689 }
4690
4691 return reg_x >= 0 && reg_x == reg_y && word_x == word_y;
4692 }
4693
4694 /* Now we have disposed of all the cases
4695 in which different rtx codes can match. */
4696 if (code != GET_CODE (y))
4697 return 0;
4698
4699 switch (code)
4700 {
4701 case PC:
4702 case CC0:
4703 case ADDR_VEC:
4704 case ADDR_DIFF_VEC:
4705 return 0;
4706
4707 case CONST_INT:
4708 return INTVAL (x) == INTVAL (y);
4709
4710 case LABEL_REF:
4711 /* We can't assume nonlocal labels have their following insns yet. */
4712 if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y))
4713 return XEXP (x, 0) == XEXP (y, 0);
4714
4715 /* Two label-refs are equivalent if they point at labels
4716 in the same position in the instruction stream. */
4717 return (next_real_insn (XEXP (x, 0))
4718 == next_real_insn (XEXP (y, 0)));
4719
4720 case SYMBOL_REF:
4721 return XSTR (x, 0) == XSTR (y, 0);
4722
4723 case CODE_LABEL:
4724 /* If we didn't match EQ equality above, they aren't the same. */
4725 return 0;
4726
4727 default:
4728 break;
4729 }
4730
4731 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */
4732
4733 if (GET_MODE (x) != GET_MODE (y))
4734 return 0;
4735
4736 /* For commutative operations, the RTX match if the operand match in any
4737 order. Also handle the simple binary and unary cases without a loop.
4738
4739 ??? Don't consider PLUS a commutative operator; see comments above. */
4740 if ((code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
4741 && code != PLUS)
4742 return ((rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
4743 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)))
4744 || (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 1))
4745 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 0))));
4746 else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
4747 return (rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0))
4748 && rtx_renumbered_equal_p (XEXP (x, 1), XEXP (y, 1)));
4749 else if (GET_RTX_CLASS (code) == '1')
4750 return rtx_renumbered_equal_p (XEXP (x, 0), XEXP (y, 0));
4751
4752 /* Compare the elements. If any pair of corresponding elements
4753 fail to match, return 0 for the whole things. */
4754
4755 fmt = GET_RTX_FORMAT (code);
4756 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4757 {
4758 register int j;
4759 switch (fmt[i])
4760 {
4761 case 'w':
4762 if (XWINT (x, i) != XWINT (y, i))
4763 return 0;
4764 break;
4765
4766 case 'i':
4767 if (XINT (x, i) != XINT (y, i))
4768 return 0;
4769 break;
4770
4771 case 's':
4772 if (strcmp (XSTR (x, i), XSTR (y, i)))
4773 return 0;
4774 break;
4775
4776 case 'e':
4777 if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
4778 return 0;
4779 break;
4780
4781 case 'u':
4782 if (XEXP (x, i) != XEXP (y, i))
4783 return 0;
4784 /* fall through. */
4785 case '0':
4786 break;
4787
4788 case 'E':
4789 if (XVECLEN (x, i) != XVECLEN (y, i))
4790 return 0;
4791 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4792 if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)))
4793 return 0;
4794 break;
4795
4796 default:
4797 abort ();
4798 }
4799 }
4800 return 1;
4801 }
4802 \f
4803 /* If X is a hard register or equivalent to one or a subregister of one,
4804 return the hard register number. If X is a pseudo register that was not
4805 assigned a hard register, return the pseudo register number. Otherwise,
4806 return -1. Any rtx is valid for X. */
4807
4808 int
4809 true_regnum (x)
4810 rtx x;
4811 {
4812 if (GET_CODE (x) == REG)
4813 {
4814 if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0)
4815 return reg_renumber[REGNO (x)];
4816 return REGNO (x);
4817 }
4818 if (GET_CODE (x) == SUBREG)
4819 {
4820 int base = true_regnum (SUBREG_REG (x));
4821 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
4822 return SUBREG_WORD (x) + base;
4823 }
4824 return -1;
4825 }
4826 \f
4827 /* Optimize code of the form:
4828
4829 for (x = a[i]; x; ...)
4830 ...
4831 for (x = a[i]; x; ...)
4832 ...
4833 foo:
4834
4835 Loop optimize will change the above code into
4836
4837 if (x = a[i])
4838 for (;;)
4839 { ...; if (! (x = ...)) break; }
4840 if (x = a[i])
4841 for (;;)
4842 { ...; if (! (x = ...)) break; }
4843 foo:
4844
4845 In general, if the first test fails, the program can branch
4846 directly to `foo' and skip the second try which is doomed to fail.
4847 We run this after loop optimization and before flow analysis. */
4848
4849 /* When comparing the insn patterns, we track the fact that different
4850 pseudo-register numbers may have been used in each computation.
4851 The following array stores an equivalence -- same_regs[I] == J means
4852 that pseudo register I was used in the first set of tests in a context
4853 where J was used in the second set. We also count the number of such
4854 pending equivalences. If nonzero, the expressions really aren't the
4855 same. */
4856
4857 static int *same_regs;
4858
4859 static int num_same_regs;
4860
4861 /* Track any registers modified between the target of the first jump and
4862 the second jump. They never compare equal. */
4863
4864 static char *modified_regs;
4865
4866 /* Record if memory was modified. */
4867
4868 static int modified_mem;
4869
4870 /* Called via note_stores on each insn between the target of the first
4871 branch and the second branch. It marks any changed registers. */
4872
4873 static void
4874 mark_modified_reg (dest, x)
4875 rtx dest;
4876 rtx x ATTRIBUTE_UNUSED;
4877 {
4878 int regno, i;
4879
4880 if (GET_CODE (dest) == SUBREG)
4881 dest = SUBREG_REG (dest);
4882
4883 if (GET_CODE (dest) == MEM)
4884 modified_mem = 1;
4885
4886 if (GET_CODE (dest) != REG)
4887 return;
4888
4889 regno = REGNO (dest);
4890 if (regno >= FIRST_PSEUDO_REGISTER)
4891 modified_regs[regno] = 1;
4892 else
4893 for (i = 0; i < HARD_REGNO_NREGS (regno, GET_MODE (dest)); i++)
4894 modified_regs[regno + i] = 1;
4895 }
4896
4897 /* F is the first insn in the chain of insns. */
4898
4899 void
4900 thread_jumps (f, max_reg, flag_before_loop)
4901 rtx f;
4902 int max_reg;
4903 int flag_before_loop;
4904 {
4905 /* Basic algorithm is to find a conditional branch,
4906 the label it may branch to, and the branch after
4907 that label. If the two branches test the same condition,
4908 walk back from both branch paths until the insn patterns
4909 differ, or code labels are hit. If we make it back to
4910 the target of the first branch, then we know that the first branch
4911 will either always succeed or always fail depending on the relative
4912 senses of the two branches. So adjust the first branch accordingly
4913 in this case. */
4914
4915 rtx label, b1, b2, t1, t2;
4916 enum rtx_code code1, code2;
4917 rtx b1op0, b1op1, b2op0, b2op1;
4918 int changed = 1;
4919 int i;
4920 int *all_reset;
4921
4922 /* Allocate register tables and quick-reset table. */
4923 modified_regs = (char *) alloca (max_reg * sizeof (char));
4924 same_regs = (int *) alloca (max_reg * sizeof (int));
4925 all_reset = (int *) alloca (max_reg * sizeof (int));
4926 for (i = 0; i < max_reg; i++)
4927 all_reset[i] = -1;
4928
4929 while (changed)
4930 {
4931 changed = 0;
4932
4933 for (b1 = f; b1; b1 = NEXT_INSN (b1))
4934 {
4935 /* Get to a candidate branch insn. */
4936 if (GET_CODE (b1) != JUMP_INSN
4937 || ! condjump_p (b1) || simplejump_p (b1)
4938 || JUMP_LABEL (b1) == 0)
4939 continue;
4940
4941 bzero (modified_regs, max_reg * sizeof (char));
4942 modified_mem = 0;
4943
4944 bcopy ((char *) all_reset, (char *) same_regs,
4945 max_reg * sizeof (int));
4946 num_same_regs = 0;
4947
4948 label = JUMP_LABEL (b1);
4949
4950 /* Look for a branch after the target. Record any registers and
4951 memory modified between the target and the branch. Stop when we
4952 get to a label since we can't know what was changed there. */
4953 for (b2 = NEXT_INSN (label); b2; b2 = NEXT_INSN (b2))
4954 {
4955 if (GET_CODE (b2) == CODE_LABEL)
4956 break;
4957
4958 else if (GET_CODE (b2) == JUMP_INSN)
4959 {
4960 /* If this is an unconditional jump and is the only use of
4961 its target label, we can follow it. */
4962 if (simplejump_p (b2)
4963 && JUMP_LABEL (b2) != 0
4964 && LABEL_NUSES (JUMP_LABEL (b2)) == 1)
4965 {
4966 b2 = JUMP_LABEL (b2);
4967 continue;
4968 }
4969 else
4970 break;
4971 }
4972
4973 if (GET_CODE (b2) != CALL_INSN && GET_CODE (b2) != INSN)
4974 continue;
4975
4976 if (GET_CODE (b2) == CALL_INSN)
4977 {
4978 modified_mem = 1;
4979 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4980 if (call_used_regs[i] && ! fixed_regs[i]
4981 && i != STACK_POINTER_REGNUM
4982 && i != FRAME_POINTER_REGNUM
4983 && i != HARD_FRAME_POINTER_REGNUM
4984 && i != ARG_POINTER_REGNUM)
4985 modified_regs[i] = 1;
4986 }
4987
4988 note_stores (PATTERN (b2), mark_modified_reg);
4989 }
4990
4991 /* Check the next candidate branch insn from the label
4992 of the first. */
4993 if (b2 == 0
4994 || GET_CODE (b2) != JUMP_INSN
4995 || b2 == b1
4996 || ! condjump_p (b2)
4997 || simplejump_p (b2))
4998 continue;
4999
5000 /* Get the comparison codes and operands, reversing the
5001 codes if appropriate. If we don't have comparison codes,
5002 we can't do anything. */
5003 b1op0 = XEXP (XEXP (SET_SRC (PATTERN (b1)), 0), 0);
5004 b1op1 = XEXP (XEXP (SET_SRC (PATTERN (b1)), 0), 1);
5005 code1 = GET_CODE (XEXP (SET_SRC (PATTERN (b1)), 0));
5006 if (XEXP (SET_SRC (PATTERN (b1)), 1) == pc_rtx)
5007 code1 = reverse_condition (code1);
5008
5009 b2op0 = XEXP (XEXP (SET_SRC (PATTERN (b2)), 0), 0);
5010 b2op1 = XEXP (XEXP (SET_SRC (PATTERN (b2)), 0), 1);
5011 code2 = GET_CODE (XEXP (SET_SRC (PATTERN (b2)), 0));
5012 if (XEXP (SET_SRC (PATTERN (b2)), 1) == pc_rtx)
5013 code2 = reverse_condition (code2);
5014
5015 /* If they test the same things and knowing that B1 branches
5016 tells us whether or not B2 branches, check if we
5017 can thread the branch. */
5018 if (rtx_equal_for_thread_p (b1op0, b2op0, b2)
5019 && rtx_equal_for_thread_p (b1op1, b2op1, b2)
5020 && (comparison_dominates_p (code1, code2)
5021 || (comparison_dominates_p (code1, reverse_condition (code2))
5022 && can_reverse_comparison_p (XEXP (SET_SRC (PATTERN (b1)),
5023 0),
5024 b1))))
5025 {
5026 t1 = prev_nonnote_insn (b1);
5027 t2 = prev_nonnote_insn (b2);
5028
5029 while (t1 != 0 && t2 != 0)
5030 {
5031 if (t2 == label)
5032 {
5033 /* We have reached the target of the first branch.
5034 If there are no pending register equivalents,
5035 we know that this branch will either always
5036 succeed (if the senses of the two branches are
5037 the same) or always fail (if not). */
5038 rtx new_label;
5039
5040 if (num_same_regs != 0)
5041 break;
5042
5043 if (comparison_dominates_p (code1, code2))
5044 new_label = JUMP_LABEL (b2);
5045 else
5046 new_label = get_label_after (b2);
5047
5048 if (JUMP_LABEL (b1) != new_label)
5049 {
5050 rtx prev = PREV_INSN (new_label);
5051
5052 if (flag_before_loop
5053 && GET_CODE (prev) == NOTE
5054 && NOTE_LINE_NUMBER (prev) == NOTE_INSN_LOOP_BEG)
5055 {
5056 /* Don't thread to the loop label. If a loop
5057 label is reused, loop optimization will
5058 be disabled for that loop. */
5059 new_label = gen_label_rtx ();
5060 emit_label_after (new_label, PREV_INSN (prev));
5061 }
5062 changed |= redirect_jump (b1, new_label);
5063 }
5064 break;
5065 }
5066
5067 /* If either of these is not a normal insn (it might be
5068 a JUMP_INSN, CALL_INSN, or CODE_LABEL) we fail. (NOTEs
5069 have already been skipped above.) Similarly, fail
5070 if the insns are different. */
5071 if (GET_CODE (t1) != INSN || GET_CODE (t2) != INSN
5072 || recog_memoized (t1) != recog_memoized (t2)
5073 || ! rtx_equal_for_thread_p (PATTERN (t1),
5074 PATTERN (t2), t2))
5075 break;
5076
5077 t1 = prev_nonnote_insn (t1);
5078 t2 = prev_nonnote_insn (t2);
5079 }
5080 }
5081 }
5082 }
5083 }
5084 \f
5085 /* This is like RTX_EQUAL_P except that it knows about our handling of
5086 possibly equivalent registers and knows to consider volatile and
5087 modified objects as not equal.
5088
5089 YINSN is the insn containing Y. */
5090
5091 int
5092 rtx_equal_for_thread_p (x, y, yinsn)
5093 rtx x, y;
5094 rtx yinsn;
5095 {
5096 register int i;
5097 register int j;
5098 register enum rtx_code code;
5099 register const char *fmt;
5100
5101 code = GET_CODE (x);
5102 /* Rtx's of different codes cannot be equal. */
5103 if (code != GET_CODE (y))
5104 return 0;
5105
5106 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
5107 (REG:SI x) and (REG:HI x) are NOT equivalent. */
5108
5109 if (GET_MODE (x) != GET_MODE (y))
5110 return 0;
5111
5112 /* For floating-point, consider everything unequal. This is a bit
5113 pessimistic, but this pass would only rarely do anything for FP
5114 anyway. */
5115 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
5116 && FLOAT_MODE_P (GET_MODE (x)) && ! flag_fast_math)
5117 return 0;
5118
5119 /* For commutative operations, the RTX match if the operand match in any
5120 order. Also handle the simple binary and unary cases without a loop. */
5121 if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
5122 return ((rtx_equal_for_thread_p (XEXP (x, 0), XEXP (y, 0), yinsn)
5123 && rtx_equal_for_thread_p (XEXP (x, 1), XEXP (y, 1), yinsn))
5124 || (rtx_equal_for_thread_p (XEXP (x, 0), XEXP (y, 1), yinsn)
5125 && rtx_equal_for_thread_p (XEXP (x, 1), XEXP (y, 0), yinsn)));
5126 else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
5127 return (rtx_equal_for_thread_p (XEXP (x, 0), XEXP (y, 0), yinsn)
5128 && rtx_equal_for_thread_p (XEXP (x, 1), XEXP (y, 1), yinsn));
5129 else if (GET_RTX_CLASS (code) == '1')
5130 return rtx_equal_for_thread_p (XEXP (x, 0), XEXP (y, 0), yinsn);
5131
5132 /* Handle special-cases first. */
5133 switch (code)
5134 {
5135 case REG:
5136 if (REGNO (x) == REGNO (y) && ! modified_regs[REGNO (x)])
5137 return 1;
5138
5139 /* If neither is user variable or hard register, check for possible
5140 equivalence. */
5141 if (REG_USERVAR_P (x) || REG_USERVAR_P (y)
5142 || REGNO (x) < FIRST_PSEUDO_REGISTER
5143 || REGNO (y) < FIRST_PSEUDO_REGISTER)
5144 return 0;
5145
5146 if (same_regs[REGNO (x)] == -1)
5147 {
5148 same_regs[REGNO (x)] = REGNO (y);
5149 num_same_regs++;
5150
5151 /* If this is the first time we are seeing a register on the `Y'
5152 side, see if it is the last use. If not, we can't thread the
5153 jump, so mark it as not equivalent. */
5154 if (REGNO_LAST_UID (REGNO (y)) != INSN_UID (yinsn))
5155 return 0;
5156
5157 return 1;
5158 }
5159 else
5160 return (same_regs[REGNO (x)] == REGNO (y));
5161
5162 break;
5163
5164 case MEM:
5165 /* If memory modified or either volatile, not equivalent.
5166 Else, check address. */
5167 if (modified_mem || MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
5168 return 0;
5169
5170 return rtx_equal_for_thread_p (XEXP (x, 0), XEXP (y, 0), yinsn);
5171
5172 case ASM_INPUT:
5173 if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
5174 return 0;
5175
5176 break;
5177
5178 case SET:
5179 /* Cancel a pending `same_regs' if setting equivalenced registers.
5180 Then process source. */
5181 if (GET_CODE (SET_DEST (x)) == REG
5182 && GET_CODE (SET_DEST (y)) == REG)
5183 {
5184 if (same_regs[REGNO (SET_DEST (x))] == REGNO (SET_DEST (y)))
5185 {
5186 same_regs[REGNO (SET_DEST (x))] = -1;
5187 num_same_regs--;
5188 }
5189 else if (REGNO (SET_DEST (x)) != REGNO (SET_DEST (y)))
5190 return 0;
5191 }
5192 else
5193 if (rtx_equal_for_thread_p (SET_DEST (x), SET_DEST (y), yinsn) == 0)
5194 return 0;
5195
5196 return rtx_equal_for_thread_p (SET_SRC (x), SET_SRC (y), yinsn);
5197
5198 case LABEL_REF:
5199 return XEXP (x, 0) == XEXP (y, 0);
5200
5201 case SYMBOL_REF:
5202 return XSTR (x, 0) == XSTR (y, 0);
5203
5204 default:
5205 break;
5206 }
5207
5208 if (x == y)
5209 return 1;
5210
5211 fmt = GET_RTX_FORMAT (code);
5212 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
5213 {
5214 switch (fmt[i])
5215 {
5216 case 'w':
5217 if (XWINT (x, i) != XWINT (y, i))
5218 return 0;
5219 break;
5220
5221 case 'n':
5222 case 'i':
5223 if (XINT (x, i) != XINT (y, i))
5224 return 0;
5225 break;
5226
5227 case 'V':
5228 case 'E':
5229 /* Two vectors must have the same length. */
5230 if (XVECLEN (x, i) != XVECLEN (y, i))
5231 return 0;
5232
5233 /* And the corresponding elements must match. */
5234 for (j = 0; j < XVECLEN (x, i); j++)
5235 if (rtx_equal_for_thread_p (XVECEXP (x, i, j),
5236 XVECEXP (y, i, j), yinsn) == 0)
5237 return 0;
5238 break;
5239
5240 case 'e':
5241 if (rtx_equal_for_thread_p (XEXP (x, i), XEXP (y, i), yinsn) == 0)
5242 return 0;
5243 break;
5244
5245 case 'S':
5246 case 's':
5247 if (strcmp (XSTR (x, i), XSTR (y, i)))
5248 return 0;
5249 break;
5250
5251 case 'u':
5252 /* These are just backpointers, so they don't matter. */
5253 break;
5254
5255 case '0':
5256 case 't':
5257 break;
5258
5259 /* It is believed that rtx's at this level will never
5260 contain anything but integers and other rtx's,
5261 except for within LABEL_REFs and SYMBOL_REFs. */
5262 default:
5263 abort ();
5264 }
5265 }
5266 return 1;
5267 }
5268 \f
5269
5270 #ifndef HAVE_cc0
5271 /* Return the insn that NEW can be safely inserted in front of starting at
5272 the jump insn INSN. Return 0 if it is not safe to do this jump
5273 optimization. Note that NEW must contain a single set. */
5274
5275 static rtx
5276 find_insert_position (insn, new)
5277 rtx insn;
5278 rtx new;
5279 {
5280 int i;
5281 rtx prev;
5282
5283 /* If NEW does not clobber, it is safe to insert NEW before INSN. */
5284 if (GET_CODE (PATTERN (new)) != PARALLEL)
5285 return insn;
5286
5287 for (i = XVECLEN (PATTERN (new), 0) - 1; i >= 0; i--)
5288 if (GET_CODE (XVECEXP (PATTERN (new), 0, i)) == CLOBBER
5289 && reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (new), 0, i), 0),
5290 insn))
5291 break;
5292
5293 if (i < 0)
5294 return insn;
5295
5296 /* There is a good chance that the previous insn PREV sets the thing
5297 being clobbered (often the CC in a hard reg). If PREV does not
5298 use what NEW sets, we can insert NEW before PREV. */
5299
5300 prev = prev_active_insn (insn);
5301 for (i = XVECLEN (PATTERN (new), 0) - 1; i >= 0; i--)
5302 if (GET_CODE (XVECEXP (PATTERN (new), 0, i)) == CLOBBER
5303 && reg_overlap_mentioned_p (XEXP (XVECEXP (PATTERN (new), 0, i), 0),
5304 insn)
5305 && ! modified_in_p (XEXP (XVECEXP (PATTERN (new), 0, i), 0),
5306 prev))
5307 return 0;
5308
5309 return reg_mentioned_p (SET_DEST (single_set (new)), prev) ? 0 : prev;
5310 }
5311 #endif /* !HAVE_cc0 */
This page took 0.281466 seconds and 6 git commands to generate.