jump.c (jump_optimize_1): Swap the incscc and the conditional mode detection code

* jump.c (jump_optimize_1): Swap the incscc and the conditional mode
        detection code

        * unroll.c (unroll_loop): Remove LOOP notes when loop is
        completely unrolled.

From-SVN: r30352
This commit is contained in:
Jan Hubicka 1999-11-02 17:37:23 +01:00 committed by Jeff Law
parent c3dfacf03a
commit f5da5c8714
3 changed files with 156 additions and 124 deletions

View File

@ -1,3 +1,11 @@
Tue Nov 2 04:10:24 1999 Jan Hubicka <hubicka@freesoft.cz>
* jump.c (jump_optimize_1): Swap the incscc and the conditional mode
detection code
* unroll.c (unroll_loop): Remove LOOP notes when loop is
completely unrolled.
Tue Nov 2 16:57:22 1999 Bernd Schmidt <bernds@cygnus.co.uk>
* cse.c (simplify_plus_minus, check_fold_const): Delete declarations.

View File

@ -1116,6 +1116,130 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
}
}
#endif
/* If branches are expensive, convert
if (foo) bar++; to bar += (foo != 0);
and similarly for "bar--;"
INSN is the conditional branch around the arithmetic. We set:
TEMP is the arithmetic insn.
TEMP1 is the SET doing the arithmetic.
TEMP2 is the operand being incremented or decremented.
TEMP3 to the condition being tested.
TEMP4 to the earliest insn used to find the condition. */
if ((BRANCH_COST >= 2
#ifdef HAVE_incscc
|| HAVE_incscc
#endif
#ifdef HAVE_decscc
|| HAVE_decscc
#endif
)
&& ! reload_completed
&& this_is_condjump && ! this_is_simplejump
&& (temp = next_nonnote_insn (insn)) != 0
&& (temp1 = single_set (temp)) != 0
&& (temp2 = SET_DEST (temp1),
GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT)
&& GET_CODE (SET_SRC (temp1)) == PLUS
&& (XEXP (SET_SRC (temp1), 1) == const1_rtx
|| XEXP (SET_SRC (temp1), 1) == constm1_rtx)
&& rtx_equal_p (temp2, XEXP (SET_SRC (temp1), 0))
&& ! side_effects_p (temp2)
&& ! may_trap_p (temp2)
/* INSN must either branch to the insn after TEMP or the insn
after TEMP must branch to the same place as INSN. */
&& (reallabelprev == temp
|| ((temp3 = next_active_insn (temp)) != 0
&& simplejump_p (temp3)
&& JUMP_LABEL (temp3) == JUMP_LABEL (insn)))
&& (temp3 = get_condition (insn, &temp4)) != 0
/* We must be comparing objects whose modes imply the size.
We could handle BLKmode if (1) emit_store_flag could
and (2) we could find the size reliably. */
&& GET_MODE (XEXP (temp3, 0)) != BLKmode
&& can_reverse_comparison_p (temp3, insn))
{
rtx temp6, target = 0, seq, init_insn = 0, init = temp2;
enum rtx_code code = reverse_condition (GET_CODE (temp3));
start_sequence ();
/* It must be the case that TEMP2 is not modified in the range
[TEMP4, INSN). The one exception we make is if the insn
before INSN sets TEMP2 to something which is also unchanged
in that range. In that case, we can move the initialization
into our sequence. */
if ((temp5 = prev_active_insn (insn)) != 0
&& no_labels_between_p (temp5, insn)
&& GET_CODE (temp5) == INSN
&& (temp6 = single_set (temp5)) != 0
&& rtx_equal_p (temp2, SET_DEST (temp6))
&& (CONSTANT_P (SET_SRC (temp6))
|| GET_CODE (SET_SRC (temp6)) == REG
|| GET_CODE (SET_SRC (temp6)) == SUBREG))
{
emit_insn (PATTERN (temp5));
init_insn = temp5;
init = SET_SRC (temp6);
}
if (CONSTANT_P (init)
|| ! reg_set_between_p (init, PREV_INSN (temp4), insn))
target = emit_store_flag (gen_reg_rtx (GET_MODE (temp2)), code,
XEXP (temp3, 0), XEXP (temp3, 1),
VOIDmode,
(code == LTU || code == LEU
|| code == GTU || code == GEU), 1);
/* If we can do the store-flag, do the addition or
subtraction. */
if (target)
target = expand_binop (GET_MODE (temp2),
(XEXP (SET_SRC (temp1), 1) == const1_rtx
? add_optab : sub_optab),
temp2, target, temp2, 0, OPTAB_WIDEN);
if (target != 0)
{
/* Put the result back in temp2 in case it isn't already.
Then replace the jump, possible a CC0-setting insn in
front of the jump, and TEMP, with the sequence we have
made. */
if (target != temp2)
emit_move_insn (temp2, target);
seq = get_insns ();
end_sequence ();
emit_insns_before (seq, temp4);
delete_insn (temp);
if (init_insn)
delete_insn (init_insn);
next = NEXT_INSN (insn);
#ifdef HAVE_cc0
delete_insn (prev_nonnote_insn (insn));
#endif
delete_insn (insn);
if (after_regscan)
{
reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
changed = 1;
continue;
}
else
end_sequence ();
}
/* Try to use a conditional move (if the target has them), or a
store-flag insn. If the target has conditional arithmetic as
@ -1505,130 +1629,6 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
}
}
/* If branches are expensive, convert
if (foo) bar++; to bar += (foo != 0);
and similarly for "bar--;"
INSN is the conditional branch around the arithmetic. We set:
TEMP is the arithmetic insn.
TEMP1 is the SET doing the arithmetic.
TEMP2 is the operand being incremented or decremented.
TEMP3 to the condition being tested.
TEMP4 to the earliest insn used to find the condition. */
if ((BRANCH_COST >= 2
#ifdef HAVE_incscc
|| HAVE_incscc
#endif
#ifdef HAVE_decscc
|| HAVE_decscc
#endif
)
&& ! reload_completed
&& this_is_condjump && ! this_is_simplejump
&& (temp = next_nonnote_insn (insn)) != 0
&& (temp1 = single_set (temp)) != 0
&& (temp2 = SET_DEST (temp1),
GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT)
&& GET_CODE (SET_SRC (temp1)) == PLUS
&& (XEXP (SET_SRC (temp1), 1) == const1_rtx
|| XEXP (SET_SRC (temp1), 1) == constm1_rtx)
&& rtx_equal_p (temp2, XEXP (SET_SRC (temp1), 0))
&& ! side_effects_p (temp2)
&& ! may_trap_p (temp2)
/* INSN must either branch to the insn after TEMP or the insn
after TEMP must branch to the same place as INSN. */
&& (reallabelprev == temp
|| ((temp3 = next_active_insn (temp)) != 0
&& simplejump_p (temp3)
&& JUMP_LABEL (temp3) == JUMP_LABEL (insn)))
&& (temp3 = get_condition (insn, &temp4)) != 0
/* We must be comparing objects whose modes imply the size.
We could handle BLKmode if (1) emit_store_flag could
and (2) we could find the size reliably. */
&& GET_MODE (XEXP (temp3, 0)) != BLKmode
&& can_reverse_comparison_p (temp3, insn))
{
rtx temp6, target = 0, seq, init_insn = 0, init = temp2;
enum rtx_code code = reverse_condition (GET_CODE (temp3));
start_sequence ();
/* It must be the case that TEMP2 is not modified in the range
[TEMP4, INSN). The one exception we make is if the insn
before INSN sets TEMP2 to something which is also unchanged
in that range. In that case, we can move the initialization
into our sequence. */
if ((temp5 = prev_active_insn (insn)) != 0
&& no_labels_between_p (temp5, insn)
&& GET_CODE (temp5) == INSN
&& (temp6 = single_set (temp5)) != 0
&& rtx_equal_p (temp2, SET_DEST (temp6))
&& (CONSTANT_P (SET_SRC (temp6))
|| GET_CODE (SET_SRC (temp6)) == REG
|| GET_CODE (SET_SRC (temp6)) == SUBREG))
{
emit_insn (PATTERN (temp5));
init_insn = temp5;
init = SET_SRC (temp6);
}
if (CONSTANT_P (init)
|| ! reg_set_between_p (init, PREV_INSN (temp4), insn))
target = emit_store_flag (gen_reg_rtx (GET_MODE (temp2)), code,
XEXP (temp3, 0), XEXP (temp3, 1),
VOIDmode,
(code == LTU || code == LEU
|| code == GTU || code == GEU), 1);
/* If we can do the store-flag, do the addition or
subtraction. */
if (target)
target = expand_binop (GET_MODE (temp2),
(XEXP (SET_SRC (temp1), 1) == const1_rtx
? add_optab : sub_optab),
temp2, target, temp2, 0, OPTAB_WIDEN);
if (target != 0)
{
/* Put the result back in temp2 in case it isn't already.
Then replace the jump, possible a CC0-setting insn in
front of the jump, and TEMP, with the sequence we have
made. */
if (target != temp2)
emit_move_insn (temp2, target);
seq = get_insns ();
end_sequence ();
emit_insns_before (seq, temp4);
delete_insn (temp);
if (init_insn)
delete_insn (init_insn);
next = NEXT_INSN (insn);
#ifdef HAVE_cc0
delete_insn (prev_nonnote_insn (insn));
#endif
delete_insn (insn);
if (after_regscan)
{
reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
old_max_reg = max_reg_num ();
}
changed = 1;
continue;
}
else
end_sequence ();
}
/* Simplify if (...) x = 1; else {...} if (x) ...
We recognize this case scanning backwards as well.

View File

@ -354,6 +354,17 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
delete_insn (prev);
#endif
}
/* Remove the loop notes since this is no longer a loop. */
if (loop_info->vtop)
delete_insn (loop_info->vtop);
if (loop_info->cont)
delete_insn (loop_info->cont);
if (loop_start)
delete_insn (loop_start);
if (loop_end)
delete_insn (loop_end);
return;
}
else if (loop_info->n_iterations > 0
@ -1282,6 +1293,19 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
emit_label_after (exit_label, loop_end);
egress:
if (unroll_type == UNROLL_COMPLETELY)
{
/* Remove the loop notes since this is no longer a loop. */
if (loop_info->vtop)
delete_insn (loop_info->vtop);
if (loop_info->cont)
delete_insn (loop_info->cont);
if (loop_start)
delete_insn (loop_start);
if (loop_end)
delete_insn (loop_end);
}
if (map->const_equiv_varray)
VARRAY_FREE (map->const_equiv_varray);
if (map->label_map)