From 2c64c808abf5d0f570c698d2730523e18a613951 Mon Sep 17 00:00:00 2001 From: Milind Date: Tue, 12 Jul 2016 21:32:05 -0700 Subject: [PATCH 01/18] Simplified the redspy temporal client --- tests/redspy_temporal_client.cpp | 105 +++++++++++++++---------------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index 82140d4..5d9153d 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -112,16 +112,20 @@ using namespace PinCCTLib; #define MAX_ALIAS_TYPE (3) //(RAX, EAX, AX),(AH),(AL) //different register group -#define ALIAS_REG_A (0) //RAX, EAX, AX, AH, or AL -#define ALIAS_REG_B (1) -#define ALIAS_REG_C (2) -#define ALIAS_REG_D (3) +enum AliasReg { + ALIAS_REG_A = 0, //RAX, EAX, AX, AH, or AL + ALIAS_REG_B, + ALIAS_REG_C, + ALIAS_REG_D}; //alias type, generic, high byte or low byte -#define ALIAS_GENERIC (0) // RAX, EAX, or AX -#define ALIAS_HIGH_BYTE (1) //AH -#define ALIAS_LOW_BYTE (2) // AL -#define ALIAS_HIGH_LOW (3) + +enum AliasGroup{ + ALIAS_GENERIC=0, // RAX, EAX, or AX + ALIAS_HIGH_BYTE, //AH + ALIAS_LOW_BYTE, // AL + ALIAS_HIGH_LOW // What is this? +}; #if __BYTE_ORDER == __LITTLE_ENDIAN //alias begin bytes for different types @@ -307,37 +311,36 @@ static ADDRINT IfEnableSample(THREADID threadId){ /* register analysis */ /*********************************************************************************/ -template +template struct HandleAliasRegisters{ - static __attribute__((always_inline)) void CheckUpdateGenericAlias(uint8_t regId, uint8_t byteOffset, T value, uint32_t opaqueHandle, THREADID threadId) { + static __attribute__((always_inline)) void CheckUpdateGenericAlias(uint8_t regId, T value, uint32_t opaqueHandle, THREADID threadId) { RedSpyThreadData* const tData = ClientGetTLS(threadId); ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - T * where = (T *)(&tData->aliasValue[regId][byteOffset]); - - if (*where == value) { - AddToRedTable(MAKE_CONTEXT_PAIR(tData->aliasCtxt[regId][ALIAS_GENERIC],curCtxtHandle),sizeof(T),threadId); - }else - * where = value; - tData->aliasCtxt[regId][ALIAS_GENERIC] = curCtxtHandle; - tData->aliasCtxt[regId][ALIAS_HIGH_BYTE] = curCtxtHandle; - tData->aliasCtxt[regId][ALIAS_LOW_BYTE] = curCtxtHandle; - } - static __attribute__((always_inline)) void CheckUpdateHighLowAlias(uint8_t regId, uint8_t byteOffset, uint8_t regType, T value, uint32_t opaqueHandle, THREADID threadId) { - - RedSpyThreadData* const tData = ClientGetTLS(threadId); - ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); + //alias begin bytes for different types + #if __BYTE_ORDER == __LITTLE_ENDIAN + uint8_t byteOffset = aliasGroup == ALIAS_HIGH_BYTE ? 1 : 0; + #else + #error "unknown endianness" + #endif + T * where = (T *)(&tData->aliasValue[regId][byteOffset]); if (*where == value) { - AddToRedTable(MAKE_CONTEXT_PAIR(tData->aliasCtxt[regId][regType],curCtxtHandle),sizeof(T),threadId); - }else - * where = value; + AddToRedTable(MAKE_CONTEXT_PAIR(tData->aliasCtxt[regId][aliasGroup], curCtxtHandle), sizeof(T), threadId); + }else { + *where = value; + } tData->aliasCtxt[regId][ALIAS_GENERIC] = curCtxtHandle; - tData->aliasCtxt[regId][regType] = curCtxtHandle; + if(aliasGroup == ALIAS_GENERIC){ + tData->aliasCtxt[regId][ALIAS_HIGH_BYTE] = curCtxtHandle; + tData->aliasCtxt[regId][ALIAS_LOW_BYTE] = curCtxtHandle; + } else { + tData->aliasCtxt[regId][aliasGroup] = curCtxtHandle; + } } }; @@ -380,6 +383,12 @@ static inline VOID CheckLargeRegAfterWrite(PIN_REGISTER* regRef, REG reg, uint3 tData->regCtxt[reg] = curCtxtHandle; } +static inline bool IsLowByteAliasReg(REG reg){ + if(reg == REG_AL || reg == REG_BL || reg == REG_CL || reg == REG_DL) + return true; + return false; +} + static inline uint32_t GetAliasIDs(REG reg){ uint8_t regGroup = 0; uint8_t byteInd = 0; @@ -447,28 +456,20 @@ inline bool RegHasAlias(REG reg){ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckLargeRegAfterWrite, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) -#define HANDLE_ALIAS_GENERIC(T, ID, OFFSET) \ -INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END); \ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID, IARG_UINT32, OFFSET, IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) - -#define HANDLE_ALIAS_HIGHLOW(ID, OFFSET, TYPE) \ +#define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END); \ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateHighLowAlias, IARG_UINT32, ID, IARG_UINT32, OFFSET, IARG_UINT32, TYPE, IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID, IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) #define HANDLE_GENERAL(T) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END); \ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) - #else #define HANDLE_LARGEREG() \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckLargeRegAfterWrite, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) -#define HANDLE_ALIAS_GENERIC(T, ID, OFFSET) \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID, IARG_UINT32, OFFSET, IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) - -#define HANDLE_ALIAS_HIGHLOW(ID, OFFSET, TYPE) \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateHighLowAlias, IARG_UINT32, ID, IARG_UINT32, OFFSET, IARG_UINT32, TYPE, IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) +#define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID,IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) #define HANDLE_GENERAL(T) \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) @@ -479,15 +480,16 @@ static inline void InstrumentAliasReg(INS ins, REG reg, uint32_t opaqueHandle){ uint32_t aliasIDs = GetAliasIDs(reg); uint8_t regId = static_cast(((aliasIDs) & 0x00ffffff) >> 16 ); - uint8_t byteOffset = static_cast(((aliasIDs) & 0x0000ffff) >> 8 ); - uint8_t type; switch (REG_Size(reg)) { - case 8: HANDLE_ALIAS_GENERIC(uint64_t, regId, byteOffset); break; - case 4: HANDLE_ALIAS_GENERIC(uint32_t, regId, byteOffset); break; - case 2: HANDLE_ALIAS_GENERIC(uint16_t, regId, byteOffset); break; - case 1: type = static_cast((aliasIDs) & 0x000000ff); - HANDLE_ALIAS_HIGHLOW(regId, byteOffset,type); break; + case 8: HANDLE_ALIAS_REG(uint64_t, ALIAS_GENERIC, regId); break; + case 4: HANDLE_ALIAS_REG(uint32_t, ALIAS_GENERIC, regId); break; + case 2: HANDLE_ALIAS_REG(uint16_t, ALIAS_GENERIC, regId); break; + case 1: if (IsLowByteAliasReg(reg)) + HANDLE_ALIAS_REG(uint8_t, ALIAS_LOW_BYTE, regId); + else + HANDLE_ALIAS_REG(uint8_t, ALIAS_HIGH_BYTE, regId); + break; default: break; } } @@ -834,14 +836,7 @@ static VOID InstrumentInsCallback(INS ins, VOID* v, const uint32_t opaqueHandle) continue; if (RegHasAlias(reg)) { - switch (reg) { - case REG_RAX: HANDLE_ALIAS_GENERIC(uint64_t, ALIAS_REG_A, ALIAS_BYTES_INDEX_64); break; - case REG_EAX: HANDLE_ALIAS_GENERIC(uint32_t, ALIAS_REG_A, ALIAS_BYTES_INDEX_32); break; - case REG_EBX: HANDLE_ALIAS_GENERIC(uint32_t, ALIAS_REG_B, ALIAS_BYTES_INDEX_32); break; - case REG_ECX: HANDLE_ALIAS_GENERIC(uint32_t, ALIAS_REG_C, ALIAS_BYTES_INDEX_32); break; - case REG_EDX: HANDLE_ALIAS_GENERIC(uint32_t, ALIAS_REG_D, ALIAS_BYTES_INDEX_32); break; - default: InstrumentAliasReg(ins, reg , opaqueHandle); break; - } + InstrumentAliasReg(ins, reg , opaqueHandle); }else{ InstrumentGeneralReg(ins, reg, opaqueHandle); } From 57043f2098a2ccb03ff1ab9504840ebe23fd0d2e Mon Sep 17 00:00:00 2001 From: Milind Date: Thu, 14 Jul 2016 00:00:31 -0700 Subject: [PATCH 02/18] Replaced handwritten lower byte register with REG_is_Lower8 and handwritten flags register check with REG_is_flags --- tests/redspy_temporal_client.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index 5d9153d..cf0125b 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -383,12 +383,6 @@ static inline VOID CheckLargeRegAfterWrite(PIN_REGISTER* regRef, REG reg, uint3 tData->regCtxt[reg] = curCtxtHandle; } -static inline bool IsLowByteAliasReg(REG reg){ - if(reg == REG_AL || reg == REG_BL || reg == REG_CL || reg == REG_DL) - return true; - return false; -} - static inline uint32_t GetAliasIDs(REG reg){ uint8_t regGroup = 0; uint8_t byteInd = 0; @@ -485,7 +479,7 @@ static inline void InstrumentAliasReg(INS ins, REG reg, uint32_t opaqueHandle){ case 8: HANDLE_ALIAS_REG(uint64_t, ALIAS_GENERIC, regId); break; case 4: HANDLE_ALIAS_REG(uint32_t, ALIAS_GENERIC, regId); break; case 2: HANDLE_ALIAS_REG(uint16_t, ALIAS_GENERIC, regId); break; - case 1: if (IsLowByteAliasReg(reg)) + case 1: if (REG_is_Lower8(reg)) HANDLE_ALIAS_REG(uint8_t, ALIAS_LOW_BYTE, regId); else HANDLE_ALIAS_REG(uint8_t, ALIAS_HIGH_BYTE, regId); @@ -766,7 +760,7 @@ static inline bool REG_IsIgnorable(REG reg){ return true; else if(reg == REG_MXCSR) return true; - else if(reg == REG_GFLAGS || reg == REG_FLAGS) + else if(REG_is_flags(reg)) return true; else if(reg == REG_ST0) return true; From d2029c0d1e3677657e4133d5d572a69dfec0a994 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Mon, 18 Jul 2016 19:48:23 -0400 Subject: [PATCH 03/18] fixing the bytes counting when sampling --- tests/redspy_temporal_client.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index cf0125b..71cb916 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -844,7 +844,7 @@ static VOID InstrumentInsCallback(INS ins, VOID* v, const uint32_t opaqueHandle) inline VOID UpdateAndCheck(uint32_t count, uint32_t bytes, THREADID threadId) { RedSpyThreadData* const tData = ClientGetTLS(threadId); - tData->bytesWritten += bytes; + if(tData->sampleFlag){ tData->numIns += count; if(tData->numIns > WINDOW_ENABLE){ @@ -859,12 +859,17 @@ inline VOID UpdateAndCheck(uint32_t count, uint32_t bytes, THREADID threadId) { tData->numIns = 0; } } + if (tData->sampleFlag) { + tData->bytesWritten += bytes; + } } inline VOID Update(uint32_t count, uint32_t bytes, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); tData->numIns += count; - tData->bytesWritten += bytes; + if (tData->sampleFlag) { + tData->bytesWritten += bytes; + } } //instrument the trace, count the number of ins in the trace, decide to instrument or not From cbd31ccce6f5d6c9936eb20deb1db7fdd5883901 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Mon, 18 Jul 2016 20:42:14 -0400 Subject: [PATCH 04/18] merging temporal client with memory writes approximation --- tests/redspy_temporal_client.cpp | 272 +++++++++++++++++++++++++------ 1 file changed, 224 insertions(+), 48 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index 71cb916..27b89e0 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -50,6 +50,11 @@ #include #include "pin.H" #include "cctlib.H" +extern "C" { +#include "xed-interface.h" +#include "xed-common-hdrs.h" +} + using namespace std; using namespace PinCCTLib; @@ -111,6 +116,13 @@ using namespace PinCCTLib; #define MAX_ALIAS_REG_SIZE (8) //RAX is 64bits #define MAX_ALIAS_TYPE (3) //(RAX, EAX, AX),(AH),(AL) +//different redundant type +enum RedType { + RED_PRECISION = 0, + RED_FLOAT, + RED_DOUBLE +}; + //different register group enum AliasReg { ALIAS_REG_A = 0, //RAX, EAX, AX, AH, or AL @@ -154,7 +166,7 @@ enum AliasGroup{ #ifdef ENABLE_SAMPLING #define WINDOW_ENABLE 1000000 -#define WINDOW_DISABLE 1000000000 +#define WINDOW_DISABLE 10000000 #define WINDOW_CLEAN 10 #endif @@ -164,6 +176,8 @@ enum AliasGroup{ #define MAKE_CONTEXT_PAIR(a, b) (((uint64_t)(a) << 32) | ((uint64_t)(b))) +#define delta 0.01 + struct AddrValPair{ void * address; @@ -252,6 +266,8 @@ static const uint64_t WRITE_ACCESS_STATES [] = {/*0 byte */0, /*1 byte */ ONE_BY static const uint8_t OVERFLOW_CHECK [] = {/*0 byte */0, /*1 byte */ 0, /*2 byte */ 0, /*3 byte */ 1, /*4 byte */ 2, /*5 byte */3, /*6 byte */4, /*7 byte */5, /*8 byte */ 6}; static unordered_map RedMap[THREAD_MAX]; +static unordered_map ApproxRedMap[THREAD_MAX]; + static inline void AddToRedTable(uint64_t key, uint16_t value, THREADID threadId) { #ifdef MULTI_THREADED LOCK_RED_MAP(); @@ -267,6 +283,22 @@ static inline void AddToRedTable(uint64_t key, uint16_t value, THREADID threadI #endif } +static inline void AddToApproximateRedTable(uint64_t key, uint16_t value, THREADID threadId) { +#ifdef MULTI_THREADED + LOCK_RED_MAP(); +#endif + unordered_map::iterator it = ApproxRedMap[threadId].find(key); + if ( it == ApproxRedMap[threadId].end()) { + ApproxRedMap[threadId][key] = value; + } else { + it->second += value; + } +#ifdef MULTI_THREADED + UNLOCK_RED_MAP(); +#endif +} + + #ifdef ENABLE_SAMPLING static inline VOID EmptyCtxt(RedSpyThreadData* tData){ @@ -307,6 +339,25 @@ static ADDRINT IfEnableSample(THREADID threadId){ #endif +static inline bool IsFloatInstruction(ADDRINT ip) { + xed_decoded_inst_t xedd; + xed_state_t xed_state; + xed_decoded_inst_zero_set_mode(&xedd, &xed_state); + + if(XED_ERROR_NONE == xed_decode(&xedd, (const xed_uint8_t*)(ip), 15)) { + unsigned int NumOperands = xed_decoded_inst_noperands(&xedd); + for(unsigned int i = 0; i < NumOperands; ++i){ + xed_operand_element_type_enum_t TypeOperand = xed_decoded_inst_operand_element_type(&xedd,i); + if(TypeOperand == XED_OPERAND_ELEMENT_TYPE_SINGLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_DOUBLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_FLOAT16 || TypeOperand == XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE) + return true; + } + return false; + } else { + assert(0 && "failed to disassemble instruction"); + return false; + } +} + /*********************************************************************************/ /* register analysis */ /*********************************************************************************/ @@ -479,11 +530,11 @@ static inline void InstrumentAliasReg(INS ins, REG reg, uint32_t opaqueHandle){ case 8: HANDLE_ALIAS_REG(uint64_t, ALIAS_GENERIC, regId); break; case 4: HANDLE_ALIAS_REG(uint32_t, ALIAS_GENERIC, regId); break; case 2: HANDLE_ALIAS_REG(uint16_t, ALIAS_GENERIC, regId); break; - case 1: if (REG_is_Lower8(reg)) + case 1: if (REG_is_Lower8(reg)){ HANDLE_ALIAS_REG(uint8_t, ALIAS_LOW_BYTE, regId); - else + }else{ HANDLE_ALIAS_REG(uint8_t, ALIAS_HIGH_BYTE, regId); - break; + }break; default: break; } } @@ -505,11 +556,11 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint32_t opaqueHandle) /*********************** memory temporal redundancy functions **************************/ /***************************************************************************************/ -template +template struct UnrolledLoop{ static __attribute__((always_inline)) void Body(function func){ func(start); // Real loop body - UnrolledLoop:: Body(func); // unroll next iteration + UnrolledLoop:: Body(func); // unroll next iteration } static __attribute__((always_inline)) void BodySamePage(ContextHandle_t * __restrict__ prevIP, const ContextHandle_t handle, THREADID threadId){ if(conditional) { @@ -518,7 +569,7 @@ struct UnrolledLoop{ } // Update context prevIP[start] = handle; - UnrolledLoop:: BodySamePage(prevIP, handle, threadId); // unroll next iteration + UnrolledLoop:: BodySamePage(prevIP, handle, threadId); // unroll next iteration } static __attribute__((always_inline)) void BodyStraddlePage(uint64_t addr, const ContextHandle_t handle, THREADID threadId){ uint8_t * status = GetOrCreateShadowBaseAddress((uint64_t)addr + start); @@ -529,12 +580,12 @@ struct UnrolledLoop{ } // Update context prevIP[0] = handle; - UnrolledLoop:: BodyStraddlePage(addr, handle, threadId); // unroll next iteration + UnrolledLoop:: BodyStraddlePage(addr, handle, threadId); // unroll next iteration } }; -template -struct UnrolledLoop{ +template +struct UnrolledLoop{ static __attribute__((always_inline)) void Body(function func){} static __attribute__((always_inline)) void BodySamePage(ContextHandle_t * __restrict__ prevIP, const ContextHandle_t handle, THREADID threadId){} static __attribute__((always_inline)) void BodyStraddlePage(uint64_t addr, const ContextHandle_t handle, THREADID threadId){} @@ -561,18 +612,38 @@ struct UnrolledConjunction{ }; -template +template struct RedSpyAnalysis{ static __attribute__((always_inline)) bool IsWriteRedundant(void * &addr, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); AddrValPair * avPair = & tData->buffer[bufferOffset]; addr = avPair->address; - switch(AccessLen){ - case 1: return *((uint8_t*)(&avPair->value)) == *(static_cast(avPair->address)); - case 2: return *((uint16_t*)(&avPair->value)) == *(static_cast(avPair->address)); - case 4: return *((uint32_t*)(&avPair->value)) == *(static_cast(avPair->address)); - case 8: return *((uint64_t*)(&avPair->value)) == *(static_cast(avPair->address)); - default: return memcmp(&avPair->value, avPair->address, AccessLen) == 0; + + if(redType == RED_FLOAT){ + float newValue32 = *(static_cast(avPair->address)); + float oldValue32 = *((float*)(&avPair->value)); + + float rate32 = (newValue32 - oldValue32)/oldValue32; + *((float*)(&avPair->value)) = newValue32; + if( rate32 <= delta && rate32 >= -delta ) return true; + else return false; + + }else if(redType == RED_DOUBLE){ + double newValue64 = *(static_cast(avPair->address)); + double oldValue64 = *((double*)(&avPair->value)); + + double rate64 = (newValue64 - oldValue64)/oldValue64; + *((double*)(&avPair->value)) = newValue64; + if( rate64 <= delta && rate64 >= -delta ) return true; + else return false; + }else{ + switch(AccessLen){ + case 1: return *((uint8_t*)(&avPair->value)) == *(static_cast(avPair->address)); + case 2: return *((uint16_t*)(&avPair->value)) == *(static_cast(avPair->address)); + case 4: return *((uint32_t*)(&avPair->value)) == *(static_cast(avPair->address)); + case 8: return *((uint64_t*)(&avPair->value)) == *(static_cast(avPair->address)); + default: return memcmp(&avPair->value, avPair->address, AccessLen) == 0; + } } } @@ -583,12 +654,20 @@ struct RedSpyAnalysis{ AddrValPair * avPair = & tData->buffer[bufferOffset]; avPair->address = addr; - switch(AccessLen){ - case 1: *((uint8_t*)(&avPair->value)) = *(static_cast(addr)); break; - case 2: *((uint16_t*)(&avPair->value)) = *(static_cast(addr)); break; - case 4: *((uint32_t*)(&avPair->value)) = *(static_cast(addr)); break; - case 8: *((uint64_t*)(&avPair->value)) = *(static_cast(addr)); break; - default:memcpy(&avPair->value, addr, AccessLen); + + switch(redType){ + case RED_FLOAT: *((float*)(&avPair->value)) = *(static_cast(addr)); break; + case RED_DOUBLE: *((double*)(&avPair->value)) = *(static_cast(addr)); break; + case RED_PRECISION: + switch(AccessLen){ + case 1: *((uint8_t*)(&avPair->value)) = *(static_cast(addr)); break; + case 2: *((uint16_t*)(&avPair->value)) = *(static_cast(addr)); break; + case 4: *((uint32_t*)(&avPair->value)) = *(static_cast(addr)); break; + case 8: *((uint64_t*)(&avPair->value)) = *(static_cast(addr)); break; + default: memcpy(&avPair->value, addr, AccessLen); + } + break; + default: memcpy(&avPair->value, addr, AccessLen); break; } } @@ -608,37 +687,46 @@ struct RedSpyAnalysis{ // All from same ctxt? if (UnrolledConjunction<0, AccessLen, 1>::BodyContextCheck(prevIP)) { // report in RedTable - AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), AccessLen, threadId); + switch(redType){ + case RED_FLOAT: + case RED_DOUBLE: AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), AccessLen, threadId);break; + case RED_PRECISION: AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), AccessLen, threadId);break; + default: break; + } // Update context - UnrolledLoop<0, AccessLen, 1, false /* redundancy is updated outside*/>::BodySamePage(prevIP, curCtxtHandle, threadId); + UnrolledLoop<0, AccessLen, 1, false, /* redundancy is updated outside*/ redType>::BodySamePage(prevIP, curCtxtHandle, threadId); } else { // different contexts - UnrolledLoop<0, AccessLen, 1, true /* redundancy is updated inside*/>::BodySamePage(prevIP, curCtxtHandle, threadId); + UnrolledLoop<0, AccessLen, 1, true, /* redundancy is updated inside*/ redType>::BodySamePage(prevIP, curCtxtHandle, threadId); } } else { // Write across a 64-K page boundary // First byte is on this page though - AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), 1, threadId); + switch(redType){ + case RED_FLOAT: + case RED_DOUBLE: AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), 1, threadId);break; + case RED_PRECISION: AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), 1, threadId);break; + default: break; + } // Update context prevIP[0] = curCtxtHandle; // Remaining bytes [1..AccessLen] somewhere will across a 64-K page boundary - UnrolledLoop<1, AccessLen, 1, true /* update redundancy */>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); + UnrolledLoop<1, AccessLen, 1, true, /* update redundancy */ redType>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); } } else { // No redundancy. // Just update contexts if(isAccessWithinPageBoundary) { // Update context - UnrolledLoop<0, AccessLen, 1, false /* not redundant*/>::BodySamePage(prevIP, curCtxtHandle, threadId); + UnrolledLoop<0, AccessLen, 1, false, /* not redundant*/ redType>::BodySamePage(prevIP, curCtxtHandle, threadId); } else { // Write across a 64-K page boundary // Update context prevIP[0] = curCtxtHandle; // Remaining bytes [1..AccessLen] somewhere will across a 64-K page boundary - UnrolledLoop<1, AccessLen, 1, false /* dont update redundancy */>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); - + UnrolledLoop<1, AccessLen, 1, false, /* not redundant*/ redType>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); } } } @@ -683,11 +771,11 @@ static inline VOID CheckAfterLargeWrite(UINT32 accessLen, uint32_t bufferOffset #ifdef ENABLE_SAMPLING -#define HANDLE_CASE(NUM, BUFFER_INDEX) \ +#define HANDLE_CASE(NUM, BUFFER_INDEX, RED_TYPE) \ case (NUM):{INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX)>::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ +INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX)>::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END);}break +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END);}break #define HANDLE_LARGE() \ INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ @@ -697,9 +785,9 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckAfterLargeWrite, #else -#define HANDLE_CASE(NUM, BUFFER_INDEX) \ -case (NUM):{INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX)>::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX)>::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END);}break +#define HANDLE_CASE(NUM, BUFFER_INDEX, RED_TYPE) \ +case (NUM):{INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END);}break #define HANDLE_LARGE() \ INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RecordValueBeforeLargeWrite, IARG_MEMORYOP_EA, memOp, IARG_MEMORYWRITE_SIZE, IARG_UINT32, readBufferSlotIndex, IARG_THREAD_ID, IARG_END);\ @@ -724,16 +812,30 @@ template struct RedSpyInstrument{ static __attribute__((always_inline)) void InstrumentReadValueBeforeAndAfterWriting(INS ins, UINT32 memOp, uint32_t opaqueHandle){ UINT32 refSize = INS_MemoryOperandSize(ins, memOp); - switch(refSize) { - HANDLE_CASE(1, readBufferSlotIndex); - HANDLE_CASE(2, readBufferSlotIndex); - HANDLE_CASE(4, readBufferSlotIndex); - HANDLE_CASE(8, readBufferSlotIndex); - HANDLE_CASE(10, readBufferSlotIndex); - HANDLE_CASE(16, readBufferSlotIndex); - - default: { - HANDLE_LARGE(); + + if (IsFloatInstruction(INS_Address(ins))) { + switch(refSize) { + HANDLE_CASE(1, readBufferSlotIndex, RED_FLOAT); + HANDLE_CASE(2, readBufferSlotIndex, RED_FLOAT); + HANDLE_CASE(4, readBufferSlotIndex, RED_FLOAT); + HANDLE_CASE(8, readBufferSlotIndex, RED_DOUBLE); + + default: { + HANDLE_LARGE(); + } + } + }else{ + switch(refSize) { + HANDLE_CASE(1, readBufferSlotIndex, RED_PRECISION); + HANDLE_CASE(2, readBufferSlotIndex, RED_PRECISION); + HANDLE_CASE(4, readBufferSlotIndex, RED_PRECISION); + HANDLE_CASE(8, readBufferSlotIndex, RED_PRECISION); + HANDLE_CASE(10, readBufferSlotIndex, RED_PRECISION); + HANDLE_CASE(16, readBufferSlotIndex, RED_PRECISION); + + default: { + HANDLE_LARGE(); + } } } } @@ -844,7 +946,7 @@ static VOID InstrumentInsCallback(INS ins, VOID* v, const uint32_t opaqueHandle) inline VOID UpdateAndCheck(uint32_t count, uint32_t bytes, THREADID threadId) { RedSpyThreadData* const tData = ClientGetTLS(threadId); - + if(tData->sampleFlag){ tData->numIns += count; if(tData->numIns > WINDOW_ENABLE){ @@ -1040,6 +1142,78 @@ static void PrintRedundancyPairs(THREADID threadId) { } } +static void PrintApproximationRedundancyPairs(THREADID threadId) { + vector tmpList; + vector::iterator tmpIt; + + uint64_t grandTotalRedundantBytes = 0; + uint64_t grandTotalRedundantIns = 0; + fprintf(gTraceFile, "*************** Dump Data(delta=%.2f%%) from Thread %d ****************\n", delta*100,threadId); + +#ifdef MERGING + for (unordered_map::iterator it = ApproxRedMap[threadId].begin(); it != ApproxRedMap[threadId].end(); ++it) { + ContextHandle_t dead = DECODE_DEAD((*it).first); + ContextHandle_t kill = DECODE_KILL((*it).first); + + for(tmpIt = tmpList.begin();tmpIt != tmpList.end(); ++tmpIt){ + if(dead == 0 || ((*tmpIt).dead) == 0){ + continue; + } + if (!HaveSameCallerPrefix(dead,(*tmpIt).dead)) { + continue; + } + if (!HaveSameCallerPrefix(kill,(*tmpIt).kill)) { + continue; + } + bool ct1 = IsSameSourceLine(dead,(*tmpIt).dead); + bool ct2 = IsSameSourceLine(kill,(*tmpIt).kill); + if(ct1 && ct2){ + (*tmpIt).frequency += (*it).second; + grandTotalRedundantBytes += (*it).second; + grandTotalRedundantIns += 1; + break; + } + } + if(tmpIt == tmpList.end()){ + RedundacyData tmp = { dead, kill, (*it).second}; + tmpList.push_back(tmp); + grandTotalRedundantBytes += tmp.frequency; + grandTotalRedundantIns += 1; + } + } +#else + for (unordered_map::iterator it = ApproxRedMap[threadId].begin(); it != ApproxRedMap[threadId].end(); ++it) { + RedundacyData tmp = { DECODE_DEAD ((*it).first), DECODE_KILL((*it).first), (*it).second}; + tmpList.push_back(tmp); + grandTotalRedundantBytes += tmp.frequency; + grandTotalRedundantIns += 1; + } +#endif + + fprintf(gTraceFile, "\n Total redundant bytes = %f %%\n", grandTotalRedundantBytes * 100.0 / ClientGetTLS(threadId)->bytesWritten); + fprintf(gTraceFile, "\n Total redundant instructions = %f %%\n", grandTotalRedundantIns * 100.0 / ClientGetTLS(threadId)->numIns); + + sort(tmpList.begin(), tmpList.end(), RedundacyCompare); + vector::iterator listIt; + int cntxtNum = 0; + for (vector::iterator listIt = tmpList.begin(); listIt != tmpList.end(); ++listIt) { + if (cntxtNum < MAX_REDUNDANT_CONTEXTS_TO_LOG) { + fprintf(gTraceFile, "\n======= (%f) %% ======\n", (*listIt).frequency * 100.0 / grandTotalRedundantBytes); + if ((*listIt).dead == 0) { + fprintf(gTraceFile, "\n Prepopulated with by OS\n"); + } else { + PrintFullCallingContext((*listIt).dead); + } + fprintf(gTraceFile, "\n---------------------Redundantly written by---------------------------\n"); + PrintFullCallingContext((*listIt).kill); + } + else { + break; + } + cntxtNum++; + } +} + // On each Unload of a loaded image, the accummulated redundancy information is dumped static VOID ImageUnload(IMG img, VOID* v) { fprintf(gTraceFile, "\n TODO .. Multi-threading is not well supported."); @@ -1048,9 +1222,11 @@ static VOID ImageUnload(IMG img, VOID* v) { // Update gTotalInstCount first PIN_LockClient(); PrintRedundancyPairs(threadid); + PrintApproximationRedundancyPairs(threadid); PIN_UnlockClient(); // clear redmap now RedMap[threadid].clear(); + ApproxRedMap[threadid].clear(); } static VOID ThreadFiniFunc(THREADID threadid, const CONTEXT *ctxt, INT32 code, VOID *v) { From 2f1fa383a8378f25932dd3388a3a604cb47aaf16 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Tue, 19 Jul 2016 20:14:11 -0400 Subject: [PATCH 05/18] merging register approximation handling, fixing mm7 register handling error, fixing index issue in large register handling --- tests/redspy_temporal_client.cpp | 123 ++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 19 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index 27b89e0..861f4d9 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -413,15 +413,63 @@ struct HandleGeneralRegisters{ } }; +template +struct HandleApproxRegisters{ + + static __attribute__((always_inline)) void CheckValues(PIN_REGISTER* regRef, uint32_t reg, uint32_t opaqueHandle, THREADID threadId){ + + RedSpyThreadData* const tData = ClientGetTLS(threadId); + + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); + + if(isAlias){ + uint8_t byteOffset = 0; + + T newValue; + if(sizeof(T) == 8) + newValue = regRef->dbl[0]; + else + newValue = regRef->flt[0]; + + T oldValue = *((T*)(&tData->aliasValue[reg][byteOffset])); + T rate = (newValue - oldValue)/oldValue; + if( rate <= delta && rate >= -delta ){ + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->aliasCtxt[reg][ALIAS_GENERIC],curCtxtHandle),sizeof(T),threadId); + } + if( newValue != oldValue) + *((T*)(&tData->aliasValue[reg][byteOffset])) = newValue; + + tData->aliasCtxt[reg][ALIAS_GENERIC] = curCtxtHandle; + tData->aliasCtxt[reg][ALIAS_HIGH_BYTE] = curCtxtHandle; + tData->aliasCtxt[reg][ALIAS_LOW_BYTE] = curCtxtHandle; + + }else{ + T newValue; + if(sizeof(T) == 8) + newValue = regRef->dbl[0]; + else + newValue = regRef->flt[0]; + + T oldValue = *((T*)(&tData->regValue[reg][0])); + if(newValue == oldValue && tData->regCtxt[reg]!=0) { + AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),sizeof(T),threadId); + } + if(newValue != oldValue) + *((T*)(&tData->regValue[reg][0])) = newValue; + tData->regCtxt[reg] = curCtxtHandle; + } + } +}; + static inline VOID CheckLargeRegAfterWrite(PIN_REGISTER* regRef, REG reg, uint32_t regSize, uint32_t opaqueHandle, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - int i; + uint16_t i; bool isRedundantWrite = true; - for(i = 0; i < 16; ++i){ + for(i = 0; i < regSize; ++i){ if(tData->regValue[reg][i] != regRef->byte[i]){ isRedundantWrite = false; tData->regValue[reg][i] = regRef->byte[i]; @@ -508,6 +556,11 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) + +#define HANDLE_APPROXREG(T, IS_ALIAS, REG_ID) \ +INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) + #else #define HANDLE_LARGEREG() \ @@ -519,35 +572,67 @@ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) +#define HANDLE_APPROXREG(T, IS_ALIAS, REG_ID) \ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) + #endif static inline void InstrumentAliasReg(INS ins, REG reg, uint32_t opaqueHandle){ + uint32_t regSize = REG_Size(reg); uint32_t aliasIDs = GetAliasIDs(reg); uint8_t regId = static_cast(((aliasIDs) & 0x00ffffff) >> 16 ); - switch (REG_Size(reg)) { - case 8: HANDLE_ALIAS_REG(uint64_t, ALIAS_GENERIC, regId); break; - case 4: HANDLE_ALIAS_REG(uint32_t, ALIAS_GENERIC, regId); break; - case 2: HANDLE_ALIAS_REG(uint16_t, ALIAS_GENERIC, regId); break; - case 1: if (REG_is_Lower8(reg)){ - HANDLE_ALIAS_REG(uint8_t, ALIAS_LOW_BYTE, regId); - }else{ - HANDLE_ALIAS_REG(uint8_t, ALIAS_HIGH_BYTE, regId); - }break; - default: break; + if (IsFloatInstruction(INS_Address(ins))){ + switch (regSize) { + case 1: + case 2: + case 4: HANDLE_APPROXREG(float, true, regId); break; + case 8: HANDLE_APPROXREG(double, true, regId); break; + default: break; + } + }else{ + switch (regSize) { + case 8: HANDLE_ALIAS_REG(uint64_t, ALIAS_GENERIC, regId); break; + case 4: HANDLE_ALIAS_REG(uint32_t, ALIAS_GENERIC, regId); break; + case 2: HANDLE_ALIAS_REG(uint16_t, ALIAS_GENERIC, regId); break; + case 1: if (REG_is_Lower8(reg)){ + HANDLE_ALIAS_REG(uint8_t, ALIAS_LOW_BYTE, regId); + }else{ + HANDLE_ALIAS_REG(uint8_t, ALIAS_HIGH_BYTE, regId); + }break; + default: break; + } + } } static inline void InstrumentGeneralReg(INS ins, REG reg, uint32_t opaqueHandle){ uint32_t regSize = REG_Size(reg); - switch(regSize) { - case 1: HANDLE_GENERAL(uint8_t); break; - case 2: HANDLE_GENERAL(uint16_t); break; - case 4: HANDLE_GENERAL(uint32_t); break; - case 8: HANDLE_GENERAL(uint64_t); break; - default: { - HANDLE_LARGEREG(); break; + + if (IsFloatInstruction(INS_Address(ins))){ + switch (regSize) { + case 1: + case 2: + case 4: HANDLE_APPROXREG(float, false, reg); break; + case 8: HANDLE_APPROXREG(double, false, reg); break; + default: { + HANDLE_LARGEREG(); break; + } + } + }else{ + if (REG_is_in_X87(reg)) { + HANDLE_LARGEREG(); + return; + } + switch(regSize) { + case 1: HANDLE_GENERAL(uint8_t); break; + case 2: HANDLE_GENERAL(uint16_t); break; + case 4: HANDLE_GENERAL(uint32_t); break; + case 8: HANDLE_GENERAL(uint64_t); break; + default: { + HANDLE_LARGEREG(); break; + } } } } From f2c3cca0f863c710e17cb52e52ff1352ac6c6f17 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Sat, 23 Jul 2016 13:00:52 -0400 Subject: [PATCH 06/18] optimize large register handling, fixing data cleaning for sampling --- tests/redspy_temporal_client.cpp | 189 +++++++++++++++++++++---------- 1 file changed, 127 insertions(+), 62 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index 861f4d9..fc2463c 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -55,6 +55,11 @@ extern "C" { #include "xed-common-hdrs.h" } +#include +#include +using google::sparse_hash_map; // namespace where class lives by default +using google::dense_hash_map; + using namespace std; using namespace PinCCTLib; @@ -265,14 +270,14 @@ static const uint64_t READ_ACCESS_STATES [] = {/*0 byte */0, /*1 byte */ ONE_BYT static const uint64_t WRITE_ACCESS_STATES [] = {/*0 byte */0, /*1 byte */ ONE_BYTE_WRITE_ACTION, /*2 byte */ TWO_BYTE_WRITE_ACTION, /*3 byte */ 0, /*4 byte */ FOUR_BYTE_WRITE_ACTION, /*5 byte */0, /*6 byte */0, /*7 byte */0, /*8 byte */ EIGHT_BYTE_WRITE_ACTION}; static const uint8_t OVERFLOW_CHECK [] = {/*0 byte */0, /*1 byte */ 0, /*2 byte */ 0, /*3 byte */ 1, /*4 byte */ 2, /*5 byte */3, /*6 byte */4, /*7 byte */5, /*8 byte */ 6}; -static unordered_map RedMap[THREAD_MAX]; -static unordered_map ApproxRedMap[THREAD_MAX]; +static dense_hash_map RedMap[THREAD_MAX]; +static dense_hash_map ApproxRedMap[THREAD_MAX]; static inline void AddToRedTable(uint64_t key, uint16_t value, THREADID threadId) { #ifdef MULTI_THREADED LOCK_RED_MAP(); #endif - unordered_map::iterator it = RedMap[threadId].find(key); + dense_hash_map::iterator it = RedMap[threadId].find(key); if ( it == RedMap[threadId].end()) { RedMap[threadId][key] = value; } else { @@ -287,7 +292,7 @@ static inline void AddToApproximateRedTable(uint64_t key, uint16_t value, THREA #ifdef MULTI_THREADED LOCK_RED_MAP(); #endif - unordered_map::iterator it = ApproxRedMap[threadId].find(key); + dense_hash_map::iterator it = ApproxRedMap[threadId].find(key); if ( it == ApproxRedMap[threadId].end()) { ApproxRedMap[threadId][key] = value; } else { @@ -303,17 +308,17 @@ static inline void AddToApproximateRedTable(uint64_t key, uint16_t value, THREA static inline VOID EmptyCtxt(RedSpyThreadData* tData){ - int i; - for( i = 0; i< REG_LAST; ++i){ - tData->regCtxt[i] = 0; - } + memset(&tData->regCtxt, 0, sizeof(uint32_t)*REG_LAST); + memset(&tData->aliasCtxt, 0, sizeof(uint32_t)*MAX_ALIAS_REGS*MAX_ALIAS_TYPE); + memset(&tData->regValue, 0, REG_LAST*[MAX_REG_LENGTH]); + memset(&tData->aliasValue, 0, MAX_ALIAS_REGS*MAX_ALIAS_REG_SIZE); /* tData->numWinds++; if(tData->numWinds > WINDOW_CLEAN){ long count = tData->bytesWritten; long delNum = 0; //printf("size of the map %lu, total reg written %lu\n",count,tData->numRegWritten); - unordered_map::iterator it,ittmp; + dense_hash_map::iterator it,ittmp; for (it = RedMap[threadId].begin(); it != RedMap[threadId].end();) { //printf("%lu\n",(*it).second); if((*it).second * 100.0 < count){ @@ -339,18 +344,15 @@ static ADDRINT IfEnableSample(THREADID threadId){ #endif -static inline bool IsFloatInstruction(ADDRINT ip) { +static inline bool IsFloatInstruction(ADDRINT ip, uint32_t oper) { xed_decoded_inst_t xedd; xed_state_t xed_state; xed_decoded_inst_zero_set_mode(&xedd, &xed_state); if(XED_ERROR_NONE == xed_decode(&xedd, (const xed_uint8_t*)(ip), 15)) { - unsigned int NumOperands = xed_decoded_inst_noperands(&xedd); - for(unsigned int i = 0; i < NumOperands; ++i){ - xed_operand_element_type_enum_t TypeOperand = xed_decoded_inst_operand_element_type(&xedd,i); - if(TypeOperand == XED_OPERAND_ELEMENT_TYPE_SINGLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_DOUBLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_FLOAT16 || TypeOperand == XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE) - return true; - } + xed_operand_element_type_enum_t TypeOperand = xed_decoded_inst_operand_element_type(&xedd,oper); + if(TypeOperand == XED_OPERAND_ELEMENT_TYPE_SINGLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_DOUBLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_FLOAT16 || TypeOperand == XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE) + return true; return false; } else { assert(0 && "failed to disassemble instruction"); @@ -358,6 +360,19 @@ static inline bool IsFloatInstruction(ADDRINT ip) { } } +static inline uint16_t OperandSize(ADDRINT ip, uint32_t oper) { + xed_decoded_inst_t xedd; + xed_state_t xed_state; + xed_decoded_inst_zero_set_mode(&xedd, &xed_state); + + if(XED_ERROR_NONE == xed_decode(&xedd, (const xed_uint8_t*)(ip), 15)) { + return xed_decoded_inst_operand_element_size_bits(&xedd,oper)/8; + } else { + assert(0 && "failed to disassemble instruction"); + return 0; + } +} + /*********************************************************************************/ /* register analysis */ /*********************************************************************************/ @@ -405,12 +420,35 @@ struct HandleGeneralRegisters{ T * regBefore = (T *)(&tData->regValue[reg][0]); - if (* regBefore == value && tData->regCtxt[reg]) { + if (* regBefore == value ) { AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),sizeof(T),threadId); }else * regBefore = value; tData->regCtxt[reg] = curCtxtHandle; } + static __attribute__((always_inline)) void CheckLargeRegValues(PIN_REGISTER* regRef, REG reg, uint32_t regSize, uint32_t opaqueHandle, THREADID threadId){ + + RedSpyThreadData* const tData = ClientGetTLS(threadId); + + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); + + uint16_t i,j; + uint16_t operandBytes = sizeof(T); + bool isRedundantWrite = true; + + + for(i = 0, j = 0; j < regSize; ++i, j += operandBytes){ + T oldValue = *((T*)(&tData->regValue[reg][j])); + T newValue = regRef->qword[i]; + if(oldValue != newValue) { + isRedundantWrite = false; + *((T*)(&tData->regValue[reg][j])) = newValue; + } + } + if(isRedundantWrite) + AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),regSize,threadId); + tData->regCtxt[reg] = curCtxtHandle; + } }; template @@ -451,36 +489,53 @@ struct HandleApproxRegisters{ newValue = regRef->flt[0]; T oldValue = *((T*)(&tData->regValue[reg][0])); - if(newValue == oldValue && tData->regCtxt[reg]!=0) { - AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),sizeof(T),threadId); + T rate = (newValue - oldValue)/oldValue; + if(rate <= delta && rate >= -delta) { + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),sizeof(T),threadId); } if(newValue != oldValue) *((T*)(&tData->regValue[reg][0])) = newValue; tData->regCtxt[reg] = curCtxtHandle; } } -}; - -static inline VOID CheckLargeRegAfterWrite(PIN_REGISTER* regRef, REG reg, uint32_t regSize, uint32_t opaqueHandle, THREADID threadId){ - - RedSpyThreadData* const tData = ClientGetTLS(threadId); - - ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - - uint16_t i; - bool isRedundantWrite = true; - for(i = 0; i < regSize; ++i){ - if(tData->regValue[reg][i] != regRef->byte[i]){ - isRedundantWrite = false; - tData->regValue[reg][i] = regRef->byte[i]; + static __attribute__((always_inline)) void CheckLargeReg(PIN_REGISTER* regRef, REG reg, uint32_t regSize, uint32_t opaqueHandle, THREADID threadId){ + + RedSpyThreadData* const tData = ClientGetTLS(threadId); + + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); + + uint16_t i,j; + uint16_t operandBytes = sizeof(T); + T oldValue, newValue, rate; + + switch(operandBytes){ + case 4: + for(i = 0, j = 0; j < regSize; ++i, j += operandBytes){ + oldValue = *((T*)(&tData->regValue[reg][j])); + newValue = regRef->flt[i]; + rate = (newValue - oldValue)/oldValue; + if(rate <= delta && rate >= -delta) { + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),operandBytes,threadId); + } + if(rate != 0) + *((T*)(&tData->regValue[reg][j])) = newValue; + }break; + case 8: + for(i = 0, j = 0; j < regSize; ++i, j += operandBytes){ + oldValue = *((T*)(&tData->regValue[reg][j])); + newValue = regRef->dbl[i]; + rate = (newValue - oldValue)/oldValue; + if(rate <= delta && rate >= -delta) { + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),operandBytes,threadId); + } + if(rate != 0) + *((T*)(&tData->regValue[reg][j])) = newValue; + }break; + default: break; } + tData->regCtxt[reg] = curCtxtHandle; } - - if(isRedundantWrite && tData->regCtxt[reg]!=0) { - AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),regSize,threadId); - } - tData->regCtxt[reg] = curCtxtHandle; -} +}; static inline uint32_t GetAliasIDs(REG reg){ uint8_t regGroup = 0; @@ -547,7 +602,11 @@ inline bool RegHasAlias(REG reg){ #define HANDLE_LARGEREG() \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckLargeRegAfterWrite, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) + +#define HANDLE_LARGEREG_APPROX(T) \ +INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END); \ @@ -564,7 +623,10 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters< #else #define HANDLE_LARGEREG() \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckLargeRegAfterWrite, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) + +#define HANDLE_LARGEREG_APPROX(T) \ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID,IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) @@ -577,13 +639,13 @@ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters(((aliasIDs) & 0x00ffffff) >> 16 ); - if (IsFloatInstruction(INS_Address(ins))){ + if (IsFloatInstruction(INS_Address(ins),oper)){ switch (regSize) { case 1: case 2: @@ -607,21 +669,26 @@ static inline void InstrumentAliasReg(INS ins, REG reg, uint32_t opaqueHandle){ } } -static inline void InstrumentGeneralReg(INS ins, REG reg, uint32_t opaqueHandle){ +static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_t opaqueHandle){ uint32_t regSize = REG_Size(reg); + unsigned int operSize = OperandSize(INS_Address(ins),oper); - if (IsFloatInstruction(INS_Address(ins))){ + if (IsFloatInstruction(INS_Address(ins),oper)){ switch (regSize) { case 1: case 2: case 4: HANDLE_APPROXREG(float, false, reg); break; case 8: HANDLE_APPROXREG(double, false, reg); break; default: { - HANDLE_LARGEREG(); break; - } + switch (operSize) { + case 4: HANDLE_LARGEREG_APPROX(float);break; + case 8: HANDLE_LARGEREG_APPROX(double);break; + default: break; + } + }break; } }else{ - if (REG_is_in_X87(reg)) { + if (REG_is_in_X87(reg) || regSize > 8) { HANDLE_LARGEREG(); return; } @@ -630,9 +697,7 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint32_t opaqueHandle) case 2: HANDLE_GENERAL(uint16_t); break; case 4: HANDLE_GENERAL(uint32_t); break; case 8: HANDLE_GENERAL(uint64_t); break; - default: { - HANDLE_LARGEREG(); break; - } + default: break; } } } @@ -898,7 +963,7 @@ struct RedSpyInstrument{ static __attribute__((always_inline)) void InstrumentReadValueBeforeAndAfterWriting(INS ins, UINT32 memOp, uint32_t opaqueHandle){ UINT32 refSize = INS_MemoryOperandSize(ins, memOp); - if (IsFloatInstruction(INS_Address(ins))) { + if (IsFloatInstruction(INS_Address(ins),INS_MemoryOperandIndexToOperandIndex(ins,memOp))) { switch(refSize) { HANDLE_CASE(1, readBufferSlotIndex, RED_FLOAT); HANDLE_CASE(2, readBufferSlotIndex, RED_FLOAT); @@ -1017,9 +1082,9 @@ static VOID InstrumentInsCallback(INS ins, VOID* v, const uint32_t opaqueHandle) continue; if (RegHasAlias(reg)) { - InstrumentAliasReg(ins, reg , opaqueHandle); + InstrumentAliasReg(ins, reg , oper, opaqueHandle); }else{ - InstrumentGeneralReg(ins, reg, opaqueHandle); + InstrumentGeneralReg(ins, reg, oper, opaqueHandle); } } } @@ -1168,7 +1233,7 @@ static void PrintRedundancyPairs(THREADID threadId) { fprintf(gTraceFile, "*************** Dump Data from Thread %d ****************\n", threadId); #ifdef MERGING - for (unordered_map::iterator it = RedMap[threadId].begin(); it != RedMap[threadId].end(); ++it) { + for (dense_hash_map::iterator it = RedMap[threadId].begin(); it != RedMap[threadId].end(); ++it) { ContextHandle_t dead = DECODE_DEAD((*it).first); ContextHandle_t kill = DECODE_KILL((*it).first); @@ -1197,7 +1262,7 @@ static void PrintRedundancyPairs(THREADID threadId) { } } #else - for (unordered_map::iterator it = RedMap[threadId].begin(); it != RedMap[threadId].end(); ++it) { + for (dense_hash_map::iterator it = RedMap[threadId].begin(); it != RedMap[threadId].end(); ++it) { RedundacyData tmp = { DECODE_DEAD ((*it).first), DECODE_KILL((*it).first), (*it).second}; tmpList.push_back(tmp); grandTotalRedundantBytes += tmp.frequency; @@ -1232,11 +1297,10 @@ static void PrintApproximationRedundancyPairs(THREADID threadId) { vector::iterator tmpIt; uint64_t grandTotalRedundantBytes = 0; - uint64_t grandTotalRedundantIns = 0; fprintf(gTraceFile, "*************** Dump Data(delta=%.2f%%) from Thread %d ****************\n", delta*100,threadId); #ifdef MERGING - for (unordered_map::iterator it = ApproxRedMap[threadId].begin(); it != ApproxRedMap[threadId].end(); ++it) { + for (dense_hash_map::iterator it = ApproxRedMap[threadId].begin(); it != ApproxRedMap[threadId].end(); ++it) { ContextHandle_t dead = DECODE_DEAD((*it).first); ContextHandle_t kill = DECODE_KILL((*it).first); @@ -1263,20 +1327,17 @@ static void PrintApproximationRedundancyPairs(THREADID threadId) { RedundacyData tmp = { dead, kill, (*it).second}; tmpList.push_back(tmp); grandTotalRedundantBytes += tmp.frequency; - grandTotalRedundantIns += 1; } } #else - for (unordered_map::iterator it = ApproxRedMap[threadId].begin(); it != ApproxRedMap[threadId].end(); ++it) { + for (dense_hash_map::iterator it = ApproxRedMap[threadId].begin(); it != ApproxRedMap[threadId].end(); ++it) { RedundacyData tmp = { DECODE_DEAD ((*it).first), DECODE_KILL((*it).first), (*it).second}; tmpList.push_back(tmp); grandTotalRedundantBytes += tmp.frequency; - grandTotalRedundantIns += 1; } #endif fprintf(gTraceFile, "\n Total redundant bytes = %f %%\n", grandTotalRedundantBytes * 100.0 / ClientGetTLS(threadId)->bytesWritten); - fprintf(gTraceFile, "\n Total redundant instructions = %f %%\n", grandTotalRedundantIns * 100.0 / ClientGetTLS(threadId)->numIns); sort(tmpList.begin(), tmpList.end(), RedundacyCompare); vector::iterator listIt; @@ -1326,6 +1387,10 @@ static void InitThreadData(RedSpyThreadData* tdata){ tdata->sampleFlag = true; tdata->numIns = 0; tdata->numWinds = 0; + for (int i = 0; i < THREAD_MAX; ++i) { + RedMap[i].set_empty_key(0); + ApproxRedMap[i].set_empty_key(0); + } } static VOID ThreadStart(THREADID threadid, CONTEXT* ctxt, INT32 flags, VOID* v) { From 6508073c75c3337192035776cbf8ea2ccf808a29 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Tue, 26 Jul 2016 19:12:40 -0400 Subject: [PATCH 07/18] using SSE instructions to handle XMM registers --- tests/redspy_temporal_client.cpp | 365 ++++++++++++++++++++++++++----- 1 file changed, 309 insertions(+), 56 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index fc2463c..5ae57c9 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,8 @@ #include #include "pin.H" #include "cctlib.H" +#include + extern "C" { #include "xed-interface.h" #include "xed-common-hdrs.h" @@ -116,11 +119,17 @@ using namespace PinCCTLib; #define MAX_WRITE_OP_LENGTH (512) #define MAX_WRITE_OPS_IN_INS (8) #define MAX_REG_LENGTH (64) +#define MAX_XMM_LENGTH (16) +#define MAX_XMM_REGS (16) #define MAX_ALIAS_REGS (4) //EAX, EBX, ECX, EDX #define MAX_ALIAS_REG_SIZE (8) //RAX is 64bits #define MAX_ALIAS_TYPE (3) //(RAX, EAX, AX),(AH),(AL) +struct x { + float y; +} __attribute__((aligned(16))); + //different redundant type enum RedType { RED_PRECISION = 0, @@ -189,12 +198,17 @@ struct AddrValPair{ uint8_t value[MAX_WRITE_OP_LENGTH]; }; +struct LargeReg{ + UINT8 value[MAX_XMM_LENGTH]; +} __attribute__((aligned(16))); + struct RedSpyThreadData{ - AddrValPair buffer[MAX_WRITE_OPS_IN_INS]; + struct LargeReg largeRegValue[MAX_XMM_REGS]; uint32_t regCtxt[REG_LAST]; UINT8 regValue[REG_LAST][MAX_REG_LENGTH]; UINT8 aliasValue[MAX_ALIAS_REGS][MAX_ALIAS_REG_SIZE]; uint32_t aliasCtxt[MAX_ALIAS_REGS][MAX_ALIAS_TYPE]; + AddrValPair buffer[MAX_WRITE_OPS_IN_INS]; uint64_t bytesWritten; long long numIns; @@ -344,6 +358,224 @@ static ADDRINT IfEnableSample(THREADID threadId){ #endif +static inline bool IsFloatInstruction(ADDRINT ip) { + xed_decoded_inst_t xedd; + xed_state_t xed_state; + xed_decoded_inst_zero_set_mode(&xedd, &xed_state); + + if(XED_ERROR_NONE == xed_decode(&xedd, (const xed_uint8_t*)(ip), 15)) { + xed_iclass_enum_t iclassType = xed_decoded_inst_get_iclass(&xedd); + if (iclassType >= XED_ICLASS_F2XM1 && iclassType <=XED_ICLASS_FYL2XP1) { + return true; + } + if (iclassType >= XED_ICLASS_VEXTRACTF128 && iclassType <=XED_ICLASS_VINSERTI128) { + return true; + } + if (iclassType >= XED_ICLASS_VRCPPS && iclassType <= XED_ICLASS_VSQRTSS) { + return true; + } + if (iclassType >= XED_ICLASS_VSUBPD && iclassType <= XED_ICLASS_VXORPS) { + return true; + } + switch (iclassType) { + case XED_ICLASS_AAD: + case XED_ICLASS_ADDPD: + case XED_ICLASS_ADDPS: + case XED_ICLASS_ADDSD: + case XED_ICLASS_ADDSS: + case XED_ICLASS_ADDSUBPD: + case XED_ICLASS_ADDSUBPS: + case XED_ICLASS_ANDNPD: + case XED_ICLASS_ANDNPS: + case XED_ICLASS_ANDPD: + case XED_ICLASS_ANDPS: + case XED_ICLASS_BLENDPD: + case XED_ICLASS_BLENDPS: + case XED_ICLASS_BLENDVPD: + case XED_ICLASS_BLENDVPS: + case XED_ICLASS_CMPPD: + case XED_ICLASS_CMPPS: + case XED_ICLASS_CMPSD: + case XED_ICLASS_CMPSD_XMM: + case XED_ICLASS_COMISD: + case XED_ICLASS_COMISS: + case XED_ICLASS_CVTDQ2PD: + case XED_ICLASS_CVTDQ2PS: + case XED_ICLASS_CVTPD2PS: + case XED_ICLASS_CVTPI2PD: + case XED_ICLASS_CVTPI2PS: + case XED_ICLASS_CVTPS2PD: + case XED_ICLASS_CVTSD2SS: + case XED_ICLASS_CVTSI2SD: + case XED_ICLASS_CVTSI2SS: + case XED_ICLASS_CVTSS2SD: + case XED_ICLASS_DIVPD: + case XED_ICLASS_DIVPS: + case XED_ICLASS_DIVSD: + case XED_ICLASS_DIVSS: + case XED_ICLASS_DPPD: + case XED_ICLASS_DPPS: + case XED_ICLASS_HADDPD: + case XED_ICLASS_HADDPS: + case XED_ICLASS_HSUBPD: + case XED_ICLASS_HSUBPS: + case XED_ICLASS_MAXPD: + case XED_ICLASS_MAXPS: + case XED_ICLASS_MAXSD: + case XED_ICLASS_MAXSS: + case XED_ICLASS_MINPD: + case XED_ICLASS_MINPS: + case XED_ICLASS_MINSD: + case XED_ICLASS_MINSS: + case XED_ICLASS_MOVAPD: + case XED_ICLASS_MOVAPS: + case XED_ICLASS_MOVD: + case XED_ICLASS_MOVHLPS: + case XED_ICLASS_MOVHPD: + case XED_ICLASS_MOVHPS: + case XED_ICLASS_MOVLHPS: + case XED_ICLASS_MOVLPD: + case XED_ICLASS_MOVLPS: + case XED_ICLASS_MOVMSKPD: + case XED_ICLASS_MOVMSKPS: + case XED_ICLASS_MOVNTPD: + case XED_ICLASS_MOVNTPS: + case XED_ICLASS_MOVNTSD: + case XED_ICLASS_MOVNTSS: + case XED_ICLASS_MOVSD: + case XED_ICLASS_MOVSD_XMM: + case XED_ICLASS_MOVSS: + case XED_ICLASS_MULPD: + case XED_ICLASS_MULPS: + case XED_ICLASS_MULSD: + case XED_ICLASS_MULSS: + case XED_ICLASS_ORPD: + case XED_ICLASS_ORPS: + case XED_ICLASS_ROUNDPD: + case XED_ICLASS_ROUNDPS: + case XED_ICLASS_ROUNDSD: + case XED_ICLASS_ROUNDSS: + case XED_ICLASS_SHUFPD: + case XED_ICLASS_SHUFPS: + case XED_ICLASS_SQRTPD: + case XED_ICLASS_SQRTPS: + case XED_ICLASS_SQRTSD: + case XED_ICLASS_SQRTSS: + case XED_ICLASS_SUBPD: + case XED_ICLASS_SUBPS: + case XED_ICLASS_SUBSD: + case XED_ICLASS_SUBSS: + case XED_ICLASS_VADDPD: + case XED_ICLASS_VADDPS: + case XED_ICLASS_VADDSD: + case XED_ICLASS_VADDSS: + case XED_ICLASS_VADDSUBPD: + case XED_ICLASS_VADDSUBPS: + case XED_ICLASS_VANDNPD: + case XED_ICLASS_VANDNPS: + case XED_ICLASS_VANDPD: + case XED_ICLASS_VANDPS: + case XED_ICLASS_VBLENDPD: + case XED_ICLASS_VBLENDPS: + case XED_ICLASS_VBLENDVPD: + case XED_ICLASS_VBLENDVPS: + case XED_ICLASS_VBROADCASTF128: + case XED_ICLASS_VBROADCASTI128: + case XED_ICLASS_VBROADCASTSD: + case XED_ICLASS_VBROADCASTSS: + case XED_ICLASS_VCMPPD: + case XED_ICLASS_VCMPPS: + case XED_ICLASS_VCMPSD: + case XED_ICLASS_VCMPSS: + case XED_ICLASS_VCOMISD: + case XED_ICLASS_VCOMISS: + case XED_ICLASS_VCVTDQ2PD: + case XED_ICLASS_VCVTDQ2PS: + case XED_ICLASS_VCVTPD2PS: + case XED_ICLASS_VCVTPH2PS: + case XED_ICLASS_VCVTPS2PD: + case XED_ICLASS_VCVTSD2SS: + case XED_ICLASS_VCVTSI2SD: + case XED_ICLASS_VCVTSI2SS: + case XED_ICLASS_VCVTSS2SD: + case XED_ICLASS_VDIVPD: + case XED_ICLASS_VDIVPS: + case XED_ICLASS_VDIVSD: + case XED_ICLASS_VDIVSS: + case XED_ICLASS_VDPPD: + case XED_ICLASS_VDPPS: + case XED_ICLASS_VMASKMOVPD: + case XED_ICLASS_VMASKMOVPS: + case XED_ICLASS_VMAXPD: + case XED_ICLASS_VMAXPS: + case XED_ICLASS_VMAXSD: + case XED_ICLASS_VMAXSS: + case XED_ICLASS_VMINPD: + case XED_ICLASS_VMINPS: + case XED_ICLASS_VMINSD: + case XED_ICLASS_VMINSS: + case XED_ICLASS_VMOVAPD: + case XED_ICLASS_VMOVAPS: + case XED_ICLASS_VMOVD: + case XED_ICLASS_VMOVHLPS: + case XED_ICLASS_VMOVHPD: + case XED_ICLASS_VMOVHPS: + case XED_ICLASS_VMOVLHPS: + case XED_ICLASS_VMOVLPD: + case XED_ICLASS_VMOVLPS: + case XED_ICLASS_VMOVMSKPD: + case XED_ICLASS_VMOVMSKPS: + case XED_ICLASS_VMOVNTPD: + case XED_ICLASS_VMOVNTPS: + case XED_ICLASS_VMOVSD: + case XED_ICLASS_VMOVSS: + case XED_ICLASS_VMOVUPD: + case XED_ICLASS_VMOVUPS: + case XED_ICLASS_VMULPD: + case XED_ICLASS_VMULPS: + case XED_ICLASS_VMULSD: + case XED_ICLASS_VMULSS: + case XED_ICLASS_VORPD: + case XED_ICLASS_VORPS: + case XED_ICLASS_VPABSD: + case XED_ICLASS_VPADDD: + case XED_ICLASS_VPCOMD: + case XED_ICLASS_VPCOMUD: + case XED_ICLASS_VPERMILPD: + case XED_ICLASS_VPERMILPS: + case XED_ICLASS_VPERMPD: + case XED_ICLASS_VPERMPS: + case XED_ICLASS_VPGATHERDD: + case XED_ICLASS_VPGATHERQD: + case XED_ICLASS_VPHADDBD: + case XED_ICLASS_VPHADDD: + case XED_ICLASS_VPHADDUBD: + case XED_ICLASS_VPHADDUWD: + case XED_ICLASS_VPHADDWD: + case XED_ICLASS_VPHSUBD: + case XED_ICLASS_VPHSUBWD: + case XED_ICLASS_VPINSRD: + case XED_ICLASS_VPMACSDD: + case XED_ICLASS_VPMACSSDD: + case XED_ICLASS_VPMASKMOVD: + case XED_ICLASS_VPMAXSD: + case XED_ICLASS_VPMAXUD: + case XED_ICLASS_VPMINSD: + case XED_ICLASS_VPMINUD: + case XED_ICLASS_VPROTD: + case XED_ICLASS_VPSUBD: + case XED_ICLASS_XORPD: + case XED_ICLASS_XORPS: + return true; + + default: return false; + } + } else { + assert(0 && "failed to disassemble instruction"); + return false; + } +} +/* static inline bool IsFloatInstruction(ADDRINT ip, uint32_t oper) { xed_decoded_inst_t xedd; xed_state_t xed_state; @@ -358,7 +590,7 @@ static inline bool IsFloatInstruction(ADDRINT ip, uint32_t oper) { assert(0 && "failed to disassemble instruction"); return false; } -} +}*/ static inline uint16_t OperandSize(ADDRINT ip, uint32_t oper) { xed_decoded_inst_t xedd; @@ -426,27 +658,25 @@ struct HandleGeneralRegisters{ * regBefore = value; tData->regCtxt[reg] = curCtxtHandle; } - static __attribute__((always_inline)) void CheckLargeRegValues(PIN_REGISTER* regRef, REG reg, uint32_t regSize, uint32_t opaqueHandle, THREADID threadId){ + static __attribute__((always_inline)) void CheckLargeRegValues(PIN_REGISTER* regRef, REG reg, uint32_t opaqueHandle, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - uint16_t i,j; - uint16_t operandBytes = sizeof(T); - bool isRedundantWrite = true; + uint32_t regInd = reg-REG_XMM_BASE; + __m128i oldValue = _mm_load_si128( (__m128i*) (&(tData->largeRegValue[regInd].value))); + __m128i newValue = _mm_load_si128( (__m128i*) (regRef)); + uint32_t result[4]; + *(__m128i*)(&result[0]) = _mm_cmpeq_epi32(oldValue,newValue); + + uint32_t isRedundantWrite = result[0] & result[1] & result[2] & result[3]; - for(i = 0, j = 0; j < regSize; ++i, j += operandBytes){ - T oldValue = *((T*)(&tData->regValue[reg][j])); - T newValue = regRef->qword[i]; - if(oldValue != newValue) { - isRedundantWrite = false; - *((T*)(&tData->regValue[reg][j])) = newValue; - } - } if(isRedundantWrite) - AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),regSize,threadId); + AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),MAX_XMM_LENGTH,threadId); + else + _mm_store_si128((__m128i*) (&(tData->largeRegValue[regInd].value)),newValue); tData->regCtxt[reg] = curCtxtHandle; } }; @@ -498,41 +728,63 @@ struct HandleApproxRegisters{ tData->regCtxt[reg] = curCtxtHandle; } } - static __attribute__((always_inline)) void CheckLargeReg(PIN_REGISTER* regRef, REG reg, uint32_t regSize, uint32_t opaqueHandle, THREADID threadId){ + static __attribute__((always_inline)) void CheckLargeReg(PIN_REGISTER* regRef, REG reg, uint32_t opaqueHandle, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - uint16_t i,j; - uint16_t operandBytes = sizeof(T); - T oldValue, newValue, rate; - - switch(operandBytes){ - case 4: - for(i = 0, j = 0; j < regSize; ++i, j += operandBytes){ - oldValue = *((T*)(&tData->regValue[reg][j])); - newValue = regRef->flt[i]; - rate = (newValue - oldValue)/oldValue; - if(rate <= delta && rate >= -delta) { - AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),operandBytes,threadId); - } - if(rate != 0) - *((T*)(&tData->regValue[reg][j])) = newValue; - }break; - case 8: - for(i = 0, j = 0; j < regSize; ++i, j += operandBytes){ - oldValue = *((T*)(&tData->regValue[reg][j])); - newValue = regRef->dbl[i]; - rate = (newValue - oldValue)/oldValue; - if(rate <= delta && rate >= -delta) { - AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),operandBytes,threadId); - } - if(rate != 0) - *((T*)(&tData->regValue[reg][j])) = newValue; - }break; - default: break; - } + uint32_t regInd = reg-REG_XMM_BASE; + if(sizeof(T) == 4){ + __m128 oldValue = _mm_load_ps( reinterpret_cast (&(tData->largeRegValue[regInd].value))); + __m128 newValue = _mm_load_ps( reinterpret_cast (regRef)); + + __m128 result = _mm_sub_ps(newValue,oldValue); + + result = _mm_div_ps(result,oldValue); + float rates[4] __attribute__((aligned(16))); + _mm_store_ps(rates,result); + + uint8_t redCount = 0; + if(rates[0] <= delta && rates[0] >= -delta) { + redCount++; + } + if(rates[1] <= delta && rates[1] >= -delta) { + redCount++; + } + if(rates[2] <= delta && rates[2] >= -delta) { + redCount++; + } + if(rates[3] <= delta && rates[3] >= -delta) { + redCount++; + } + if(redCount) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),4*redCount,threadId); + _mm_store_ps(reinterpret_cast (&(tData->largeRegValue[regInd].value)),newValue); + + }else if(sizeof(T) == 8){ + __m128d oldValue = _mm_load_pd( reinterpret_cast (&(tData->largeRegValue[regInd].value))); + __m128d newValue = _mm_load_pd( reinterpret_cast (regRef)); + + __m128d result = _mm_sub_pd(newValue,oldValue); + + result = _mm_div_pd(result,oldValue); + + double rate[2]; + _mm_storel_pd(&rate[0],result); + _mm_storeh_pd(&rate[1],result); + + uint8_t redCount = 0; + if(rate[0] <= delta && rate[0] >=-delta) + redCount++; + if(rate[1] <= delta && rate[1] >= -delta) + redCount++; + + if(redCount) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),8*redCount,threadId); + _mm_store_pd(reinterpret_cast (&(tData->largeRegValue[regInd].value)),newValue); + }else + ; tData->regCtxt[reg] = curCtxtHandle; } }; @@ -602,11 +854,11 @@ inline bool RegHasAlias(REG reg){ #define HANDLE_LARGEREG() \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_LARGEREG_APPROX(T) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END); \ @@ -623,10 +875,10 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters< #else #define HANDLE_LARGEREG() \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_LARGEREG_APPROX(T) \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, regSize, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID,IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) @@ -645,7 +897,7 @@ static inline void InstrumentAliasReg(INS ins, REG reg, uint16_t oper, uint32_t uint32_t aliasIDs = GetAliasIDs(reg); uint8_t regId = static_cast(((aliasIDs) & 0x00ffffff) >> 16 ); - if (IsFloatInstruction(INS_Address(ins),oper)){ + if (IsFloatInstruction(INS_Address(ins))){ switch (regSize) { case 1: case 2: @@ -673,22 +925,23 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_ uint32_t regSize = REG_Size(reg); unsigned int operSize = OperandSize(INS_Address(ins),oper); - if (IsFloatInstruction(INS_Address(ins),oper)){ + if (IsFloatInstruction(INS_Address(ins))){ switch (regSize) { case 1: case 2: case 4: HANDLE_APPROXREG(float, false, reg); break; case 8: HANDLE_APPROXREG(double, false, reg); break; - default: { + case 16: { switch (operSize) { case 4: HANDLE_LARGEREG_APPROX(float);break; case 8: HANDLE_LARGEREG_APPROX(double);break; default: break; } }break; + default: assert(0 & "larger than 128 bits register!\n"); } }else{ - if (REG_is_in_X87(reg) || regSize > 8) { + if (REG_is_in_X87(reg) || regSize == 16) { HANDLE_LARGEREG(); return; } @@ -697,7 +950,7 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_ case 2: HANDLE_GENERAL(uint16_t); break; case 4: HANDLE_GENERAL(uint32_t); break; case 8: HANDLE_GENERAL(uint64_t); break; - default: break; + default: assert(0 & "larger than 128 bits register!\n"); break; } } } @@ -963,7 +1216,7 @@ struct RedSpyInstrument{ static __attribute__((always_inline)) void InstrumentReadValueBeforeAndAfterWriting(INS ins, UINT32 memOp, uint32_t opaqueHandle){ UINT32 refSize = INS_MemoryOperandSize(ins, memOp); - if (IsFloatInstruction(INS_Address(ins),INS_MemoryOperandIndexToOperandIndex(ins,memOp))) { + if (IsFloatInstruction(INS_Address(ins))) { switch(refSize) { HANDLE_CASE(1, readBufferSlotIndex, RED_FLOAT); HANDLE_CASE(2, readBufferSlotIndex, RED_FLOAT); @@ -1394,7 +1647,7 @@ static void InitThreadData(RedSpyThreadData* tdata){ } static VOID ThreadStart(THREADID threadid, CONTEXT* ctxt, INT32 flags, VOID* v) { - RedSpyThreadData* tdata = new RedSpyThreadData(); + RedSpyThreadData* tdata = (RedSpyThreadData*)memalign(16,sizeof(RedSpyThreadData)); InitThreadData(tdata); // __sync_fetch_and_add(&gClientNumThreads, 1); #ifdef MULTI_THREADED From 24924d92b36a467537271bf2af5494ffd5b5fcf0 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Thu, 28 Jul 2016 19:24:24 -0400 Subject: [PATCH 08/18] add large memory writes approximation, specialize X87 ST registers reading(with contxt) and approximation(ignore the lower 4 bits) --- tests/redspy_temporal_client.cpp | 364 ++++++++++++++++++------------- 1 file changed, 212 insertions(+), 152 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index 5ae57c9..e71cb49 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -126,17 +126,6 @@ using namespace PinCCTLib; #define MAX_ALIAS_REG_SIZE (8) //RAX is 64bits #define MAX_ALIAS_TYPE (3) //(RAX, EAX, AX),(AH),(AL) -struct x { - float y; -} __attribute__((aligned(16))); - -//different redundant type -enum RedType { - RED_PRECISION = 0, - RED_FLOAT, - RED_DOUBLE -}; - //different register group enum AliasReg { ALIAS_REG_A = 0, //RAX, EAX, AX, AH, or AL @@ -194,9 +183,9 @@ enum AliasGroup{ struct AddrValPair{ - void * address; uint8_t value[MAX_WRITE_OP_LENGTH]; -}; + void * address; +} __attribute__((aligned(16))); struct LargeReg{ UINT8 value[MAX_XMM_LENGTH]; @@ -204,11 +193,11 @@ struct LargeReg{ struct RedSpyThreadData{ struct LargeReg largeRegValue[MAX_XMM_REGS]; + AddrValPair buffer[MAX_WRITE_OPS_IN_INS]; uint32_t regCtxt[REG_LAST]; UINT8 regValue[REG_LAST][MAX_REG_LENGTH]; UINT8 aliasValue[MAX_ALIAS_REGS][MAX_ALIAS_REG_SIZE]; uint32_t aliasCtxt[MAX_ALIAS_REGS][MAX_ALIAS_TYPE]; - AddrValPair buffer[MAX_WRITE_OPS_IN_INS]; uint64_t bytesWritten; long long numIns; @@ -287,6 +276,7 @@ static const uint8_t OVERFLOW_CHECK [] = {/*0 byte */0, /*1 byte */ 0, /*2 byte static dense_hash_map RedMap[THREAD_MAX]; static dense_hash_map ApproxRedMap[THREAD_MAX]; +static inline void AddToRedTable(uint64_t key, uint16_t value, THREADID threadId) __attribute__((always_inline,flatten)); static inline void AddToRedTable(uint64_t key, uint16_t value, THREADID threadId) { #ifdef MULTI_THREADED LOCK_RED_MAP(); @@ -302,6 +292,7 @@ static inline void AddToRedTable(uint64_t key, uint16_t value, THREADID threadI #endif } +static inline void AddToApproximateRedTable(uint64_t key, uint16_t value, THREADID threadId) __attribute__((always_inline,flatten)); static inline void AddToApproximateRedTable(uint64_t key, uint16_t value, THREADID threadId) { #ifdef MULTI_THREADED LOCK_RED_MAP(); @@ -326,26 +317,6 @@ static inline VOID EmptyCtxt(RedSpyThreadData* tData){ memset(&tData->aliasCtxt, 0, sizeof(uint32_t)*MAX_ALIAS_REGS*MAX_ALIAS_TYPE); memset(&tData->regValue, 0, REG_LAST*[MAX_REG_LENGTH]); memset(&tData->aliasValue, 0, MAX_ALIAS_REGS*MAX_ALIAS_REG_SIZE); - /* - tData->numWinds++; - if(tData->numWinds > WINDOW_CLEAN){ - long count = tData->bytesWritten; - long delNum = 0; - //printf("size of the map %lu, total reg written %lu\n",count,tData->numRegWritten); - dense_hash_map::iterator it,ittmp; - for (it = RedMap[threadId].begin(); it != RedMap[threadId].end();) { - //printf("%lu\n",(*it).second); - if((*it).second * 100.0 < count){ - delNum += (*it).second; - ittmp = it; - it++; - RedMap[threadId].erase(ittmp); - }else - it++; - } - tData->numWinds=0; - tData->bytesWritten -= delNum; - }*/ } static ADDRINT IfEnableSample(THREADID threadId){ @@ -378,7 +349,6 @@ static inline bool IsFloatInstruction(ADDRINT ip) { return true; } switch (iclassType) { - case XED_ICLASS_AAD: case XED_ICLASS_ADDPD: case XED_ICLASS_ADDPS: case XED_ICLASS_ADDSD: @@ -479,8 +449,6 @@ static inline bool IsFloatInstruction(ADDRINT ip) { case XED_ICLASS_VBLENDPS: case XED_ICLASS_VBLENDVPD: case XED_ICLASS_VBLENDVPS: - case XED_ICLASS_VBROADCASTF128: - case XED_ICLASS_VBROADCASTI128: case XED_ICLASS_VBROADCASTSD: case XED_ICLASS_VBROADCASTSS: case XED_ICLASS_VCMPPD: @@ -592,15 +560,25 @@ static inline bool IsFloatInstruction(ADDRINT ip, uint32_t oper) { } }*/ -static inline uint16_t OperandSize(ADDRINT ip, uint32_t oper) { +static inline uint16_t FloatOperandSize(ADDRINT ip, uint32_t oper) { xed_decoded_inst_t xedd; xed_state_t xed_state; xed_decoded_inst_zero_set_mode(&xedd, &xed_state); if(XED_ERROR_NONE == xed_decode(&xedd, (const xed_uint8_t*)(ip), 15)) { - return xed_decoded_inst_operand_element_size_bits(&xedd,oper)/8; + xed_operand_element_type_enum_t TypeOperand = xed_decoded_inst_operand_element_type(&xedd,oper); + if(TypeOperand == XED_OPERAND_ELEMENT_TYPE_SINGLE || TypeOperand == XED_OPERAND_ELEMENT_TYPE_FLOAT16) + return 4; + if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_DOUBLE) { + return 8; + } + if (TypeOperand == XED_OPERAND_ELEMENT_TYPE_LONGDOUBLE) { + return 16; + } + assert(0 && "float instruction with unknown operand\n"); + return 0; } else { - assert(0 && "failed to disassemble instruction"); + assert(0 && "failed to disassemble instruction\n"); return 0; } } @@ -609,6 +587,7 @@ static inline uint16_t OperandSize(ADDRINT ip, uint32_t oper) { /* register analysis */ /*********************************************************************************/ +/**************** handleing align registers ****************/ template struct HandleAliasRegisters{ @@ -642,7 +621,8 @@ struct HandleAliasRegisters{ } }; -template +/**************** handleing general registers ****************/ +template struct HandleGeneralRegisters{ static __attribute__((always_inline)) void CheckValues(T value, REG reg, uint32_t opaqueHandle, THREADID threadId) { @@ -664,23 +644,54 @@ struct HandleGeneralRegisters{ ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - uint32_t regInd = reg-REG_XMM_BASE; - __m128i oldValue = _mm_load_si128( (__m128i*) (&(tData->largeRegValue[regInd].value))); - __m128i newValue = _mm_load_si128( (__m128i*) (regRef)); - - uint32_t result[4]; - *(__m128i*)(&result[0]) = _mm_cmpeq_epi32(oldValue,newValue); - - uint32_t isRedundantWrite = result[0] & result[1] & result[2] & result[3]; - - if(isRedundantWrite) - AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),MAX_XMM_LENGTH,threadId); - else - _mm_store_si128((__m128i*) (&(tData->largeRegValue[regInd].value)),newValue); + if(len == 1){ + uint64_t *oldValue = (uint64_t*)&(tData->regValue[reg][0]); + if(*oldValue == regRef->qword[0]) + AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),8,threadId); + else + *oldValue = regRef->qword[0]; + }else{ + uint32_t regInd = reg-REG_XMM_BASE; + uint64_t *oldValue1 = (uint64_t*)&(tData->largeRegValue[regInd].value); + uint64_t *oldValue2 = (uint64_t*)&(tData->largeRegValue[regInd].value[8]); + if(*oldValue1 == regRef->qword[0] && *oldValue2 == regRef->qword[1]) + AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),MAX_XMM_LENGTH,threadId); + else{ + *oldValue1 = regRef->qword[0]; + *oldValue2 = regRef->qword[1]; + } + } tData->regCtxt[reg] = curCtxtHandle; } }; +/**************** handleing registers approximation ****************/ +//static void Check10BytesReg(PIN_REGISTER* regRef, REG reg, uint32_t opaqueHandle, THREADID threadId)__attribute__((always_inline)); +static void Check10BytesReg(CONTEXT * ctxt, REG reg, uint32_t opaqueHandle, THREADID threadId){ + + RedSpyThreadData* const tData = ClientGetTLS(threadId); + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); + + UINT8 * valueAfter; + valueAfter = (UINT8 *)malloc(10*sizeof(UINT8)); + PIN_GetContextRegval(ctxt,reg,valueAfter); + + bool isRedundantWrite = true; + if((tData->regValue[reg][0] & 0xf0) == (valueAfter[0] & 0xf0)){ + for(int i = 1; i < 10; ++i){ + if(tData->regValue[reg][i] != valueAfter[i]){ + isRedundantWrite = false; + break; + } + } + }else + isRedundantWrite = false; + if(isRedundantWrite) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),10,threadId); + memcpy(&tData->regValue[reg][0], valueAfter, 10); + tData->regCtxt[reg] = curCtxtHandle; +} + template struct HandleApproxRegisters{ @@ -728,6 +739,7 @@ struct HandleApproxRegisters{ tData->regCtxt[reg] = curCtxtHandle; } } + static __attribute__((always_inline)) void CheckLargeReg(PIN_REGISTER* regRef, REG reg, uint32_t opaqueHandle, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); @@ -737,7 +749,7 @@ struct HandleApproxRegisters{ uint32_t regInd = reg-REG_XMM_BASE; if(sizeof(T) == 4){ __m128 oldValue = _mm_load_ps( reinterpret_cast (&(tData->largeRegValue[regInd].value))); - __m128 newValue = _mm_load_ps( reinterpret_cast (regRef)); + __m128 newValue = _mm_loadu_ps( reinterpret_cast (regRef)); __m128 result = _mm_sub_ps(newValue,oldValue); @@ -764,7 +776,7 @@ struct HandleApproxRegisters{ }else if(sizeof(T) == 8){ __m128d oldValue = _mm_load_pd( reinterpret_cast (&(tData->largeRegValue[regInd].value))); - __m128d newValue = _mm_load_pd( reinterpret_cast (regRef)); + __m128d newValue = _mm_loadu_pd( reinterpret_cast (regRef)); __m128d result = _mm_sub_pd(newValue,oldValue); @@ -817,7 +829,7 @@ static inline uint32_t GetAliasIDs(REG reg){ case REG_DX: regGroup = ALIAS_REG_D; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; case REG_DH: regGroup = ALIAS_REG_D; byteInd = ALIAS_BYTES_INDEX_8_H; type = ALIAS_HIGH_BYTE; break; case REG_DL: regGroup = ALIAS_REG_D; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_LOW_BYTE; break; - default: assert(0 & "not alias registers! should not reach here!"); break; + default: assert(0 && "not alias registers! should not reach here!"); break; } uint32_t aliasGroupByteType = ((uint32_t)regGroup << 16) | ((uint32_t)byteInd << 8) | ((uint32_t)type); return aliasGroupByteType; @@ -852,9 +864,9 @@ inline bool RegHasAlias(REG reg){ #ifdef ENABLE_SAMPLING -#define HANDLE_LARGEREG() \ +#define HANDLE_LARGEREG(LEN) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_LARGEREG_APPROX(T) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ @@ -866,16 +878,20 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) #define HANDLE_APPROXREG(T, IS_ALIAS, REG_ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +#define HANDLE_10BYTES_APPROX(REG_ID) \ +INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) Check10BytesReg, IARG_CONTEXT, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) + #else -#define HANDLE_LARGEREG() \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +#define HANDLE_LARGEREG(LEN) \ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_LARGEREG_APPROX(T) \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) @@ -884,11 +900,14 @@ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID,IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) #define HANDLE_GENERAL(T) \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) #define HANDLE_APPROXREG(T, IS_ALIAS, REG_ID) \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +#define HANDLE_10BYTES_APPROX(REG_ID) \ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) Check10BytesReg, IARG_CONTEXT, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) + #endif static inline void InstrumentAliasReg(INS ins, REG reg, uint16_t oper, uint32_t opaqueHandle){ @@ -923,26 +942,27 @@ static inline void InstrumentAliasReg(INS ins, REG reg, uint16_t oper, uint32_t static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_t opaqueHandle){ uint32_t regSize = REG_Size(reg); - unsigned int operSize = OperandSize(INS_Address(ins),oper); if (IsFloatInstruction(INS_Address(ins))){ + unsigned int operSize = FloatOperandSize(INS_Address(ins),oper); switch (regSize) { case 1: case 2: case 4: HANDLE_APPROXREG(float, false, reg); break; case 8: HANDLE_APPROXREG(double, false, reg); break; + case 10: HANDLE_10BYTES_APPROX(reg); break; case 16: { switch (operSize) { case 4: HANDLE_LARGEREG_APPROX(float);break; case 8: HANDLE_LARGEREG_APPROX(double);break; - default: break; + default: assert(0 && "handle large reg with large operand size\n"); break; } }break; - default: assert(0 & "larger than 128 bits register!\n"); + default: assert(0 && "not recoganized register size for floating instruction!\n"); } }else{ - if (REG_is_in_X87(reg) || regSize == 16) { - HANDLE_LARGEREG(); + if (REG_is_in_X87(reg)) { + HANDLE_LARGEREG(1); return; } switch(regSize) { @@ -950,7 +970,8 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_ case 2: HANDLE_GENERAL(uint16_t); break; case 4: HANDLE_GENERAL(uint32_t); break; case 8: HANDLE_GENERAL(uint64_t); break; - default: assert(0 & "larger than 128 bits register!\n"); break; + case 16: HANDLE_LARGEREG(2); break; + default: assert(0 && "not recoganized register size for integer instruction!\n"); break; } } } @@ -959,36 +980,42 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_ /*********************** memory temporal redundancy functions **************************/ /***************************************************************************************/ -template +template struct UnrolledLoop{ static __attribute__((always_inline)) void Body(function func){ func(start); // Real loop body - UnrolledLoop:: Body(func); // unroll next iteration + UnrolledLoop:: Body(func); // unroll next iteration } static __attribute__((always_inline)) void BodySamePage(ContextHandle_t * __restrict__ prevIP, const ContextHandle_t handle, THREADID threadId){ if(conditional) { // report in RedTable - AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[start], handle), 1, threadId); + if(approx) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[start], handle), 1, threadId); + else + AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[start], handle), 1, threadId); } // Update context prevIP[start] = handle; - UnrolledLoop:: BodySamePage(prevIP, handle, threadId); // unroll next iteration + UnrolledLoop:: BodySamePage(prevIP, handle, threadId); // unroll next iteration } static __attribute__((always_inline)) void BodyStraddlePage(uint64_t addr, const ContextHandle_t handle, THREADID threadId){ uint8_t * status = GetOrCreateShadowBaseAddress((uint64_t)addr + start); ContextHandle_t * prevIP = (ContextHandle_t*)(status + PAGE_OFFSET(((uint64_t)addr + start)) * sizeof(ContextHandle_t)); if (conditional) { // report in RedTable - AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0 /* 0 is correct*/ ], handle), 1, threadId); + if(approx) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0 /* 0 is correct*/ ], handle), 1, threadId); + else + AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0 /* 0 is correct*/ ], handle), 1, threadId); } // Update context prevIP[0] = handle; - UnrolledLoop:: BodyStraddlePage(addr, handle, threadId); // unroll next iteration + UnrolledLoop:: BodyStraddlePage(addr, handle, threadId); // unroll next iteration } }; -template -struct UnrolledLoop{ +template +struct UnrolledLoop{ static __attribute__((always_inline)) void Body(function func){} static __attribute__((always_inline)) void BodySamePage(ContextHandle_t * __restrict__ prevIP, const ContextHandle_t handle, THREADID threadId){} static __attribute__((always_inline)) void BodyStraddlePage(uint64_t addr, const ContextHandle_t handle, THREADID threadId){} @@ -1015,39 +1042,73 @@ struct UnrolledConjunction{ }; -template +template struct RedSpyAnalysis{ static __attribute__((always_inline)) bool IsWriteRedundant(void * &addr, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); AddrValPair * avPair = & tData->buffer[bufferOffset]; addr = avPair->address; - if(redType == RED_FLOAT){ - float newValue32 = *(static_cast(avPair->address)); - float oldValue32 = *((float*)(&avPair->value)); - - float rate32 = (newValue32 - oldValue32)/oldValue32; - *((float*)(&avPair->value)) = newValue32; - if( rate32 <= delta && rate32 >= -delta ) return true; - else return false; - - }else if(redType == RED_DOUBLE){ - double newValue64 = *(static_cast(avPair->address)); - double oldValue64 = *((double*)(&avPair->value)); + if(isApprox){ + if(AccessLen>=16){ + if(sizeof(T) == 4){ + __m128 oldValue = _mm_load_ps( reinterpret_cast (&avPair->value)); + __m128 newValue = _mm_loadu_ps( reinterpret_cast (avPair->address)); + + __m128 result = _mm_sub_ps(newValue,oldValue); + + result = _mm_div_ps(result,oldValue); + float rates[4] __attribute__((aligned(16))); + _mm_store_ps(rates,result); + + for(int i = 0; i < 4; ++i){ + if(rates[i] < -delta || rates[i] > delta) { + return false; + } + } + return true; + + }else if(sizeof(T) == 8){ + __m128d oldValue = _mm_load_pd( reinterpret_cast (&avPair->value)); + __m128d newValue = _mm_loadu_pd( reinterpret_cast (avPair->address)); + + __m128d result = _mm_sub_pd(newValue,oldValue); + + result = _mm_div_pd(result,oldValue); + + double rate[2]; + _mm_storel_pd(&rate[0],result); + _mm_storeh_pd(&rate[1],result); + + if(rate[0] < -delta || rate[0] > delta) + return false; + if(rate[1] < -delta || rate[1] > delta) + return false; + return true; + } + }else if(AccessLen == 10){ + UINT8 newValue[10]; + memcpy(newValue, addr, AccessLen); + if((avPair->value[0] & 0xf0) == (newValue[0] & 0xf0)){ + for(int i = 1; i < 10; ++i){ + if(avPair->value[i] != newValue[i]) + return false; + } + } + return true; + }else{ + T newValue = *(static_cast(avPair->address)); + T oldValue = *((T*)(&avPair->value)); - double rate64 = (newValue64 - oldValue64)/oldValue64; - *((double*)(&avPair->value)) = newValue64; - if( rate64 <= delta && rate64 >= -delta ) return true; - else return false; - }else{ - switch(AccessLen){ - case 1: return *((uint8_t*)(&avPair->value)) == *(static_cast(avPair->address)); - case 2: return *((uint16_t*)(&avPair->value)) == *(static_cast(avPair->address)); - case 4: return *((uint32_t*)(&avPair->value)) == *(static_cast(avPair->address)); - case 8: return *((uint64_t*)(&avPair->value)) == *(static_cast(avPair->address)); - default: return memcmp(&avPair->value, avPair->address, AccessLen) == 0; + T rate = (newValue - oldValue)/oldValue; + *((T*)(&avPair->value)) = newValue; + if( rate <= delta && rate >= -delta ) return true; + else return false; } + }else{ + return *((T*)(&avPair->value)) == *(static_cast(avPair->address)); } + return false; } static __attribute__((always_inline)) VOID RecordNByteValueBeforeWrite(void* addr, THREADID threadId){ @@ -1058,20 +1119,19 @@ struct RedSpyAnalysis{ avPair->address = addr; - switch(redType){ - case RED_FLOAT: *((float*)(&avPair->value)) = *(static_cast(addr)); break; - case RED_DOUBLE: *((double*)(&avPair->value)) = *(static_cast(addr)); break; - case RED_PRECISION: - switch(AccessLen){ - case 1: *((uint8_t*)(&avPair->value)) = *(static_cast(addr)); break; - case 2: *((uint16_t*)(&avPair->value)) = *(static_cast(addr)); break; - case 4: *((uint32_t*)(&avPair->value)) = *(static_cast(addr)); break; - case 8: *((uint64_t*)(&avPair->value)) = *(static_cast(addr)); break; - default: memcpy(&avPair->value, addr, AccessLen); - } - break; - default: memcpy(&avPair->value, addr, AccessLen); break; - } + if(AccessLen>=16){ + if(sizeof(T) == 4){ + __m128 newValue = _mm_loadu_ps( reinterpret_cast (addr)); + _mm_store_ps(reinterpret_cast (&avPair->value), newValue); + + }else if(sizeof(T) == 8){ + __m128d newValue = _mm_loadu_pd(reinterpret_cast (addr)); + _mm_store_pd(reinterpret_cast (&avPair->value), newValue); + } + }else if(AccessLen == 10){ + memcpy(&avPair->value, addr, AccessLen); + }else + *((T*)(&avPair->value)) = *(static_cast(addr)); } static __attribute__((always_inline)) VOID CheckNByteValueAfterWrite(uint32_t opaqueHandle, THREADID threadId){ @@ -1090,46 +1150,42 @@ struct RedSpyAnalysis{ // All from same ctxt? if (UnrolledConjunction<0, AccessLen, 1>::BodyContextCheck(prevIP)) { // report in RedTable - switch(redType){ - case RED_FLOAT: - case RED_DOUBLE: AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), AccessLen, threadId);break; - case RED_PRECISION: AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), AccessLen, threadId);break; - default: break; - } + if(isApprox) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), AccessLen, threadId); + else + AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), AccessLen, threadId); // Update context - UnrolledLoop<0, AccessLen, 1, false, /* redundancy is updated outside*/ redType>::BodySamePage(prevIP, curCtxtHandle, threadId); + UnrolledLoop<0, AccessLen, 1, false, /* redundancy is updated outside*/ isApprox>::BodySamePage(prevIP, curCtxtHandle, threadId); } else { // different contexts - UnrolledLoop<0, AccessLen, 1, true, /* redundancy is updated inside*/ redType>::BodySamePage(prevIP, curCtxtHandle, threadId); + UnrolledLoop<0, AccessLen, 1, true, /* redundancy is updated inside*/ isApprox>::BodySamePage(prevIP, curCtxtHandle, threadId); } } else { // Write across a 64-K page boundary // First byte is on this page though - switch(redType){ - case RED_FLOAT: - case RED_DOUBLE: AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), 1, threadId);break; - case RED_PRECISION: AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), 1, threadId);break; - default: break; - } + if(isApprox) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), 1, threadId); + else + AddToRedTable(MAKE_CONTEXT_PAIR(prevIP[0], curCtxtHandle), 1, threadId); // Update context prevIP[0] = curCtxtHandle; // Remaining bytes [1..AccessLen] somewhere will across a 64-K page boundary - UnrolledLoop<1, AccessLen, 1, true, /* update redundancy */ redType>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); + UnrolledLoop<1, AccessLen, 1, true, /* update redundancy */ isApprox>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); } } else { // No redundancy. // Just update contexts if(isAccessWithinPageBoundary) { // Update context - UnrolledLoop<0, AccessLen, 1, false, /* not redundant*/ redType>::BodySamePage(prevIP, curCtxtHandle, threadId); + UnrolledLoop<0, AccessLen, 1, false, /* not redundant*/ isApprox>::BodySamePage(prevIP, curCtxtHandle, threadId); } else { // Write across a 64-K page boundary // Update context prevIP[0] = curCtxtHandle; // Remaining bytes [1..AccessLen] somewhere will across a 64-K page boundary - UnrolledLoop<1, AccessLen, 1, false, /* not redundant*/ redType>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); + UnrolledLoop<1, AccessLen, 1, false, /* not redundant*/ isApprox>::BodyStraddlePage( (uint64_t) addr, curCtxtHandle, threadId); } } } @@ -1174,11 +1230,11 @@ static inline VOID CheckAfterLargeWrite(UINT32 accessLen, uint32_t bufferOffset #ifdef ENABLE_SAMPLING -#define HANDLE_CASE(NUM, BUFFER_INDEX, RED_TYPE) \ -case (NUM):{INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ +#define HANDLE_CASE(T, ACCESS_LEN, BUFFER_INDEX, IS_APPROX) \ +INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ +INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END);}break +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END) #define HANDLE_LARGE() \ INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ @@ -1188,9 +1244,9 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckAfterLargeWrite, #else -#define HANDLE_CASE(NUM, BUFFER_INDEX, RED_TYPE) \ -case (NUM):{INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis<(NUM), (BUFFER_INDEX),(RED_TYPE)>::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END);}break +#define HANDLE_CASE(T, ACCESS_LEN, BUFFER_INDEX, IS_APPROX) \ +INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END) #define HANDLE_LARGE() \ INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RecordValueBeforeLargeWrite, IARG_MEMORYOP_EA, memOp, IARG_MEMORYWRITE_SIZE, IARG_UINT32, readBufferSlotIndex, IARG_THREAD_ID, IARG_END);\ @@ -1217,24 +1273,28 @@ struct RedSpyInstrument{ UINT32 refSize = INS_MemoryOperandSize(ins, memOp); if (IsFloatInstruction(INS_Address(ins))) { + unsigned int operSize = FloatOperandSize(INS_Address(ins),INS_MemoryOperandIndexToOperandIndex(ins,memOp)); switch(refSize) { - HANDLE_CASE(1, readBufferSlotIndex, RED_FLOAT); - HANDLE_CASE(2, readBufferSlotIndex, RED_FLOAT); - HANDLE_CASE(4, readBufferSlotIndex, RED_FLOAT); - HANDLE_CASE(8, readBufferSlotIndex, RED_DOUBLE); - - default: { - HANDLE_LARGE(); + case 1: + case 2: assert(0 && "memory write floating data with unexptected small size"); + case 4: HANDLE_CASE(float, 4, readBufferSlotIndex, true); break; + case 8: HANDLE_CASE(double, 8, readBufferSlotIndex, true); break; + case 10: HANDLE_CASE(long double, 10, readBufferSlotIndex, true); break; + case 16: { + switch (operSize) { + case 4: HANDLE_CASE(float, 16, readBufferSlotIndex, true); break; + case 8: HANDLE_CASE(double, 16, readBufferSlotIndex, true); break; + default: assert(0 && "handle large mem write with unexpected operand size\n"); break; + } } + default: assert(0 && "unexpected large memory writes\n"); break; } }else{ switch(refSize) { - HANDLE_CASE(1, readBufferSlotIndex, RED_PRECISION); - HANDLE_CASE(2, readBufferSlotIndex, RED_PRECISION); - HANDLE_CASE(4, readBufferSlotIndex, RED_PRECISION); - HANDLE_CASE(8, readBufferSlotIndex, RED_PRECISION); - HANDLE_CASE(10, readBufferSlotIndex, RED_PRECISION); - HANDLE_CASE(16, readBufferSlotIndex, RED_PRECISION); + case 1: HANDLE_CASE(uint8_t, 1, readBufferSlotIndex, false); break; + case 2: HANDLE_CASE(uint16_t, 2, readBufferSlotIndex, false); break; + case 4: HANDLE_CASE(uint32_t, 4, readBufferSlotIndex, false); break; + case 8: HANDLE_CASE(uint64_t, 8, readBufferSlotIndex, false); break; default: { HANDLE_LARGE(); From 07e0856fee10d3e1970f252a9e002e9cc98c0c22 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Sat, 6 Aug 2016 23:53:41 -0400 Subject: [PATCH 09/18] fix instrument ordering issue in sampling --- tests/redspy_temporal_client.cpp | 113 ++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index e71cb49..fbde3d3 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -169,7 +169,7 @@ enum AliasGroup{ #ifdef ENABLE_SAMPLING #define WINDOW_ENABLE 1000000 -#define WINDOW_DISABLE 10000000 +#define WINDOW_DISABLE 100000000 #define WINDOW_CLEAN 10 #endif @@ -315,16 +315,13 @@ static inline VOID EmptyCtxt(RedSpyThreadData* tData){ memset(&tData->regCtxt, 0, sizeof(uint32_t)*REG_LAST); memset(&tData->aliasCtxt, 0, sizeof(uint32_t)*MAX_ALIAS_REGS*MAX_ALIAS_TYPE); - memset(&tData->regValue, 0, REG_LAST*[MAX_REG_LENGTH]); + memset(&tData->regValue, 0, REG_LAST*MAX_REG_LENGTH); memset(&tData->aliasValue, 0, MAX_ALIAS_REGS*MAX_ALIAS_REG_SIZE); } static ADDRINT IfEnableSample(THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); - if(tData->sampleFlag){ - return 1; - } - return 0; + return tData->sampleFlag; } #endif @@ -676,19 +673,17 @@ static void Check10BytesReg(CONTEXT * ctxt, REG reg, uint32_t opaqueHandle, THRE valueAfter = (UINT8 *)malloc(10*sizeof(UINT8)); PIN_GetContextRegval(ctxt,reg,valueAfter); - bool isRedundantWrite = true; - if((tData->regValue[reg][0] & 0xf0) == (valueAfter[0] & 0xf0)){ - for(int i = 1; i < 10; ++i){ - if(tData->regValue[reg][i] != valueAfter[i]){ - isRedundantWrite = false; - break; - } - } - }else - isRedundantWrite = false; - if(isRedundantWrite) + uint64_t * upperOld = (uint64_t*)&(tData->regValue[reg][2]); + uint64_t * upperNew = (uint64_t*)&(valueAfter[2]); + + uint16_t * lowOld = (uint16_t*)&(tData->regValue[reg][0]); + uint16_t * lowNew = (uint16_t*)(valueAfter); + + if((*lowOld & 0xfff0) == (*lowNew & 0xfff0) && *upperNew == *upperOld){ AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),10,threadId); - memcpy(&tData->regValue[reg][0], valueAfter, 10); + *lowOld = *lowNew; + }else + memcpy(&tData->regValue[reg][0], valueAfter, 10); tData->regCtxt[reg] = curCtxtHandle; } @@ -866,7 +861,7 @@ inline bool RegHasAlias(REG reg){ #define HANDLE_LARGEREG(LEN) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_LARGEREG_APPROX(T) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ @@ -1089,19 +1084,22 @@ struct RedSpyAnalysis{ }else if(AccessLen == 10){ UINT8 newValue[10]; memcpy(newValue, addr, AccessLen); - if((avPair->value[0] & 0xf0) == (newValue[0] & 0xf0)){ - for(int i = 1; i < 10; ++i){ - if(avPair->value[i] != newValue[i]) - return false; - } + + uint64_t * upperOld = (uint64_t*)&(avPair->value[2]); + uint64_t * upperNew = (uint64_t*)&(newValue[2]); + + uint16_t * lowOld = (uint16_t*)&(avPair->value[0]); + uint16_t * lowNew = (uint16_t*)&(newValue[0]); + + if((*lowOld & 0xfff0) == (*lowNew & 0xfff0) && *upperNew == *upperOld){ + return true; } - return true; + return false; }else{ T newValue = *(static_cast(avPair->address)); T oldValue = *((T*)(&avPair->value)); T rate = (newValue - oldValue)/oldValue; - *((T*)(&avPair->value)) = newValue; if( rate <= delta && rate >= -delta ) return true; else return false; } @@ -1189,6 +1187,37 @@ struct RedSpyAnalysis{ } } } + static __attribute__((always_inline)) VOID ApproxCheckAfterWrite(uint32_t opaqueHandle, THREADID threadId){ + RedSpyThreadData* const tData = ClientGetTLS(threadId); + void * addr; + bool isRedundantWrite = IsWriteRedundant(addr, threadId); + + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); + + UINT32 const interv = sizeof(T); + uint8_t* status = GetOrCreateShadowBaseAddress((uint64_t)addr); + ContextHandle_t * __restrict__ prevIP = (ContextHandle_t*)(status + PAGE_OFFSET((uint64_t)addr) * sizeof(ContextHandle_t)); + + if(isRedundantWrite){ + for(UINT32 index = 0 ; index < AccessLen; index+=interv){ + status = GetOrCreateShadowBaseAddress((uint64_t)addr + index); + prevIP = (ContextHandle_t*)(status + PAGE_OFFSET(((uint64_t)addr + index)) * sizeof(ContextHandle_t)); + // report in RedTable + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0 /* 0 is correct*/ ], curCtxtHandle), interv, threadId); + // Update context + prevIP[0] = curCtxtHandle; + } + }else{ + for(UINT32 index = 0 ; index < AccessLen; index+=interv){ + status = GetOrCreateShadowBaseAddress((uint64_t)addr + index); + prevIP = (ContextHandle_t*)(status + PAGE_OFFSET(((uint64_t)addr + index)) * sizeof(ContextHandle_t)); + // report in RedTable + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(prevIP[0 /* 0 is correct*/ ], curCtxtHandle), interv, threadId); + // Update context + prevIP[0] = curCtxtHandle; + } + } + } }; @@ -1236,6 +1265,12 @@ INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END) +#define HANDLE_APPROX_CASE(T, ACCESS_LEN, BUFFER_INDEX, IS_APPROX) \ +INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ +INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ +INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis::ApproxCheckAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END) + #define HANDLE_LARGE() \ INS_InsertIfPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ INS_InsertThenPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RecordValueBeforeLargeWrite, IARG_MEMORYOP_EA, memOp, IARG_MEMORYWRITE_SIZE, IARG_UINT32, readBufferSlotIndex, IARG_THREAD_ID, IARG_END);\ @@ -1248,6 +1283,10 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckAfterLargeWrite, INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis::CheckNByteValueAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END) +#define HANDLE_APPROX_CASE(T, ACCESS_LEN, BUFFER_INDEX, IS_APPROX) \ +INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RedSpyAnalysis::RecordNByteValueBeforeWrite, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END);\ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) RedSpyAnalysis::ApproxCheckAfterWrite, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_INST_PTR,IARG_END) + #define HANDLE_LARGE() \ INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR) RecordValueBeforeLargeWrite, IARG_MEMORYOP_EA, memOp, IARG_MEMORYWRITE_SIZE, IARG_UINT32, readBufferSlotIndex, IARG_THREAD_ID, IARG_END);\ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) CheckAfterLargeWrite, IARG_MEMORYREAD_SIZE, IARG_UINT32, readBufferSlotIndex, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) @@ -1277,16 +1316,16 @@ struct RedSpyInstrument{ switch(refSize) { case 1: case 2: assert(0 && "memory write floating data with unexptected small size"); - case 4: HANDLE_CASE(float, 4, readBufferSlotIndex, true); break; - case 8: HANDLE_CASE(double, 8, readBufferSlotIndex, true); break; - case 10: HANDLE_CASE(long double, 10, readBufferSlotIndex, true); break; + case 4: HANDLE_APPROX_CASE(float, 4, readBufferSlotIndex, true); break; + case 8: HANDLE_APPROX_CASE(double, 8, readBufferSlotIndex, true); break; + case 10: HANDLE_APPROX_CASE(uint8_t, 10, readBufferSlotIndex, true); break; case 16: { switch (operSize) { - case 4: HANDLE_CASE(float, 16, readBufferSlotIndex, true); break; - case 8: HANDLE_CASE(double, 16, readBufferSlotIndex, true); break; + case 4: HANDLE_APPROX_CASE(float, 16, readBufferSlotIndex, true); break; + case 8: HANDLE_APPROX_CASE(double, 16, readBufferSlotIndex, true); break; default: assert(0 && "handle large mem write with unexpected operand size\n"); break; } - } + }break; default: assert(0 && "unexpected large memory writes\n"); break; } }else{ @@ -1327,8 +1366,6 @@ static inline bool REG_IsIgnorable(REG reg){ return true; else if(REG_is_flags(reg)) return true; - else if(reg == REG_ST0) - return true; return false; } @@ -1470,15 +1507,15 @@ static void InstrumentTrace(TRACE trace, void* f) { } if (BBL_InsTail(bbl) == BBL_InsHead(bbl)) { - BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)UpdateAndCheck,IARG_UINT32, totInsInBbl, IARG_UINT32,totBytes, IARG_THREAD_ID,IARG_END); + BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)UpdateAndCheck,IARG_UINT32, totInsInBbl, IARG_UINT32,totBytes, IARG_THREAD_ID, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END); }else if(INS_IsIndirectBranchOrCall(BBL_InsTail(bbl))){ - BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)UpdateAndCheck,IARG_UINT32, totInsInBbl, IARG_UINT32,totBytes, IARG_THREAD_ID,IARG_END); + BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)UpdateAndCheck,IARG_UINT32, totInsInBbl, IARG_UINT32,totBytes, IARG_THREAD_ID,IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END); }else{ if (check) { - BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)UpdateAndCheck,IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID,IARG_END); + BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)UpdateAndCheck,IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID,IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END); check = false; } else { - BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)Update,IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_END); + BBL_InsertCall(bbl,IPOINT_BEFORE,(AFUNPTR)Update,IARG_UINT32, totInsInBbl, IARG_UINT32, totBytes, IARG_THREAD_ID, IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_END); check = true; } } From b8594e2655f49be0d684dd1ad77202af82d957d4 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Mon, 10 Oct 2016 10:56:59 -0400 Subject: [PATCH 10/18] updated in August --- AUTHORS | 0 COPYING | 0 ChangeLog | 0 INSTALL | 0 Makefile.am | 0 Makefile.in | 0 NEWS | 0 README | 0 aclocal.m4 | 0 build.sh | 0 configure.ac | 0 externals/boost_1_56_0.tar.bz2 | Bin externals/libelf-0.8.9.tar.gz | Bin externals/sparsehash-2.0.2.tar.gz | Bin src/Makefile.am | 0 src/Makefile.in | 0 src/cctlib.H | 0 src/cctlib.cpp | 0 src/config.h.in | 0 tests/Makefile.am | 0 tests/Makefile.in | 0 tests/cct_client.cpp | 0 tests/cct_client_mem_only.cpp | 0 tests/cct_data_centric_client.cpp | 0 tests/cct_data_centric_client_tree_based.cpp | 0 tests/cct_data_name.cpp | 0 tests/cct_metric_client.cpp | 0 tests/cctlib_reader.cpp | 0 tests/deadWrites.cpp | 0 tests/deadspy_client.cpp | 0 tests/footprint_client.cpp | 0 tests/footprint_client2.cpp | 0 tests/footprint_test/Makefile | 0 tests/footprint_test/test1.c | 0 tests/footprint_test/test2.c | 0 tests/footprint_test/test3.c | 0 tests/footprint_test/test4.c | 0 tests/footprint_test/test5.c | 0 tests/footprint_test/test6.c | 0 tests/omp_datarace_client.cpp | 0 tests/redspy_client.cpp | 0 tests/redspy_client_merge.cpp | 0 tests/redspy_reg_client.cpp | 0 tests/redspy_spatial_approx_client.cpp | 0 tests/redspy_spatial_client.cpp | 0 tests/redspy_temporal_approx_client.cpp | 0 tests/redspy_temporal_client.cpp | 0 tests/shadow_memory.cpp | 0 tests/snippet.cpp | 0 tests/threaded.c | 0 tests/valueNum.cpp | 0 tests/valueNum_test/Makefile | 0 tests/valueNum_test/test.c | 0 tests/valueNum_test/test2.c | 0 tests/valueNum_test/test3.c | 0 tests/valueNum_test/test4.c | 0 tests/valueNum_test/test5.c | 0 tests/valueNum_test/test6.c | 0 tests/valueNum_test/testArray.c | 0 59 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 AUTHORS mode change 100644 => 100755 COPYING mode change 100644 => 100755 ChangeLog mode change 100644 => 100755 INSTALL mode change 100644 => 100755 Makefile.am mode change 100644 => 100755 Makefile.in mode change 100644 => 100755 NEWS mode change 100644 => 100755 README mode change 100644 => 100755 aclocal.m4 mode change 100644 => 100755 build.sh mode change 100644 => 100755 configure.ac mode change 100644 => 100755 externals/boost_1_56_0.tar.bz2 mode change 100644 => 100755 externals/libelf-0.8.9.tar.gz mode change 100644 => 100755 externals/sparsehash-2.0.2.tar.gz mode change 100644 => 100755 src/Makefile.am mode change 100644 => 100755 src/Makefile.in mode change 100644 => 100755 src/cctlib.H mode change 100644 => 100755 src/cctlib.cpp mode change 100644 => 100755 src/config.h.in mode change 100644 => 100755 tests/Makefile.am mode change 100644 => 100755 tests/Makefile.in mode change 100644 => 100755 tests/cct_client.cpp mode change 100644 => 100755 tests/cct_client_mem_only.cpp mode change 100644 => 100755 tests/cct_data_centric_client.cpp mode change 100644 => 100755 tests/cct_data_centric_client_tree_based.cpp mode change 100644 => 100755 tests/cct_data_name.cpp mode change 100644 => 100755 tests/cct_metric_client.cpp mode change 100644 => 100755 tests/cctlib_reader.cpp mode change 100644 => 100755 tests/deadWrites.cpp mode change 100644 => 100755 tests/deadspy_client.cpp mode change 100644 => 100755 tests/footprint_client.cpp mode change 100644 => 100755 tests/footprint_client2.cpp mode change 100644 => 100755 tests/footprint_test/Makefile mode change 100644 => 100755 tests/footprint_test/test1.c mode change 100644 => 100755 tests/footprint_test/test2.c mode change 100644 => 100755 tests/footprint_test/test3.c mode change 100644 => 100755 tests/footprint_test/test4.c mode change 100644 => 100755 tests/footprint_test/test5.c mode change 100644 => 100755 tests/footprint_test/test6.c mode change 100644 => 100755 tests/omp_datarace_client.cpp mode change 100644 => 100755 tests/redspy_client.cpp mode change 100644 => 100755 tests/redspy_client_merge.cpp mode change 100644 => 100755 tests/redspy_reg_client.cpp mode change 100644 => 100755 tests/redspy_spatial_approx_client.cpp mode change 100644 => 100755 tests/redspy_spatial_client.cpp mode change 100644 => 100755 tests/redspy_temporal_approx_client.cpp mode change 100644 => 100755 tests/redspy_temporal_client.cpp mode change 100644 => 100755 tests/shadow_memory.cpp mode change 100644 => 100755 tests/snippet.cpp mode change 100644 => 100755 tests/threaded.c mode change 100644 => 100755 tests/valueNum.cpp mode change 100644 => 100755 tests/valueNum_test/Makefile mode change 100644 => 100755 tests/valueNum_test/test.c mode change 100644 => 100755 tests/valueNum_test/test2.c mode change 100644 => 100755 tests/valueNum_test/test3.c mode change 100644 => 100755 tests/valueNum_test/test4.c mode change 100644 => 100755 tests/valueNum_test/test5.c mode change 100644 => 100755 tests/valueNum_test/test6.c mode change 100644 => 100755 tests/valueNum_test/testArray.c diff --git a/AUTHORS b/AUTHORS old mode 100644 new mode 100755 diff --git a/COPYING b/COPYING old mode 100644 new mode 100755 diff --git a/ChangeLog b/ChangeLog old mode 100644 new mode 100755 diff --git a/INSTALL b/INSTALL old mode 100644 new mode 100755 diff --git a/Makefile.am b/Makefile.am old mode 100644 new mode 100755 diff --git a/Makefile.in b/Makefile.in old mode 100644 new mode 100755 diff --git a/NEWS b/NEWS old mode 100644 new mode 100755 diff --git a/README b/README old mode 100644 new mode 100755 diff --git a/aclocal.m4 b/aclocal.m4 old mode 100644 new mode 100755 diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/configure.ac b/configure.ac old mode 100644 new mode 100755 diff --git a/externals/boost_1_56_0.tar.bz2 b/externals/boost_1_56_0.tar.bz2 old mode 100644 new mode 100755 diff --git a/externals/libelf-0.8.9.tar.gz b/externals/libelf-0.8.9.tar.gz old mode 100644 new mode 100755 diff --git a/externals/sparsehash-2.0.2.tar.gz b/externals/sparsehash-2.0.2.tar.gz old mode 100644 new mode 100755 diff --git a/src/Makefile.am b/src/Makefile.am old mode 100644 new mode 100755 diff --git a/src/Makefile.in b/src/Makefile.in old mode 100644 new mode 100755 diff --git a/src/cctlib.H b/src/cctlib.H old mode 100644 new mode 100755 diff --git a/src/cctlib.cpp b/src/cctlib.cpp old mode 100644 new mode 100755 diff --git a/src/config.h.in b/src/config.h.in old mode 100644 new mode 100755 diff --git a/tests/Makefile.am b/tests/Makefile.am old mode 100644 new mode 100755 diff --git a/tests/Makefile.in b/tests/Makefile.in old mode 100644 new mode 100755 diff --git a/tests/cct_client.cpp b/tests/cct_client.cpp old mode 100644 new mode 100755 diff --git a/tests/cct_client_mem_only.cpp b/tests/cct_client_mem_only.cpp old mode 100644 new mode 100755 diff --git a/tests/cct_data_centric_client.cpp b/tests/cct_data_centric_client.cpp old mode 100644 new mode 100755 diff --git a/tests/cct_data_centric_client_tree_based.cpp b/tests/cct_data_centric_client_tree_based.cpp old mode 100644 new mode 100755 diff --git a/tests/cct_data_name.cpp b/tests/cct_data_name.cpp old mode 100644 new mode 100755 diff --git a/tests/cct_metric_client.cpp b/tests/cct_metric_client.cpp old mode 100644 new mode 100755 diff --git a/tests/cctlib_reader.cpp b/tests/cctlib_reader.cpp old mode 100644 new mode 100755 diff --git a/tests/deadWrites.cpp b/tests/deadWrites.cpp old mode 100644 new mode 100755 diff --git a/tests/deadspy_client.cpp b/tests/deadspy_client.cpp old mode 100644 new mode 100755 diff --git a/tests/footprint_client.cpp b/tests/footprint_client.cpp old mode 100644 new mode 100755 diff --git a/tests/footprint_client2.cpp b/tests/footprint_client2.cpp old mode 100644 new mode 100755 diff --git a/tests/footprint_test/Makefile b/tests/footprint_test/Makefile old mode 100644 new mode 100755 diff --git a/tests/footprint_test/test1.c b/tests/footprint_test/test1.c old mode 100644 new mode 100755 diff --git a/tests/footprint_test/test2.c b/tests/footprint_test/test2.c old mode 100644 new mode 100755 diff --git a/tests/footprint_test/test3.c b/tests/footprint_test/test3.c old mode 100644 new mode 100755 diff --git a/tests/footprint_test/test4.c b/tests/footprint_test/test4.c old mode 100644 new mode 100755 diff --git a/tests/footprint_test/test5.c b/tests/footprint_test/test5.c old mode 100644 new mode 100755 diff --git a/tests/footprint_test/test6.c b/tests/footprint_test/test6.c old mode 100644 new mode 100755 diff --git a/tests/omp_datarace_client.cpp b/tests/omp_datarace_client.cpp old mode 100644 new mode 100755 diff --git a/tests/redspy_client.cpp b/tests/redspy_client.cpp old mode 100644 new mode 100755 diff --git a/tests/redspy_client_merge.cpp b/tests/redspy_client_merge.cpp old mode 100644 new mode 100755 diff --git a/tests/redspy_reg_client.cpp b/tests/redspy_reg_client.cpp old mode 100644 new mode 100755 diff --git a/tests/redspy_spatial_approx_client.cpp b/tests/redspy_spatial_approx_client.cpp old mode 100644 new mode 100755 diff --git a/tests/redspy_spatial_client.cpp b/tests/redspy_spatial_client.cpp old mode 100644 new mode 100755 diff --git a/tests/redspy_temporal_approx_client.cpp b/tests/redspy_temporal_approx_client.cpp old mode 100644 new mode 100755 diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp old mode 100644 new mode 100755 diff --git a/tests/shadow_memory.cpp b/tests/shadow_memory.cpp old mode 100644 new mode 100755 diff --git a/tests/snippet.cpp b/tests/snippet.cpp old mode 100644 new mode 100755 diff --git a/tests/threaded.c b/tests/threaded.c old mode 100644 new mode 100755 diff --git a/tests/valueNum.cpp b/tests/valueNum.cpp old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/Makefile b/tests/valueNum_test/Makefile old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/test.c b/tests/valueNum_test/test.c old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/test2.c b/tests/valueNum_test/test2.c old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/test3.c b/tests/valueNum_test/test3.c old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/test4.c b/tests/valueNum_test/test4.c old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/test5.c b/tests/valueNum_test/test5.c old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/test6.c b/tests/valueNum_test/test6.c old mode 100644 new mode 100755 diff --git a/tests/valueNum_test/testArray.c b/tests/valueNum_test/testArray.c old mode 100644 new mode 100755 From 947fc720969ef78f3612a74c8a5ffd6844fe58b1 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Mon, 10 Oct 2016 11:10:57 -0400 Subject: [PATCH 11/18] Revert "updated in August" This reverts commit b8594e2655f49be0d684dd1ad77202af82d957d4. --- AUTHORS | 0 COPYING | 0 ChangeLog | 0 INSTALL | 0 Makefile.am | 0 Makefile.in | 0 NEWS | 0 README | 0 aclocal.m4 | 0 build.sh | 0 configure.ac | 0 externals/boost_1_56_0.tar.bz2 | Bin externals/libelf-0.8.9.tar.gz | Bin externals/sparsehash-2.0.2.tar.gz | Bin src/Makefile.am | 0 src/Makefile.in | 0 src/cctlib.H | 0 src/cctlib.cpp | 0 src/config.h.in | 0 tests/Makefile.am | 0 tests/Makefile.in | 0 tests/cct_client.cpp | 0 tests/cct_client_mem_only.cpp | 0 tests/cct_data_centric_client.cpp | 0 tests/cct_data_centric_client_tree_based.cpp | 0 tests/cct_data_name.cpp | 0 tests/cct_metric_client.cpp | 0 tests/cctlib_reader.cpp | 0 tests/deadWrites.cpp | 0 tests/deadspy_client.cpp | 0 tests/footprint_client.cpp | 0 tests/footprint_client2.cpp | 0 tests/footprint_test/Makefile | 0 tests/footprint_test/test1.c | 0 tests/footprint_test/test2.c | 0 tests/footprint_test/test3.c | 0 tests/footprint_test/test4.c | 0 tests/footprint_test/test5.c | 0 tests/footprint_test/test6.c | 0 tests/omp_datarace_client.cpp | 0 tests/redspy_client.cpp | 0 tests/redspy_client_merge.cpp | 0 tests/redspy_reg_client.cpp | 0 tests/redspy_spatial_approx_client.cpp | 0 tests/redspy_spatial_client.cpp | 0 tests/redspy_temporal_approx_client.cpp | 0 tests/redspy_temporal_client.cpp | 0 tests/shadow_memory.cpp | 0 tests/snippet.cpp | 0 tests/threaded.c | 0 tests/valueNum.cpp | 0 tests/valueNum_test/Makefile | 0 tests/valueNum_test/test.c | 0 tests/valueNum_test/test2.c | 0 tests/valueNum_test/test3.c | 0 tests/valueNum_test/test4.c | 0 tests/valueNum_test/test5.c | 0 tests/valueNum_test/test6.c | 0 tests/valueNum_test/testArray.c | 0 59 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 AUTHORS mode change 100755 => 100644 COPYING mode change 100755 => 100644 ChangeLog mode change 100755 => 100644 INSTALL mode change 100755 => 100644 Makefile.am mode change 100755 => 100644 Makefile.in mode change 100755 => 100644 NEWS mode change 100755 => 100644 README mode change 100755 => 100644 aclocal.m4 mode change 100755 => 100644 build.sh mode change 100755 => 100644 configure.ac mode change 100755 => 100644 externals/boost_1_56_0.tar.bz2 mode change 100755 => 100644 externals/libelf-0.8.9.tar.gz mode change 100755 => 100644 externals/sparsehash-2.0.2.tar.gz mode change 100755 => 100644 src/Makefile.am mode change 100755 => 100644 src/Makefile.in mode change 100755 => 100644 src/cctlib.H mode change 100755 => 100644 src/cctlib.cpp mode change 100755 => 100644 src/config.h.in mode change 100755 => 100644 tests/Makefile.am mode change 100755 => 100644 tests/Makefile.in mode change 100755 => 100644 tests/cct_client.cpp mode change 100755 => 100644 tests/cct_client_mem_only.cpp mode change 100755 => 100644 tests/cct_data_centric_client.cpp mode change 100755 => 100644 tests/cct_data_centric_client_tree_based.cpp mode change 100755 => 100644 tests/cct_data_name.cpp mode change 100755 => 100644 tests/cct_metric_client.cpp mode change 100755 => 100644 tests/cctlib_reader.cpp mode change 100755 => 100644 tests/deadWrites.cpp mode change 100755 => 100644 tests/deadspy_client.cpp mode change 100755 => 100644 tests/footprint_client.cpp mode change 100755 => 100644 tests/footprint_client2.cpp mode change 100755 => 100644 tests/footprint_test/Makefile mode change 100755 => 100644 tests/footprint_test/test1.c mode change 100755 => 100644 tests/footprint_test/test2.c mode change 100755 => 100644 tests/footprint_test/test3.c mode change 100755 => 100644 tests/footprint_test/test4.c mode change 100755 => 100644 tests/footprint_test/test5.c mode change 100755 => 100644 tests/footprint_test/test6.c mode change 100755 => 100644 tests/omp_datarace_client.cpp mode change 100755 => 100644 tests/redspy_client.cpp mode change 100755 => 100644 tests/redspy_client_merge.cpp mode change 100755 => 100644 tests/redspy_reg_client.cpp mode change 100755 => 100644 tests/redspy_spatial_approx_client.cpp mode change 100755 => 100644 tests/redspy_spatial_client.cpp mode change 100755 => 100644 tests/redspy_temporal_approx_client.cpp mode change 100755 => 100644 tests/redspy_temporal_client.cpp mode change 100755 => 100644 tests/shadow_memory.cpp mode change 100755 => 100644 tests/snippet.cpp mode change 100755 => 100644 tests/threaded.c mode change 100755 => 100644 tests/valueNum.cpp mode change 100755 => 100644 tests/valueNum_test/Makefile mode change 100755 => 100644 tests/valueNum_test/test.c mode change 100755 => 100644 tests/valueNum_test/test2.c mode change 100755 => 100644 tests/valueNum_test/test3.c mode change 100755 => 100644 tests/valueNum_test/test4.c mode change 100755 => 100644 tests/valueNum_test/test5.c mode change 100755 => 100644 tests/valueNum_test/test6.c mode change 100755 => 100644 tests/valueNum_test/testArray.c diff --git a/AUTHORS b/AUTHORS old mode 100755 new mode 100644 diff --git a/COPYING b/COPYING old mode 100755 new mode 100644 diff --git a/ChangeLog b/ChangeLog old mode 100755 new mode 100644 diff --git a/INSTALL b/INSTALL old mode 100755 new mode 100644 diff --git a/Makefile.am b/Makefile.am old mode 100755 new mode 100644 diff --git a/Makefile.in b/Makefile.in old mode 100755 new mode 100644 diff --git a/NEWS b/NEWS old mode 100755 new mode 100644 diff --git a/README b/README old mode 100755 new mode 100644 diff --git a/aclocal.m4 b/aclocal.m4 old mode 100755 new mode 100644 diff --git a/build.sh b/build.sh old mode 100755 new mode 100644 diff --git a/configure.ac b/configure.ac old mode 100755 new mode 100644 diff --git a/externals/boost_1_56_0.tar.bz2 b/externals/boost_1_56_0.tar.bz2 old mode 100755 new mode 100644 diff --git a/externals/libelf-0.8.9.tar.gz b/externals/libelf-0.8.9.tar.gz old mode 100755 new mode 100644 diff --git a/externals/sparsehash-2.0.2.tar.gz b/externals/sparsehash-2.0.2.tar.gz old mode 100755 new mode 100644 diff --git a/src/Makefile.am b/src/Makefile.am old mode 100755 new mode 100644 diff --git a/src/Makefile.in b/src/Makefile.in old mode 100755 new mode 100644 diff --git a/src/cctlib.H b/src/cctlib.H old mode 100755 new mode 100644 diff --git a/src/cctlib.cpp b/src/cctlib.cpp old mode 100755 new mode 100644 diff --git a/src/config.h.in b/src/config.h.in old mode 100755 new mode 100644 diff --git a/tests/Makefile.am b/tests/Makefile.am old mode 100755 new mode 100644 diff --git a/tests/Makefile.in b/tests/Makefile.in old mode 100755 new mode 100644 diff --git a/tests/cct_client.cpp b/tests/cct_client.cpp old mode 100755 new mode 100644 diff --git a/tests/cct_client_mem_only.cpp b/tests/cct_client_mem_only.cpp old mode 100755 new mode 100644 diff --git a/tests/cct_data_centric_client.cpp b/tests/cct_data_centric_client.cpp old mode 100755 new mode 100644 diff --git a/tests/cct_data_centric_client_tree_based.cpp b/tests/cct_data_centric_client_tree_based.cpp old mode 100755 new mode 100644 diff --git a/tests/cct_data_name.cpp b/tests/cct_data_name.cpp old mode 100755 new mode 100644 diff --git a/tests/cct_metric_client.cpp b/tests/cct_metric_client.cpp old mode 100755 new mode 100644 diff --git a/tests/cctlib_reader.cpp b/tests/cctlib_reader.cpp old mode 100755 new mode 100644 diff --git a/tests/deadWrites.cpp b/tests/deadWrites.cpp old mode 100755 new mode 100644 diff --git a/tests/deadspy_client.cpp b/tests/deadspy_client.cpp old mode 100755 new mode 100644 diff --git a/tests/footprint_client.cpp b/tests/footprint_client.cpp old mode 100755 new mode 100644 diff --git a/tests/footprint_client2.cpp b/tests/footprint_client2.cpp old mode 100755 new mode 100644 diff --git a/tests/footprint_test/Makefile b/tests/footprint_test/Makefile old mode 100755 new mode 100644 diff --git a/tests/footprint_test/test1.c b/tests/footprint_test/test1.c old mode 100755 new mode 100644 diff --git a/tests/footprint_test/test2.c b/tests/footprint_test/test2.c old mode 100755 new mode 100644 diff --git a/tests/footprint_test/test3.c b/tests/footprint_test/test3.c old mode 100755 new mode 100644 diff --git a/tests/footprint_test/test4.c b/tests/footprint_test/test4.c old mode 100755 new mode 100644 diff --git a/tests/footprint_test/test5.c b/tests/footprint_test/test5.c old mode 100755 new mode 100644 diff --git a/tests/footprint_test/test6.c b/tests/footprint_test/test6.c old mode 100755 new mode 100644 diff --git a/tests/omp_datarace_client.cpp b/tests/omp_datarace_client.cpp old mode 100755 new mode 100644 diff --git a/tests/redspy_client.cpp b/tests/redspy_client.cpp old mode 100755 new mode 100644 diff --git a/tests/redspy_client_merge.cpp b/tests/redspy_client_merge.cpp old mode 100755 new mode 100644 diff --git a/tests/redspy_reg_client.cpp b/tests/redspy_reg_client.cpp old mode 100755 new mode 100644 diff --git a/tests/redspy_spatial_approx_client.cpp b/tests/redspy_spatial_approx_client.cpp old mode 100755 new mode 100644 diff --git a/tests/redspy_spatial_client.cpp b/tests/redspy_spatial_client.cpp old mode 100755 new mode 100644 diff --git a/tests/redspy_temporal_approx_client.cpp b/tests/redspy_temporal_approx_client.cpp old mode 100755 new mode 100644 diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp old mode 100755 new mode 100644 diff --git a/tests/shadow_memory.cpp b/tests/shadow_memory.cpp old mode 100755 new mode 100644 diff --git a/tests/snippet.cpp b/tests/snippet.cpp old mode 100755 new mode 100644 diff --git a/tests/threaded.c b/tests/threaded.c old mode 100755 new mode 100644 diff --git a/tests/valueNum.cpp b/tests/valueNum.cpp old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/Makefile b/tests/valueNum_test/Makefile old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/test.c b/tests/valueNum_test/test.c old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/test2.c b/tests/valueNum_test/test2.c old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/test3.c b/tests/valueNum_test/test3.c old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/test4.c b/tests/valueNum_test/test4.c old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/test5.c b/tests/valueNum_test/test5.c old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/test6.c b/tests/valueNum_test/test6.c old mode 100755 new mode 100644 diff --git a/tests/valueNum_test/testArray.c b/tests/valueNum_test/testArray.c old mode 100755 new mode 100644 From ebe2afb33289c8202c2d8161f3f450d3a7cd722b Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Mon, 10 Oct 2016 16:02:20 -0400 Subject: [PATCH 12/18] add spatial userdefined client --- tests/redspy_spatial_userdefine_client.cpp | 411 +++++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 tests/redspy_spatial_userdefine_client.cpp diff --git a/tests/redspy_spatial_userdefine_client.cpp b/tests/redspy_spatial_userdefine_client.cpp new file mode 100644 index 0000000..2f78976 --- /dev/null +++ b/tests/redspy_spatial_userdefine_client.cpp @@ -0,0 +1,411 @@ +// * BeginRiceCopyright ***************************************************** +// +// Copyright ((c)) 2002-2014, Rice University +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of Rice University (RICE) nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// This software is provided by RICE and contributors "as is" and any +// express or implied warranties, including, but not limited to, the +// implied warranties of merchantability and fitness for a particular +// purpose are disclaimed. In no event shall RICE or contributors be +// liable for any direct, indirect, incidental, special, exemplary, or +// consequential damages (including, but not limited to, procurement of +// substitute goods or services; loss of use, data, or profits; or +// business interruption) however caused and on any theory of liability, +// whether in contract, strict liability, or tort (including negligence +// or otherwise) arising in any way out of the use of this software, even +// if advised of the possibility of such damage. +// +// ******************************************************* EndRiceCopyright * + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pin.H" + +//enable Data-centric +#define USE_TREE_BASED_FOR_DATA_CENTRIC +#define USE_TREE_WITH_ADDR +#include "cctlib.H" +using namespace std; +using namespace PinCCTLib; + +#define THREAD_MAX (1024) + + +#define MAX_WRITE_OP_LENGTH (512) +#define MAX_WRITE_OPS_IN_INS (8) + +#define DATA_TYPES_NUM (2) +#define DATA_DYNAMIC (0) +#define DATA_STATIC (1) + +#define ARRAY_SIZE_LIMIT (10) + +#define SAME_RATE (0.1) +#define SAME_RECORD_LIMIT (0) +#define RED_RATE (0.9) + +#define ARRAY_UPDATE_THRESHOLD(a) (a/4) +#define MAKE_CONTEXT_PAIR(a, b) (((uint64_t)(a) << 32) | ((uint64_t)(b))) + +#define ARRAY_ANALYSIS_FN_NAME "Analyze_this_array" + + +typedef struct valueGroup{ + list indexes; +}ValueGroup; + +typedef struct intraRedRecord{ + double redundancy; + uint32_t curCtxt; + list group; + list spatialRedInd; +}IntraRedRecord; + +struct RedSpyThreadData{ + + long long numIns; +}; + +//helper struct used to + +// key for accessing TLS storage in the threads. initialized once in main() +static TLS_KEY client_tls_key; +static RedSpyThreadData* gSingleThreadedTData; + +// function to access thread-specific data +inline RedSpyThreadData* ClientGetTLS(const THREADID threadId) { +#ifdef MULTI_THREADED + RedSpyThreadData* tdata = + static_cast(PIN_GetThreadData(client_tls_key, threadId)); + return tdata; +#else + return gSingleThreadedTData; +#endif +} + + +INT32 Usage2() { + PIN_ERROR("Pin tool to gather calling context on each load and store.\n" + KNOB_BASE::StringKnobSummary() + "\n"); + return -1; +} + +// Main for RedSpy, initialize the tool, register instrumentation functions and call the target program. +static FILE* gTraceFile; +uint32_t lastStatic; +// Initialized the needed data structures before launching the target program +static void ClientInit(int argc, char* argv[]) { + // Create output file + char name[MAX_FILE_PATH] = "redspy_spatial_selected.out."; + char* envPath = getenv("CCTLIB_CLIENT_OUTPUT_FILE"); + + if(envPath) { + // assumes max of MAX_FILE_PATH + strcpy(name, envPath); + } + + gethostname(name + strlen(name), MAX_FILE_PATH - strlen(name)); + pid_t pid = getpid(); + sprintf(name + strlen(name), "%d", pid); + cerr << "\n Creating log file at:" << name << "\n"; + gTraceFile = fopen(name, "w"); + // print the arguments passed + fprintf(gTraceFile, "\n"); + + for(int i = 0 ; i < argc; i++) { + fprintf(gTraceFile, "%s ", argv[i]); + } + + fprintf(gTraceFile, "\n"); +} + +static unordered_map> arrayDataRed[THREAD_MAX]; + + + +//type:DATA_DYNAMIC means dynamic data object while DATA_STATIC means static +VOID inline RecordIntraArrayRedundancy(string name, IntraRedRecord redPair,THREADID threadId){ + + unordered_map>::iterator it; + it = arrayDataRed[threadId].find(name); + if(it == arrayDataRed[threadId].end()){ + list newlist; + newlist.push_back(redPair); + arrayDataRed[threadId].insert(std::pair>(name,newlist)); + }else{ + it->second.push_back(redPair); + } +} + +template +struct ArrayAnalysis{ + + typedef typename unordered_map>::iterator MyIterator; + + static __attribute__((always_inline)) bool CheckIntraArrayRedundancy(uint64_t begAddr, uint64_t endAddr, uint32_t stride, IntraRedRecord * newPair ){ + + unordered_map> valuesMap; + MyIterator mapIt; + list spatialRedIndex; + uint64_t address = begAddr; + uint32_t index = 0; + T valueLast = 0; + while(address < endAddr){ + + T value = *static_cast((void *)address); + if(value == valueLast) + spatialRedIndex.push_back(index); + mapIt = valuesMap.find(value); + if(mapIt == valuesMap.end()){ + list newlist; + newlist.push_back(index); + valuesMap.insert(std::pair>(value,newlist)); + }else{ + mapIt->second.push_back(index); + } + address += stride; + index++; + valueLast = value; + } + uint32_t numUniqueValue = valuesMap.size(); + double redRate = (double)(index - numUniqueValue)/index; + list maxList; + for (mapIt = valuesMap.begin(); mapIt != valuesMap.end(); ++mapIt){ + if(mapIt->second.size() > index*SAME_RATE){ + ValueGroup newGroup; + newGroup.indexes = mapIt->second; + maxList.push_back(newGroup); + } + } + if(redRate > RED_RATE || maxList.size() > SAME_RECORD_LIMIT){ + newPair->redundancy = redRate; + newPair->group = maxList; + newPair->spatialRedInd = spatialRedIndex; + return true; + } + return false; + } +}; + +static VOID InstrumentInsCallback(INS ins, VOID* v, const uint32_t opaqueHandle) { + ; +} + +void new_ARRAY_ANALYSIS_FN_NAME(char * name, void * addr, uint32_t typeSize, uint32_t stride, THREADID threadId){ + printf("name:%s, addr:%p, type:%d, stride:%d\n",name,addr,typeSize,stride); + string str(name); + + DataHandle_t dataHandle = GetDataObjectHandle(addr,threadId); + IntraRedRecord newRecord; + bool hasRedundant = false; + + switch (typeSize) { + case 1: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + case 2: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + case 4: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + case 8: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + default: + break; + } + if(hasRedundant) + RecordIntraArrayRedundancy( name, newRecord, threadId); +} + +VOID Overrides (IMG img, VOID * v) { + // Master setup + RTN rtn = RTN_FindByName (img, ARRAY_ANALYSIS_FN_NAME); + if (RTN_Valid (rtn)) { + // Define a function prototype that describes the application routine + // that will be replaced. + // + PROTO proto_master = PROTO_Allocate (PIN_PARG (void), CALLINGSTD_DEFAULT, + ARRAY_ANALYSIS_FN_NAME,PIN_PARG (char *),PIN_PARG (void *),PIN_PARG (uint32_t),PIN_PARG (uint32_t), + PIN_PARG_END ()); + + // Replace the application routine with the replacement function. + // Additional arguments have been added to the replacement routine. + // + RTN_ReplaceSignature (rtn, AFUNPTR (new_ARRAY_ANALYSIS_FN_NAME), + IARG_PROTOTYPE, proto_master, + IARG_FUNCARG_ENTRYPOINT_VALUE, 0, + IARG_FUNCARG_ENTRYPOINT_VALUE, 1, + IARG_FUNCARG_ENTRYPOINT_VALUE, 2, + IARG_FUNCARG_ENTRYPOINT_VALUE, 3, + IARG_THREAD_ID, IARG_END); + // Free the function prototype. + PROTO_Free (proto_master); + } +} + + +struct RedundacyData { + ContextHandle_t dead; + ContextHandle_t kill; + uint64_t frequency; +}; + +static inline string ConvertListToString(list inlist){ + + list::iterator it = inlist.begin(); + uint32_t tmp = (*it); + string indexList = "[" + to_string(tmp) + ","; + it++; + while(it != inlist.end()){ + if(*it == tmp + 1){ + tmp = *it; + } + else{ + indexList += to_string(tmp) + "],[" + to_string(*it)+ ","; + tmp = *it; + } + it++; + } + indexList += to_string(tmp) + "]"; + return indexList; +} + + +static inline bool RedundacyCompare(const struct RedundacyData &first, const struct RedundacyData &second) { + return first.frequency > second.frequency ? true : false; +} + +static void PrintRedundancyPairs(THREADID threadId) { + + fprintf(gTraceFile,"\n*************** Intra Array Redundancy of Thread %d ***************\n",threadId); + unordered_map>::iterator itIntra; + + fprintf(gTraceFile,"========== Selected Dataobjecy Redundancy ==========\n"); + for(itIntra = arrayDataRed[threadId].begin(); itIntra != arrayDataRed[threadId].end(); ++itIntra){ + + fprintf(gTraceFile,"\nVariable %s at \n",(itIntra->first).c_str()); + ////////////////////////////////////////////////////////////// + // PrintFullCallingContext(contxt); + list::iterator listIt; + for(listIt = itIntra->second.begin(); listIt != itIntra->second.end(); ++listIt){ + + fprintf(gTraceFile,"\nRed:%.2f, unique value large index group:\n",(*listIt).redundancy); + list::iterator groupIt; + int num = 0; + for (groupIt = (*listIt).group.begin(); groupIt != (*listIt).group.end(); ++groupIt) { + string indexlist = ConvertListToString((*groupIt).indexes); + fprintf(gTraceFile,"Group %d: %s\n",num, indexlist.c_str()); + } + string indexlist = ConvertListToString((*listIt).spatialRedInd); + fprintf(gTraceFile,"redundant spatial indexes:%s\n",indexlist.c_str()); + + } + fprintf(gTraceFile,"\n----------------------------"); + } +} + +// On each Unload of a loaded image, the accummulated redundancy information is dumped +static VOID ImageUnload(IMG img, VOID* v) { + fprintf(gTraceFile, "\n TODO .. Multi-threading is not well supported."); + THREADID threadid = PIN_ThreadId(); + fprintf(gTraceFile, "\nUnloading %s", IMG_Name(img).c_str()); + // Update gTotalInstCount first + PIN_LockClient(); + PrintRedundancyPairs(threadid); + PIN_UnlockClient(); + // clear redmap now + arrayDataRed[threadid].clear(); +} + +static VOID ThreadFiniFunc(THREADID threadId, const CONTEXT *ctxt, INT32 code, VOID *v) { + +} + +static VOID FiniFunc(INT32 code, VOID *v) { + // do whatever you want to the full CCT with footpirnt +} + + +static void InitThreadData(RedSpyThreadData* tdata){ + + tdata->numIns = 0; +} + +static VOID ThreadStart(THREADID threadid, CONTEXT* ctxt, INT32 flags, VOID* v) { + RedSpyThreadData* tdata = new RedSpyThreadData(); + InitThreadData(tdata); + // __sync_fetch_and_add(&gClientNumThreads, 1); + PIN_SetThreadData(client_tls_key, tdata, threadid); +#ifdef MULTI_THREADED + PIN_SetThreadData(client_tls_key, tdata, threadid); +#else + gSingleThreadedTData = tdata; +#endif +} + + +int main(int argc, char* argv[]) { + // Initialize PIN + if(PIN_Init(argc, argv)) + return Usage2(); + + // Initialize Symbols, we need them to report functions and lines + PIN_InitSymbols(); + + // Init Client + ClientInit(argc, argv); + // Intialize CCTLib + PinCCTLibInit(INTERESTING_INS_MEMORY_ACCESS, gTraceFile, InstrumentInsCallback, 0, true); + + + // Obtain a key for TLS storage. + client_tls_key = PIN_CreateThreadDataKey(0 /*TODO have a destructir*/); + // Register ThreadStart to be called when a thread starts. + PIN_AddThreadStartFunction(ThreadStart, 0); + + + // fini function for post-mortem analysis + PIN_AddThreadFiniFunction(ThreadFiniFunc, 0); + PIN_AddFiniFunction(FiniFunc, 0); + + IMG_AddInstrumentFunction(Overrides, 0); + + // Register ImageUnload to be called when an image is unloaded + IMG_AddUnloadFunction(ImageUnload, 0); + + // Launch program now + PIN_StartProgram(); + return 0; +} + + From 7540e6a1f8ae0af341d528af2bf54fcb589a34ed Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Thu, 1 Dec 2016 16:54:26 -0500 Subject: [PATCH 13/18] add context and register spatial locality for spatial userdefine client; add more register alias and handle AVX256 for temporal client; --- tests/redspy_spatial_userdefine_client.cpp | 300 ++++++++++-- tests/redspy_temporal_client.cpp | 504 +++++++++++++++++---- 2 files changed, 679 insertions(+), 125 deletions(-) diff --git a/tests/redspy_spatial_userdefine_client.cpp b/tests/redspy_spatial_userdefine_client.cpp index 2f78976..cac712f 100644 --- a/tests/redspy_spatial_userdefine_client.cpp +++ b/tests/redspy_spatial_userdefine_client.cpp @@ -59,19 +59,17 @@ using namespace PinCCTLib; #define THREAD_MAX (1024) - -#define MAX_WRITE_OP_LENGTH (512) -#define MAX_WRITE_OPS_IN_INS (8) - -#define DATA_TYPES_NUM (2) -#define DATA_DYNAMIC (0) -#define DATA_STATIC (1) - -#define ARRAY_SIZE_LIMIT (10) +#define GEN_REG_NUM (16) +#define GEN_REG_LEN (8) +#define X87_REG_NUM (8) +#define X87_REG_LEN (10) +#define SIMD_REG_NUM (16) +#define SIMD_REG_LEN (32) #define SAME_RATE (0.1) #define SAME_RECORD_LIMIT (0) #define RED_RATE (0.9) +#define APPROX_RATE (0.01) #define ARRAY_UPDATE_THRESHOLD(a) (a/4) #define MAKE_CONTEXT_PAIR(a, b) (((uint64_t)(a) << 32) | ((uint64_t)(b))) @@ -90,6 +88,12 @@ typedef struct intraRedRecord{ list spatialRedInd; }IntraRedRecord; +typedef struct intraRegsRed{ + double genRegRed; + double x87RegRed; + double simdRegRed; +}IntraRegsRed; + struct RedSpyThreadData{ long long numIns; @@ -148,10 +152,22 @@ static void ClientInit(int argc, char* argv[]) { } static unordered_map> arrayDataRed[THREAD_MAX]; +static unordered_map> regsRed[THREAD_MAX]; +VOID inline RecordIntraRegsRedundancy(uint32_t ctxt, IntraRegsRed redPair,THREADID threadId){ + + unordered_map>::iterator it; + it = regsRed[threadId].find(ctxt); + if(it == regsRed[threadId].end()){ + list newlist; + newlist.push_back(redPair); + regsRed[threadId].insert(std::pair>(ctxt,newlist)); + }else{ + it->second.push_back(redPair); + } +} -//type:DATA_DYNAMIC means dynamic data object while DATA_STATIC means static VOID inline RecordIntraArrayRedundancy(string name, IntraRedRecord redPair,THREADID threadId){ unordered_map>::iterator it; @@ -165,7 +181,152 @@ VOID inline RecordIntraArrayRedundancy(string name, IntraRedRecord redPair,THREA } } -template +static void CheckRegValues(CONTEXT * ctxt,THREADID threadId){ + + RedSpyThreadData* const tData = ClientGetTLS(threadId); + //ContextHandle_t curCtxtHandle = GetContextHandle(threadId, 0); + + //get values for general registers + UINT8 ** genRegs; + genRegs = (UINT8 **)malloc(GEN_REG_NUM * sizeof(UINT8 *)); + for (int i = 0; i < GEN_REG_NUM; ++i) { + genRegs[i] = (UINT8 *)malloc(GEN_REG_LEN * sizeof(UINT8)); + } + + PIN_GetContextRegval(ctxt,REG_RAX,genRegs[0]); + PIN_GetContextRegval(ctxt,REG_RBX,genRegs[1]); + PIN_GetContextRegval(ctxt,REG_RCX,genRegs[2]); + PIN_GetContextRegval(ctxt,REG_RDX,genRegs[3]); + + PIN_GetContextRegval(ctxt,REG_RBP,genRegs[4]); + PIN_GetContextRegval(ctxt,REG_RDI,genRegs[5]); + PIN_GetContextRegval(ctxt,REG_RSI,genRegs[6]); + PIN_GetContextRegval(ctxt,REG_RSP,genRegs[7]); + + PIN_GetContextRegval(ctxt,REG_R8,genRegs[8]); + PIN_GetContextRegval(ctxt,REG_R9,genRegs[9]); + PIN_GetContextRegval(ctxt,REG_R10,genRegs[10]); + PIN_GetContextRegval(ctxt,REG_R11,genRegs[11]); + PIN_GetContextRegval(ctxt,REG_R12,genRegs[12]); + PIN_GetContextRegval(ctxt,REG_R13,genRegs[13]); + PIN_GetContextRegval(ctxt,REG_R14,genRegs[14]); + PIN_GetContextRegval(ctxt,REG_R15,genRegs[15]); + + //get values for X87 registers + UINT8 ** x87Regs; + x87Regs = (UINT8 **)malloc(X87_REG_NUM * sizeof(UINT8 *)); + for (int i = 0; i < X87_REG_NUM; ++i) { + x87Regs[i] = (UINT8 *)malloc(X87_REG_LEN * sizeof(UINT8)); + } + + PIN_GetContextRegval(ctxt,REG_ST0,x87Regs[0]); + PIN_GetContextRegval(ctxt,REG_ST1,x87Regs[1]); + PIN_GetContextRegval(ctxt,REG_ST2,x87Regs[2]); + PIN_GetContextRegval(ctxt,REG_ST3,x87Regs[3]); + PIN_GetContextRegval(ctxt,REG_ST4,x87Regs[4]); + PIN_GetContextRegval(ctxt,REG_ST5,x87Regs[5]); + PIN_GetContextRegval(ctxt,REG_ST6,x87Regs[6]); + PIN_GetContextRegval(ctxt,REG_ST7,x87Regs[7]); + + //get values for SIMD registers + UINT8 ** simdRegs; + simdRegs = (UINT8 **)malloc(SIMD_REG_NUM * sizeof(UINT8 *)); + for (int i = 0; i < SIMD_REG_NUM; ++i) { + simdRegs[i] = (UINT8 *)malloc(SIMD_REG_LEN * sizeof(UINT8)); + } + + PIN_GetContextRegval(ctxt,REG_YMM0,simdRegs[0]); + PIN_GetContextRegval(ctxt,REG_YMM1,simdRegs[1]); + PIN_GetContextRegval(ctxt,REG_YMM2,simdRegs[2]); + PIN_GetContextRegval(ctxt,REG_YMM3,simdRegs[3]); + PIN_GetContextRegval(ctxt,REG_YMM4,simdRegs[4]); + PIN_GetContextRegval(ctxt,REG_YMM5,simdRegs[5]); + PIN_GetContextRegval(ctxt,REG_YMM6,simdRegs[6]); + PIN_GetContextRegval(ctxt,REG_YMM7,simdRegs[7]); + PIN_GetContextRegval(ctxt,REG_YMM8,simdRegs[8]); + PIN_GetContextRegval(ctxt,REG_YMM9,simdRegs[9]); + PIN_GetContextRegval(ctxt,REG_YMM10,simdRegs[10]); + PIN_GetContextRegval(ctxt,REG_YMM11,simdRegs[11]); + PIN_GetContextRegval(ctxt,REG_YMM12,simdRegs[12]); + PIN_GetContextRegval(ctxt,REG_YMM13,simdRegs[13]); + PIN_GetContextRegval(ctxt,REG_YMM14,simdRegs[14]); + PIN_GetContextRegval(ctxt,REG_YMM15,simdRegs[15]); + + int index = 0; + int i,j; + + //check redundancy in general registers + uint64_t valuesMap[GEN_REG_NUM]; + valuesMap[index++] = *(uint64_t *)(genRegs[0]); + + for (int i = 1; i < GEN_REG_NUM; ++i) { + + for (j = 0; j < index; ++j) { + if (*(uint64_t *)(genRegs[i]) == valuesMap[j]) { + break; + } + } + if (j >= index) { + valuesMap[index++] = *(uint64_t *)(genRegs[i]); + } + } + + float genRegRate = (float)index/GEN_REG_NUM; + + //check redundancy in x87 registers + UINT8 ** x87values; + x87values = (UINT8 **)malloc(X87_REG_NUM * sizeof(UINT8 *)); + for (int i = 0; i < X87_REG_NUM; ++i) { + x87values[i] = (UINT8 *)malloc(X87_REG_LEN * sizeof(UINT8)); + } + index = 0; + memcpy(x87values[index++], x87Regs[0], X87_REG_LEN * sizeof(UINT8)); + for (int i = 1; i < X87_REG_NUM; ++i) { + + for (j = 0; j < index; ++j) { + if (memcmp(x87values[j],x87Regs[i],X87_REG_LEN * sizeof(UINT8))==0) { + break; + } + } + if (j >= index) { + memcpy(x87values[index++], x87Regs[i], X87_REG_LEN * sizeof(UINT8)); + } + } + float x87RegRate = (float)index/X87_REG_NUM; + + //check redundancy in SIMD registers + UINT8 ** simdValues; + simdValues = (UINT8 **)malloc(SIMD_REG_NUM * sizeof(UINT8 *)); + for (int i = 0; i < SIMD_REG_NUM; ++i) { + simdValues[i] = (UINT8 *)malloc(SIMD_REG_LEN * sizeof(UINT8)); + } + index = 0; + memcpy(simdValues[index++], simdRegs[0], SIMD_REG_LEN * sizeof(UINT8)); + for (int i = 1; i < 8; ++i) { + + for (j = 0; j < index; ++j) { + if (memcmp(simdValues[j],simdRegs[i],SIMD_REG_LEN * sizeof(UINT8))==0) { + break; + } + } + if (j >= index) { + memcpy(simdValues[index++], simdRegs[i], SIMD_REG_LEN * sizeof(UINT8)); + } + } + float simdRegRate = (float)index/SIMD_REG_NUM; + + if (genRegRate > RED_RATE || x87RegRate > RED_RATE || simdRegRate > RED_RATE) { + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, 0); + IntraRegsRed newpair; + newpair.genRegRed = genRegRate; + newpair.x87RegRed = x87RegRate; + newpair.simdRegRed = simdRegRate; + RecordIntraRegsRedundancy(curCtxtHandle,newpair,threadId); + } +} + + +template struct ArrayAnalysis{ typedef typename unordered_map>::iterator MyIterator; @@ -181,15 +342,34 @@ struct ArrayAnalysis{ while(address < endAddr){ T value = *static_cast((void *)address); - if(value == valueLast) - spatialRedIndex.push_back(index); - mapIt = valuesMap.find(value); - if(mapIt == valuesMap.end()){ - list newlist; - newlist.push_back(index); - valuesMap.insert(std::pair>(value,newlist)); + + if(isApprox){ + T r = (value - valueLast)/value; + if (r < APPROX_RATE && r > -APPROX_RATE) + spatialRedIndex.push_back(index); + for(mapIt=valuesMap.begin(); mapIt != valuesMap.end(); ++mapIt){ + r = (value - mapIt->first)/value; + if (r < APPROX_RATE && r > -APPROX_RATE){ + mapIt->second.push_back(index); + break; + } + } + if(mapIt == valuesMap.end()){ + list newlist; + newlist.push_back(index); + valuesMap.insert(std::pair>(value,newlist)); + } }else{ - mapIt->second.push_back(index); + if(value == valueLast) + spatialRedIndex.push_back(index); + mapIt = valuesMap.find(value); + if(mapIt == valuesMap.end()){ + list newlist; + newlist.push_back(index); + valuesMap.insert(std::pair>(value,newlist)); + }else{ + mapIt->second.push_back(index); + } } address += stride; index++; @@ -219,7 +399,7 @@ static VOID InstrumentInsCallback(INS ins, VOID* v, const uint32_t opaqueHandle) ; } -void new_ARRAY_ANALYSIS_FN_NAME(char * name, void * addr, uint32_t typeSize, uint32_t stride, THREADID threadId){ +void new_ARRAY_ANALYSIS_FN_NAME(char * name, void * addr, uint32_t typeSize, uint32_t stride, bool isApprox, THREADID threadId){ printf("name:%s, addr:%p, type:%d, stride:%d\n",name,addr,typeSize,stride); string str(name); @@ -227,35 +407,56 @@ void new_ARRAY_ANALYSIS_FN_NAME(char * name, void * addr, uint32_t typeSize, uin IntraRedRecord newRecord; bool hasRedundant = false; - switch (typeSize) { - case 1: - hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); - break; - case 2: - hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); - break; - case 4: - hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); - break; - case 8: - hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); - break; - default: - break; + if (isApprox) { + switch (typeSize) { + case 4: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + case 8: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + default: + assert(0 && "approx inappropriate type size, should not reach here!"); + break; + } + }else{ + + switch (typeSize) { + case 1: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + case 2: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + case 4: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + case 8: + hasRedundant = ArrayAnalysis::CheckIntraArrayRedundancy(dataHandle.beg_addr,dataHandle.end_addr,stride,&newRecord); + break; + default: + assert(0 && "unknow element size, should not reach here!"); + break; + } } - if(hasRedundant) + if(hasRedundant){ + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, 0); + newRecord.curCtxt = curCtxtHandle; RecordIntraArrayRedundancy( name, newRecord, threadId); + } } VOID Overrides (IMG img, VOID * v) { // Master setup RTN rtn = RTN_FindByName (img, ARRAY_ANALYSIS_FN_NAME); if (RTN_Valid (rtn)) { + + RTN_InsertCall (rtn, IPOINT_BEFORE, (AFUNPTR) CheckRegValues, IARG_CONTEXT, IARG_THREAD_ID,IARG_END); // Define a function prototype that describes the application routine // that will be replaced. // PROTO proto_master = PROTO_Allocate (PIN_PARG (void), CALLINGSTD_DEFAULT, - ARRAY_ANALYSIS_FN_NAME,PIN_PARG (char *),PIN_PARG (void *),PIN_PARG (uint32_t),PIN_PARG (uint32_t), + ARRAY_ANALYSIS_FN_NAME,PIN_PARG (char *),PIN_PARG (void *),PIN_PARG (uint32_t),PIN_PARG (uint32_t), PIN_PARG (bool), PIN_PARG_END ()); // Replace the application routine with the replacement function. @@ -267,6 +468,7 @@ VOID Overrides (IMG img, VOID * v) { IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_FUNCARG_ENTRYPOINT_VALUE, 3, + IARG_FUNCARG_ENTRYPOINT_VALUE, 4, IARG_THREAD_ID, IARG_END); // Free the function prototype. PROTO_Free (proto_master); @@ -313,12 +515,12 @@ static void PrintRedundancyPairs(THREADID threadId) { fprintf(gTraceFile,"========== Selected Dataobjecy Redundancy ==========\n"); for(itIntra = arrayDataRed[threadId].begin(); itIntra != arrayDataRed[threadId].end(); ++itIntra){ - fprintf(gTraceFile,"\nVariable %s at \n",(itIntra->first).c_str()); - ////////////////////////////////////////////////////////////// - // PrintFullCallingContext(contxt); + fprintf(gTraceFile,"\nVariable %s: \n",(itIntra->first).c_str()); + list::iterator listIt; for(listIt = itIntra->second.begin(); listIt != itIntra->second.end(); ++listIt){ + PrintFullCallingContext((*listIt).curCtxt); fprintf(gTraceFile,"\nRed:%.2f, unique value large index group:\n",(*listIt).redundancy); list::iterator groupIt; int num = 0; @@ -332,6 +534,24 @@ static void PrintRedundancyPairs(THREADID threadId) { } fprintf(gTraceFile,"\n----------------------------"); } + + fprintf(gTraceFile,"\n*************** Intra Registers Redundancy of Thread %d ***************\n",threadId); + unordered_map>::iterator itIntraReg; + + fprintf(gTraceFile,"========== ==========\n"); + for(itIntraReg = regsRed[threadId].begin(); itIntraReg != regsRed[threadId].end(); ++itIntraReg){ + + PrintFullCallingContext(itIntraReg->first); + + list::iterator listItReg; + for(listItReg = itIntraReg->second.begin(); listItReg != itIntraReg->second.end(); ++listItReg){ + + fprintf(gTraceFile,"\n general registers redundancy: %.2f\n",(*listItReg).genRegRed); + fprintf(gTraceFile,"\n X87 registers redundancy: %.2f\n",(*listItReg).x87RegRed); + fprintf(gTraceFile,"\n SIMD registers redundancy: %.2f\n",(*listItReg).simdRegRed); + } + fprintf(gTraceFile,"\n----------------------------"); + } } // On each Unload of a loaded image, the accummulated redundancy information is dumped diff --git a/tests/redspy_temporal_client.cpp b/tests/redspy_temporal_client.cpp index fbde3d3..96b03e8 100644 --- a/tests/redspy_temporal_client.cpp +++ b/tests/redspy_temporal_client.cpp @@ -52,6 +52,7 @@ #include "pin.H" #include "cctlib.H" #include +#include extern "C" { #include "xed-interface.h" @@ -119,10 +120,11 @@ using namespace PinCCTLib; #define MAX_WRITE_OP_LENGTH (512) #define MAX_WRITE_OPS_IN_INS (8) #define MAX_REG_LENGTH (64) -#define MAX_XMM_LENGTH (16) -#define MAX_XMM_REGS (16) -#define MAX_ALIAS_REGS (4) //EAX, EBX, ECX, EDX +#define MAX_SIMD_LENGTH (64) +#define MAX_SIMD_REGS (32) + +#define MAX_ALIAS_REGS (16) //EAX, EBX, ECX, EDX, EBP, EDI, ESI, ESP, R8-R15 #define MAX_ALIAS_REG_SIZE (8) //RAX is 64bits #define MAX_ALIAS_TYPE (3) //(RAX, EAX, AX),(AH),(AL) @@ -131,15 +133,26 @@ enum AliasReg { ALIAS_REG_A = 0, //RAX, EAX, AX, AH, or AL ALIAS_REG_B, ALIAS_REG_C, - ALIAS_REG_D}; + ALIAS_REG_D, + ALIAS_REG_BP, + ALIAS_REG_DI, + ALIAS_REG_SI, + ALIAS_REG_SP, + ALIAS_REG_R8, + ALIAS_REG_R9, + ALIAS_REG_R10, + ALIAS_REG_R11, + ALIAS_REG_R12, + ALIAS_REG_R13, + ALIAS_REG_R14, + ALIAS_REG_R15}; //alias type, generic, high byte or low byte enum AliasGroup{ ALIAS_GENERIC=0, // RAX, EAX, or AX ALIAS_HIGH_BYTE, //AH - ALIAS_LOW_BYTE, // AL - ALIAS_HIGH_LOW // What is this? + ALIAS_LOW_BYTE // AL }; #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -188,16 +201,20 @@ struct AddrValPair{ } __attribute__((aligned(16))); struct LargeReg{ - UINT8 value[MAX_XMM_LENGTH]; -} __attribute__((aligned(16))); + UINT8 value[MAX_SIMD_LENGTH]; +} __attribute__((aligned(32))); struct RedSpyThreadData{ - struct LargeReg largeRegValue[MAX_XMM_REGS]; + AddrValPair buffer[MAX_WRITE_OPS_IN_INS]; + struct LargeReg simdValue[MAX_SIMD_REGS]; + uint32_t regCtxt[REG_LAST]; UINT8 regValue[REG_LAST][MAX_REG_LENGTH]; UINT8 aliasValue[MAX_ALIAS_REGS][MAX_ALIAS_REG_SIZE]; uint32_t aliasCtxt[MAX_ALIAS_REGS][MAX_ALIAS_TYPE]; + uint32_t simdCtxt[MAX_SIMD_REGS]; + uint64_t bytesWritten; long long numIns; @@ -635,30 +652,90 @@ struct HandleGeneralRegisters{ * regBefore = value; tData->regCtxt[reg] = curCtxtHandle; } - static __attribute__((always_inline)) void CheckLargeRegValues(PIN_REGISTER* regRef, REG reg, uint32_t opaqueHandle, THREADID threadId){ +}; + +//lenInt64: 1(X87), 2(XMM), 4(YMM), 8(ZMM) +template +struct HandleSpecialRegisters{ + + //check the MM_x part registers in X87 + static __attribute__((always_inline)) void CheckRegValues(PIN_REGISTER* regRef, REG regID, uint32_t opaqueHandle, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - - if(len == 1){ - uint64_t *oldValue = (uint64_t*)&(tData->regValue[reg][0]); + + if(lenInt64 == 1){ + uint64_t *oldValue = (uint64_t*)&(tData->regValue[regID][0]); if(*oldValue == regRef->qword[0]) - AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),8,threadId); + AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[regID],curCtxtHandle),8,threadId); else *oldValue = regRef->qword[0]; + + tData->regCtxt[regID] = curCtxtHandle; + }else if(lenInt64 == 2){ + + uint64_t *oldValue1 = (uint64_t*)&(tData->simdValue[regID].value); + uint64_t *oldValue2 = (uint64_t*)&(tData->simdValue[regID].value[8]); + if(*oldValue1 == regRef->qword[0] && *oldValue2 == regRef->qword[1]) + AddToRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[regID],curCtxtHandle),16,threadId); + else{ + *oldValue1 = regRef->qword[0]; + *oldValue2 = regRef->qword[1]; + } + tData->simdCtxt[regID] = curCtxtHandle; + }else{ - uint32_t regInd = reg-REG_XMM_BASE; - uint64_t *oldValue1 = (uint64_t*)&(tData->largeRegValue[regInd].value); - uint64_t *oldValue2 = (uint64_t*)&(tData->largeRegValue[regInd].value[8]); + + uint64_t *oldValue; + bool isRedundant = true; + for(int i = 0,j = 0; i < lenInt64; ++i, j += 8){ + oldValue = (uint64_t*)&(tData->simdValue[regID].value[j]); + if(*oldValue != regRef->qword[i]){ + isRedundant = false; + *oldValue = regRef->qword[i]; + } + } + + if(isRedundant) + AddToRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[regID],curCtxtHandle),lenInt64*8,threadId); + + tData->simdCtxt[regID] = curCtxtHandle; + } + } + + static __attribute__((always_inline)) void CheckSIMDRegValues(PIN_REGISTER* regRef, uint8_t simdID, uint32_t opaqueHandle, THREADID threadId){ + + RedSpyThreadData* const tData = ClientGetTLS(threadId); + + ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); + + if(lenInt64 == 2){ + + uint64_t *oldValue1 = (uint64_t*)&(tData->simdValue[simdID].value[0]); + uint64_t *oldValue2 = (uint64_t*)&(tData->simdValue[simdID].value[8]); if(*oldValue1 == regRef->qword[0] && *oldValue2 == regRef->qword[1]) - AddToRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),MAX_XMM_LENGTH,threadId); + AddToRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[simdID],curCtxtHandle),16,threadId); else{ *oldValue1 = regRef->qword[0]; *oldValue2 = regRef->qword[1]; } + }else{ + + uint64_t *oldValue; + bool isRedundant = true; + for(int i = 0,j = 0; i < lenInt64; ++i, j += 8){ + oldValue = (uint64_t*)&(tData->simdValue[simdID].value[j]); + if(*oldValue != regRef->qword[i]){ + isRedundant = false; + *oldValue = regRef->qword[i]; + } + } + + if(isRedundant) + AddToRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[simdID],curCtxtHandle),lenInt64*8,threadId); } - tData->regCtxt[reg] = curCtxtHandle; + tData->simdCtxt[simdID] = curCtxtHandle; } }; @@ -687,8 +764,9 @@ static void Check10BytesReg(CONTEXT * ctxt, REG reg, uint32_t opaqueHandle, THRE tData->regCtxt[reg] = curCtxtHandle; } +//approximate general registers template -struct HandleApproxRegisters{ +struct ApproxGeneralRegisters{ static __attribute__((always_inline)) void CheckValues(PIN_REGISTER* regRef, uint32_t reg, uint32_t opaqueHandle, THREADID threadId){ @@ -734,65 +812,145 @@ struct HandleApproxRegisters{ tData->regCtxt[reg] = curCtxtHandle; } } +}; + +//approximate SIMD registers, simdType:0(XMM), 1(YMM), 2(ZMM) +template +struct ApproxLargeRegisters{ - static __attribute__((always_inline)) void CheckLargeReg(PIN_REGISTER* regRef, REG reg, uint32_t opaqueHandle, THREADID threadId){ + static __attribute__((always_inline)) void CheckValues(PIN_REGISTER* regRef, uint8_t regInd, uint32_t opaqueHandle, THREADID threadId){ RedSpyThreadData* const tData = ClientGetTLS(threadId); ContextHandle_t curCtxtHandle = GetContextHandle(threadId, opaqueHandle); - uint32_t regInd = reg-REG_XMM_BASE; - if(sizeof(T) == 4){ - __m128 oldValue = _mm_load_ps( reinterpret_cast (&(tData->largeRegValue[regInd].value))); - __m128 newValue = _mm_loadu_ps( reinterpret_cast (regRef)); + if(simdType == 0){ - __m128 result = _mm_sub_ps(newValue,oldValue); - - result = _mm_div_ps(result,oldValue); - float rates[4] __attribute__((aligned(16))); - _mm_store_ps(rates,result); - - uint8_t redCount = 0; - if(rates[0] <= delta && rates[0] >= -delta) { - redCount++; - } - if(rates[1] <= delta && rates[1] >= -delta) { - redCount++; - } - if(rates[2] <= delta && rates[2] >= -delta) { - redCount++; - } - if(rates[3] <= delta && rates[3] >= -delta) { - redCount++; - } - if(redCount) - AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),4*redCount,threadId); - _mm_store_ps(reinterpret_cast (&(tData->largeRegValue[regInd].value)),newValue); - - }else if(sizeof(T) == 8){ - __m128d oldValue = _mm_load_pd( reinterpret_cast (&(tData->largeRegValue[regInd].value))); - __m128d newValue = _mm_loadu_pd( reinterpret_cast (regRef)); + if(sizeof(T) == 4){ + __m128 oldValue = _mm_load_ps( reinterpret_cast (&(tData->simdValue[regInd].value[0]))); + __m128 newValue = _mm_loadu_ps( reinterpret_cast (regRef)); + + __m128 result = _mm_sub_ps(newValue,oldValue); + + result = _mm_div_ps(result,oldValue); + float rates[4] __attribute__((aligned(16))); + _mm_store_ps(rates,result); + + uint8_t redCount = 0; + if(rates[0] <= delta && rates[0] >= -delta) redCount++; + if(rates[1] <= delta && rates[1] >= -delta) redCount++; + if(rates[2] <= delta && rates[2] >= -delta) redCount++; + if(rates[3] <= delta && rates[3] >= -delta) redCount++; + + if(redCount) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[regInd],curCtxtHandle),4*redCount,threadId); + _mm_store_ps(reinterpret_cast (&(tData->simdValue[regInd].value[0])),newValue); + + }else if(sizeof(T) == 8){ + __m128d oldValue = _mm_load_pd( reinterpret_cast (&(tData->simdValue[regInd].value[0]))); + __m128d newValue = _mm_loadu_pd( reinterpret_cast (regRef)); + + __m128d result = _mm_sub_pd(newValue,oldValue); + + result = _mm_div_pd(result,oldValue); + + double rate[2]; + _mm_storel_pd(&rate[0],result); + _mm_storeh_pd(&rate[1],result); + + uint8_t redCount = 0; + if(rate[0] <= delta && rate[0] >=-delta) redCount++; + if(rate[1] <= delta && rate[1] >= -delta) redCount++; + + if(redCount) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[regInd],curCtxtHandle),8*redCount,threadId); + _mm_store_pd(reinterpret_cast (&(tData->simdValue[regInd].value[0])),newValue); + }else ; - __m128d result = _mm_sub_pd(newValue,oldValue); + }else if(simdType == 1){ - result = _mm_div_pd(result,oldValue); + if(sizeof(T) == 4){ + __m256 oldValue = _mm256_load_ps( reinterpret_cast (&(tData->simdValue[regInd].value[0]))); + __m256 newValue = _mm256_loadu_ps( reinterpret_cast (regRef)); + + __m256 result = _mm256_sub_ps(newValue,oldValue); + + result = _mm256_div_ps(result,oldValue); + float rates[8] __attribute__((aligned(32))); + _mm256_store_ps(rates,result); + + uint8_t redCount = 0; + for(int i = 0; i < 7; ++i) + if(rates[i] <= delta && rates[i] >= -delta) redCount++; + + if(redCount) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[regInd],curCtxtHandle),4*redCount,threadId); + _mm256_store_ps(reinterpret_cast (&(tData->simdValue[regInd].value[0])),newValue); + + }else if(sizeof(T) == 8){ + __m256d oldValue = _mm256_load_pd( reinterpret_cast (&(tData->simdValue[regInd].value[0]))); + __m256d newValue = _mm256_loadu_pd( reinterpret_cast (regRef)); + + __m256d result = _mm256_sub_pd(newValue,oldValue); + + result = _mm256_div_pd(result,oldValue); + + double rate[4] __attribute__((aligned(32))); + _mm256_store_pd(rate,result); + + uint8_t redCount = 0; + if(rate[0] <= delta && rate[0] >=-delta) redCount++; + if(rate[1] <= delta && rate[1] >= -delta) redCount++; + if(rate[2] <= delta && rate[2] >=-delta) redCount++; + if(rate[3] <= delta && rate[3] >= -delta) redCount++; + + if(redCount) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[regInd],curCtxtHandle),8*redCount,threadId); + _mm256_store_pd(reinterpret_cast (&(tData->simdValue[regInd].value[0])),newValue); + }else ; - double rate[2]; - _mm_storel_pd(&rate[0],result); - _mm_storeh_pd(&rate[1],result); - - uint8_t redCount = 0; - if(rate[0] <= delta && rate[0] >=-delta) - redCount++; - if(rate[1] <= delta && rate[1] >= -delta) - redCount++; + }else ;/*else{ - if(redCount) + if(sizeof(T) == 4){ + __m512 oldValue = _mm512_load_ps( reinterpret_cast (&(tData->simdValue[regInd].value[0]))); + __m512 newValue = _mm512_loadu_ps( reinterpret_cast (regRef)); + + __m512 result = _mm512_sub_ps(newValue,oldValue); + + result = _mm512_div_ps(result,oldValue); + float rates[16] __attribute__((aligned(64))); + _mm512_store_ps(rates,result); + + uint8_t redCount = 0; + for(int i = 0; i < 15; ++i) + if(rates[i] <= delta && rates[i] >= -delta) redCount++; + + if(redCount) + AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->simdCtxt[regInd],curCtxtHandle),4*redCount,threadId); + _mm512_store_ps(reinterpret_cast (&(tData->simdValue[regInd].value[0])),newValue); + + }else if(sizeof(T) == 8){ + __m512d oldValue = _mm512_load_pd( reinterpret_cast (&(tData->simdValue[regInd].value[0]))); + __m512d newValue = _mm512_loadu_pd( reinterpret_cast (regRef)); + + __m512d result = _mm512_sub_pd(newValue,oldValue); + + result = _mm512_div_pd(result,oldValue); + + double rates[8] __attribute__((aligned(64))); + _mm512_store_ps(rates,result); + + uint8_t redCount = 0; + for(int i = 0; i < 7; ++i) + if(rates[i] <= delta && rates[i] >= -delta) redCount++; + + if(redCount) AddToApproximateRedTable(MAKE_CONTEXT_PAIR(tData->regCtxt[reg],curCtxtHandle),8*redCount,threadId); - _mm_store_pd(reinterpret_cast (&(tData->largeRegValue[regInd].value)),newValue); - }else - ; - tData->regCtxt[reg] = curCtxtHandle; + _mm512_store_pd(reinterpret_cast (&(tData->simdValue[regInd].value[0])),newValue); + }else ; + }*/ + + tData->simdCtxt[regInd] = curCtxtHandle; } }; @@ -824,6 +982,67 @@ static inline uint32_t GetAliasIDs(REG reg){ case REG_DX: regGroup = ALIAS_REG_D; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; case REG_DH: regGroup = ALIAS_REG_D; byteInd = ALIAS_BYTES_INDEX_8_H; type = ALIAS_HIGH_BYTE; break; case REG_DL: regGroup = ALIAS_REG_D; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_LOW_BYTE; break; + + case REG_RBP: regGroup = ALIAS_REG_BP; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_EBP: regGroup = ALIAS_REG_BP; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_BP: regGroup = ALIAS_REG_BP; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_BPL: regGroup = ALIAS_REG_BP; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_RDI: regGroup = ALIAS_REG_DI; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_EDI: regGroup = ALIAS_REG_DI; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_DI: regGroup = ALIAS_REG_DI; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_DIL: regGroup = ALIAS_REG_DI; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_RSI: regGroup = ALIAS_REG_SI; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_ESI: regGroup = ALIAS_REG_SI; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_SI: regGroup = ALIAS_REG_SI; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_SIL: regGroup = ALIAS_REG_SI; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_RSP: regGroup = ALIAS_REG_SP; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_ESP: regGroup = ALIAS_REG_SP; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_SP: regGroup = ALIAS_REG_SP; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_SPL: regGroup = ALIAS_REG_SP; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R8: regGroup = ALIAS_REG_R8; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R8D: regGroup = ALIAS_REG_R8; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R8W: regGroup = ALIAS_REG_R8; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R8B: regGroup = ALIAS_REG_R8; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R9: regGroup = ALIAS_REG_R9; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R9D: regGroup = ALIAS_REG_R9; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R9W: regGroup = ALIAS_REG_R9; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R9B: regGroup = ALIAS_REG_R9; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R10: regGroup = ALIAS_REG_R10; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R10D: regGroup = ALIAS_REG_R10; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R10W: regGroup = ALIAS_REG_R10; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R10B: regGroup = ALIAS_REG_R10; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R11: regGroup = ALIAS_REG_R11; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R11D: regGroup = ALIAS_REG_R11; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R11W: regGroup = ALIAS_REG_R11; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R11B: regGroup = ALIAS_REG_R11; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R12: regGroup = ALIAS_REG_R12; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R12D: regGroup = ALIAS_REG_R12; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R12W: regGroup = ALIAS_REG_R12; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R12B: regGroup = ALIAS_REG_R12; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R13: regGroup = ALIAS_REG_R13; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R13D: regGroup = ALIAS_REG_R13; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R13W: regGroup = ALIAS_REG_R13; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R13B: regGroup = ALIAS_REG_R13; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R14: regGroup = ALIAS_REG_R14; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R14D: regGroup = ALIAS_REG_R14; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R14W: regGroup = ALIAS_REG_R14; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R14B: regGroup = ALIAS_REG_R14; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + + case REG_R15: regGroup = ALIAS_REG_R15; byteInd = ALIAS_BYTES_INDEX_64; type = ALIAS_GENERIC; break; + case REG_R15D: regGroup = ALIAS_REG_R15; byteInd = ALIAS_BYTES_INDEX_32; type = ALIAS_GENERIC; break; + case REG_R15W: regGroup = ALIAS_REG_R15; byteInd = ALIAS_BYTES_INDEX_16; type = ALIAS_GENERIC; break; + case REG_R15B: regGroup = ALIAS_REG_R15; byteInd = ALIAS_BYTES_INDEX_8_L; type = ALIAS_GENERIC; break; + default: assert(0 && "not alias registers! should not reach here!"); break; } uint32_t aliasGroupByteType = ((uint32_t)regGroup << 16) | ((uint32_t)byteInd << 8) | ((uint32_t)type); @@ -852,6 +1071,54 @@ inline bool RegHasAlias(REG reg){ case REG_BL: case REG_CL: case REG_DL: + case REG_RBP: + case REG_EBP: + case REG_BP: + case REG_BPL: + case REG_RDI: + case REG_EDI: + case REG_DI: + case REG_DIL: + case REG_RSI: + case REG_ESI: + case REG_SI: + case REG_SIL: + case REG_RSP: + case REG_ESP: + case REG_SP: + case REG_SPL: + case REG_R8: + case REG_R8D: + case REG_R8W: + case REG_R8B: + case REG_R9: + case REG_R9D: + case REG_R9W: + case REG_R9B: + case REG_R10: + case REG_R10D: + case REG_R10W: + case REG_R10B: + case REG_R11: + case REG_R11D: + case REG_R11W: + case REG_R11B: + case REG_R12: + case REG_R12D: + case REG_R12W: + case REG_R12B: + case REG_R13: + case REG_R13D: + case REG_R13W: + case REG_R13B: + case REG_R14: + case REG_R14D: + case REG_R14W: + case REG_R14B: + case REG_R15: + case REG_R15D: + case REG_R15W: + case REG_R15B: return true; default: return false; } @@ -859,13 +1126,13 @@ inline bool RegHasAlias(REG reg){ #ifdef ENABLE_SAMPLING -#define HANDLE_LARGEREG(LEN) \ +#define HANDLE_SPECIALREG(LEN,REG_ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleSpecialRegisters::CheckRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) -#define HANDLE_LARGEREG_APPROX(T) \ +#define HANDLE_LARGEREG_APPROX(T, SIMD_TYPE, REG_ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) ApproxLargeRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END); \ @@ -877,7 +1144,7 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters #define HANDLE_APPROXREG(T, IS_ALIAS, REG_ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ -INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) ApproxGeneralRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_10BYTES_APPROX(REG_ID) \ INS_InsertIfPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR)IfEnableSample, IARG_THREAD_ID,IARG_END);\ @@ -885,11 +1152,11 @@ INS_InsertThenPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) Check10BytesReg, IARG_ #else -#define HANDLE_LARGEREG(LEN) \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleGeneralRegisters::CheckLargeRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +#define HANDLE_SPECIALREG(LEN,REG_ID) \ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleSpecialRegisters::CheckRegValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) -#define HANDLE_LARGEREG_APPROX(T) \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckLargeReg, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +#define HANDLE_LARGEREG_APPROX(T, SIMD_TYPE, REG_ID) \ +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) ApproxLargeRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_ALIAS_REG(T, ALIAS_GRP, ID) \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckUpdateGenericAlias, IARG_UINT32, ID,IARG_REG_VALUE, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) @@ -898,7 +1165,7 @@ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleAliasRegisters::CheckValues,IARG_REG_VALUE,reg,IARG_UINT32, reg, IARG_UINT32, opaqueHandle, IARG_THREAD_ID, IARG_END) #define HANDLE_APPROXREG(T, IS_ALIAS, REG_ID) \ -INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) HandleApproxRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) +INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) ApproxGeneralRegisters::CheckValues, IARG_REG_CONST_REFERENCE,reg, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) #define HANDLE_10BYTES_APPROX(REG_ID) \ INS_InsertPredicatedCall(ins, IPOINT_AFTER, (AFUNPTR) Check10BytesReg, IARG_CONTEXT, IARG_UINT32, REG_ID, IARG_UINT32, opaqueHandle, IARG_THREAD_ID,IARG_END) @@ -948,8 +1215,22 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_ case 10: HANDLE_10BYTES_APPROX(reg); break; case 16: { switch (operSize) { - case 4: HANDLE_LARGEREG_APPROX(float);break; - case 8: HANDLE_LARGEREG_APPROX(double);break; + case 4: HANDLE_LARGEREG_APPROX(float,0,reg-REG_XMM_BASE);break; + case 8: HANDLE_LARGEREG_APPROX(double,0,reg-REG_XMM_BASE);break; + default: assert(0 && "handle large reg with large operand size\n"); break; + } + }break; + case 32:{ + switch (operSize) { + case 4: HANDLE_LARGEREG_APPROX(float,1,reg-REG_YMM_BASE);break; + case 8: HANDLE_LARGEREG_APPROX(double,1,reg-REG_YMM_BASE);break; + default: assert(0 && "handle large reg with large operand size\n"); break; + } + }break; + case 64: { + switch (operSize) { + case 4: HANDLE_LARGEREG_APPROX(float,2,reg-REG_ZMM_BASE);break; + case 8: HANDLE_LARGEREG_APPROX(double,2,reg-REG_ZMM_BASE);break; default: assert(0 && "handle large reg with large operand size\n"); break; } }break; @@ -957,7 +1238,7 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_ } }else{ if (REG_is_in_X87(reg)) { - HANDLE_LARGEREG(1); + HANDLE_SPECIALREG(1,reg); return; } switch(regSize) { @@ -965,7 +1246,9 @@ static inline void InstrumentGeneralReg(INS ins, REG reg, uint16_t oper, uint32_ case 2: HANDLE_GENERAL(uint16_t); break; case 4: HANDLE_GENERAL(uint32_t); break; case 8: HANDLE_GENERAL(uint64_t); break; - case 16: HANDLE_LARGEREG(2); break; + case 16: HANDLE_SPECIALREG(2,reg-REG_XMM_BASE); break; + case 32: HANDLE_SPECIALREG(4,reg-REG_YMM_BASE); break; + case 64: HANDLE_SPECIALREG(8,reg-REG_ZMM_BASE); break; default: assert(0 && "not recoganized register size for integer instruction!\n"); break; } } @@ -1045,7 +1328,43 @@ struct RedSpyAnalysis{ addr = avPair->address; if(isApprox){ - if(AccessLen>=16){ + if(AccessLen>=32){ + if(sizeof(T) == 4){ + __m256 oldValue = _mm256_load_ps( reinterpret_cast (&avPair->value)); + __m256 newValue = _mm256_loadu_ps( reinterpret_cast (avPair->address)); + + __m256 result = _mm256_sub_ps(newValue,oldValue); + + result = _mm256_div_ps(result,oldValue); + float rates[8] __attribute__((aligned(32))); + _mm256_store_ps(rates,result); + + for(int i = 0; i < 8; ++i){ + if(rates[i] < -delta || rates[i] > delta) { + return false; + } + } + return true; + + }else if(sizeof(T) == 8){ + __m256d oldValue = _mm256_load_pd( reinterpret_cast (&avPair->value)); + __m256d newValue = _mm256_loadu_pd( reinterpret_cast (avPair->address)); + + __m256d result = _mm256_sub_pd(newValue,oldValue); + + result = _mm256_div_pd(result,oldValue); + + double rates[4] __attribute__((aligned(32))); + _mm256_store_pd(rates,result); + + for(int i = 0; i < 4; ++i){ + if(rates[i] < -delta || rates[i] > delta) { + return false; + } + } + return true; + } + }else if(AccessLen == 16){ if(sizeof(T) == 4){ __m128 oldValue = _mm_load_ps( reinterpret_cast (&avPair->value)); __m128 newValue = _mm_loadu_ps( reinterpret_cast (avPair->address)); @@ -1116,8 +1435,16 @@ struct RedSpyAnalysis{ AddrValPair * avPair = & tData->buffer[bufferOffset]; avPair->address = addr; - - if(AccessLen>=16){ + if(AccessLen >= 32){ + if(sizeof(T) == 4){ + __m256 newValue = _mm256_loadu_ps( reinterpret_cast (addr)); + _mm256_store_ps(reinterpret_cast (&avPair->value), newValue); + + }else if(sizeof(T) == 8){ + __m256d newValue = _mm256_loadu_pd(reinterpret_cast (addr)); + _mm256_store_pd(reinterpret_cast (&avPair->value), newValue); + } + }else if(AccessLen == 16){ if(sizeof(T) == 4){ __m128 newValue = _mm_loadu_ps( reinterpret_cast (addr)); _mm_store_ps(reinterpret_cast (&avPair->value), newValue); @@ -1326,6 +1653,13 @@ struct RedSpyInstrument{ default: assert(0 && "handle large mem write with unexpected operand size\n"); break; } }break; + case 32: { + switch (operSize) { + case 4: HANDLE_APPROX_CASE(float, 32, readBufferSlotIndex, true); break; + case 8: HANDLE_APPROX_CASE(double, 32, readBufferSlotIndex, true); break; + default: assert(0 && "handle large mem write with unexpected operand size\n"); break; + } + }break; default: assert(0 && "unexpected large memory writes\n"); break; } }else{ @@ -1744,7 +2078,7 @@ static void InitThreadData(RedSpyThreadData* tdata){ } static VOID ThreadStart(THREADID threadid, CONTEXT* ctxt, INT32 flags, VOID* v) { - RedSpyThreadData* tdata = (RedSpyThreadData*)memalign(16,sizeof(RedSpyThreadData)); + RedSpyThreadData* tdata = (RedSpyThreadData*)memalign(32,sizeof(RedSpyThreadData)); InitThreadData(tdata); // __sync_fetch_and_add(&gClientNumThreads, 1); #ifdef MULTI_THREADED From 999be779b61358e0893e1ff4135ec881c4a4d9f9 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Mon, 5 Dec 2016 16:38:48 -0500 Subject: [PATCH 14/18] correct the RTN instrumentation. seperate the array and registers analysis. --- tests/redspy_spatial_userdefine_client.cpp | 41 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/tests/redspy_spatial_userdefine_client.cpp b/tests/redspy_spatial_userdefine_client.cpp index cac712f..fef6567 100644 --- a/tests/redspy_spatial_userdefine_client.cpp +++ b/tests/redspy_spatial_userdefine_client.cpp @@ -75,6 +75,7 @@ using namespace PinCCTLib; #define MAKE_CONTEXT_PAIR(a, b) (((uint64_t)(a) << 32) | ((uint64_t)(b))) #define ARRAY_ANALYSIS_FN_NAME "Analyze_this_array" +#define REG_ANALYSIS_FN_NAME "Analyze_regs" typedef struct valueGroup{ @@ -400,7 +401,7 @@ static VOID InstrumentInsCallback(INS ins, VOID* v, const uint32_t opaqueHandle) } void new_ARRAY_ANALYSIS_FN_NAME(char * name, void * addr, uint32_t typeSize, uint32_t stride, bool isApprox, THREADID threadId){ - printf("name:%s, addr:%p, type:%d, stride:%d\n",name,addr,typeSize,stride); + //printf("name:%s, addr:%p, type:%d, stride:%d\n",name,addr,typeSize,stride); string str(name); DataHandle_t dataHandle = GetDataObjectHandle(addr,threadId); @@ -445,7 +446,7 @@ void new_ARRAY_ANALYSIS_FN_NAME(char * name, void * addr, uint32_t typeSize, uin RecordIntraArrayRedundancy( name, newRecord, threadId); } } - +/* VOID Overrides (IMG img, VOID * v) { // Master setup RTN rtn = RTN_FindByName (img, ARRAY_ANALYSIS_FN_NAME); @@ -473,6 +474,42 @@ VOID Overrides (IMG img, VOID * v) { // Free the function prototype. PROTO_Free (proto_master); } +}*/ + +VOID Overrides (IMG img, VOID * v) { + // Master setup + for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ){ + for( RTN rtn= SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn) ){ + string rtnName = RTN_Name(rtn); + if (rtnName.find(ARRAY_ANALYSIS_FN_NAME) != std::string::npos) { + + // Define a function prototype that describes the application routine + // that will be replaced. + // + PROTO proto_master = PROTO_Allocate (PIN_PARG (void), CALLINGSTD_DEFAULT, + ARRAY_ANALYSIS_FN_NAME,PIN_PARG (char *),PIN_PARG (void *),PIN_PARG (uint32_t),PIN_PARG (uint32_t), PIN_PARG (bool), + PIN_PARG_END ()); + + // Replace the application routine with the replacement function. + // Additional arguments have been added to the replacement routine. + // + RTN_ReplaceSignature (rtn, AFUNPTR (new_ARRAY_ANALYSIS_FN_NAME), + IARG_PROTOTYPE, proto_master, + IARG_FUNCARG_ENTRYPOINT_VALUE, 0, + IARG_FUNCARG_ENTRYPOINT_VALUE, 1, + IARG_FUNCARG_ENTRYPOINT_VALUE, 2, + IARG_FUNCARG_ENTRYPOINT_VALUE, 3, + IARG_FUNCARG_ENTRYPOINT_VALUE, 4, + IARG_THREAD_ID, IARG_END); + // Free the function prototype. + PROTO_Free (proto_master); + }else if (rtnName.find(REG_ANALYSIS_FN_NAME) != std::string::npos) { + RTN_Open(rtn); + RTN_InsertCall (rtn, IPOINT_BEFORE, (AFUNPTR) CheckRegValues, IARG_CONTEXT, IARG_THREAD_ID,IARG_END); + RTN_Close(rtn); + } + } + } } From 70bba04d64593b17c55ef88949ff9bb3b93c322b Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Wed, 25 Jan 2017 11:16:29 -0500 Subject: [PATCH 15/18] update make.am file --- tests/Makefile.am | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index f40b14a..7228ae4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,7 +3,7 @@ CONFIG_ROOT=$(PIN_ROOT)/source/tools/Config include $(CONFIG_ROOT)/makefile.config -TEST_TOOL_ROOTS = cct_client deadspy_client redspy_client redspy_temporal_client redspy_temporal_approx_client cct_data_centric_client cct_client_mem_only cct_data_centric_client_tree_based redspy_spatial_client redspy_spatial_approx_client cct_metric_client cctlib_reader footprint_client footprint_client2 valueNum omp_datarace_client +TEST_TOOL_ROOTS = cct_client deadspy_client redspy_client redspy_temporal_client cct_data_centric_client cct_client_mem_only cct_data_centric_client_tree_based redspy_spatial_userdefine_client redspy_spatial_client cct_metric_client cctlib_reader footprint_client footprint_client2 valueNum omp_datarace_client APP_ROOTS = deadWrites threaded #all: cct_client.so deadspy_client.so cct_data_centric_client.so cct_client_mem_only.so cct_data_centric_client_tree_based.so deadWrites @@ -39,18 +39,11 @@ $(OBJDIR)redspy_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_client$(OBJ_SUFFIX) $(C $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) $(OBJDIR)redspy_temporal_client$(OBJ_SUFFIX): redspy_temporal_client.cpp ../src/cctlib.H - $(CXX) -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< + $(CXX) -mavx -DENABLE_SAMPLING -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< $(OBJDIR)redspy_temporal_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_temporal_client$(OBJ_SUFFIX) $(CCTLIB_SHADOW_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) -$(OBJDIR)redspy_temporal_approx_client$(OBJ_SUFFIX): redspy_temporal_approx_client.cpp ../src/cctlib.H - $(CXX) -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< - -$(OBJDIR)redspy_temporal_approx_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_temporal_approx_client$(OBJ_SUFFIX) $(CCTLIB_SHADOW_BASED_LIBRARY) - $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) - - $(OBJDIR)omp_datarace_client$(OBJ_SUFFIX): omp_datarace_client.cpp ../src/cctlib.H shadow_memory.cpp $(CXX) -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< @@ -85,19 +78,19 @@ $(OBJDIR)cct_data_centric_client_tree_based$(OBJ_SUFFIX): cct_data_centric_clien $(OBJDIR)cct_data_centric_client_tree_based$(PINTOOL_SUFFIX): $(OBJDIR)cct_data_centric_client_tree_based$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib_tree_based $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) -$(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX): redspy_spatial_client.cpp ../src/cctlib.H +$(OBJDIR)redspy_spatial_userdefine_client$(OBJ_SUFFIX): redspy_spatial_userdefine_client.cpp ../src/cctlib.H $(CXX) $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< -$(OBJDIR)redspy_spatial_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) +$(OBJDIR)redspy_spatial_userdefine_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_userdefine_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib_tree_with_addr $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) -$(OBJDIR)redspy_spatial_approx_client$(OBJ_SUFFIX): redspy_spatial_approx_client.cpp ../src/cctlib.H + +$(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX): redspy_spatial_client.cpp ../src/cctlib.H $(CXX) $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< -$(OBJDIR)redspy_spatial_approx_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_approx_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) +$(OBJDIR)redspy_spatial_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib_tree_with_addr $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) - $(OBJDIR)cct_metric_client$(OBJ_SUFFIX): cct_metric_client.cpp ../src/cctlib.H $(CXX) $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< From d376b6fd1cfe83f0c9d1c2d94c7462fdee94b396 Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Fri, 27 Jan 2017 13:29:48 -0500 Subject: [PATCH 16/18] update branch shasha-dev --- Makefile.in | 8 ++- aclocal.m4 | 122 +++++++++++++++++++++++++++++++++++++++++++--- configure | 102 +++++++++++++++++++++++++++++++++++++- src/Makefile.in | 6 +-- tests/Makefile.in | 20 +++----- 5 files changed, 234 insertions(+), 24 deletions(-) diff --git a/Makefile.in b/Makefile.in index ffc52f6..69f2aed 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -515,10 +515,16 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) diff --git a/aclocal.m4 b/aclocal.m4 index f6192c7..83c8b4f 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.13.4 -*- Autoconf -*- +# generated automatically by aclocal 1.14 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.13' +[am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.13.4], [], +m4_if([$1], [1.14], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,7 +51,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.13.4])dnl +[AM_AUTOMAKE_VERSION([1.14])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) @@ -418,6 +418,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- @@ -526,7 +532,48 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further @@ -534,7 +581,6 @@ dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. @@ -716,6 +762,70 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. diff --git a/configure b/configure index 2833923..d991303 100755 --- a/configure +++ b/configure @@ -1865,7 +1865,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # The argument here is just something that should be in the current directory # (for sanity checking) -am__api_version='1.13' +am__api_version='1.14' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -2431,6 +2431,47 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi ac_config_headers="$ac_config_headers src/config.h" ac_ext=cpp @@ -3670,6 +3711,65 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 diff --git a/src/Makefile.in b/src/Makefile.in index 843e4f4..ed52980 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -296,8 +296,8 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): config.h: stamp-h1 - @if test ! -f $@; then rm -f stamp-h1; else :; fi - @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 diff --git a/tests/Makefile.in b/tests/Makefile.in index ac733ad..62ced57 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -207,7 +207,7 @@ top_srcdir = @top_srcdir@ #include ../Makefile.inc #PIN_ROOT=$(PIN_PATH) CONFIG_ROOT = $(PIN_ROOT)/source/tools/Config -TEST_TOOL_ROOTS = cct_client deadspy_client redspy_client redspy_temporal_client redspy_temporal_approx_client cct_data_centric_client cct_client_mem_only cct_data_centric_client_tree_based redspy_spatial_client redspy_spatial_approx_client cct_metric_client cctlib_reader footprint_client footprint_client2 valueNum omp_datarace_client +TEST_TOOL_ROOTS = cct_client deadspy_client redspy_client redspy_temporal_client cct_data_centric_client cct_client_mem_only cct_data_centric_client_tree_based redspy_spatial_userdefine_client redspy_spatial_client cct_metric_client cctlib_reader footprint_client footprint_client2 valueNum omp_datarace_client APP_ROOTS = deadWrites threaded #all: cct_client.so deadspy_client.so cct_data_centric_client.so cct_client_mem_only.so cct_data_centric_client_tree_based.so deadWrites ALLOW_UNUSED_BUT_SET = -Wno-unused-but-set-variable @@ -424,17 +424,11 @@ $(OBJDIR)redspy_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_client$(OBJ_SUFFIX) $(C $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) $(OBJDIR)redspy_temporal_client$(OBJ_SUFFIX): redspy_temporal_client.cpp ../src/cctlib.H - $(CXX) -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< + $(CXX) -mavx -DENABLE_SAMPLING -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< $(OBJDIR)redspy_temporal_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_temporal_client$(OBJ_SUFFIX) $(CCTLIB_SHADOW_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) -$(OBJDIR)redspy_temporal_approx_client$(OBJ_SUFFIX): redspy_temporal_approx_client.cpp ../src/cctlib.H - $(CXX) -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< - -$(OBJDIR)redspy_temporal_approx_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_temporal_approx_client$(OBJ_SUFFIX) $(CCTLIB_SHADOW_BASED_LIBRARY) - $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) - $(OBJDIR)omp_datarace_client$(OBJ_SUFFIX): omp_datarace_client.cpp ../src/cctlib.H shadow_memory.cpp $(CXX) -Wno-deprecated $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< @@ -465,16 +459,16 @@ $(OBJDIR)cct_data_centric_client_tree_based$(OBJ_SUFFIX): cct_data_centric_clien $(OBJDIR)cct_data_centric_client_tree_based$(PINTOOL_SUFFIX): $(OBJDIR)cct_data_centric_client_tree_based$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib_tree_based $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) -$(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX): redspy_spatial_client.cpp ../src/cctlib.H +$(OBJDIR)redspy_spatial_userdefine_client$(OBJ_SUFFIX): redspy_spatial_userdefine_client.cpp ../src/cctlib.H $(CXX) $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< -$(OBJDIR)redspy_spatial_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) +$(OBJDIR)redspy_spatial_userdefine_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_userdefine_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib_tree_with_addr $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) -$(OBJDIR)redspy_spatial_approx_client$(OBJ_SUFFIX): redspy_spatial_approx_client.cpp ../src/cctlib.H +$(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX): redspy_spatial_client.cpp ../src/cctlib.H $(CXX) $(CCTLIB_TEST_FLAGS) $(COMP_OBJ)$@ $< -$(OBJDIR)redspy_spatial_approx_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_approx_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) +$(OBJDIR)redspy_spatial_client$(PINTOOL_SUFFIX): $(OBJDIR)redspy_spatial_client$(OBJ_SUFFIX) $(CCTLIB_TREE_BASED_LIBRARY) $(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $< -L../src/$(OBJDIR) $(TOOL_LPATHS) -lcctlib_tree_with_addr $(TOOL_LIBS) $(CLIENT_LD_FLAGS) $(CLIENT_LIBS) $(OBJDIR)cct_metric_client$(OBJ_SUFFIX): cct_metric_client.cpp ../src/cctlib.H From b0c8a8474fa0f310e9f800a4005a93a782b177ca Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Fri, 27 Jan 2017 14:04:39 -0500 Subject: [PATCH 17/18] handle conflict --- aclocal.m4 | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/aclocal.m4 b/aclocal.m4 index aef04a2..b85f6ae 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.14.1 -*- Autoconf -*- +# generated automatically by aclocal 1.14 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. @@ -35,11 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -<<<<<<< HEAD m4_if([$1], [1.14], [], -======= -m4_if([$1], [1.14.1], [], ->>>>>>> master [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -55,11 +51,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -<<<<<<< HEAD [AM_AUTOMAKE_VERSION([1.14])dnl -======= -[AM_AUTOMAKE_VERSION([1.14.1])dnl ->>>>>>> master m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) From ae36ae42ca49e34dd92f2c4307541f1c70ff532c Mon Sep 17 00:00:00 2001 From: Shasha Wen Date: Fri, 27 Jan 2017 14:17:47 -0500 Subject: [PATCH 18/18] handle merge conflict --- Makefile.in | 5 ++--- src/Makefile.in | 2 +- tests/Makefile.in | 6 +----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index e8922f6..8053bc7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -567,10 +567,9 @@ distcheck: dist && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ diff --git a/src/Makefile.in b/src/Makefile.in index e31baea..78a3989 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. diff --git a/tests/Makefile.in b/tests/Makefile.in index 5fe77a7..da412e0 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.14 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -208,11 +208,7 @@ top_srcdir = @top_srcdir@ #include ../Makefile.inc #PIN_ROOT=$(PIN_PATH) CONFIG_ROOT = $(PIN_ROOT)/source/tools/Config -<<<<<<< HEAD TEST_TOOL_ROOTS = cct_client deadspy_client redspy_client redspy_temporal_client cct_data_centric_client cct_client_mem_only cct_data_centric_client_tree_based redspy_spatial_userdefine_client redspy_spatial_client cct_metric_client cctlib_reader footprint_client footprint_client2 valueNum omp_datarace_client -======= -TEST_TOOL_ROOTS = cct_client deadspy_client redspy_client redspy_temporal_client redspy_temporal_approx_client cct_data_centric_client cct_client_mem_only cct_data_centric_client_tree_based redspy_spatial_client redspy_spatial_approx_client cct_metric_client cctlib_reader footprint_client footprint_client2 valueNum omp_datarace_client cache ->>>>>>> master APP_ROOTS = deadWrites threaded #all: cct_client.so deadspy_client.so cct_data_centric_client.so cct_client_mem_only.so cct_data_centric_client_tree_based.so deadWrites ALLOW_UNUSED_BUT_SET = -Wno-unused-but-set-variable