From 9edc8458befa2733da69c58f05e642584fd2f61f Mon Sep 17 00:00:00 2001 From: Philippe Waroquiers Date: Wed, 1 Aug 2012 22:04:13 +0000 Subject: [PATCH] VEX part (remove --vex-iropt-precise-memory-exns, add --vex-iropt-register-updates) git-svn-id: svn://svn.valgrind.org/vex/trunk@2454 --- VEX/priv/ir_opt.c | 65 ++++++++++++++++++++++++++++++++------------ VEX/priv/main_main.c | 2 +- VEX/pub/libvex.h | 23 +++++++++++++--- 3 files changed, 68 insertions(+), 22 deletions(-) diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 5dc6b4635c..481e605c80 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -69,12 +69,20 @@ not marked as being read or modified by the helper cannot be assumed to be up-to-date at the point where the helper is called. - * Immediately prior to any load or store, those parts of the guest + * If iropt_register_updates == VexRegUpdUnwindregsAtMemAccess : + Immediately prior to any load or store, those parts of the guest state marked as requiring precise exceptions will be up to date. Also, guest memory will be up to date. Parts of the guest state not marked as requiring precise exceptions cannot be assumed to be up-to-date at the point of the load/store. + If iropt_register_updates == VexRegUpdAllregsAtMemAccess: + Same as minimal, but all the guest state is up to date at memory + exception points. + + If iropt_register_updates == VexRegUpdAllregsAtEachInsn : + Guest state is up to date at each instruction. + The relative order of loads and stores (including loads/stores of guest memory done by dirty helpers annotated as such) is not changed. However, the relative order of loads with no intervening @@ -774,20 +782,29 @@ static void handle_gets_Stmt ( of the environment corresponding to guest state that may not be reordered with respect to memory references. That means at least the stack pointer. */ - for (j = 0; j < env->used; j++) { - if (!env->inuse[j]) - continue; - if (vex_control.iropt_precise_memory_exns) { - /* Precise exceptions required. Flush all guest state. */ - env->inuse[j] = False; - } else { - /* Just flush the minimal amount required, as computed by - preciseMemExnsFn. */ - HWord k_lo = (env->key[j] >> 16) & 0xFFFF; - HWord k_hi = env->key[j] & 0xFFFF; - if (preciseMemExnsFn( k_lo, k_hi )) + switch (vex_control.iropt_register_updates) { + case VexRegUpdAllregsAtMemAccess: + /* Precise exceptions required at mem access. + Flush all guest state. */ + for (j = 0; j < env->used; j++) env->inuse[j] = False; - } + break; + case VexRegUpdUnwindregsAtMemAccess: + for (j = 0; j < env->used; j++) { + if (!env->inuse[j]) + continue; + /* Just flush the minimal amount required, as computed by + preciseMemExnsFn. */ + HWord k_lo = (env->key[j] >> 16) & 0xFFFF; + HWord k_hi = env->key[j] & 0xFFFF; + if (preciseMemExnsFn( k_lo, k_hi )) + env->inuse[j] = False; + } + break; + default: + // VexRegUpdAllregsAtEachInsn cannot happen here. + // Neither any rubbish other value. + vassert(0); } } /* if (memRW) */ @@ -820,6 +837,10 @@ static void redundant_put_removal_BB ( IRStmt* st; UInt key = 0; /* keep gcc -O happy */ + vassert + (vex_control.iropt_register_updates == VexRegUpdUnwindregsAtMemAccess + || vex_control.iropt_register_updates == VexRegUpdAllregsAtMemAccess); + HashHW* env = newHHW(); /* Initialise the running env with the fact that the final exit @@ -3937,6 +3958,10 @@ void do_redundant_PutI_elimination ( IRSB* bb ) Bool delete; IRStmt *st, *stj; + vassert + (vex_control.iropt_register_updates == VexRegUpdUnwindregsAtMemAccess + || vex_control.iropt_register_updates == VexRegUpdAllregsAtMemAccess); + for (i = 0; i < bb->stmts_used; i++) { st = bb->stmts[i]; if (st->tag != Ist_PutI) @@ -5176,7 +5201,9 @@ IRSB* cheap_transformations ( ppIRSB(bb); } - redundant_put_removal_BB ( bb, preciseMemExnsFn ); + if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) { + redundant_put_removal_BB ( bb, preciseMemExnsFn ); + } if (iropt_verbose) { vex_printf("\n========= REDUNDANT PUT\n\n" ); ppIRSB(bb); @@ -5214,7 +5241,9 @@ IRSB* expensive_transformations( IRSB* bb ) (void)do_cse_BB( bb ); collapse_AddSub_chains_BB( bb ); do_redundant_GetI_elimination( bb ); - do_redundant_PutI_elimination( bb ); + if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) { + do_redundant_PutI_elimination( bb ); + } do_deadcode_BB( bb ); return bb; } @@ -5363,7 +5392,9 @@ IRSB* do_iropt_BB( work extra hard to get rid of it. */ bb = cprop_BB(bb); bb = spec_helpers_BB ( bb, specHelper ); - redundant_put_removal_BB ( bb, preciseMemExnsFn ); + if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) { + redundant_put_removal_BB ( bb, preciseMemExnsFn ); + } do_cse_BB( bb ); do_deadcode_BB( bb ); } diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index bcad06272a..08d6ebdb27 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -82,7 +82,7 @@ void LibVEX_default_VexControl ( /*OUT*/ VexControl* vcon ) { vcon->iropt_verbosity = 0; vcon->iropt_level = 2; - vcon->iropt_precise_memory_exns = False; + vcon->iropt_register_updates = VexRegUpdUnwindregsAtMemAccess; vcon->iropt_unroll_thresh = 120; vcon->guest_max_insns = 60; vcon->guest_chase_thresh = 10; diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 8b6306e723..68479fdcfe 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -307,6 +307,23 @@ void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi ); /*--- Control of Vex's optimiser (iropt). ---*/ /*-------------------------------------------------------*/ + +/* VexRegisterUpdates specifies when to ensure that the guest state is + up to date. + + VexRegUpdUnwindregsAtMemAccess : registers needed to make a stack trace are + up to date at memory exception points. Typically, these are PC/SP/FP. The + minimal registers are described by the arch specific functions + guest__state_requires_precise_mem_exns. + + VexRegUpdAllregsAtMemAccess : all registers up to date at memory exception + points. + + VexRegUpdAllregsAtEachInsn : all registers up to date at each instruction. */ +typedef enum { VexRegUpdUnwindregsAtMemAccess, + VexRegUpdAllregsAtMemAccess, + VexRegUpdAllregsAtEachInsn } VexRegisterUpdates; + /* Control of Vex's optimiser. */ typedef @@ -316,10 +333,8 @@ typedef /* 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; + /* Controls when registers are updated in guest state. */ + VexRegisterUpdates iropt_register_updates; /* 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. */ -- 2.47.2