target/sparc: Discard cpu_cond at the end of each insn

If the insn raises no exceptions, there will be no path in which
cpu_cond is used, and so the computation may be optimized away.

Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-10-16 12:24:23 -07:00
parent 533f042f14
commit 89527e3a75

View File

@ -171,6 +171,7 @@ typedef struct DisasContext {
target_ulong jump_pc[2];
int mem_idx;
bool cpu_cond_live;
bool fpu_enabled;
bool address_mask_32bit;
#ifndef CONFIG_USER_ONLY
@ -912,6 +913,19 @@ static void gen_op_eval_fbo(TCGv dst, TCGv src, unsigned int fcc_offset)
tcg_gen_xori_tl(dst, dst, 0x1);
}
static void finishing_insn(DisasContext *dc)
{
/*
* From here, there is no future path through an unwinding exception.
* If the current insn cannot raise an exception, the computation of
* cpu_cond may be able to be elided.
*/
if (dc->cpu_cond_live) {
tcg_gen_discard_tl(cpu_cond);
dc->cpu_cond_live = false;
}
}
static void gen_generic_branch(DisasContext *dc)
{
TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
@ -958,6 +972,7 @@ static void save_state(DisasContext *dc)
static void gen_exception(DisasContext *dc, int which)
{
finishing_insn(dc);
save_state(dc);
gen_helper_raise_exception(tcg_env, tcg_constant_i32(which));
dc->base.is_jmp = DISAS_NORETURN;
@ -999,6 +1014,8 @@ static void gen_check_align(DisasContext *dc, TCGv addr, int mask)
static void gen_mov_pc_npc(DisasContext *dc)
{
finishing_insn(dc);
if (dc->npc & 3) {
switch (dc->npc) {
case JUMP_PC:
@ -2339,6 +2356,8 @@ static bool advance_pc(DisasContext *dc)
{
TCGLabel *l1;
finishing_insn(dc);
if (dc->npc & 3) {
switch (dc->npc) {
case DYNAMIC_PC:
@ -2383,6 +2402,8 @@ static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
target_ulong dest = address_mask_i(dc, dc->pc + disp * 4);
target_ulong npc;
finishing_insn(dc);
if (cmp->cond == TCG_COND_ALWAYS) {
if (annul) {
dc->pc = dest;
@ -2449,6 +2470,7 @@ static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
} else {
tcg_gen_setcondi_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
}
dc->cpu_cond_live = true;
}
}
return true;
@ -2585,6 +2607,8 @@ static bool do_tcc(DisasContext *dc, int cond, int cc,
tcg_gen_addi_i32(trap, trap, TT_TRAP);
}
finishing_insn(dc);
/* Trap always. */
if (cond == 8) {
save_state(dc);
@ -3201,6 +3225,7 @@ TRANS(WRSTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrstick_cmpr)
static void do_wrpowerdown(DisasContext *dc, TCGv src)
{
finishing_insn(dc);
save_state(dc);
gen_helper_power_down(tcg_env);
}
@ -5080,6 +5105,8 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
DisasDelayException *e, *e_next;
bool may_lookup;
finishing_insn(dc);
switch (dc->base.is_jmp) {
case DISAS_NEXT:
case DISAS_TOO_MANY: