From: Julian Seward Date: Thu, 27 Dec 2012 12:02:15 +0000 (+0000) Subject: Teach Callgrind about IRLoadG and IRStoreG. X-Git-Tag: svn/VALGRIND_3_9_0~445^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8f2fb5b514383b4df515c8a81b3f8a84ff78968;p=thirdparty%2Fvalgrind.git Teach Callgrind about IRLoadG and IRStoreG. git-svn-id: svn://svn.valgrind.org/valgrind/branches/COMEM@13206 --- diff --git a/callgrind/main.c b/callgrind/main.c index c15e6c29be..fa29084b03 100644 --- a/callgrind/main.c +++ b/callgrind/main.c @@ -668,6 +668,50 @@ void addEvent_Dw ( ClgState* clgs, InstrInfo* inode, Int datasize, IRAtom* ea ) clgs->events_used++; } +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 ) { @@ -912,13 +956,13 @@ IRSB* CLG_(instrument)( VgCallbackClosure* closure, 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. */ @@ -1022,6 +1066,31 @@ IRSB* CLG_(instrument)( VgCallbackClosure* closure, 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; diff --git a/callgrind/sim.c b/callgrind/sim.c index 3ce0890038..4d3fcc1d7e 100644 --- a/callgrind/sim.c +++ b/callgrind/sim.c @@ -1189,6 +1189,9 @@ static void log_1I1Dr(InstrInfo* ii, Addr data_addr, Word data_size) } +/* 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 @@ static void log_1I1Dw(InstrInfo* ii, Addr data_addr, Word data_size) } } +/* See comment on log_0I1Dr. */ VG_REGPARM(3) static void log_0I1Dw(InstrInfo* ii, Addr data_addr, Word data_size) {