From: Julian Seward Date: Tue, 2 Nov 2004 01:34:15 +0000 (+0000) Subject: Give dirty helper calls a guard field (IRExpr* of type Ity_Bit) which X-Git-Tag: svn/VALGRIND_3_0_1^2~859 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=267d60f7de573a11d9d1eedbe12f36216434a8be;p=thirdparty%2Fvalgrind.git Give dirty helper calls a guard field (IRExpr* of type Ity_Bit) which 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 --- diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index 38e84db1c2..a956975728 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -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; } diff --git a/VEX/priv/ir/iropt.c b/VEX/priv/ir/iropt.c index 40c019dac8..c265e98e99 100644 --- a/VEX/priv/ir/iropt.c +++ b/VEX/priv/ir/iropt.c @@ -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) diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 84429ff1d4..477bf47969 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -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 );