|
From: <sv...@va...> - 2005-10-16 00:17:46
|
Author: njn
Date: 2005-10-16 01:17:37 +0100 (Sun, 16 Oct 2005)
New Revision: 4937
Log:
A small Cachegrind cleanup: previously it was copying some things (eg.
instr_size and instr_addr) into Ir events, then later copying those into
instrInfo nodes. Now it just allocates the instrInfo nodes earlier and
copies them in directly. This is a bit more concise and easier to
understand.
Modified:
trunk/cachegrind/cg_main.c
Modified: trunk/cachegrind/cg_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/cachegrind/cg_main.c 2005-10-15 22:07:28 UTC (rev 4936)
+++ trunk/cachegrind/cg_main.c 2005-10-16 00:17:37 UTC (rev 4937)
@@ -414,10 +414,10 @@
=20
typedef
struct {
- EventKind ekind;
- Int size; /* ALL */
- Addr64 iaddr; /* ALL. For Dr/Dw/Dm is & of parent insn. */
- IRAtom* dataEA; /* Dr/Dw/Dm only */ /* IR ATOM ONLY */
+ EventKind ekind; // All
+ InstrInfo* inode; // All; inode for this event's instructio=
n
+ Int datasize; // Dr/Dw/Dm only
+ IRAtom* dataEA; // Dr/Dw/Dm only; IR ATOM ONLY
}
Event;
=20
@@ -486,32 +486,24 @@
}
=20
=20
-static
-void init_InstrInfo( InstrInfo* n, Addr instr_addr, Int instr_len )
-{
- n->instr_addr =3D instr_addr;
- n->instr_len =3D instr_len;
- n->parent =3D get_lineCC(instr_addr);
-}
-
static void showEvent ( Event* ev )
{
switch (ev->ekind) {
case Event_Ir:=20
- VG_(printf)("Ir %d 0x%llx\n", ev->size, ev->iaddr);
+ VG_(printf)("Ir %p\n", ev->inode);
break;
case Event_Dr:
- VG_(printf)("Dr %d 0x%llx EA=3D", ev->size, ev->iaddr);
+ VG_(printf)("Dr %p %d EA=3D", ev->inode, ev->datasize);
ppIRExpr(ev->dataEA);=20
VG_(printf)("\n");
break;
case Event_Dw:
- VG_(printf)("Dw %d 0x%llx EA=3D", ev->size, ev->iaddr);
+ VG_(printf)("Dw %p %d EA=3D", ev->inode, ev->datasize);
ppIRExpr(ev->dataEA);=20
VG_(printf)("\n");
break;
case Event_Dm:
- VG_(printf)("Dm %d 0x%llx EA=3D", ev->size, ev->iaddr);
+ VG_(printf)("Dm %p %d EA=3D", ev->inode, ev->datasize);
ppIRExpr(ev->dataEA);=20
VG_(printf)("\n");
break;
@@ -521,29 +513,22 @@
}
}
=20
-/* Reserve InstrInfo for the first mention of a new insn. */
-
-static InstrInfo* reserve_InstrInfo ( CgState* cgs )
+// Reserve and initialise an InstrInfo for the first mention of a new in=
sn.
+static
+InstrInfo* setup_InstrInfo ( CgState* cgs, Addr instr_addr, UInt instr_l=
en )
{
InstrInfo* i_node;
tl_assert(cgs->bbInfo_i >=3D 0);
tl_assert(cgs->bbInfo_i < cgs->bbInfo->n_instrs);
i_node =3D &cgs->bbInfo->instrs[ cgs->bbInfo_i ];
+ i_node->instr_addr =3D instr_addr;
+ i_node->instr_len =3D instr_len;
+ i_node->parent =3D get_lineCC(instr_addr);
cgs->bbInfo_i++;
return i_node;
}
=20
=20
-/* Find the most recently allocated InstrInfo. */
-
-static InstrInfo* find_most_recent_InstrInfo ( CgState* cgs )
-{
- tl_assert(cgs->bbInfo_i >=3D 0);
- tl_assert(cgs->bbInfo_i <=3D cgs->bbInfo->n_instrs);
- return &cgs->bbInfo->instrs[ cgs->bbInfo_i - 1 ];
-}
-
-
/* Generate code for all outstanding memory events, and mark the queue
empty. Code is generated into cgs->bbOut, and this activity
'consumes' slots in cgs->bbInfo. */
@@ -555,12 +540,7 @@
void* helperAddr;
IRExpr** argv;
IRExpr* i_node_expr;
- IRExpr* i_node2_expr;
- IRExpr* i_node3_expr;
IRDirty* di;
- InstrInfo* i_node;
- InstrInfo* i_node2;
- InstrInfo* i_node3;
Event* ev;
Event* ev2;
Event* ev3;
@@ -586,53 +566,32 @@
showEvent( ev );
}
=20
- /* For any event we find the relevant InstrInfo. The following
- assumes that Event_Ir is the first event to refer to any
- specific insn, and so a new entry in the cgs->bbInfo->instrs
- is allocated. All other events (Dr,Dw,Dm) must refer to the
- most recently encountered IMark and so we use the
- most-recently allocated instrs[] entry, which must exist. */
+ i_node_expr =3D mkIRExpr_HWord( (HWord)ev->inode );
=20
- if (ev->ekind =3D=3D Event_Ir) {
- /* allocate an InstrInfo and fill in its addr/size. */
- i_node =3D reserve_InstrInfo( cgs );
- init_InstrInfo( i_node,
- (Addr)ev->iaddr, /* i addr */
- ev->size /* i size */);
- } else {
- /* use the most-recently allocated i_node but don't mess with
- its internals */
- i_node =3D find_most_recent_InstrInfo( cgs );
- /* it must match the declared parent instruction of this event.=
*/
- tl_assert(i_node->instr_addr =3D=3D ev->iaddr);
- }
-
- i_node_expr =3D mkIRExpr_HWord( (HWord)i_node );
-
/* Decide on helper fn to call and args to pass it, and advance
i appropriately. */
switch (ev->ekind) {
case Event_Ir:
/* Merge with a following Dr/Dm if it is from this insn. */
if (ev2 && (ev2->ekind =3D=3D Event_Dr || ev2->ekind =3D=3D =
Event_Dm)) {
- tl_assert(ev2->iaddr =3D=3D ev->iaddr);
+ tl_assert(ev2->inode =3D=3D ev->inode);
helperName =3D "log_1I_1Dr_cache_access";
helperAddr =3D &log_1I_1Dr_cache_access;
argv =3D mkIRExprVec_3( i_node_expr,
ev2->dataEA,
- mkIRExpr_HWord( ev2->size ) );
+ mkIRExpr_HWord( ev2->datasize ) );
regparms =3D 3;
i +=3D 2;
}
/* Merge with a following Dw if it is from this insn. */
else
if (ev2 && ev2->ekind =3D=3D Event_Dw) {
- tl_assert(ev2->iaddr =3D=3D ev->iaddr);
+ tl_assert(ev2->inode =3D=3D ev->inode);
helperName =3D "log_1I_1Dw_cache_access";
helperAddr =3D &log_1I_1Dw_cache_access;
argv =3D mkIRExprVec_3( i_node_expr,
ev2->dataEA,
- mkIRExpr_HWord( ev2->size ) );
+ mkIRExpr_HWord( ev2->datasize ) );
regparms =3D 3;
i +=3D 2;
}
@@ -642,20 +601,9 @@
{
helperName =3D "log_3I_0D_cache_access";
helperAddr =3D &log_3I_0D_cache_access;
-
- i_node2 =3D reserve_InstrInfo( cgs );
- init_InstrInfo( i_node2,
- (Addr)ev2->iaddr, /* i addr */
- ev2->size /* i size */);
- i_node2_expr =3D mkIRExpr_HWord( (HWord)i_node2 );
-
- i_node3 =3D reserve_InstrInfo( cgs );
- init_InstrInfo( i_node3,
- (Addr)ev3->iaddr, /* i addr */
- ev3->size /* i size */);
- i_node3_expr =3D mkIRExpr_HWord( (HWord)i_node3 );
-
- argv =3D mkIRExprVec_3( i_node_expr, i_node2_expr, i_node=
3_expr );
+ argv =3D mkIRExprVec_3( i_node_expr,=20
+ mkIRExpr_HWord( (HWord)ev2->inode )=
,=20
+ mkIRExpr_HWord( (HWord)ev3->inode )=
);
regparms =3D 3;
i +=3D 3;
}
@@ -664,14 +612,8 @@
if (ev2 && ev2->ekind =3D=3D Event_Ir) {
helperName =3D "log_2I_0D_cache_access";
helperAddr =3D &log_2I_0D_cache_access;
-
- i_node2 =3D reserve_InstrInfo( cgs );
- init_InstrInfo( i_node2,
- (Addr)ev2->iaddr, /* i addr */
- ev2->size /* i size */);
-
- i_node2_expr =3D mkIRExpr_HWord( (HWord)i_node2 );
- argv =3D mkIRExprVec_2( i_node_expr, i_node2_expr );
+ argv =3D mkIRExprVec_2( i_node_expr,
+ mkIRExpr_HWord( (HWord)ev2->inode )=
);
regparms =3D 2;
i +=3D 2;
}
@@ -694,7 +636,7 @@
helperAddr =3D &log_0I_1Dr_cache_access;
argv =3D mkIRExprVec_3( i_node_expr,=20
ev->dataEA,=20
- mkIRExpr_HWord( ev->size ) );
+ mkIRExpr_HWord( ev->datasize ) );
regparms =3D 3;
i++;
break;
@@ -703,7 +645,7 @@
helperAddr =3D &log_0I_1Dw_cache_access;
argv =3D mkIRExprVec_3( i_node_expr,
ev->dataEA,=20
- mkIRExpr_HWord( ev->size ) );
+ mkIRExpr_HWord( ev->datasize ) );
regparms =3D 3;
i++;
break;
@@ -722,56 +664,55 @@
cgs->events_used =3D 0;
}
=20
-
-static void addEvent_Ir ( CgState* cgs, Int size, Addr64 iaddr )
+static void addEvent_Ir ( CgState* cgs, InstrInfo* inode )
{
Event* evt;
- tl_assert(size >=3D 0 && size <=3D MIN_LINE_SIZE);
if (cgs->events_used =3D=3D N_EVENTS)
flushEvents(cgs);
tl_assert(cgs->events_used >=3D 0 && cgs->events_used < N_EVENTS);
- /* If vex fails to decode an insn, the size will be zero, but that
- can't really be true -- the cpu couldn't have determined the
- insn was undecodable without looking at it. Hence: */
- if (size =3D=3D 0)
- size =3D 1;
evt =3D &cgs->events[cgs->events_used];
- evt->ekind =3D Event_Ir;
- evt->size =3D size;
- evt->iaddr =3D iaddr;
- evt->dataEA =3D NULL; /*paranoia*/
+ evt->ekind =3D Event_Ir;
+ evt->inode =3D inode;
+ evt->datasize =3D 0;
+ evt->dataEA =3D NULL; /*paranoia*/
cgs->events_used++;
}
=20
-static void addEvent_Dr ( CgState* cgs, Int size, Addr64 iaddr, IRAtom* =
ea )
+static
+void addEvent_Dr ( CgState* cgs, InstrInfo* inode, Int datasize, IRAtom*=
ea )
{
Event* evt;
tl_assert(isIRAtom(ea));
- tl_assert(size >=3D 1 && size <=3D MIN_LINE_SIZE);
+ tl_assert(datasize >=3D 1 && datasize <=3D MIN_LINE_SIZE);
if (cgs->events_used =3D=3D N_EVENTS)
flushEvents(cgs);
tl_assert(cgs->events_used >=3D 0 && cgs->events_used < N_EVENTS);
evt =3D &cgs->events[cgs->events_used];
- evt->ekind =3D Event_Dr;
- evt->size =3D size;
- evt->iaddr =3D iaddr;
- evt->dataEA =3D ea;
+ evt->ekind =3D Event_Dr;
+ evt->inode =3D inode;
+ evt->datasize =3D datasize;
+ evt->dataEA =3D ea;
cgs->events_used++;
}
=20
-static void addEvent_Dw ( CgState* cgs, Int size, Addr64 iaddr, IRAtom* =
ea )
+static
+void addEvent_Dw ( CgState* cgs, InstrInfo* inode, Int datasize, IRAtom*=
ea )
{
+ Event* lastEvt;
+ Event* evt;
+
tl_assert(isIRAtom(ea));
- tl_assert(size >=3D 1 && size <=3D MIN_LINE_SIZE);
+ tl_assert(datasize >=3D 1 && datasize <=3D MIN_LINE_SIZE);
=20
- /* Is it possible to merge this write into an immediately preceding
- read? */
+ /* Is it possible to merge this write with the preceding read? */
+ lastEvt =3D &cgs->events[cgs->events_used-1];
if (cgs->events_used > 0
- && cgs->events[cgs->events_used-1].ekind =3D=3D Event_Dr
- && cgs->events[cgs->events_used-1].size =3D=3D size
- && cgs->events[cgs->events_used-1].iaddr =3D=3D iaddr
- && eqIRAtom(cgs->events[cgs->events_used-1].dataEA, ea)) {
- cgs->events[cgs->events_used-1].ekind =3D Event_Dm;
+ && lastEvt->ekind =3D=3D Event_Dr
+ && lastEvt->datasize =3D=3D datasize
+ && lastEvt->inode =3D=3D inode
+ && eqIRAtom(lastEvt->dataEA, ea))
+ {
+ lastEvt->ekind =3D Event_Dm;
return;
}
=20
@@ -779,10 +720,11 @@
if (cgs->events_used =3D=3D N_EVENTS)
flushEvents(cgs);
tl_assert(cgs->events_used >=3D 0 && cgs->events_used < N_EVENTS);
- cgs->events[cgs->events_used].ekind =3D Event_Dw;
- cgs->events[cgs->events_used].size =3D size;
- cgs->events[cgs->events_used].iaddr =3D iaddr;
- cgs->events[cgs->events_used].dataEA =3D ea;
+ evt =3D &cgs->events[cgs->events_used];
+ evt->ekind =3D Event_Dw;
+ evt->inode =3D inode;
+ evt->datasize =3D datasize;
+ evt->dataEA =3D ea;
cgs->events_used++;
}
=20
@@ -792,11 +734,12 @@
static IRBB* cg_instrument ( IRBB* bbIn, VexGuestLayout* layout,=20
IRType gWordTy, IRType hWordTy )
{
- Int i;
+ Int i, isize;
IRStmt* st;
Addr64 cia; /* address of current insn */
CgState cgs;
IRTypeEnv* tyenv =3D bbIn->tyenv;
+ InstrInfo* curr_inode =3D NULL;
=20
=20
if (gWordTy !=3D hWordTy) {
@@ -804,9 +747,12 @@
VG_(tool_panic)("host/guest word size mismatch");
}
=20
- /* Set up BB */
- cgs.bbOut =3D emptyIRBB();
- cgs.bbOut->tyenv =3D dopyIRTypeEnv(tyenv);
+ /* Set up BB, including copying of the where-next stuff. */
+ cgs.bbOut =3D emptyIRBB();
+ cgs.bbOut->tyenv =3D dopyIRTypeEnv(tyenv);
+ tl_assert( isIRAtom(bbIn->next) );
+ cgs.bbOut->next =3D dopyIRExpr(bbIn->next);
+ cgs.bbOut->jumpkind =3D bbIn->jumpkind;
=20
// Get the first statement, and initial cia from it
i =3D 0;
@@ -823,7 +769,8 @@
if (DEBUG_CG)
VG_(printf)("\n\n---------- cg_instrument ----------\n");
=20
- // Traverse the block, adding events and flushing as necessary.
+ // Traverse the block, initialising inodes, adding events and flushin=
g as
+ // necessary.
for (i =3D 0; i < bbIn->stmts_used; i++) {
=20
st =3D bbIn->stmts[i];
@@ -838,19 +785,32 @@
break;
=20
case Ist_IMark:
- cia =3D st->Ist.IMark.addr;
- addEvent_Ir( &cgs, st->Ist.IMark.len, cia );
+ cia =3D st->Ist.IMark.addr;
+ isize =3D st->Ist.IMark.len;
+
+ // If Vex fails to decode an instruction, the size will be z=
ero.
+ // Pretend otherwise.
+ if (isize =3D=3D 0) isize =3D VG_MIN_INSTR_SZB;
+
+ // Check size. XXX: broken for client requests!
+ tl_assert(VG_MIN_INSTR_SZB <=3D isize && isize <=3D VG_MAX_I=
NSTR_SZB);
+
+ // Get space for and init the inode, record it as the curren=
t one.
+ // Subsequent Dr/Dw/Dm events from the same instruction will=
=20
+ // also use it.
+ curr_inode =3D setup_InstrInfo(&cgs, cia, isize);
+
+ addEvent_Ir( &cgs, curr_inode );
break;
=20
case Ist_Tmp: {
IRExpr* data =3D st->Ist.Tmp.data;
if (data->tag =3D=3D Iex_Load) {
IRExpr* aexpr =3D data->Iex.Load.addr;
- tl_assert( isIRAtom(aexpr) );
// Note also, endianness info is ignored. I guess
// that's not interesting.
- addEvent_Dr( &cgs, sizeofIRType(data->Iex.Load.ty),=20
- cia, aexpr );
+ addEvent_Dr( &cgs, curr_inode, sizeofIRType(data->Iex.Loa=
d.ty),=20
+ aexpr );
}
break;
}
@@ -858,10 +818,8 @@
case Ist_Store: {
IRExpr* data =3D st->Ist.Store.data;
IRExpr* aexpr =3D st->Ist.Store.addr;
- tl_assert( isIRAtom(aexpr) );
- addEvent_Dw( &cgs,=20
- sizeofIRType(typeOfIRExpr(tyenv, data)),=20
- cia, aexpr );
+ addEvent_Dw( &cgs, curr_inode,=20
+ sizeofIRType(typeOfIRExpr(tyenv, data)), aexpr =
);
break;
}
=20
@@ -869,8 +827,7 @@
Int dataSize;
IRDirty* d =3D st->Ist.Dirty.details;
if (d->mFx !=3D Ifx_None) {
- /* This dirty helper accesses memory. Collect the
- details. */
+ /* This dirty helper accesses memory. Collect the detail=
s. */
tl_assert(d->mAddr !=3D NULL);
tl_assert(d->mSize !=3D 0);
dataSize =3D d->mSize;
@@ -881,9 +838,9 @@
if (dataSize > MIN_LINE_SIZE)
dataSize =3D MIN_LINE_SIZE;
if (d->mFx =3D=3D Ifx_Read || d->mFx =3D=3D Ifx_Modify)
- addEvent_Dr( &cgs, dataSize, cia, d->mAddr );
+ addEvent_Dr( &cgs, curr_inode, dataSize, d->mAddr );
if (d->mFx =3D=3D Ifx_Write || d->mFx =3D=3D Ifx_Modify)
- addEvent_Dw( &cgs, dataSize, cia, d->mAddr );
+ addEvent_Dw( &cgs, curr_inode, dataSize, d->mAddr );
} else {
tl_assert(d->mAddr =3D=3D NULL);
tl_assert(d->mSize =3D=3D 0);
@@ -912,13 +869,8 @@
}
=20
/* At the end of the bb. Flush outstandings. */
- tl_assert(isIRAtom(bbIn->next));
flushEvents( &cgs );
=20
- /* copy where-next stuff. */
- cgs.bbOut->next =3D dopyIRExpr(bbIn->next);
- cgs.bbOut->jumpkind =3D bbIn->jumpkind;
-
/* done. stay sane ... */
tl_assert(cgs.bbInfo_i =3D=3D cgs.bbInfo->n_instrs);
=20
|