Commit 59d7c14e authored by Richard Henderson's avatar Richard Henderson
Browse files

tcg: Optimize spills of constants



While we can store constants via constrants on INDEX_op_st_i32 et al,
we weren't able to spill constants to backing store.

Add a new backend interface, tcg_out_sti, which may store the constant
(and is allowed to fail).  Rearrange the temp_* helpers so that we only
attempt to directly store a constant when the temp is becoming dead/free.

Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent 120c1084
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -716,6 +716,16 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
                 arg, arg1, arg2);
}

static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
                               TCGReg base, intptr_t ofs)
{
    if (val == 0) {
        tcg_out_st(s, type, TCG_REG_XZR, base, ofs);
        return true;
    }
    return false;
}

static inline void tcg_out_bfm(TCGContext *s, TCGType ext, TCGReg rd,
                               TCGReg rn, unsigned int a, unsigned int b)
{
+6 −0
Original line number Diff line number Diff line
@@ -2046,6 +2046,12 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
    tcg_out_st32(s, COND_AL, arg, arg1, arg2);
}

static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
                               TCGReg base, intptr_t ofs)
{
    return false;
}

static inline void tcg_out_mov(TCGContext *s, TCGType type,
                               TCGReg ret, TCGReg arg)
{
+14 −7
Original line number Diff line number Diff line
@@ -710,12 +710,19 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
    tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
}

static inline void tcg_out_sti(TCGContext *s, TCGType type, TCGReg base,
                               tcg_target_long ofs, tcg_target_long val)
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
                        TCGReg base, intptr_t ofs)
{
    int opc = OPC_MOVL_EvIz + (type == TCG_TYPE_I64 ? P_REXW : 0);
    tcg_out_modrm_offset(s, opc, 0, base, ofs);
    int rexw = 0;
    if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I64) {
        if (val != (int32_t)val) {
            return false;
        }
        rexw = P_REXW;
    }
    tcg_out_modrm_offset(s, OPC_MOVL_EvIz | rexw, 0, base, ofs);
    tcg_out32(s, val);
    return true;
}

static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
@@ -1321,10 +1328,10 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
            ofs += 4;
        }

        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi);
        tcg_out_sti(s, TCG_TYPE_I32, oi, TCG_REG_ESP, ofs);
        ofs += 4;

        tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, ofs, (uintptr_t)l->raddr);
        tcg_out_sti(s, TCG_TYPE_PTR, (uintptr_t)l->raddr, TCG_REG_ESP, ofs);
    } else {
        tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
        /* The second argument is already loaded with addrlo.  */
@@ -1413,7 +1420,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
            ofs += 4;
        }

        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, oi);
        tcg_out_sti(s, TCG_TYPE_I32, oi, TCG_REG_ESP, ofs);
        ofs += 4;

        retaddr = TCG_REG_EAX;
+10 −0
Original line number Diff line number Diff line
@@ -973,6 +973,16 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
    }
}

static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
                               TCGReg base, intptr_t ofs)
{
    if (val == 0) {
        tcg_out_st(s, type, TCG_REG_R0, base, ofs);
        return true;
    }
    return false;
}

static inline void tcg_out_alu(TCGContext *s, uint64_t opc_a1, uint64_t opc_a3,
                               TCGReg ret, TCGArg arg1, int const_arg1,
                               TCGArg arg2, int const_arg2)
+10 −0
Original line number Diff line number Diff line
@@ -576,6 +576,16 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
}

static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
                               TCGReg base, intptr_t ofs)
{
    if (val == 0) {
        tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
        return true;
    }
    return false;
}

static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
{
    if (val == (int16_t)val) {
Loading