#include "guest-x86/gdefs.h"
-#define RESTEER_THRESH 10
-
-
/*------------------------------------------------------------*/
/*--- Globals ---*/
/*------------------------------------------------------------*/
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;
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");
*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;
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);
#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.
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");
}
}
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;
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
IRBB *bb, *bb2;
/* Completely disable iropt? */
- if (IROPT_LEVEL <= 0) return bb0;
+ if (vex_control.iropt_level <= 0) return bb0;
n_total++;
bb = cheap_transformations( bb, specHelper );
- if (IROPT_LEVEL > 1) {
+ if (vex_control.iropt_level > 1) {
do_expensive = hasGetIorPutI(bb);
if (do_expensive) {
n_expensive++;
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 };
#define __VEX_GLOBALS_H
#include "libvex_basictypes.h"
+#include "libvex.h"
/* Global settings for the VEX library. These are the
/* 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 */
/* --------- 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 (
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;
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
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 );
}
/*---------------------------------------------------------------*/
+/* 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 (
Int verbosity,
/* Are we supporting valgrind checking? */
Bool valgrind_support,
- /* Max # guest insns per bb */
- Int guest_insns_per_bb
+ /* Control ... */
+ /*READONLY*/VexControl* vcon
);