|
From: <sv...@va...> - 2009-06-18 23:06:14
|
Author: sewardj
Date: 2009-06-19 00:06:01 +0100 (Fri, 19 Jun 2009)
New Revision: 10350
Log:
Modify the instrumentation functions of the following tools to handle
the new IRCAS statenent:
cachegrind callgrind drd exp-ptrcheck(stack/global only)
helgrind lackey
Modified:
branches/DCAS/cachegrind/cg_main.c
branches/DCAS/callgrind/main.c
branches/DCAS/drd/drd_load_store.c
branches/DCAS/exp-ptrcheck/sg_main.c
branches/DCAS/helgrind/hg_main.c
branches/DCAS/lackey/lk_main.c
Modified: branches/DCAS/cachegrind/cg_main.c
===================================================================
--- branches/DCAS/cachegrind/cg_main.c 2009-06-16 06:56:53 UTC (rev 10349)
+++ branches/DCAS/cachegrind/cg_main.c 2009-06-18 23:06:01 UTC (rev 10350)
@@ -1032,6 +1032,27 @@
break;
}
+ case Ist_CAS: {
+ /* We treat it as a read and a write of the location. I
+ think that is the same behaviour as it was before IRCAS
+ was introduced, since prior to that point, the Vex
+ front ends would translate a lock-prefixed instruction
+ into a (normal) read followed by a (normal) write. */
+ Int dataSize;
+ IRCAS* cas = st->Ist.CAS.details;
+ tl_assert(cas->addr != NULL);
+ tl_assert(cas->dataLo != NULL);
+ dataSize = sizeofIRType(typeOfIRExpr(tyenv, cas->dataLo));
+ if (cas->dataHi != NULL)
+ dataSize *= 2; /* since it's a doubleword-CAS */
+ /* I don't think this can ever happen, but play safe. */
+ if (dataSize > MIN_LINE_SIZE)
+ dataSize = MIN_LINE_SIZE;
+ addEvent_Dr( &cgs, curr_inode, dataSize, cas->addr );
+ addEvent_Dw( &cgs, curr_inode, dataSize, cas->addr );
+ break;
+ }
+
case Ist_Exit: {
/* Stuff to widen the guard expression to a host word, so
we can pass it to the branch predictor simulation
Modified: branches/DCAS/callgrind/main.c
===================================================================
--- branches/DCAS/callgrind/main.c 2009-06-16 06:56:53 UTC (rev 10349)
+++ branches/DCAS/callgrind/main.c 2009-06-18 23:06:01 UTC (rev 10350)
@@ -466,6 +466,28 @@
break;
}
+ case Ist_CAS: {
+ /* We treat it as a read and a write of the location. I think
+ that is the same behaviour as it was before IRCAS was
+ introduced, since prior to that point, the Vex front ends
+ would translate a lock-prefixed instruction into a (normal)
+ read followed by a (normal) write. */
+ IRCAS* cas = st->Ist.CAS.details;
+ CLG_ASSERT(cas->addr && isIRAtom(cas->addr));
+ CLG_ASSERT(cas->dataLo);
+ if (*storeAddrExpr == NULL)
+ *storeAddrExpr = cas->addr;
+ if (*loadAddrExpr == NULL)
+ *loadAddrExpr = cas->addr;
+ if (*dataSize == 0) {
+ CLG_ASSERT(cas->dataLo != NULL);
+ *dataSize = sizeofIRType(typeOfIRExpr(tyenv, cas->dataLo));
+ if (cas->dataHi != NULL)
+ *dataSize *= 2; /* since this is a doubleword-cas */
+ }
+ break;
+ }
+
case Ist_Put:
case Ist_PutI:
case Ist_MBE:
Modified: branches/DCAS/drd/drd_load_store.c
===================================================================
--- branches/DCAS/drd/drd_load_store.c 2009-06-16 06:56:53 UTC (rev 10349)
+++ branches/DCAS/drd/drd_load_store.c 2009-06-18 23:06:01 UTC (rev 10350)
@@ -553,6 +553,26 @@
addStmtToIRSB(bb, st);
break;
+ case Ist_CAS:
+ if (instrument)
+ {
+ /* Just treat this as a read of the location. I believe
+ this is equivalent to the previous logic, which
+ observed bus-lock/unlock Ist_MBEs, and ignored all
+ writes within sections bracketed by bus-lock and
+ bus-unlock annotations. */
+ Int dataSize;
+ IRCAS* cas = st->Ist.CAS.details;
+ tl_assert(cas->addr != NULL);
+ tl_assert(cas->dataLo != NULL);
+ dataSize = sizeofIRType(typeOfIRExpr(bb->tyenv, cas->dataLo));
+ if (cas->dataHi != NULL)
+ dataSize *= 2; /* since it's a doubleword-CAS */
+ instrument_load(bb, cas->addr, dataSize);
+ }
+ addStmtToIRSB(bb, st);
+ break;
+
default:
addStmtToIRSB(bb, st);
break;
Modified: branches/DCAS/exp-ptrcheck/sg_main.c
===================================================================
--- branches/DCAS/exp-ptrcheck/sg_main.c 2009-06-16 06:56:53 UTC (rev 10349)
+++ branches/DCAS/exp-ptrcheck/sg_main.c 2009-06-18 23:06:01 UTC (rev 10350)
@@ -2226,6 +2226,33 @@
break;
}
+ case Ist_CAS: {
+ /* We treat it as a read and a write of the location. I
+ think that is the same behaviour as it was before IRCAS
+ was introduced, since prior to that point, the Vex front
+ ends would translate a lock-prefixed instruction into a
+ (normal) read followed by a (normal) write. */
+ if (env->firstRef) {
+ Int dataSize;
+ IRCAS* cas = st->Ist.CAS.details;
+ tl_assert(cas->addr != NULL);
+ tl_assert(cas->dataLo != NULL);
+ dataSize = sizeofIRType(typeOfIRExpr(sbOut->tyenv, cas->dataLo));
+ if (cas->dataHi != NULL)
+ dataSize *= 2; /* since it's a doubleword-CAS */
+ instrument_mem_access(
+ sbOut, cas->addr, dataSize, False/*!isStore*/,
+ sizeofIRType(hWordTy), env->curr_IP, layout
+ );
+ instrument_mem_access(
+ sbOut, cas->addr, dataSize, True/*isStore*/,
+ sizeofIRType(hWordTy), env->curr_IP, layout
+ );
+ env->firstRef = False;
+ }
+ break;
+ }
+
default:
tl_assert(0);
Modified: branches/DCAS/helgrind/hg_main.c
===================================================================
--- branches/DCAS/helgrind/hg_main.c 2009-06-16 06:56:53 UTC (rev 10349)
+++ branches/DCAS/helgrind/hg_main.c 2009-06-18 23:06:01 UTC (rev 10350)
@@ -3670,14 +3670,13 @@
case Ist_CAS: {
/* Atomic read-modify-write cycle. Just pretend it's a
read. */
- IRCAS* cas = st->Ist.CAS.details;
- /* FIXME: handle DCAS ! */
- if (cas->oldHi != IRTemp_INVALID || cas->expdHi || cas->dataHi)
- goto unhandled;
+ IRCAS* cas = st->Ist.CAS.details;
+ Bool isDCAS = cas->dataHi != NULL;
instrument_mem_access(
bbOut,
cas->addr,
- sizeofIRType(typeOfIRExpr(bbIn->tyenv, cas->dataLo)),
+ (isDCAS ? 2 : 1)
+ * sizeofIRType(typeOfIRExpr(bbIn->tyenv, cas->dataLo)),
False/*!isStore*/,
sizeofIRType(hWordTy)
);
Modified: branches/DCAS/lackey/lk_main.c
===================================================================
--- branches/DCAS/lackey/lk_main.c 2009-06-16 06:56:53 UTC (rev 10349)
+++ branches/DCAS/lackey/lk_main.c 2009-06-18 23:06:01 UTC (rev 10350)
@@ -784,6 +784,27 @@
break;
}
+ case Ist_CAS: {
+ /* We treat it as a read and a write of the location. I
+ think that is the same behaviour as it was before IRCAS
+ was introduced, since prior to that point, the Vex
+ front ends would translate a lock-prefixed instruction
+ into a (normal) read followed by a (normal) write. */
+ if (clo_trace_mem) {
+ Int dataSize;
+ IRCAS* cas = st->Ist.CAS.details;
+ tl_assert(cas->addr != NULL);
+ tl_assert(cas->dataLo != NULL);
+ dataSize = sizeofIRType(typeOfIRExpr(tyenv, cas->dataLo));
+ if (cas->dataHi != NULL)
+ dataSize *= 2; /* since it's a doubleword-CAS */
+ addEvent_Dr( sbOut, cas->addr, dataSize );
+ addEvent_Dw( sbOut, cas->addr, dataSize );
+ }
+ addStmtToIRSB( sbOut, st );
+ break;
+ }
+
case Ist_Exit:
if (clo_basic_counts) {
// The condition of a branch was inverted by VEX if a taken
|