16 #include <unordered_set>
18 #include <unordered_map>
28 #define PAGE_OFFSET_BITS (16LL)
29 #define PAGE_OFFSET(addr) (addr & 0xFFFF)
30 #define PAGE_OFFSET_MASK (0xFFFF)
33 #define PAGE_SIZE (1 << PAGE_OFFSET_BITS)
36 #define PTR_SIZE (sizeof(void*))
37 #define LEVEL_1_PAGE_TABLE_BITS (20)
38 #define LEVEL_1_PAGE_TABLE_ENTRIES (1 << LEVEL_1_PAGE_TABLE_BITS)
39 #define LEVEL_1_PAGE_TABLE_SIZE (LEVEL_1_PAGE_TABLE_ENTRIES * PTR_SIZE)
41 #define LEVEL_2_PAGE_TABLE_BITS (12)
42 #define LEVEL_2_PAGE_TABLE_ENTRIES (1 << LEVEL_2_PAGE_TABLE_BITS)
43 #define LEVEL_2_PAGE_TABLE_SIZE (LEVEL_2_PAGE_TABLE_ENTRIES * PTR_SIZE)
45 #define LEVEL_1_PAGE_TABLE_SLOT(addr) (((addr) >> (LEVEL_2_PAGE_TABLE_BITS + PAGE_OFFSET_BITS)) & 0xfffff)
46 #define LEVEL_2_PAGE_TABLE_SLOT(addr) (((addr) >> (PAGE_OFFSET_BITS)) & 0xFFF)
50 #define READ_ACTION (0)
51 #define WRITE_ACTION (0xff)
53 #define ONE_BYTE_READ_ACTION (0)
54 #define TWO_BYTE_READ_ACTION (0)
55 #define FOUR_BYTE_READ_ACTION (0)
56 #define EIGHT_BYTE_READ_ACTION (0)
58 #define ONE_BYTE_WRITE_ACTION (0xff)
59 #define TWO_BYTE_WRITE_ACTION (0xffff)
60 #define FOUR_BYTE_WRITE_ACTION (0xffffffff)
61 #define EIGHT_BYTE_WRITE_ACTION (0xffffffffffffffff)
65 #define MAX_FOOTPRINT_CONTEXTS_TO_LOG (1000)
66 #define THREAD_MAX (1024)
68 #define ENCODE_ADDRESS_AND_ACCESS_LEN(addr, len) ((addr) | (((uint64_t)(len)) << 48))
69 #define DECODE_ADDRESS(addrAndLen) ((addrAndLen) & ((1L << 48) - 1))
70 #define DECODE_ACCESS_LEN(addrAndLen) ((addrAndLen) >> 48)
89 static std::unordered_map<uint32_t, struct RawMetric_t>*
hmap_vector;
92 template <
int start,
int end,
int incr>
94 static inline void Body(
const function<
void(
const int)>& func) {
100 template <
int end,
int incr>
102 static inline void Body(
const function<
void(
const int)>& func) {
107 template <
int start,
int end,
int incr>
109 static inline bool Body(
const function<
bool(
const int)>& func) {
114 template <
int end,
int incr>
116 static inline bool Body(
const function<
void(
const int)>& func) {
122 PIN_ERROR(
"Pin tool to gather calling context on each load and store.\n" + KNOB_BASE::StringKnobSummary() +
"\n");
134 char* envPath = getenv(
"CCTLIB_CLIENT_OUTPUT_FILE");
138 snprintf(name,
sizeof(name),
"%s", envPath);
141 gethostname(name + strlen(name),
MAX_FILE_PATH - strlen(name));
142 pid_t pid = getpid();
143 sprintf(name + strlen(name),
"%d", pid);
144 cerr <<
"\n Creating log file at:" << name <<
"\n";
149 for (
int i = 0; i < argc; i++) {
162 if (*l1Ptr ==
nullptr) {
172 uint32_t lineNo1, lineNo2;
173 string filePath1, filePath2;
176 PIN_GetSourceLocation(prevAddr,
nullptr, (INT32*)&lineNo1, &filePath1);
177 PIN_GetSourceLocation(curAddr,
nullptr, (INT32*)&lineNo2, &filePath2);
180 return static_cast<bool>((filePath1 == filePath2) && (lineNo1 <= lineNo2));
184 static VOID
MemFunc(THREADID
id,
void*
address,
bool rwFlag, UINT32 refSize) {
185 uint64_t addr = (uint64_t)
address;
189 void **metricPtr = GetIPNodeMetric(
id, 0);
192 if (*metricPtr == NULL) {
198 metric->addressSet.insert(encodedAddrAndLen);
199 metric->accessNum+=refSize;
202 uint64_t *prevAddr = (uint64_t *)(
status +
PAGE_OFFSET(addr) *
sizeof(uint64_t));
205 if (!rwFlag && (*prevFlag))
206 metric->dependentNum+=refSize;
217 void** metricPtr = GetIPNodeMetric(threadId, 0);
220 if (*metricPtr ==
nullptr) {
226 metric->addressSet.insert(encodedAddrAndLen);
227 metric->accessNum += accessLen;
238 return (prevIp < curIp);
244 ADDRINT* __restrict__ prevIP = (ADDRINT*)(
status +
PAGE_OFFSET((uint64_t)addr) *
sizeof(ADDRINT));
251 ADDRINT* __restrict__ prevIP = (ADDRINT*)(
status +
PAGE_OFFSET((uint64_t)addr) *
sizeof(ADDRINT));
254 metric->forwardDependence += 1;
256 metric->backwardsDependence += 1;
259 template <u
int16_t AccessLen>
261 static inline VOID
RecordNByteMemRead(
void* addr, uint32_t opaqueHandle, ADDRINT insPtr, THREADID threadId) {
265 ADDRINT* __restrict__ prevIP = (ADDRINT*)(
status +
PAGE_OFFSET((uint64_t)addr) *
sizeof(ADDRINT));
272 metric->forwardDependence += AccessLen;
274 metric->backwardsDependence += AccessLen;
279 metric->forwardDependence += AccessLen;
281 metric->backwardsDependence += AccessLen;
286 metric->forwardDependence += AccessLen;
288 metric->backwardsDependence += AccessLen;
293 static inline VOID
RecordNByteMemWrite(
void* addr, uint32_t opaqueHandle, ADDRINT insPtr, THREADID threadId) {
298 ADDRINT* __restrict__ prevIP = (ADDRINT*)(
status +
PAGE_OFFSET((uint64_t)addr) *
sizeof(ADDRINT));
310 static inline VOID
RecordLargeMemRead(
void* addr, UINT32 accessLen, uint32_t opaqueHandle, ADDRINT insPtr, THREADID threadId) {
313 for (UINT32 i = 0; i < accessLen; i++)
317 static inline VOID
RecordLargeMemWrite(
void* addr, UINT32 accessLen, uint32_t opaqueHandle, ADDRINT insPtr, THREADID threadId) {
320 for (UINT32 i = 0; i < accessLen; i++)
324 #define HANDLE_CASE(NUM) \
326 if (INS_MemoryOperandIsRead(ins, memOp)) { \
327 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)MemAnalysis<(NUM)>::RecordNByteMemRead, IARG_MEMORYOP_EA, memOp, IARG_UINT32, opaqueHandle, IARG_INST_PTR, IARG_THREAD_ID, IARG_END); \
329 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)MemAnalysis<(NUM)>::RecordNByteMemWrite, IARG_MEMORYOP_EA, memOp, IARG_UINT32, opaqueHandle, IARG_INST_PTR, IARG_THREAD_ID, IARG_END); \
335 if (!INS_IsMemoryRead(ins) && !INS_IsMemoryWrite(ins))
337 if (INS_IsStackRead(ins) || INS_IsStackWrite(ins))
339 if (INS_IsControlFlow(ins) || INS_IsRet(ins))
341 UINT32 memOperands = INS_MemoryOperandCount(ins);
343 for (UINT32 memOp = 0; memOp < memOperands; memOp++) {
344 UINT32 refSize = INS_MemoryOperandSize(ins, memOp);
355 if (INS_MemoryOperandIsRead(ins, memOp)) {
356 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)
RecordLargeMemRead, IARG_MEMORYOP_EA, memOp, IARG_MEMORYREAD_SIZE, IARG_UINT32, opaqueHandle, IARG_INST_PTR, IARG_THREAD_ID, IARG_END);
359 if (INS_MemoryOperandIsWritten(ins, memOp)) {
360 INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)
RecordLargeMemWrite, IARG_MEMORYOP_EA, memOp, IARG_MEMORYWRITE_SIZE,
361 IARG_UINT32, opaqueHandle, IARG_INST_PTR,
362 IARG_THREAD_ID, IARG_END);
370 if (*myMetric ==
nullptr)
373 unordered_set<uint64_t>::iterator it;
377 assert(refSize != 0);
378 for (
unsigned int i = 0; i < refSize; i++) {
386 if (*myMetric ==
nullptr)
390 if (*parentMetric ==
nullptr) {
391 *parentMetric = &((
hmap_vector[threadid])[parentHandle]);
411 uint64_t cntxtNum = 0;
412 vector<struct AnalyzedMetric_t> TmpList;
414 fprintf(
gTraceFile,
"*************** Dump Data from Thread %d ****************\n", threadid);
415 unordered_map<uint32_t, struct RawMetric_t>& hmap =
hmap_vector[threadid];
416 unordered_map<uint32_t, struct RawMetric_t>::iterator it;
417 for (it = hmap.begin(); it != hmap.end(); ++it) {
420 tmp.
footprint = (uint64_t)(*it).second.addressSetDecoded.size();
421 tmp.
accessNum = (uint64_t)(*it).second.accessNum;
424 TmpList.emplace_back(tmp);
427 vector<struct AnalyzedMetric_t>::iterator ListIt;
428 for (ListIt = TmpList.begin(); ListIt != TmpList.end(); ++ListIt) {
430 fprintf(
gTraceFile,
"Footprint is %lu, #reuse is %ld, fwd dependence is %lu, carried dependence is %lu context is:", ((*ListIt).footprint), (*ListIt).accessNum - (*ListIt).footprint, (*ListIt).forwardDependence, (*ListIt).backwardsDependence);
432 fprintf(
gTraceFile,
"\n------------------------------------------------\n");
440 static VOID
ThreadFiniFunc(THREADID threadid,
const CONTEXT* ctxt, INT32 code, VOID* v) {
457 int main(
int argc,
char* argv[]) {
459 if (PIN_Init(argc, argv))
472 PIN_AddFiniFunction(
FiniFunc,
nullptr);
#define INTERESTING_INS_MEMORY_ACCESS
int PinCCTLibInit(IsInterestingInsFptr isInterestingIns, FILE *logFile, CCTLibInstrumentInsCallback userCallback, VOID *userCallbackArg, BOOL doDataCentric=false)
VOID PrintFullCallingContext(const ContextHandle_t ctxtHandle)
ContextHandle_t GetContextHandle(const THREADID id, const uint32_t slot)
uint64_t backwardsDependence
uint64_t forwardDependence
static VOID RecordNByteMemWrite(void *addr, uint32_t opaqueHandle, ADDRINT insPtr, THREADID threadId)
static VOID RecordNByteMemRead(void *addr, uint32_t opaqueHandle, ADDRINT insPtr, THREADID threadId)
uint64_t backwardsDependence
uint64_t forwardDependence
unordered_set< uint64_t > addressSetDecoded
unordered_set< uint64_t > addressSet
static bool Body(const function< void(const int)> &func)
static bool Body(const function< bool(const int)> &func)
static void Body(const function< void(const int)> &func)
static void Body(const function< void(const int)> &func)