diff mbox

[for-2.5,01/10] tcg/optimize: optimize temps tracking

Message ID 1437755447-10537-2-git-send-email-aurelien@aurel32.net
State New
Headers show

Commit Message

Aurelien Jarno July 24, 2015, 4:30 p.m. UTC
The tcg_temp_info structure uses 24 bytes per temp. Now that we emulate
vector registers on most guests, it's not uncommon to have more than 100
used temps. This means we have initialize more than 2kB at least twice
per TB, often more when there is a few goto_tb.

Instead used a TCGTempSet bit array to track which temps are in used in
the current basic block. This means there are only around 16 bytes to
initialize.

This improves the boot time of a MIPS guest on an x86-64 host by around
7% and moves out tcg_optimize from the the top of the profiler list.

Cc: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 tcg/optimize.c | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

Comments

Paolo Bonzini July 27, 2015, 8:21 a.m. UTC | #1
On 24/07/2015 18:30, Aurelien Jarno wrote:
> The tcg_temp_info structure uses 24 bytes per temp. Now that we emulate
> vector registers on most guests, it's not uncommon to have more than 100
> used temps. This means we have initialize more than 2kB at least twice
> per TB, often more when there is a few goto_tb.
> 
> Instead used a TCGTempSet bit array to track which temps are in used in
> the current basic block. This means there are only around 16 bytes to
> initialize.
> 
> This improves the boot time of a MIPS guest on an x86-64 host by around
> 7% and moves out tcg_optimize from the the top of the profiler list.
> 
> Cc: Richard Henderson <rth@twiddle.net>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  tcg/optimize.c | 32 ++++++++++++++++++++++----------
>  1 file changed, 22 insertions(+), 10 deletions(-)
> 
> diff --git a/tcg/optimize.c b/tcg/optimize.c
> index cd0e793..20e24b3 100644
> --- a/tcg/optimize.c
> +++ b/tcg/optimize.c
> @@ -50,6 +50,7 @@ struct tcg_temp_info {
>  };
>  
>  static struct tcg_temp_info temps[TCG_MAX_TEMPS];
> +static TCGTempSet temps_used;
>  
>  /* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
>     the copy flag from the left temp.  */
> @@ -67,6 +68,22 @@ static void reset_temp(TCGArg temp)
>      temps[temp].mask = -1;
>  }
>  
> +/* Reset all temporaries, given that there are NB_TEMPS of them.  */
> +static void reset_all_temps(int nb_temps)
> +{
> +    memset(&temps_used.l, 0, sizeof(long) * BITS_TO_LONGS(nb_temps));

You can use bitmap_zero here.

Paolo

> +}
> +
> +/* Initialize and activate a temporary.  */
> +static void init_temp_info(TCGArg temp)
> +{
> +    if (!test_bit(temp, temps_used.l)) {
> +        temps[temp].state = TCG_TEMP_UNDEF;
> +        temps[temp].mask = -1;
> +        set_bit(temp, temps_used.l);
> +    }
> +}
> +
>  static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op,
>                                  TCGOpcode opc, int nargs)
>  {
> @@ -98,16 +115,6 @@ static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op,
>      return new_op;
>  }
>  
> -/* Reset all temporaries, given that there are NB_TEMPS of them.  */
> -static void reset_all_temps(int nb_temps)
> -{
> -    int i;
> -    for (i = 0; i < nb_temps; i++) {
> -        temps[i].state = TCG_TEMP_UNDEF;
> -        temps[i].mask = -1;
> -    }
> -}
> -
>  static int op_bits(TCGOpcode op)
>  {
>      const TCGOpDef *def = &tcg_op_defs[op];
> @@ -606,6 +613,11 @@ void tcg_optimize(TCGContext *s)
>              nb_iargs = def->nb_iargs;
>          }
>  
> +        /* Initialize the temps that are going to be used */
> +        for (i = 0; i < nb_oargs + nb_iargs; i++) {
> +            init_temp_info(args[i]);
> +        }
> +
>          /* Do copy propagation */
>          for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
>              if (temps[args[i]].state == TCG_TEMP_COPY) {
>
Aurelien Jarno July 27, 2015, 9:09 a.m. UTC | #2
On 2015-07-27 10:21, Paolo Bonzini wrote:
> 
> 
> On 24/07/2015 18:30, Aurelien Jarno wrote:
> > The tcg_temp_info structure uses 24 bytes per temp. Now that we emulate
> > vector registers on most guests, it's not uncommon to have more than 100
> > used temps. This means we have initialize more than 2kB at least twice
> > per TB, often more when there is a few goto_tb.
> > 
> > Instead used a TCGTempSet bit array to track which temps are in used in
> > the current basic block. This means there are only around 16 bytes to
> > initialize.
> > 
> > This improves the boot time of a MIPS guest on an x86-64 host by around
> > 7% and moves out tcg_optimize from the the top of the profiler list.
> > 
> > Cc: Richard Henderson <rth@twiddle.net>
> > Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> > ---
> >  tcg/optimize.c | 32 ++++++++++++++++++++++----------
> >  1 file changed, 22 insertions(+), 10 deletions(-)
> > 
> > diff --git a/tcg/optimize.c b/tcg/optimize.c
> > index cd0e793..20e24b3 100644
> > --- a/tcg/optimize.c
> > +++ b/tcg/optimize.c
> > @@ -50,6 +50,7 @@ struct tcg_temp_info {
> >  };
> >  
> >  static struct tcg_temp_info temps[TCG_MAX_TEMPS];
> > +static TCGTempSet temps_used;
> >  
> >  /* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
> >     the copy flag from the left temp.  */
> > @@ -67,6 +68,22 @@ static void reset_temp(TCGArg temp)
> >      temps[temp].mask = -1;
> >  }
> >  
> > +/* Reset all temporaries, given that there are NB_TEMPS of them.  */
> > +static void reset_all_temps(int nb_temps)
> > +{
> > +    memset(&temps_used.l, 0, sizeof(long) * BITS_TO_LONGS(nb_temps));
> 
> You can use bitmap_zero here.
> 

Indeed, thanks for the hint. That will be in v2.
diff mbox

Patch

diff --git a/tcg/optimize.c b/tcg/optimize.c
index cd0e793..20e24b3 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -50,6 +50,7 @@  struct tcg_temp_info {
 };
 
 static struct tcg_temp_info temps[TCG_MAX_TEMPS];
+static TCGTempSet temps_used;
 
 /* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
    the copy flag from the left temp.  */
@@ -67,6 +68,22 @@  static void reset_temp(TCGArg temp)
     temps[temp].mask = -1;
 }
 
+/* Reset all temporaries, given that there are NB_TEMPS of them.  */
+static void reset_all_temps(int nb_temps)
+{
+    memset(&temps_used.l, 0, sizeof(long) * BITS_TO_LONGS(nb_temps));
+}
+
+/* Initialize and activate a temporary.  */
+static void init_temp_info(TCGArg temp)
+{
+    if (!test_bit(temp, temps_used.l)) {
+        temps[temp].state = TCG_TEMP_UNDEF;
+        temps[temp].mask = -1;
+        set_bit(temp, temps_used.l);
+    }
+}
+
 static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op,
                                 TCGOpcode opc, int nargs)
 {
@@ -98,16 +115,6 @@  static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op,
     return new_op;
 }
 
-/* Reset all temporaries, given that there are NB_TEMPS of them.  */
-static void reset_all_temps(int nb_temps)
-{
-    int i;
-    for (i = 0; i < nb_temps; i++) {
-        temps[i].state = TCG_TEMP_UNDEF;
-        temps[i].mask = -1;
-    }
-}
-
 static int op_bits(TCGOpcode op)
 {
     const TCGOpDef *def = &tcg_op_defs[op];
@@ -606,6 +613,11 @@  void tcg_optimize(TCGContext *s)
             nb_iargs = def->nb_iargs;
         }
 
+        /* Initialize the temps that are going to be used */
+        for (i = 0; i < nb_oargs + nb_iargs; i++) {
+            init_temp_info(args[i]);
+        }
+
         /* Do copy propagation */
         for (i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
             if (temps[args[i]].state == TCG_TEMP_COPY) {