]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add run-time controllability to iropt.
authorJulian Seward <jseward@acm.org>
Mon, 25 Oct 2004 13:01:45 +0000 (13:01 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 25 Oct 2004 13:01:45 +0000 (13:01 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@420

VEX/priv/guest-x86/toIR.c
VEX/priv/ir/iropt.c
VEX/priv/main/vex_globals.c
VEX/priv/main/vex_globals.h
VEX/priv/main/vex_main.c
VEX/pub/libvex.h

index 817a5c243cea6439c1357389e4bae765678f9264..41272fed8df3f327fd4ae0a5a18115db02432775 100644 (file)
@@ -37,9 +37,6 @@
 #include "guest-x86/gdefs.h"
 
 
-#define RESTEER_THRESH 10
-
-
 /*------------------------------------------------------------*/
 /*--- Globals                                              ---*/
 /*------------------------------------------------------------*/
@@ -133,7 +130,12 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
    DisResult  dres;
    static Int n_resteers = 0;
    Int        d_resteers = 0;
-   Int        resteerBelow = RESTEER_THRESH;  /* the threshold value */
+
+   /* check sanity .. */
+   vassert(vex_control.guest_max_insns >= 1);
+   vassert(vex_control.guest_max_insns < 1000);
+   vassert(vex_control.guest_chase_thresh >= 0);
+   vassert(vex_control.guest_chase_thresh < vex_control.guest_max_insns);
 
    /* Set up globals. */
    host_is_bigendian = host_bigendian;
@@ -142,14 +144,7 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
    guest_eip_bbstart = (Addr32)guest_eip_start;
    irbb              = emptyIRBB();
 
-   if (vex_guest_insns_per_bb <= resteerBelow)
-      resteerBelow = vex_guest_insns_per_bb-1;
-
    vassert((guest_eip_start >> 32) == 0);
-   vassert(vex_guest_insns_per_bb >= 1);
-   vassert(resteerBelow < vex_guest_insns_per_bb);
-   vassert(resteerBelow >= 0);
-   vassert(vex_guest_insns_per_bb);
 
    DIP("Original x86 code to IR:\n\n");
 
@@ -160,10 +155,10 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
    *guest_bytes_read = 0;
 
    while (True) {
-      vassert(n_instrs < vex_guest_insns_per_bb);
+      vassert(n_instrs < vex_control.guest_max_insns);
 
       guest_next = 0;
-      resteerOK = n_instrs < resteerBelow;
+      resteerOK = n_instrs < vex_control.guest_chase_thresh;
       dres = disInstr( resteerOK, delta, &size, &guest_next );
       delta += size;
       *guest_bytes_read += size;
@@ -179,7 +174,7 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
       switch (dres) {
          case Dis_Continue:
             vassert(irbb->next == NULL);
-            if (n_instrs < vex_guest_insns_per_bb) {
+            if (n_instrs < vex_control.guest_max_insns) {
                /* keep going */
             } else {
                irbb->next = mkU32(((Addr32)guest_eip_start)+delta);
index abd88f109935422b4ab90cfd20ec5cb44809fc3f..ab478a0847100fabe700b46cd33529311df2f1af 100644 (file)
 #include "libvex.h"
 
 #include "main/vex_util.h"
+#include "main/vex_globals.h"
 #include "ir/iropt.h"
 
-/* Possibly disable iropt for drastic debugging:
-   Set to 0 to completely disable iropt
-          1 for simple optimisation
-          2 for maximum optimisation (the default) */
-#define IROPT_LEVEL 2
 
 /* Set to 1 for lots of debugging output. */
 #define DEBUG_IROPT 0
 
-/* Controls the enthusiasm of the loop unroller.  It tries to
-   unroll loops enough times to get somewhere near this number of SSA
-   statements, as measured after initial cleanup pass.  Set to zero to
-   disable the unroller. */
-#define UNROLL_TARGET 120
-
-/* Set to 1 to get details of loop unrolling. */
-#define UNROLL_VERBOSE 0
-
 
 /* Implementation notes, 12 Oct 04.
 
@@ -770,7 +757,8 @@ static IRStmt* subst_and_fold_Stmt ( IRExpr** env, IRStmt* st )
                   it is for now, since we'd have to truncate the BB at
                   this point, which is tricky. */
                /* fall out into the reconstruct-the-exit code. */
-               if (UNROLL_VERBOSE) /* really a misuse of UNROLL_VERBOSE */
+               if (vex_control.iropt_verbosity > 0) 
+                  /* really a misuse of vex_control.iropt_verbosity */
                   vex_printf("vex iropt: IRStmt_Exit became unconditional\n");
             }
          }
@@ -2852,27 +2840,27 @@ static Int calc_unroll_factor( IRBB* bb )
      if (bb->stmts[i])
         n_stmts++;
 
-   if (n_stmts <= UNROLL_TARGET/8) {
-      if (UNROLL_VERBOSE)
+   if (n_stmts <= vex_control.iropt_unroll_thresh/8) {
+      if (vex_control.iropt_verbosity > 0)
          vex_printf("vex iropt: 8 x unrolling (%d sts -> %d sts)\n",
                     n_stmts, 8* n_stmts);
       return 8;
    }
-   if (n_stmts <= UNROLL_TARGET/4) {
-      if (UNROLL_VERBOSE)
+   if (n_stmts <= vex_control.iropt_unroll_thresh/4) {
+      if (vex_control.iropt_verbosity > 0)
          vex_printf("vex iropt: 4 x unrolling (%d sts -> %d sts)\n",
                     n_stmts, 4* n_stmts);
       return 4;
    }
 
-   if (n_stmts <= UNROLL_TARGET/2) {
-      if (UNROLL_VERBOSE)
+   if (n_stmts <= vex_control.iropt_unroll_thresh/2) {
+      if (vex_control.iropt_verbosity > 0)
          vex_printf("vex iropt: 2 x unrolling (%d sts -> %d sts)\n",
                     n_stmts, 2* n_stmts);
       return 2;
    }
 
-   if (UNROLL_VERBOSE)
+   if (vex_control.iropt_verbosity > 0)
       vex_printf("vex iropt: not unrolling (%d sts)\n", n_stmts);
 
    return 1;
@@ -2890,7 +2878,7 @@ static IRBB* maybe_loop_unroll_BB ( IRBB* bb0, Addr64 my_addr )
    IRBB     *bb1, *bb2;
    Int      unroll_factor;
 
-   if (UNROLL_TARGET <= 0)
+   if (vex_control.iropt_unroll_thresh <= 0)
       return NULL;
 
    /* First off, figure out if we can unroll this loop.  Do this
@@ -3193,7 +3181,7 @@ IRBB* do_iropt_BB ( IRBB* bb0,
    IRBB *bb, *bb2;
 
    /* Completely disable iropt? */
-   if (IROPT_LEVEL <= 0) return bb0;
+   if (vex_control.iropt_level <= 0) return bb0;
 
    n_total++;
 
@@ -3215,7 +3203,7 @@ IRBB* do_iropt_BB ( IRBB* bb0,
 
    bb = cheap_transformations( bb, specHelper );
 
-   if (IROPT_LEVEL > 1) {
+   if (vex_control.iropt_level > 1) {
       do_expensive = hasGetIorPutI(bb);
       if (do_expensive) {
          n_expensive++;
index 8407177ef1a44ef07f6d4c6bd998a711f576790a..1ab086682407a3d487458de943d677e944d0c231 100644 (file)
@@ -35,7 +35,7 @@ Int vex_verbosity = 0;
 Bool vex_valgrind_support = False;
 
 /* Max # guest insns per bb */
-Int vex_guest_insns_per_bb = 0;
+VexControl vex_control = { 0,0,False,0,0,0 };
 
 
 
index 3f77d97a71b23ee01e256304a21258dd3ed36d6e..0c1417d6f49107c4de43d9ba0344dfd6fcfc7698 100644 (file)
@@ -10,6 +10,7 @@
 #define __VEX_GLOBALS_H
 
 #include "libvex_basictypes.h"
+#include "libvex.h"
 
 
 /* Global settings for the VEX library.  These are the
@@ -34,8 +35,8 @@ extern Int vex_verbosity;
 /* Are we supporting valgrind checking? */
 extern Bool vex_valgrind_support;
 
-/* Max # guest insns per bb */
-extern Int vex_guest_insns_per_bb;
+/* Optimiser/front-end control */
+extern VexControl vex_control;
 
 
 #endif /* ndef __VEX_GLOBALS_H */
index b9a4bdede6b6db40009aefda2ac48d14a22ac9b4..e04247a5bc2018a8428b8981fb8e4e891a446b97 100644 (file)
 
 /* --------- Initialise the library. --------- */
 
+/* Exported to library client. */
+
+void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon )
+{
+   vcon->iropt_verbosity            = 0;
+   vcon->iropt_level                = 2;
+   vcon->iropt_precise_memory_exns  = False;
+   vcon->iropt_unroll_thresh        = 120;
+   vcon->guest_max_insns            = 50;
+   vcon->guest_chase_thresh         = 10;
+}
+
+
 /* Exported to library client. */
 
 void LibVEX_Init (
@@ -34,12 +47,12 @@ void LibVEX_Init (
    Int verbosity,
    /* Are we supporting valgrind checking? */
    Bool valgrind_support,
-   /* Max # guest insns per bb */
-   Int guest_insns_per_bb
+   /* Control ... */
+   /*READONLY*/VexControl* vcon
 )
 {
-   /* First off, do enough minimal setup so that the follow asserts can
-      fail in a sane fashion, if need be. */
+   /* First off, do enough minimal setup so that the following
+      assertions can fail in a sane fashion, if need be. */
    vex_failure_exit = failure_exit;
    vex_log_bytes    = log_bytes;
 
@@ -49,7 +62,16 @@ void LibVEX_Init (
    vassert(log_bytes);
    vassert(debuglevel >= 0);
    vassert(verbosity >= 0);
-   vassert(guest_insns_per_bb >= 1 && guest_insns_per_bb <= 100);
+
+   vassert(vcon->iropt_verbosity >= 0);
+   vassert(vcon->iropt_level >= 0);
+   vassert(vcon->iropt_level <= 2);
+   vassert(vcon->iropt_unroll_thresh >= 0);
+   vassert(vcon->iropt_unroll_thresh <= 400);
+   vassert(vcon->guest_max_insns >= 1);
+   vassert(vcon->guest_max_insns <= 100);
+   vassert(vcon->guest_chase_thresh >= 0);
+   vassert(vcon->guest_chase_thresh < vcon->guest_max_insns);
 
    /* Check that Vex has been built with sizes of basic types as
       stated in priv/libvex_basictypes.h.  Failure of any of these is
@@ -79,7 +101,7 @@ void LibVEX_Init (
    vex_debuglevel         = debuglevel;
    vex_verbosity          = verbosity;
    vex_valgrind_support   = valgrind_support;
-   vex_guest_insns_per_bb = guest_insns_per_bb;
+   vex_control            = *vcon;
    vex_initdone           = True;
    LibVEX_SetAllocMode ( AllocModeTEMPORARY );
 }
index 702a91b44f5c7525b2fa32c2f5b92089a874a165..60a889570a972229d74be8b7d7c38d39bde5ec30 100644 (file)
 /*---------------------------------------------------------------*/
 
 
+/* Control of Vex's optimiser. */
+
+typedef
+   struct {
+      /* Controls verbosity of iropt.  0 = no output. */
+      Int iropt_verbosity;
+      /* Control aggressiveness of iropt.  0 = no opt, 1 = simple
+         opts, 2 (default) = max optimisation. */
+      Int iropt_level;
+      /* Ensure all integer registers are up to date at potential
+         memory exception points?  True(default)=yes, False=no, only
+         the guest's stack pointer. */
+      Bool iropt_precise_memory_exns;
+      /* How aggressive should iropt be in unrolling loops?  Higher
+         numbers make it more enthusiastic about loop unrolling.
+         Default=120.  A setting of zero disables unrolling.  */
+      Int iropt_unroll_thresh;
+      /* What's the maximum basic block length the front end(s) allow?
+         BBs longer than this are split up.  Default=50 (guest
+         insns). */
+      Int guest_max_insns;
+      /* How aggressive should front ends be in following
+         unconditional branches to known destinations?  Default=10,
+         meaning that if a block contains less than 10 guest insns so
+         far, the front end(s) will attempt to chase into its
+         successor. A setting of zero disables chasing.  */
+      Int guest_chase_thresh;
+   }
+   VexControl;
+
+
+/* Write the default settings into *vcon. */
+extern void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon );
+
+
 /* Initialise the translator. */
 
 extern void LibVEX_Init (
@@ -33,8 +68,8 @@ extern void LibVEX_Init (
    Int verbosity,
    /* Are we supporting valgrind checking? */
    Bool valgrind_support,
-   /* Max # guest insns per bb */
-   Int guest_insns_per_bb
+   /* Control ... */
+   /*READONLY*/VexControl* vcon
 );