+2000-05-19 Richard Henderson <rth@cygnus.com>
+
+ * jump.c (redirect_jump): Add delete_unused argument. Don't
+ remove labels and code following when LABEL_NUSES goes to zero.
+ (invert_jump): Likewise.
+ (jump_optimize_1): Fix redirect/invert arguments.
+ (do_cross_jump, thread_jumps): Likewise.
+ * flow.c (split_edge): Likewise.
+ * reorg.c (optimize_skip): Likewise.
+ (reorg_redirect_jump, relax_delay_slots, dbr_schedule): Likewise.
+ * profile.c (instrument_arcs): Likewise.
+ * loop.c (find_and_verify_loops): Likewise. Fix indentation.
+ * rtl.h: Update prototypes.
+
Fri May 19 12:05:13 2000 Clinton Popetz <cpopetz@cygnus.com>
* ssa.c (convert_from_ssa): Tell life_analysis we need death
2000-05-18 Mark Elbrecht <snowball3@bigfoot.com>
- * configure.in (*-pc-msdosdjgpp): Set float_format to none.
+ * configure.in (*-pc-msdosdjgpp): Set float_format to none.
* configure: Rebuilt.
2000-05-18 Zack Weinberg <zack@wolery.cumb.org>
if (JUMP_LABEL (insn) != old_label)
abort ();
- redirect_jump (insn, new_label);
+ redirect_jump (insn, new_label, 0);
}
emit_label_before (new_label, bb_note);
/* See if this jump goes to another jump and redirect if so. */
nlabel = follow_jumps (JUMP_LABEL (insn));
if (nlabel != JUMP_LABEL (insn))
- changed |= redirect_jump (insn, nlabel);
+ changed |= redirect_jump (insn, nlabel, 1);
if (! optimize || minimal)
continue;
if (prev_label)
++LABEL_NUSES (prev_label);
- if (invert_jump (insn, JUMP_LABEL (reallabelprev)))
+ if (invert_jump (insn, JUMP_LABEL (reallabelprev), 1))
{
/* It is very likely that if there are USE insns before
this jump, they hold REG_DEAD notes. These REG_DEAD
}
delete_insn (temp);
- redirect_jump (insn, get_label_before (temp1));
+ redirect_jump (insn, get_label_before (temp1), 1);
reallabelprev = prev_real_insn (temp1);
changed = 1;
next = NEXT_INSN (insn);
&& swap_condition (GET_CODE (temp2)) == GET_CODE (tc)
&& rtx_equal_p (XEXP (tc, 0), XEXP (temp2, 0))
&& rtx_equal_p (XEXP (tc, 1), XEXP (temp2, 1))
- && redirect_jump (insn, get_label_after (temp)))
+ && redirect_jump (insn, get_label_after (temp), 1))
{
changed = 1;
continue;
}
}
else
- redirect_jump (insn, label);
+ redirect_jump (insn, label, 1);
/* Delete the matching insns before the jump. Also, remove any REG_EQUAL
or REG_EQUIV note in the NEWLPOS stream that isn't also present in
(this can only occur for NLABEL == 0). */
int
-redirect_jump (jump, nlabel)
+redirect_jump (jump, nlabel, delete_unused)
rtx jump, nlabel;
+ int delete_unused;
{
register rtx olabel = JUMP_LABEL (jump);
&& NOTE_LINE_NUMBER (NEXT_INSN (olabel)) == NOTE_INSN_FUNCTION_END)
emit_note_after (NOTE_INSN_FUNCTION_END, nlabel);
- if (olabel && --LABEL_NUSES (olabel) == 0)
+ if (olabel && --LABEL_NUSES (olabel) == 0 && delete_unused)
delete_insn (olabel);
return 1;
NLABEL instead of where it jumps now. Return true if successful. */
int
-invert_jump (jump, nlabel)
+invert_jump (jump, nlabel, delete_unused)
rtx jump, nlabel;
+ int delete_unused;
{
/* We have to either invert the condition and change the label or
do neither. Either operation could fail. We first try to invert
if (! invert_exp (PATTERN (jump), jump))
return 0;
- if (redirect_jump (jump, nlabel))
+ if (redirect_jump (jump, nlabel, delete_unused))
{
/* An inverted jump means that a probability taken becomes a
probability not taken. Subtract the branch probability from the
new_label = gen_label_rtx ();
emit_label_after (new_label, PREV_INSN (prev));
}
- changed |= redirect_jump (b1, new_label);
+ changed |= redirect_jump (b1, new_label, 1);
}
break;
}
/* Verify that uid_loop is large enough and that
we can invert P. */
- if (invert_jump (p, new_label))
- {
- rtx q, r;
-
- /* If no suitable BARRIER was found, create a suitable
- one before TARGET. Since TARGET is a fall through
- path, we'll need to insert an jump around our block
- and a add a BARRIER before TARGET.
-
- This creates an extra unconditional jump outside
- the loop. However, the benefits of removing rarely
- executed instructions from inside the loop usually
- outweighs the cost of the extra unconditional jump
- outside the loop. */
- if (loc == 0)
- {
- rtx temp;
-
- temp = gen_jump (JUMP_LABEL (insn));
- temp = emit_jump_insn_before (temp, target);
- JUMP_LABEL (temp) = JUMP_LABEL (insn);
- LABEL_NUSES (JUMP_LABEL (insn))++;
- loc = emit_barrier_before (target);
- }
-
- /* Include the BARRIER after INSN and copy the
- block after LOC. */
- new_label = squeeze_notes (new_label,
- last_insn_to_move);
- reorder_insns (new_label, last_insn_to_move, loc);
-
- /* All those insns are now in TARGET_LOOP. */
- for (q = new_label;
- q != NEXT_INSN (last_insn_to_move);
- q = NEXT_INSN (q))
- uid_loop[INSN_UID (q)] = target_loop;
-
- /* The label jumped to by INSN is no longer a loop exit.
- Unless INSN does not have a label (e.g., it is a
- RETURN insn), search loop->exit_labels to find
- its label_ref, and remove it. Also turn off
- LABEL_OUTSIDE_LOOP_P bit. */
- if (JUMP_LABEL (insn))
- {
- for (q = 0,
- r = this_loop->exit_labels;
- r; q = r, r = LABEL_NEXTREF (r))
- if (XEXP (r, 0) == JUMP_LABEL (insn))
- {
- LABEL_OUTSIDE_LOOP_P (r) = 0;
- if (q)
- LABEL_NEXTREF (q) = LABEL_NEXTREF (r);
- else
- this_loop->exit_labels = LABEL_NEXTREF (r);
- break;
- }
-
- for (loop = this_loop; loop && loop != target_loop;
- loop = loop->outer)
- loop->exit_count--;
-
- /* If we didn't find it, then something is
- wrong. */
- if (! r)
- abort ();
- }
-
- /* P is now a jump outside the loop, so it must be put
- in loop->exit_labels, and marked as such.
- The easiest way to do this is to just call
- mark_loop_jump again for P. */
- mark_loop_jump (PATTERN (p), this_loop);
-
- /* If INSN now jumps to the insn after it,
- delete INSN. */
- if (JUMP_LABEL (insn) != 0
- && (next_real_insn (JUMP_LABEL (insn))
- == next_real_insn (insn)))
- delete_insn (insn);
- }
+ if (invert_jump (p, new_label, 1))
+ {
+ rtx q, r;
+
+ /* If no suitable BARRIER was found, create a suitable
+ one before TARGET. Since TARGET is a fall through
+ path, we'll need to insert an jump around our block
+ and a add a BARRIER before TARGET.
+
+ This creates an extra unconditional jump outside
+ the loop. However, the benefits of removing rarely
+ executed instructions from inside the loop usually
+ outweighs the cost of the extra unconditional jump
+ outside the loop. */
+ if (loc == 0)
+ {
+ rtx temp;
+
+ temp = gen_jump (JUMP_LABEL (insn));
+ temp = emit_jump_insn_before (temp, target);
+ JUMP_LABEL (temp) = JUMP_LABEL (insn);
+ LABEL_NUSES (JUMP_LABEL (insn))++;
+ loc = emit_barrier_before (target);
+ }
+
+ /* Include the BARRIER after INSN and copy the
+ block after LOC. */
+ new_label = squeeze_notes (new_label,
+ last_insn_to_move);
+ reorder_insns (new_label, last_insn_to_move, loc);
+
+ /* All those insns are now in TARGET_LOOP. */
+ for (q = new_label;
+ q != NEXT_INSN (last_insn_to_move);
+ q = NEXT_INSN (q))
+ uid_loop[INSN_UID (q)] = target_loop;
+
+ /* The label jumped to by INSN is no longer a loop
+ exit. Unless INSN does not have a label (e.g.,
+ it is a RETURN insn), search loop->exit_labels
+ to find its label_ref, and remove it. Also turn
+ off LABEL_OUTSIDE_LOOP_P bit. */
+ if (JUMP_LABEL (insn))
+ {
+ for (q = 0,
+ r = this_loop->exit_labels;
+ r; q = r, r = LABEL_NEXTREF (r))
+ if (XEXP (r, 0) == JUMP_LABEL (insn))
+ {
+ LABEL_OUTSIDE_LOOP_P (r) = 0;
+ if (q)
+ LABEL_NEXTREF (q) = LABEL_NEXTREF (r);
+ else
+ this_loop->exit_labels = LABEL_NEXTREF (r);
+ break;
+ }
+
+ for (loop = this_loop; loop && loop != target_loop;
+ loop = loop->outer)
+ loop->exit_count--;
+
+ /* If we didn't find it, then something is
+ wrong. */
+ if (! r)
+ abort ();
+ }
+
+ /* P is now a jump outside the loop, so it must be put
+ in loop->exit_labels, and marked as such.
+ The easiest way to do this is to just call
+ mark_loop_jump again for P. */
+ mark_loop_jump (PATTERN (p), this_loop);
+
+ /* If INSN now jumps to the insn after it,
+ delete INSN. */
+ if (JUMP_LABEL (insn) != 0
+ && (next_real_insn (JUMP_LABEL (insn))
+ == next_real_insn (insn)))
+ delete_insn (insn);
+ }
/* Continue the loop after where the conditional
branch used to jump, since the only branch insn
if (this_is_simplejump)
{
after = NEXT_INSN (arcptr->branch_insn);
- if (! redirect_jump (arcptr->branch_insn, new_label))
+ if (! redirect_jump (arcptr->branch_insn, new_label, 1))
/* Don't know what to do if this branch won't
redirect. */
abort ();
}
else
{
- if (! invert_jump (arcptr->branch_insn, new_label))
+ if (! invert_jump (arcptr->branch_insn, new_label, 1))
/* Don't know what to do if this branch won't invert. */
abort ();
{
if (eligible_for_annul_false (insn, 0, trial, flags))
{
- if (invert_jump (insn, JUMP_LABEL (insn)))
+ if (invert_jump (insn, JUMP_LABEL (insn), 1))
INSN_FROM_TARGET_P (trial) = 1;
else if (! eligible_for_annul_true (insn, 0, trial, flags))
return 0;
rtx nlabel;
{
incr_ticks_for_insn (jump);
- return redirect_jump (jump, nlabel);
+ return redirect_jump (jump, nlabel, 1);
}
/* Called when INSN is being moved forward into a delay slot of DELAYED_INSN.
if (label)
++LABEL_NUSES (label);
- if (invert_jump (insn, label))
+ if (invert_jump (insn, label, 1))
{
delete_insn (next);
next = insn;
rtx other_target = JUMP_LABEL (other);
target_label = JUMP_LABEL (insn);
- /* Increment the count of OTHER_TARGET, so it doesn't get deleted
- as we move the label. */
- if (other_target)
- ++LABEL_NUSES (other_target);
-
- if (invert_jump (other, target_label))
+ if (invert_jump (other, target_label, 0))
reorg_redirect_jump (insn, other_target);
-
- if (other_target)
- --LABEL_NUSES (other_target);
}
/* Now look only at cases where we have filled a delay slot. */
if (old_label)
++LABEL_NUSES (old_label);
- if (invert_jump (delay_insn, label))
+ if (invert_jump (delay_insn, label, 1))
{
int i;
&& JUMP_LABEL (insn) != 0
&& ((target = prev_label (next_active_insn (JUMP_LABEL (insn))))
!= JUMP_LABEL (insn)))
- redirect_jump (insn, target);
+ redirect_jump (insn, target, 1);
}
init_resource_info (epilogue_insn);
extern int onlyjump_p PARAMS ((rtx));
extern int sets_cc0_p PARAMS ((rtx));
extern int invert_jump_1 PARAMS ((rtx, rtx));
-extern int invert_jump PARAMS ((rtx, rtx));
+extern int invert_jump PARAMS ((rtx, rtx, int));
extern int rtx_renumbered_equal_p PARAMS ((rtx, rtx));
extern int true_regnum PARAMS ((rtx));
extern int redirect_jump_1 PARAMS ((rtx, rtx));
-extern int redirect_jump PARAMS ((rtx, rtx));
+extern int redirect_jump PARAMS ((rtx, rtx, int));
extern void jump_optimize PARAMS ((rtx, int, int, int));
extern void jump_optimize_minimal PARAMS ((rtx));
extern void rebuild_jump_labels PARAMS ((rtx));