|
From: <sv...@va...> - 2012-12-27 12:02:28
|
sewardj 2012-12-27 12:02:15 +0000 (Thu, 27 Dec 2012)
New Revision: 13206
Log:
Teach Callgrind about IRLoadG and IRStoreG.
Modified files:
branches/COMEM/callgrind/main.c
branches/COMEM/callgrind/sim.c
Modified: branches/COMEM/callgrind/sim.c (+4 -0)
===================================================================
--- branches/COMEM/callgrind/sim.c 2012-12-27 03:00:49 +00:00 (rev 13205)
+++ branches/COMEM/callgrind/sim.c 2012-12-27 12:02:15 +00:00 (rev 13206)
@@ -1189,6 +1189,9 @@
}
+/* Note that addEvent_D_guarded assumes that log_0I1Dr and log_0I1Dw
+ have exactly the same prototype. If you change them, you must
+ change addEvent_D_guarded too. */
VG_REGPARM(3)
static void log_0I1Dr(InstrInfo* ii, Addr data_addr, Word data_size)
{
@@ -1248,6 +1251,7 @@
}
}
+/* See comment on log_0I1Dr. */
VG_REGPARM(3)
static void log_0I1Dw(InstrInfo* ii, Addr data_addr, Word data_size)
{
Modified: branches/COMEM/callgrind/main.c (+75 -6)
===================================================================
--- branches/COMEM/callgrind/main.c 2012-12-27 03:00:49 +00:00 (rev 13205)
+++ branches/COMEM/callgrind/main.c 2012-12-27 12:02:15 +00:00 (rev 13206)
@@ -669,6 +669,50 @@
}
static
+void addEvent_D_guarded ( ClgState* clgs, InstrInfo* inode,
+ Int datasize, IRAtom* ea, IRAtom* guard,
+ Bool isWrite )
+{
+ tl_assert(isIRAtom(ea));
+ tl_assert(guard);
+ tl_assert(isIRAtom(guard));
+ tl_assert(datasize >= 1);
+ if (!CLG_(clo).simulate_cache) return;
+ tl_assert(datasize <= CLG_(min_line_size));
+
+ /* Adding guarded memory actions and merging them with the existing
+ queue is too complex. Simply flush the queue and add this
+ action immediately. Since guarded loads and stores are pretty
+ rare, this is not thought likely to cause any noticeable
+ performance loss as a result of the loss of event-merging
+ opportunities. */
+ tl_assert(clgs->events_used >= 0);
+ flushEvents(clgs);
+ tl_assert(clgs->events_used == 0);
+ /* Same as case Ev_Dw / case Ev_Dr in flushEvents, except with guard */
+ IRExpr* i_node_expr;
+ const HChar* helperName;
+ void* helperAddr;
+ IRExpr** argv;
+ Int regparms;
+ IRDirty* di;
+ i_node_expr = mkIRExpr_HWord( (HWord)inode );
+ helperName = isWrite ? CLG_(cachesim).log_0I1Dw_name
+ : CLG_(cachesim).log_0I1Dr_name;
+ helperAddr = isWrite ? CLG_(cachesim).log_0I1Dw
+ : CLG_(cachesim).log_0I1Dr;
+ argv = mkIRExprVec_3( i_node_expr,
+ ea, mkIRExpr_HWord( datasize ) );
+ regparms = 3;
+ di = unsafeIRDirty_0_N(
+ regparms,
+ helperName, VG_(fnptr_to_fnentry)( helperAddr ),
+ argv );
+ di->guard = guard;
+ addStmtToIRSB( clgs->sbOut, IRStmt_Dirty(di) );
+}
+
+static
void addEvent_Bc ( ClgState* clgs, InstrInfo* inode, IRAtom* guard )
{
Event* evt;
@@ -912,14 +956,14 @@
VexArchInfo* archinfo_host,
IRType gWordTy, IRType hWordTy )
{
- Int i;
- IRStmt* st;
- Addr origAddr;
+ Int i;
+ IRStmt* st;
+ Addr origAddr;
InstrInfo* curr_inode = NULL;
- ClgState clgs;
- UInt cJumps = 0;
+ ClgState clgs;
+ UInt cJumps = 0;
+ IRTypeEnv* tyenv = sbIn->tyenv;
-
if (gWordTy != hWordTy) {
/* We don't currently support this case. */
VG_(tool_panic)("host/guest word size mismatch");
@@ -1022,6 +1066,31 @@
break;
}
+ case Ist_StoreG: {
+ IRStoreG* sg = st->Ist.StoreG.details;
+ IRExpr* data = sg->data;
+ IRExpr* addr = sg->addr;
+ IRType type = typeOfIRExpr(tyenv, data);
+ tl_assert(type != Ity_INVALID);
+ addEvent_D_guarded( &clgs, curr_inode,
+ sizeofIRType(type), addr, sg->guard,
+ True/*isWrite*/ );
+ 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);
+ addEvent_D_guarded( &clgs, curr_inode,
+ sizeofIRType(type), addr, lg->guard,
+ False/*!isWrite*/ );
+ break;
+ }
+
case Ist_Dirty: {
Int dataSize;
IRDirty* d = st->Ist.Dirty.details;
|