]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Generic fixes to iropt to enable it to be as sloppy with exceptions as
authorJulian Seward <jseward@acm.org>
Mon, 25 Oct 2004 14:50:21 +0000 (14:50 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 25 Oct 2004 14:50:21 +0000 (14:50 +0000)
we can get away with.

git-svn-id: svn://svn.valgrind.org/vex/trunk@423

VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/priv/ir/iropt.c
VEX/priv/ir/iropt.h
VEX/priv/main/vex_main.c
VEX/pub/libvex_basictypes.h
VEX/pub/libvex_guest_x86.h

index 8ba9b31b3d8e1d4e15be18dbc6a678aea2209618..0a4d9f290471d17642c8b0d4e12ee6d9004a169b 100644 (file)
@@ -1439,6 +1439,41 @@ static void dirtyhelper_CPUID ( VexGuestX86State* st )
    }
 }
 
+/*-----------------------------------------------------------*/
+/*--- Describing the x86 guest state, for the benefit     ---*/
+/*--- of iropt and instrumenters.                         ---*/
+/*-----------------------------------------------------------*/
+
+/* Figure out if any part of the guest state contained in minoff
+   .. maxoff requires precise memory exceptions.  If in doubt return
+   True (but this is generates significantly slower code).  
+
+   We enforce precise exns for guest %ESP and %EIP only.
+*/
+Bool guest_x86_state_requires_precise_mem_exns ( Int minoff, 
+                                                 Int maxoff)
+{
+   Int esp_min = offsetof(VexGuestX86State, guest_ESP);
+   Int esp_max = esp_min + 4 - 1;
+   Int eip_min = offsetof(VexGuestX86State, guest_EIP);
+   Int eip_max = eip_min + 4 - 1;
+
+   if (maxoff < esp_min || minoff > esp_max) {
+     /* no overlap with esp */
+   } else {
+     return True;
+   }
+
+   if (maxoff < eip_min || minoff > eip_max) {
+     /* no overlap with eip */
+   } else {
+     return True;
+   }
+
+   return False;
+}
+
+
 /*---------------------------------------------------------------*/
 /*--- end                                guest-x86/ghelpers.c ---*/
 /*---------------------------------------------------------------*/
index 41272fed8df3f327fd4ae0a5a18115db02432775..6da101ec2ff4b4b77cb50a56b02b5ed671b29f24 100644 (file)
@@ -204,8 +204,6 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
 /*--- Offsets of various parts of the x86 guest state.     ---*/
 /*------------------------------------------------------------*/
 
-#define offsetof(type,memb) ((Int)&((type*)0)->memb)
-
 #define OFFB_FPREGS  offsetof(VexGuestX86State,guest_FPREG[0])
 #define OFFB_FPTAGS  offsetof(VexGuestX86State,guest_FPTAG[0])
 #define OFFB_EAX     offsetof(VexGuestX86State,guest_EAX)
index ab478a0847100fabe700b46cd33529311df2f1af..aa9e50fac3ae48afad5ca7c7ee80244bda4f2873 100644 (file)
@@ -1146,7 +1146,11 @@ static void redundant_get_removal_BB ( IRBB* bb )
    overlapping ranges listed in env.  Due to the flattening phase, the
    only stmt kind we expect to find a Get on is IRStmt_Tmp. */
 
-static void handle_gets_Stmt ( HashHW* env, IRStmt* st )
+static void handle_gets_Stmt ( 
+               HashHW* env, 
+               IRStmt* st,
+               Bool (*preciseMemExnsFn)(Int,Int)
+            )
 {
    Int     j;
    UInt    key = 0; /* keep gcc -O happy */
@@ -1225,17 +1229,22 @@ static void handle_gets_Stmt ( HashHW* env, IRStmt* st )
          be reordered with respect to memory references.  That means
          at least the stack pointer. */
       for (j = 0; j < env->used; j++) {
-#if 0
-         if (env->inuse[j]
-             && env->key[j] == (HWord)((16 << 16) | 19)) {
-            //vex_printf("found esp assignment\n");
+         if (!env->inuse[j])
+            continue;
+         if (vex_control.iropt_precise_memory_exns) {
+            /* Precise exceptions required.  Flush all guest state. */
             env->inuse[j] = False;
-        }
-#else
-         env->inuse[j] = False;
-#endif
+         } 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 ))
+               env->inuse[j] = False;
+         }
       }
-   }
+   } /* if (memRW) */
+
 }
 
 
@@ -1253,7 +1262,10 @@ static void handle_gets_Stmt ( HashHW* env, IRStmt* st )
    overlapping (minoff,maxoff).
 */
 
-static void redundant_put_removal_BB ( IRBB* bb )
+static void redundant_put_removal_BB ( 
+               IRBB* bb,
+               Bool (*preciseMemExnsFn)(Int,Int)
+            )
 {
    Int     i, j;
    Bool    isPut;
@@ -1320,7 +1332,7 @@ static void redundant_put_removal_BB ( IRBB* bb )
       /* Deal with Gets.  These remove bits of the environment since
          appearance of a Get means that the next event for that slice
          of the guest state is no longer a write, but a read. */
-      handle_gets_Stmt( env, st );
+      handle_gets_Stmt( env, st, preciseMemExnsFn );
    }
 }
 
@@ -3055,7 +3067,9 @@ static Bool iropt_verbose = False; //True;
 static 
 IRBB* cheap_transformations ( 
          IRBB* bb,
-         IRExpr* (*specHelper) ( Char*, IRExpr**) )
+         IRExpr* (*specHelper) ( Char*, IRExpr**),
+         Bool (*preciseMemExnsFn)(Int,Int)
+      )
 {
    redundant_get_removal_BB ( bb );
    if (iropt_verbose) {
@@ -3063,7 +3077,7 @@ IRBB* cheap_transformations (
       ppIRBB(bb);
    }
 
-   redundant_put_removal_BB ( bb );
+   redundant_put_removal_BB ( bb, preciseMemExnsFn );
    if (iropt_verbose) {
       vex_printf("\n========= REDUNDANT PUT\n\n" );
       ppIRBB(bb);
@@ -3171,6 +3185,7 @@ static Bool hasGetIorPutI ( IRBB* bb )
 
 IRBB* do_iropt_BB ( IRBB* bb0,
                     IRExpr* (*specHelper) ( Char*, IRExpr**),
+                    Bool (*preciseMemExnsFn)(Int,Int),
                     Addr64 guest_addr )
 {
    static UInt n_total     = 0;
@@ -3201,7 +3216,7 @@ IRBB* do_iropt_BB ( IRBB* bb0,
       If needed, do expensive transformations and then another cheap
       cleanup pass. */
 
-   bb = cheap_transformations( bb, specHelper );
+   bb = cheap_transformations( bb, specHelper, preciseMemExnsFn );
 
    if (vex_control.iropt_level > 1) {
       do_expensive = hasGetIorPutI(bb);
@@ -3211,7 +3226,7 @@ IRBB* do_iropt_BB ( IRBB* bb0,
          if (DEBUG_IROPT)
             vex_printf("***** EXPENSIVE %d %d\n", n_total, n_expensive);
          bb = expensive_transformations( bb );
-         bb = cheap_transformations( bb, specHelper );
+         bb = cheap_transformations( bb, specHelper, preciseMemExnsFn );
       }
 
       /* Now have a go at unrolling simple (single-BB) loops.  If
@@ -3220,10 +3235,10 @@ IRBB* do_iropt_BB ( IRBB* bb0,
       bb2 = maybe_loop_unroll_BB( bb, guest_addr );
       if (bb2) {
          show_res = False; //True;
-         bb = cheap_transformations( bb2, specHelper );
+         bb = cheap_transformations( bb2, specHelper, preciseMemExnsFn );
          if (do_expensive) {
             bb = expensive_transformations( bb );
-            bb = cheap_transformations( bb, specHelper );
+            bb = cheap_transformations( bb, specHelper, preciseMemExnsFn );
          } else {
             /* at least do CSE and dead code removal */
             cse_BB( bb );
index 9535541142083f633446a540b3431ea71451cb44..ec47b980635f0f0a16582333337dac01a0f52112 100644 (file)
@@ -13,6 +13,7 @@
 
 extern IRBB* do_iropt_BB ( IRBB* bb,
                            IRExpr* (*specHelper) ( Char*, IRExpr**),
+                           Bool (*preciseMemExnsFn)(Int,Int),
                            Addr64 guest_addr );
 
 /*---------------------------------------------------------------*/
index e04247a5bc2018a8428b8981fb8e4e891a446b97..878224bac94b0b06883f2ffac5d1677454f3c3f1 100644 (file)
@@ -7,6 +7,7 @@
 /*---------------------------------------------------------------*/
 
 #include "libvex.h"
+#include "libvex_guest_x86.h"
 
 #include "main/vex_globals.h"
 #include "main/vex_util.h"
@@ -151,6 +152,7 @@ TranslateResult LibVEX_Translate (
    Int          (*emit)        ( UChar*, Int, HInstr* );
    Addr64       (*findHelper)  ( Char* );
    IRExpr*      (*specHelper)  ( Char*, IRExpr** );
+   Bool         (*preciseMemExnsFn) ( Int, Int );
 
    Bool         host_is_bigendian = False;
    IRBB*        irbb;
@@ -173,6 +175,7 @@ TranslateResult LibVEX_Translate (
    emit                   = NULL;
    findHelper             = NULL;
    specHelper             = NULL;
+   preciseMemExnsFn       = NULL;
 
    saved_verbosity = vex_verbosity;
    if (bb_verbosity > 0)
@@ -204,9 +207,10 @@ TranslateResult LibVEX_Translate (
 
    switch (iset_guest) {
       case InsnSetX86:
-         bbToIR     = bbToIR_X86Instr;
-         findHelper = x86guest_findhelper;
-         specHelper = x86guest_spechelper;
+         preciseMemExnsFn = guest_x86_state_requires_precise_mem_exns;
+         bbToIR           = bbToIR_X86Instr;
+         findHelper       = x86guest_findhelper;
+         specHelper       = x86guest_spechelper;
          break;
       default:
          vpanic("LibVEX_Translate: unsupported guest insn set");
@@ -239,7 +243,8 @@ TranslateResult LibVEX_Translate (
    sanityCheckIRBB(irbb, Ity_I32);
 
    /* Clean it up, hopefully a lot. */
-   irbb = do_iropt_BB ( irbb, specHelper, guest_bytes_addr );
+   irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn, 
+                              guest_bytes_addr );
    sanityCheckIRBB(irbb, Ity_I32);
 
    if (vex_verbosity > 0) {
index 25fa2ed87358f5d47ac7c09699b5f70e9b6875cc..b44e4a4a540563ccd0cedaa02bdc31b00f6fc5f4 100644 (file)
@@ -49,6 +49,10 @@ typedef  ULong     Addr64;
 typedef  unsigned long HWord;
 
 
+/* This is so useful it should be visible absolutely everywhere. */
+#define offsetof(type,memb) ((Int)&((type*)0)->memb)
+
+
 #endif /* ndef __LIBVEX_BASICTYPES_H */
 
 
index c534c7a8df903216f2239f73c1f5a163074d61d1..72a03e4e5f31b068458464ad99dd427d0f98b1bf 100644 (file)
@@ -106,10 +106,21 @@ typedef
    VexGuestX86State;
 
 
+/* This is logically part of the guest state description. */
+/* Not visible to library client. */
+extern Bool guest_x86_state_requires_precise_mem_exns ( Int, Int );
+
+
+
 /*---------------------------------------------------------------*/
 /*--- Utility functions for x86 guest stuff.                  ---*/
 /*---------------------------------------------------------------*/
 
+
+
+
+/* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
+
 /* Convert a saved x87 FPU image (as created by fsave) and write it
    into the supplied VexGuestX86State structure.  The non-FP parts of
    said structure are left unchanged.