From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:34936) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QOarm-0005b0-95 for qemu-devel@nongnu.org; Mon, 23 May 2011 15:32:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QOark-0007bN-Sk for qemu-devel@nongnu.org; Mon, 23 May 2011 15:32:38 -0400 Received: from mail-qy0-f180.google.com ([209.85.216.180]:64296) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QOark-0007bI-Nq for qemu-devel@nongnu.org; Mon, 23 May 2011 15:32:36 -0400 Received: by qyk10 with SMTP id 10so3605929qyk.4 for ; Mon, 23 May 2011 12:32:36 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1306161654-4388-9-git-send-email-batuzovk@ispras.ru> References: <1306161654-4388-1-git-send-email-batuzovk@ispras.ru> <1306161654-4388-9-git-send-email-batuzovk@ispras.ru> From: Blue Swirl Date: Mon, 23 May 2011 22:32:16 +0300 Message-ID: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC][PATCH v0 8/8] Add spill count profiling. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Kirill Batuzov Cc: qemu-devel@nongnu.org, zhur@ispras.ru On Mon, May 23, 2011 at 5:40 PM, Kirill Batuzov wrote: > Gather generated spills statistics. =C2=A0It is useful for debugging and = evaluating > of new register allocator. > > Signed-off-by: Kirill Batuzov > --- > =C2=A0tcg/tcg.c | =C2=A0 69 +++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++ > =C2=A0tcg/tcg.h | =C2=A0 =C2=A06 +++++ > =C2=A02 files changed, 75 insertions(+), 0 deletions(-) > > diff --git a/tcg/tcg.c b/tcg/tcg.c > index 022eef9..ba2cddc 100644 > --- a/tcg/tcg.c > +++ b/tcg/tcg.c > @@ -1530,6 +1530,11 @@ static void temp_allocate_frame(TCGContext *s, int= temp) > =C2=A0 =C2=A0 s->current_frame_offset +=3D sizeof(tcg_target_long); > =C2=A0} > > +#ifdef CONFIG_PROFILER > +enum { SPILL_REAL, SPILL_BB_END, SPILL_CALL_HWREG, > + =C2=A0 =C2=A0 =C2=A0 SPILL_CALL_IARG, SPILL_CALL_CLOBBER } spill_cause; > +#endif How about moving this to TCGContext instead of using static variables? > + > =C2=A0/* free register 'reg' by spilling the corresponding temporary if n= ecessary */ > =C2=A0static void tcg_reg_free(TCGContext *s, int reg) > =C2=A0{ > @@ -1544,6 +1549,26 @@ static void tcg_reg_free(TCGContext *s, int reg) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!ts->mem_allocated) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 temp_allocate_fra= me(s, temp); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg_out_st(s, ts->type, reg, ts= ->mem_reg, ts->mem_offset); > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0s->spill_count++; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0switch (spill_cause) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case SPILL_REAL: > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0s->spill_real++; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case SPILL_BB_END: > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0s->spill_bb_end+= +; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case SPILL_CALL_HWREG: > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0s->spill_call_hw= reg++; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case SPILL_CALL_IARG: > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0s->spill_call_ia= rg++; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case SPILL_CALL_CLOBBER: > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0s->spill_call_cl= obber++; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 =C2=A0 =C2=A0 ts->val_type =3D TEMP_VAL_MEM; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 s->reg_to_temp[reg] =3D -1; > @@ -1582,6 +1607,9 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet r= eg1, TCGRegSet reg2) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0#else > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0spill_cause =3D SPILL_REAL; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg_reg_free(s, reg); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return reg; > =C2=A0#endif > @@ -1590,6 +1618,9 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet r= eg1, TCGRegSet reg2) > > =C2=A0#ifdef USE_ADVANCED_REGALLOC > =C2=A0 =C2=A0 if (best_score >=3D 0 && best_reg >=3D 0) { > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0spill_cause =3D SPILL_REAL; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg_reg_free(s, best_reg); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 return best_reg; > =C2=A0 =C2=A0 } > @@ -1653,6 +1684,9 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCG= RegSet allocated_regs) > =C2=A0 =C2=A0 for(i =3D s->nb_globals; i < s->nb_temps; i++) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 ts =3D &s->temps[i]; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ts->temp_local) { > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0spill_cause =3D SPILL_BB_END; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 temp_save(s, i, allocated_regs)= ; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 } else { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ts->val_type =3D=3D TEMP_VA= L_REG) { > @@ -1662,6 +1696,10 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TC= GRegSet allocated_regs) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 } > > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0spill_cause =3D SPILL_BB_END; > +#endif > + > =C2=A0 =C2=A0 save_globals(s, allocated_regs); > =C2=A0} > > @@ -1860,12 +1898,18 @@ static void tcg_reg_alloc_op(TCGContext *s, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* XXX: permit generic clobber = register list ? */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for(reg =3D 0; reg < TCG_TARGET= _NB_REGS; reg++) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (tcg_regset_te= st_reg(tcg_target_call_clobber_regs, reg)) { > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sp= ill_cause =3D SPILL_CALL_CLOBBER; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg= _reg_free(s, reg); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* XXX: for load/store we could= do that only for the slow path > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(i.e. when a memor= y callback is called) */ > > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0spill_cause =3D SPILL_CALL_HWR= EG; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* store globals and free assoc= iated registers (we assume the insn > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0can modify any glo= bal. */ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 save_globals(s, allocated_regs)= ; > @@ -2001,6 +2045,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const = TCGOpDef *def, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (arg !=3D TCG_CALL_DUMMY_ARG) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ts =3D &s->temps[arg]; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 reg =3D tcg_target_call_iarg_re= gs[i]; > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0spill_cause =3D SPILL_CALL_IAR= G; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg_reg_free(s, reg); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ts->val_type =3D=3D TEMP_VA= L_REG) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (ts->reg !=3D = reg) { > @@ -2071,6 +2118,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const = TCGOpDef *def, > =C2=A0 =C2=A0 /* clobber call registers */ > =C2=A0 =C2=A0 for(reg =3D 0; reg < TCG_TARGET_NB_REGS; reg++) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (tcg_regset_test_reg(tcg_target_call_clobb= er_regs, reg)) { > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0spill_cause =3D SPILL_CALL_CLO= BBER; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg_reg_free(s, reg); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 } > @@ -2078,6 +2128,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const = TCGOpDef *def, > =C2=A0 =C2=A0 /* store globals and free associated registers (we assume t= he call > =C2=A0 =C2=A0 =C2=A0 =C2=A0can modify any global. */ > =C2=A0 =C2=A0 if (!(flags & TCG_CALL_CONST)) { > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0spill_cause =3D SPILL_CALL_HWREG; > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 save_globals(s, allocated_regs); > =C2=A0 =C2=A0 } > > @@ -2209,6 +2262,14 @@ static inline int tcg_gen_code_common(TCGContext *= s, uint8_t *gen_code_buf, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (args[0] < s->nb_globals) { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (tcg_op_defs[g= en_opc_buf[param_next_use_ptr[0]]].flags > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 & (TCG_OPF_CALL_CLOBBER | TCG_OPF_BB_END)) { > +#ifdef CONFIG_PROFILER > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if= (tcg_op_defs[gen_opc_buf[param_next_use_ptr[0]]].flags > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0& TCG_OPF_CALL_CLOBBER) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0spill_cause =3D SPILL_CALL_HWREG; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} = else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0spill_cause =3D SPILL_BB_END; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} > +#endif > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tcg= _reg_free(s, s->temps[args[0]].reg); > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > @@ -2354,6 +2415,14 @@ void tcg_dump_info(FILE *f, fprintf_function cpu_f= printf) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 s->restore_count)= ; > =C2=A0 =C2=A0 cpu_fprintf(f, " =C2=A0avg cycles =C2=A0 =C2=A0 =C2=A0 =C2= =A0%0.1f\n", > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 s->restore_count = ? (double)s->restore_time / s->restore_count : 0); > + =C2=A0 =C2=A0cpu_fprintf(f, "spill count =C2=A0 =C2=A0 =C2=A0 =C2=A0 %"= PRId64 "\n", > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0s->spill_count); > + =C2=A0 =C2=A0cpu_fprintf(f, " =C2=A0real spills =C2=A0 =C2=A0 =C2=A0 %"= PRId64 "\n", s->spill_real); > + =C2=A0 =C2=A0cpu_fprintf(f, " =C2=A0spills at bb end =C2=A0%" PRId64 "\= n", s->spill_bb_end); > + =C2=A0 =C2=A0cpu_fprintf(f, " =C2=A0spills at call:\n"); > + =C2=A0 =C2=A0cpu_fprintf(f, " =C2=A0 =C2=A0globals =C2=A0 =C2=A0 =C2=A0= =C2=A0 %" PRId64 "\n", s->spill_call_hwreg); > + =C2=A0 =C2=A0cpu_fprintf(f, " =C2=A0 =C2=A0iarg passing =C2=A0 =C2=A0%"= PRId64 "\n", s->spill_call_iarg); > + =C2=A0 =C2=A0cpu_fprintf(f, " =C2=A0 =C2=A0call cloobers =C2=A0 %" PRId= 64 "\n", s->spill_call_clobber); cloober? > > =C2=A0 =C2=A0 dump_op_count(); > =C2=A0} > diff --git a/tcg/tcg.h b/tcg/tcg.h > index 9ff519e..722bd72 100644 > --- a/tcg/tcg.h > +++ b/tcg/tcg.h > @@ -328,6 +328,12 @@ struct TCGContext { > =C2=A0 =C2=A0 int64_t la_time; > =C2=A0 =C2=A0 int64_t restore_count; > =C2=A0 =C2=A0 int64_t restore_time; > + =C2=A0 =C2=A0int64_t spill_count; > + =C2=A0 =C2=A0int64_t spill_bb_end; > + =C2=A0 =C2=A0int64_t spill_call_hwreg; > + =C2=A0 =C2=A0int64_t spill_call_iarg; > + =C2=A0 =C2=A0int64_t spill_call_clobber; > + =C2=A0 =C2=A0int64_t spill_real; > =C2=A0#endif > > =C2=A0#ifdef CONFIG_DEBUG_TCG > -- > 1.7.4.1 > > >