|
From: David G. <dav...@gm...> - 2011-07-12 05:41:08
|
Hi! I'm currently trying to develop a simple profiling tool on top of
callgrind. I've created a structure that contains information about
every executed block and its memory accesses. To do that, every time
the function callgrind/bbcc.c/CLG_(setup_bbcc) is called I add a new
block to that structure and then go through every statement of that
block and:
add an address to the read list of that block every time I get an
Ist_WrTmp statement;
and add an address to the write list of that block every time I get
an Ist_Store statement:
for (/*use current i*/; i < sbInCalc->stmts_used; i++) {
st = sbInCalc->stmts[i];
VG_(printf)("\n");
ppIRStmt(st);
switch (st->tag) {
..........
case Ist_WrTmp: {
IRExpr* data = st->Ist.WrTmp.data;
if (data->tag == Iex_Load) {
IRExpr* aexpr = data->Iex.Load.addr;
addRead(aexpr);
VG_(printf)("____Ist_WrTmp/Iex_Load -> addRead()\n");
}
break;
}
case Ist_Store: {
IRExpr* aexpr = st->Ist.Store.addr;
addWrite(aexpr);
VG_(printf)("____Ist_Store -> addWrite()\n");
break;
}
......
default:
break;
}
The problem is that most of the time, the addresses I get are from
temporaries (ex: t25) which is undesirable:
------ IMark(0x1000016A8, 1) ------
t0 = GET:I64(40)
t21 = GET:I64(32)
t20 = Sub64(t21,0x8:I64)
PUT(32) = t20
STle(t20) = t0____Ist_Store -> addWrite()
------ IMark(0x1000016A9, 3) ------
PUT(40) = t20
------ IMark(0x1000016AC, 4) ------
PUT(168) = 0x1000016AC:I64
t23 = Add64(t20,0xFFFFFFFFFFFFFFE8:I64)
t25 = GET:I64(56)
STle(t23) = t25____Ist_Store -> addWrite()
------ IMark(0x1000016B0, 4) ------
PUT(168) = 0x1000016B0:I64
t26 = Add64(t20,0xFFFFFFFFFFFFFFE8:I64)
t28 = LDle:I64(t26)____Ist_WrTmp/Iex_Load -> addRead()
Sometimes the addresses are like I want them to be:
------ IMark(0x100001647, 3) ------
PUT(40) = t12
------ IMark(0x10000164A, 7) ------
------ IMark(0x100001651, 2) ------
PUT(168) = 0x100001651:I64
t16 = LDle:I32(0x100002090:I64)____Ist_WrTmp/Iex_Load -> addRead()
Is there any way I can get the address stored at those temporaries?
Thank you very much!
|
|
From: Julian S. <js...@ac...> - 2011-07-12 06:00:04
|
> Is there any way I can get the address stored at those temporaries? Sounds like you're confusing the concepts of JIT-time and run-time. JIT-time is one-time instrumentation of each block, immediately before it is used, and is what you're doing in the code fragment you posted. Run-time is when the instrumented block is run, and can happen any number of times. The addresses in "those temporaries" aren't known until run time, but you are looking at the code at JIT time. What you need to do in your instrumentation routine is insert calls to helper functions (which you'll also need to write) passing to them, the values of the temporaries in which you're interested. Then the helpers will see the actual values. There are undoubtedly examples already in the Callgrind instrumentation function of adding calls to helper functions, if only because Callgrind's cache simulators need to look at each load and store address. Look out for IRDirty and IRStmt_Dirty in the code. J |
|
From: Josef W. <Jos...@gm...> - 2011-07-12 08:52:54
|
On Tuesday 12 July 2011, David Granchinho wrote: > Hi! I'm currently trying to develop a simple profiling tool on top of > callgrind. I've created a structure that contains information about > every executed block and its memory accesses. To do that, every time > the function callgrind/bbcc.c/CLG_(setup_bbcc) is called I add a new > block to that structure and then go through every statement of that > block There must be something wrong here. CLG_(setup_bbcc) is a function which is instrumented to be called at run time whenever a BB is to be executed. If you added code to that function, you can not have access to the statements as you cited. Josef |
|
From: David G. <dav...@gm...> - 2011-07-12 19:51:13
|
Yes. I'm sorry for not explaining it correctly:
During CLG_(instrument) I store sbIn in a global variable which I then
access in runtime on CLG_(setup_bbcc). Something like this:
CLG_(instrument) {
.....
sbInAct = deepCopyIRSB(sbIn); //Actualizes sbInAct
clgs.bb->id = CLG_(stat).bb_executions + 1;
addBBSetupCall(&clgs);
....
}
On CLG_(setup_bbcc) I first check to see if the block has already been
translated/instrumented with a trick not worth mentioning (I compare
the CLG_(stat).bb_executions with bb->id). If it is the first time the
block is executed (thus translated) I check sbInAct and go through its
statements like I said before. So I'm accessing a structure which has
JIT-time information, even though I'm accessing it on run-time right?
What I would like to know is if there is any way for me to access the
real addresses (so that I can later check for data dependencies
between blocks).
|
|
From: David G. <dav...@gm...> - 2011-07-12 19:52:11
|
Yes. I'm sorry for not explaining it correctly:
During CLG_(instrument) I store sbIn in a global variable which I then
access in runtime on CLG_(setup_bbcc). Something like this:
CLG_(instrument) {
.....
sbInAct = deepCopyIRSB(sbIn); //Actualizes sbInAct
clgs.bb->id = CLG_(stat).bb_executions + 1;
addBBSetupCall(&clgs);
....
}
On CLG_(setup_bbcc) I first check to see if the block has already been
translated/instrumented with a trick not worth mentioning (I compare
the CLG_(stat).bb_executions with bb->id). If it is the first time the
block is executed (thus translated) I check sbInAct and go through its
statements like I said before. So I'm accessing a structure which has
JIT-time information, even though I'm accessing it on run-time right?
What I would like to know is if there is any way for me to access the
real addresses (so that I can later check for data dependencies
between blocks).
|
|
From: David G. <dav...@gm...> - 2011-07-13 18:17:44
|
Yes, thank you so much for the help. lackey seems to be the answer! 2011/7/13 Julian Seward <js...@ac...>: > > I think JosefW provided a better followup on the mailing list, yes? > > J > > On Tuesday, July 12, 2011, you wrote: >> Hi! First of all, thank you for the quick response! But I'm afraid it >> wasn't of much help as I am not familiar with helper functions (C) and >> valgrind/callgrinds code is quite complex. I know that setup_bbcc is a >> helper function called by addBBSetupCall, but it is run at JIT-time. >> How can I set calls to helper functions and then have them run at >> run-time? Can you give me an example from callgrind? >> >> Once again, thank you very much! >> >> 2011/7/12 Julian Seward <js...@ac...>: >> >> Is there any way I can get the address stored at those temporaries? >> > >> > Sounds like you're confusing the concepts of JIT-time and run-time. >> > JIT-time is one-time instrumentation of each block, immediately before it >> > is used, and is what you're doing in the code fragment you posted. >> > Run-time is when the instrumented block is run, and can happen any >> > number of times. >> > >> > The addresses in "those temporaries" aren't known until run time, but >> > you are looking at the code at JIT time. What you need to do in your >> > instrumentation routine is insert calls to helper functions (which >> > you'll also need to write) passing to them, the values of the temporaries >> > in which you're interested. Then the helpers will see the actual >> > values. >> > >> > There are undoubtedly examples already in the Callgrind instrumentation >> > function of adding calls to helper functions, if only because Callgrind's >> > cache simulators need to look at each load and store address. Look out >> > for IRDirty and IRStmt_Dirty in the code. >> > >> > J > > |