Merge, from branches/COMEM, revisions 13139 to 13235.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13236 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index f5e3625..d6da7ca 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -4126,18 +4126,40 @@
/*--- Instrumentation ---*/
/*--------------------------------------------------------------*/
+#define unop(_op, _arg1) IRExpr_Unop((_op),(_arg1))
#define binop(_op, _arg1, _arg2) IRExpr_Binop((_op),(_arg1),(_arg2))
#define mkexpr(_tmp) IRExpr_RdTmp((_tmp))
#define mkU32(_n) IRExpr_Const(IRConst_U32(_n))
#define mkU64(_n) IRExpr_Const(IRConst_U64(_n))
#define assign(_t, _e) IRStmt_WrTmp((_t), (_e))
+/* This takes and returns atoms, of course. Not full IRExprs. */
+static IRExpr* mk_And1 ( IRSB* sbOut, IRExpr* arg1, IRExpr* arg2 )
+{
+ tl_assert(arg1 && arg2);
+ tl_assert(isIRAtom(arg1));
+ tl_assert(isIRAtom(arg2));
+ /* Generate 32to1(And32(1Uto32(arg1), 1Uto32(arg2))). Appalling
+ code, I know. */
+ IRTemp wide1 = newIRTemp(sbOut->tyenv, Ity_I32);
+ IRTemp wide2 = newIRTemp(sbOut->tyenv, Ity_I32);
+ IRTemp anded = newIRTemp(sbOut->tyenv, Ity_I32);
+ IRTemp res = newIRTemp(sbOut->tyenv, Ity_I1);
+ addStmtToIRSB(sbOut, assign(wide1, unop(Iop_1Uto32, arg1)));
+ addStmtToIRSB(sbOut, assign(wide2, unop(Iop_1Uto32, arg2)));
+ addStmtToIRSB(sbOut, assign(anded, binop(Iop_And32, mkexpr(wide1),
+ mkexpr(wide2))));
+ addStmtToIRSB(sbOut, assign(res, unop(Iop_32to1, mkexpr(anded))));
+ return mkexpr(res);
+}
+
static void instrument_mem_access ( IRSB* sbOut,
IRExpr* addr,
Int szB,
Bool isStore,
Int hWordTy_szB,
- Int goff_sp )
+ Int goff_sp,
+ IRExpr* guard ) /* NULL => True */
{
IRType tyAddr = Ity_INVALID;
const HChar* hName = NULL;
@@ -4273,15 +4295,23 @@
: binop(Iop_Add64, mkexpr(addr_minus_sp), mkU64(rz_szB)))
);
- IRTemp guard = newIRTemp(sbOut->tyenv, Ity_I1);
+ /* guardA == "guard on the address" */
+ IRTemp guardA = newIRTemp(sbOut->tyenv, Ity_I1);
addStmtToIRSB(
sbOut,
- assign(guard,
+ assign(guardA,
tyAddr == Ity_I32
? binop(Iop_CmpLT32U, mkU32(THRESH), mkexpr(diff))
: binop(Iop_CmpLT64U, mkU64(THRESH), mkexpr(diff)))
);
- di->guard = mkexpr(guard);
+ di->guard = mkexpr(guardA);
+ }
+
+ /* If there's a guard on the access itself (as supplied by the
+ caller of this routine), we need to AND that in to any guard we
+ might already have. */
+ if (guard) {
+ di->guard = mk_And1(sbOut, di->guard, guard);
}
/* Add the helper. */
@@ -4428,7 +4458,8 @@
(isDCAS ? 2 : 1)
* sizeofIRType(typeOfIRExpr(bbIn->tyenv, cas->dataLo)),
False/*!isStore*/,
- sizeofIRType(hWordTy), goff_sp
+ sizeofIRType(hWordTy), goff_sp,
+ NULL/*no-guard*/
);
}
break;
@@ -4448,7 +4479,8 @@
st->Ist.LLSC.addr,
sizeofIRType(dataTy),
False/*!isStore*/,
- sizeofIRType(hWordTy), goff_sp
+ sizeofIRType(hWordTy), goff_sp,
+ NULL/*no-guard*/
);
}
} else {
@@ -4459,22 +4491,46 @@
}
case Ist_Store:
- /* It seems we pretend that store-conditionals don't
- exist, viz, just ignore them ... */
if (!inLDSO) {
instrument_mem_access(
bbOut,
st->Ist.Store.addr,
sizeofIRType(typeOfIRExpr(bbIn->tyenv, st->Ist.Store.data)),
True/*isStore*/,
- sizeofIRType(hWordTy), goff_sp
+ sizeofIRType(hWordTy), goff_sp,
+ NULL/*no-guard*/
);
}
break;
+ case Ist_StoreG: {
+ IRStoreG* sg = st->Ist.StoreG.details;
+ IRExpr* data = sg->data;
+ IRExpr* addr = sg->addr;
+ IRType type = typeOfIRExpr(bbIn->tyenv, data);
+ tl_assert(type != Ity_INVALID);
+ instrument_mem_access( bbOut, addr, sizeofIRType(type),
+ True/*isStore*/,
+ sizeofIRType(hWordTy),
+ goff_sp, sg->guard );
+ break;
+ }
+
+ case Ist_LoadG: {
+ IRLoadG* lg = st->Ist.LoadG.details;
+ IRType type = Ity_INVALID; /* loaded type */
+ IRType typeWide = Ity_INVALID; /* after implicit widening */
+ IRExpr* addr = lg->addr;
+ typeOfIRLoadGOp(lg->cvt, &typeWide, &type);
+ tl_assert(type != Ity_INVALID);
+ instrument_mem_access( bbOut, addr, sizeofIRType(type),
+ False/*!isStore*/,
+ sizeofIRType(hWordTy),
+ goff_sp, lg->guard );
+ break;
+ }
+
case Ist_WrTmp: {
- /* ... whereas here we don't care whether a load is a
- vanilla one or a load-linked. */
IRExpr* data = st->Ist.WrTmp.data;
if (data->tag == Iex_Load) {
if (!inLDSO) {
@@ -4483,7 +4539,8 @@
data->Iex.Load.addr,
sizeofIRType(data->Iex.Load.ty),
False/*!isStore*/,
- sizeofIRType(hWordTy), goff_sp
+ sizeofIRType(hWordTy), goff_sp,
+ NULL/*no-guard*/
);
}
}
@@ -4503,7 +4560,7 @@
if (!inLDSO) {
instrument_mem_access(
bbOut, d->mAddr, dataSize, False/*!isStore*/,
- sizeofIRType(hWordTy), goff_sp
+ sizeofIRType(hWordTy), goff_sp, NULL/*no-guard*/
);
}
}
@@ -4511,7 +4568,7 @@
if (!inLDSO) {
instrument_mem_access(
bbOut, d->mAddr, dataSize, True/*isStore*/,
- sizeofIRType(hWordTy), goff_sp
+ sizeofIRType(hWordTy), goff_sp, NULL/*no-guard*/
);
}
}