]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Give dirty helper calls a guard field (IRExpr* of type Ity_Bit) which
authorJulian Seward <jseward@acm.org>
Tue, 2 Nov 2004 01:34:15 +0000 (01:34 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 2 Nov 2004 01:34:15 +0000 (01:34 +0000)
gates whether or not the call really happens.  Push this through
iropt.  Has no effect at the instruction selectors yet.

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

VEX/priv/ir/irdefs.c
VEX/priv/ir/iropt.c
VEX/pub/libvex_ir.h

index 38e84db1c25bef797776ad88d9c6c195d2fcecd7..a956975728b8a87c9eb29e04e1e00ced6c257e92 100644 (file)
@@ -283,7 +283,8 @@ void ppIREffect ( IREffect fx )
 void ppIRDirty ( IRDirty* d )
 {
    Int i;
-   vex_printf("DIRTY");
+   vex_printf("DIRTY ");
+   ppIRExpr(d->guard);
    if (d->needsBBP)
       vex_printf(" NeedsBBP");
    if (d->mFx != Ifx_None) {
@@ -614,6 +615,7 @@ IRExpr** mkIRExprVec_4 ( IRExpr* arg1, IRExpr* arg2,
 IRDirty* emptyIRDirty ( void ) {
    IRDirty* d = LibVEX_Alloc(sizeof(IRDirty));
    d->cee      = NULL;
+   d->guard    = NULL;
    d->args     = NULL;
    d->tmp      = INVALID_IRTEMP;
    d->mFx      = Ifx_None;
@@ -803,6 +805,7 @@ IRDirty* dopyIRDirty ( IRDirty* d )
    Int      i;
    IRDirty* d2 = emptyIRDirty();
    d2->cee   = dopyIRCallee(d->cee);
+   d2->guard = dopyIRExpr(d->guard);
    d2->args  = dopyIRExprVec(d->args);
    d2->tmp   = d->tmp;
    d2->mFx   = d->mFx;
@@ -1443,6 +1446,9 @@ void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
             if (d->fxState[i].size <= 0) goto bad_dirty;
          }
          /* check types, minimally */
+         if (d->guard == NULL) goto bad_dirty;
+         if (typeOfIRExpr(tyenv, d->guard) != Ity_Bit)
+            sanityCheckFail(bb,stmt,"IRStmt.Dirty.guard not :: Ity_Bit");
          if (d->tmp != INVALID_IRTEMP
              && typeOfIRTemp(tyenv, d->tmp) == Ity_Bit)
             sanityCheckFail(bb,stmt,"IRStmt.Dirty.dst :: Ity_Bit");
@@ -1589,8 +1595,9 @@ IRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr,
                              IRExpr** args ) 
 {
    IRDirty* d = emptyIRDirty();
-   d->cee  = mkIRCallee ( regparms, name, addr );
-   d->args = args;
+   d->cee   = mkIRCallee ( regparms, name, addr );
+   d->guard = IRExpr_Const(IRConst_Bit(True));
+   d->args  = args;
    return d;
 }
 
@@ -1599,9 +1606,10 @@ IRDirty* unsafeIRDirty_1_N ( IRTemp dst,
                              IRExpr** args ) 
 {
    IRDirty* d = emptyIRDirty();
-   d->cee  = mkIRCallee ( regparms, name, addr );
-   d->args = args;
-   d->tmp  = dst;
+   d->cee   = mkIRCallee ( regparms, name, addr );
+   d->guard = IRExpr_Const(IRConst_Bit(True));
+   d->args  = args;
+   d->tmp   = dst;
    return d;
 }
 
index 40c019dac85f0b3325af6909f20e9de0adb4d509..c265e98e99db8e5f3005b2621431cc0c3543e071 100644 (file)
@@ -86,23 +86,6 @@ static Bool lookupHHW ( HashHW* h, /*OUT*/HWord* val, HWord key )
 }
 
 
-#if 0
-/* Apparently unused */
-/* Delete any binding for key in h. */
-
-static void delFromHHW ( HashHW* h, HWord key )
-{
-   Int i;
-   for (i = 0; i < h->used; i++) {
-      if (h->inuse[i] && h->key[i] == key) {
-         h->inuse[i] = False;
-         return;
-      }
-   }
-}
-#endif
-
-
 /* Add key->val to the map.  Replaces any existing binding for key. */
 
 static void addToHHW ( HashHW* h, HWord key, HWord val )
@@ -311,6 +294,7 @@ static void flatten_Stmt ( IRBB* bb, IRStmt* st )
          } else {
             vassert(d2->mAddr == NULL);
          }
+         d2->guard = flatten_Expr(bb, d2->guard);
          for (i = 0; d2->args[i]; i++)
             d2->args[i] = flatten_Expr(bb, d2->args[i]);
          addStmtToIRBB(bb, IRStmt_Dirty(d2));
@@ -737,6 +721,8 @@ static IRStmt* subst_and_fold_Stmt ( IRExpr** env, IRStmt* st )
             vassert(isAtom(d2->mAddr));
             d2->mAddr = fold_Expr(subst_Expr(env, d2->mAddr));
          }
+         vassert(isAtom(d2->guard));
+         d2->guard = fold_Expr(subst_Expr(env, d2->guard));
          for (i = 0; d2->args[i]; i++) {
             vassert(isAtom(d2->args[i]));
             d2->args[i] = fold_Expr(subst_Expr(env, d2->args[i]));
@@ -923,6 +909,7 @@ static void addUses_Stmt ( Bool* set, IRStmt* st )
          d = st->Ist.Dirty.details;
          if (d->mFx != Ifx_None)
             addUses_Expr(set, d->mAddr);
+         addUses_Expr(set, d->guard);
          for (i = 0; d->args[i] != NULL; i++)
             addUses_Expr(set, d->args[i]);
          return;
@@ -1496,6 +1483,7 @@ static void occCount_Stmt ( TmpInfo** env, IRStmt* st )
          d = st->Ist.Dirty.details;
          if (d->mFx != Ifx_None)
             occCount_Expr(env, d->mAddr);
+         occCount_Expr(env, d->guard);
          for (i = 0; d->args[i]; i++)
             occCount_Expr(env, d->args[i]);
          return;
@@ -1634,6 +1622,7 @@ static IRStmt* tbSubst_Stmt ( TmpInfo** env, IRStmt* st )
          *d2 = *d;
          if (d2->mFx != Ifx_None)
             d2->mAddr = tbSubst_Expr(env, d2->mAddr);
+         d2->guard = tbSubst_Expr(env, d2->guard);
          for (i = 0; d2->args[i]; i++)
             d2->args[i] = tbSubst_Expr(env, d2->args[i]);
          return IRStmt_Dirty(d2);
@@ -2824,6 +2813,7 @@ static void deltaIRStmt ( IRStmt* st, Int delta )
          break;
       case Ist_Dirty:
          d = st->Ist.Dirty.details;
+         deltaIRExpr(d->guard, delta);
          for (i = 0; d->args[i]; i++)
             deltaIRExpr(d->args[i], delta);
          if (d->tmp != INVALID_IRTEMP)
@@ -3169,6 +3159,7 @@ static Bool hasGetIorPutI ( IRBB* bb )
             break;
          case Ist_Dirty:
             d = st->Ist.Dirty.details;
+            vassert(isAtom(d->guard));
             for (j = 0; d->args[j]; j++)
                vassert(isAtom(d->args[j]));
             if (d->mFx != Ifx_None)
index 84429ff1d44f534145998f709f04b0535e193c93..477bf47969c796f147fc20f570bf7f6c07ec0f8f 100644 (file)
@@ -490,6 +490,11 @@ inline static Bool isAtom ( IRExpr* e ) {
    access the guest state.  It is invalid for .nFxState to be zero
    but .needsBBP to be True, since .nFxState==0 is a claim that the
    call does not access guest state.
+
+   IMPORTANT NOTE re GUARDS: Dirty calls are strict, very strict.  The
+   arguments are evaluated REGARDLESS of the guard value.  It is
+   unspecified the relative order of arg evaluation and guard
+   evaluation.
 */
 
 #define VEX_N_FXSTATE  4   /* enough for CPUID on x86 */
@@ -510,6 +515,7 @@ typedef
    struct {
       /* What to call, and details of args/results */
       IRCallee* cee;    /* where to call */
+      IRExpr*   guard;  /* :: Ity_Bit.  Controls whether call happens */
       IRExpr**  args;   /* arg list, ends in NULL */
       IRTemp    tmp;    /* to assign result to, or INVALID_IRTEMP if none */
 
@@ -536,10 +542,10 @@ extern IRDirty* dopyIRDirty ( IRDirty* );
 
 /* A handy function which takes some of the tedium out of constructing
    dirty helper calls.  The called function impliedly does not return
-   any value.  The call is marked as accessing neither guest state nor
-   memory (hence the "unsafe" designation) -- you can mess with this
-   later if need be.  A suitable IRCallee is constructed from the
-   supplied bits. */
+   any value and has a constant-True guard.  The call is marked as
+   accessing neither guest state nor memory (hence the "unsafe"
+   designation) -- you can mess with this later if need be.  A
+   suitable IRCallee is constructed from the supplied bits. */
 extern 
 IRDirty* unsafeIRDirty_0_N ( Int regparms, Char* name, void* addr, 
                              IRExpr** args );