[llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp
Anand Shukla
ashukla at cs.uiuc.edu
Fri Jul 18 11:04:22 PDT 2003
Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger:
SecondTrigger.cpp added (r1.1)
---
Log message:
Major revision for runtime tracing framework
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp
diff -c /dev/null llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.1
*** /dev/null Fri Jul 18 11:03:44 2003
--- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp Fri Jul 18 11:03:34 2003
***************
*** 0 ****
--- 1,1229 ----
+
+ //==llvm/Reoptimizer/LightwtProfiling/Trigger/SecondTrigger.cpp----*- C++ -*--=//
+ // Implements Second level trigger function
+ //
+ // The trigger function is called at run time by instrumented code.
+ // The trigger function must analyse, and potentially optimize
+ // the trace that executes
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "llvm/Reoptimizer/Mapping/LLVMinfo.h"
+ #include "llvm/Reoptimizer/VirtualMem.h"
+ #include "llvm/Reoptimizer/InstrUtils.h"
+ #include "llvm/Reoptimizer/TraceCache.h"
+ #include "llvm/Reoptimizer/GetTraceTime.h"
+ #include "llvm/iTerminators.h"
+ #include "llvm/Support/CFG.h"
+ #include "llvm/Module.h"
+ #include "GetTimer.h"
+ #include <sys/time.h>
+ #include <stdlib.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <iostream>
+ #include <fstream>
+ #include <map>
+
+ #ifdef __sparc
+ #include <libcpc.h>
+ #endif
+
+ using std::map;
+ using std::vector;
+ using std::pair;
+
+ //#define GET_COVERAGE
+ //undef GET_COVERAGE
+
+ extern "C" void llvm_time_end2();
+ extern "C" void llvm_time_start();
+
+ #define MAX_PATH_HISTORIES 12
+ #define MAX_ALLOWED_PATHS 6
+ //#define THRESHOLD_LEVEL_2 50
+ #define THRESHOLD_PERCENTAGE 90
+ #define CALL 0x40000000
+
+
+ long THRESHOLD_LEVEL_2;
+ long LEVEL_TWO_EXITS;
+
+ extern TraceCache *tr;
+ extern TraceCache *tr2;
+ extern VirtualMem *vm;
+ extern Module *M;
+
+
+ static std::map<uint64_t, std::map<uint64_t, int> *> pathCounter;
+ static std::map<uint64_t, int> totalCount;
+
+ extern "C" void llvm_first_trigger(int *cnt);
+
+ //global counters for diagonistcs
+ void insert_address_at(uint64_t n, uint64_t m);
+ void generateTraces(uint64_t start, uint64_t end,
+ std::vector<uint64_t> &paths,
+ uint64_t firstLevelTraceStartAddr);
+ void getReturnCode(vector<unsigned int> &traces, int &index,
+ uint64_t ret);
+
+
+ extern uint64_t llvm_interval_counter;
+ std::map<uint64_t, int> exitCounter;
+ //std::map<uint64_t, int> iterationCounter;
+ std::map<uint64_t, uint64_t> firstTriggerAddr; //tracestart addr
+ std::map<uint64_t, pair<long, long> > backOffCounters;
+
+ void triggerBB(vector<BasicBlock *> &vBB, VirtualMem *vm, TraceCache *tr,
+ TraceCache *tr2, uint64_t a);
+
+
+ extern "C" void llvm_time_start(){
+ #ifdef __sparc
+ cpc_count_usr_events(1);
+ #endif
+ }
+
+ extern "C" void llvm_time_end2(){
+ #ifdef __sparc
+ cpc_count_usr_events(0);
+ #endif
+ }
+
+ extern "C" void llvm_time_end(){
+ uint64_t i_reg_save[6];
+
+ uint32_t f_reg_save[32];
+ uint64_t fd_reg_save[16];
+ uint64_t ccr_reg;
+ uint64_t fprs_reg;
+ uint64_t fsr_reg;
+ uint64_t g1_reg;
+ uint64_t g5_reg;
+
+ asm volatile ("stx %%i0, %0": "=m"(i_reg_save[0]));
+ asm volatile ("stx %%i1, %0": "=m"(i_reg_save[1]));
+ asm volatile ("stx %%i2, %0": "=m"(i_reg_save[2]));
+ asm volatile ("stx %%i3, %0": "=m"(i_reg_save[3]));
+ asm volatile ("stx %%i4, %0": "=m"(i_reg_save[4]));
+ asm volatile ("stx %%i5, %0": "=m"(i_reg_save[5]));
+
+ asm volatile ("stx %%g1, %0": "=m"(g1_reg));
+ asm volatile ("stx %%g5, %0": "=m"(g5_reg));
+
+ asm volatile ("st %%f0, %0": "=m"(f_reg_save[0]));
+ asm volatile ("st %%f1, %0": "=m"(f_reg_save[1]));
+ asm volatile ("st %%f2, %0": "=m"(f_reg_save[2]));
+ asm volatile ("st %%f3, %0": "=m"(f_reg_save[3]));
+ asm volatile ("st %%f4, %0": "=m"(f_reg_save[4]));
+ asm volatile ("st %%f5, %0": "=m"(f_reg_save[5]));
+ asm volatile ("st %%f6, %0": "=m"(f_reg_save[6]));
+ asm volatile ("st %%f7, %0": "=m"(f_reg_save[7]));
+ asm volatile ("st %%f8, %0": "=m"(f_reg_save[8]));
+ asm volatile ("st %%f9, %0": "=m"(f_reg_save[9]));
+ asm volatile ("st %%f10, %0": "=m"(f_reg_save[10]));
+ asm volatile ("st %%f11, %0": "=m"(f_reg_save[11]));
+ asm volatile ("st %%f12, %0": "=m"(f_reg_save[12]));
+ asm volatile ("st %%f13, %0": "=m"(f_reg_save[13]));
+ asm volatile ("st %%f14, %0": "=m"(f_reg_save[14]));
+ asm volatile ("st %%f15, %0": "=m"(f_reg_save[15]));
+ /*
+ asm volatile ("st %%f16, %0": "=m"(f_reg_save[16]));
+ asm volatile ("st %%f17, %0": "=m"(f_reg_save[17]));
+ asm volatile ("st %%f18, %0": "=m"(f_reg_save[18]));
+ asm volatile ("st %%f19, %0": "=m"(f_reg_save[19]));
+ asm volatile ("st %%f20, %0": "=m"(f_reg_save[20]));
+ asm volatile ("st %%f21, %0": "=m"(f_reg_save[21]));
+ asm volatile ("st %%f22, %0": "=m"(f_reg_save[22]));
+ asm volatile ("st %%f23, %0": "=m"(f_reg_save[23]));
+ asm volatile ("st %%f24, %0": "=m"(f_reg_save[24]));
+ asm volatile ("st %%f25, %0": "=m"(f_reg_save[25]));
+ asm volatile ("st %%f26, %0": "=m"(f_reg_save[26]));
+ asm volatile ("st %%f27, %0": "=m"(f_reg_save[27]));
+ asm volatile ("st %%f28, %0": "=m"(f_reg_save[28]));
+ asm volatile ("st %%f29, %0": "=m"(f_reg_save[29]));
+ asm volatile ("st %%f30, %0": "=m"(f_reg_save[30]));
+ asm volatile ("st %%f31, %0": "=m"(f_reg_save[31]));
+ */
+ asm volatile ("std %%f32, %0": "=m"(fd_reg_save[32/2-16]));
+ asm volatile ("std %%f34, %0": "=m"(fd_reg_save[34/2-16]));
+ asm volatile ("std %%f36, %0": "=m"(fd_reg_save[36/2-16]));
+ asm volatile ("std %%f38, %0": "=m"(fd_reg_save[38/2-16]));
+ asm volatile ("std %%f40, %0": "=m"(fd_reg_save[40/2-16]));
+ asm volatile ("std %%f42, %0": "=m"(fd_reg_save[42/2-16]));
+ asm volatile ("std %%f44, %0": "=m"(fd_reg_save[44/2-16]));
+ asm volatile ("std %%f46, %0": "=m"(fd_reg_save[46/2-16]));
+
+ asm volatile ("std %%f48, %0": "=m"(fd_reg_save[48/2-16]));
+ asm volatile ("std %%f50, %0": "=m"(fd_reg_save[50/2-16]));
+ asm volatile ("std %%f52, %0": "=m"(fd_reg_save[52/2-16]));
+ asm volatile ("std %%f54, %0": "=m"(fd_reg_save[54/2-16]));
+ asm volatile ("std %%f56, %0": "=m"(fd_reg_save[56/2-16]));
+ asm volatile ("std %%f58, %0": "=m"(fd_reg_save[58/2-16]));
+ asm volatile ("std %%f60, %0": "=m"(fd_reg_save[60/2-16]));
+ asm volatile ("std %%f62, %0": "=m"(fd_reg_save[62/2-16]));
+
+ asm volatile ("stx %%fsr, %0": "=m" (fsr_reg));
+ asm volatile ("rd %%fprs, %0": "=r"(fprs_reg));
+
+ asm volatile ("rd %%ccr, %0": "=r"(ccr_reg));
+
+
+ uint64_t brAddr;
+ #ifdef __sparc
+ asm("add %%i7, %1, %0":"=r"(brAddr):"i" (0));
+ #endif
+ uint64_t reverseAddr = tr->getOriginalAddress(tr->getAddrLessThan(brAddr));
+ int accumulate = exitCounter[reverseAddr]++;
+
+ if(accumulate > LEVEL_TWO_EXITS){
+
+ #ifdef GET_ALL_INFO
+ std::cerr<<"Rejected-too-many-exits\t"<<
+ (void *)tr->getOriginalAddress(tr->getAddrLessThan(brAddr))<<
+ "\t"<<(void *)tr->getEndAddress(tr->getOriginalAddress(tr->getAddrLessThan(brAddr)))
+ <<"\n";
+ #endif
+
+ exitCounter[reverseAddr] = 0;
+ delete pathCounter[reverseAddr];
+ pathCounter.erase(reverseAddr);
+ totalCount[reverseAddr] = 0;
+ // iterationCounter[reverseAddr] = 0;
+
+ tr->patchTrace(tr->getAddrLessThan(brAddr));
+ if(!backOffCounters[reverseAddr].second)
+ backOffCounters[reverseAddr].second = 1;
+
+ backOffCounters[reverseAddr].second *= 2;
+ assert(firstTriggerAddr.find(reverseAddr) != firstTriggerAddr.end());
+
+ insert_address_at(llvm_interval_counter +
+ backOffCounters[reverseAddr].second,
+ firstTriggerAddr[reverseAddr]);
+ }
+
+
+ fprs_reg ^= 0;
+ ccr_reg ^= 0;
+ asm volatile ("wr %0, 0, %%ccr":: "r"(ccr_reg));
+ asm volatile ("ldx %0, %%i0":: "m"(i_reg_save[0]));
+ asm volatile ("ldx %0, %%i1":: "m"(i_reg_save[1]));
+ asm volatile ("ldx %0, %%i2":: "m"(i_reg_save[2]));
+ asm volatile ("ldx %0, %%i3":: "m"(i_reg_save[3]));
+ asm volatile ("ldx %0, %%i4":: "m"(i_reg_save[4]));
+ asm volatile ("ldx %0, %%i5":: "m"(i_reg_save[5]));
+
+ asm volatile ("ldx %0, %%g1":: "m"(g1_reg));
+ asm volatile ("ldx %0, %%g5":: "m"(g5_reg));
+
+ asm volatile ("wr %0, 0, %%fprs":: "r"(fprs_reg));
+ asm volatile ("ld %0, %%f0":: "m"(f_reg_save[0]));
+ asm volatile ("ld %0, %%f1":: "m"(f_reg_save[1]));
+ asm volatile ("ld %0, %%f2":: "m"(f_reg_save[2]));
+ asm volatile ("ld %0, %%f3":: "m"(f_reg_save[3]));
+ asm volatile ("ld %0, %%f4":: "m"(f_reg_save[4]));
+ asm volatile ("ld %0, %%f5":: "m"(f_reg_save[5]));
+ asm volatile ("ld %0, %%f6":: "m"(f_reg_save[6]));
+ asm volatile ("ld %0, %%f7":: "m"(f_reg_save[7]));
+ asm volatile ("ld %0, %%f8":: "m"(f_reg_save[8]));
+ asm volatile ("ld %0, %%f9":: "m"(f_reg_save[9]));
+ asm volatile ("ld %0, %%f10":: "m"(f_reg_save[10]));
+ asm volatile ("ld %0, %%f11":: "m"(f_reg_save[11]));
+ asm volatile ("ld %0, %%f12":: "m"(f_reg_save[12]));
+ asm volatile ("ld %0, %%f13":: "m"(f_reg_save[13]));
+ asm volatile ("ld %0, %%f14":: "m"(f_reg_save[14]));
+ asm volatile ("ld %0, %%f15":: "m"(f_reg_save[15]));
+ /*
+ asm volatile ("ld %0, %%f16":: "m"(f_reg_save[16]));
+ asm volatile ("ld %0, %%f17":: "m"(f_reg_save[17]));
+ asm volatile ("ld %0, %%f18":: "m"(f_reg_save[18]));
+ asm volatile ("ld %0, %%f19":: "m"(f_reg_save[19]));
+ asm volatile ("ld %0, %%f20":: "m"(f_reg_save[20]));
+ asm volatile ("ld %0, %%f21":: "m"(f_reg_save[21]));
+ asm volatile ("ld %0, %%f22":: "m"(f_reg_save[22]));
+ asm volatile ("ld %0, %%f23":: "m"(f_reg_save[23]));
+ asm volatile ("ld %0, %%f24":: "m"(f_reg_save[24]));
+ asm volatile ("ld %0, %%f25":: "m"(f_reg_save[25]));
+ asm volatile ("ld %0, %%f26":: "m"(f_reg_save[26]));
+ asm volatile ("ld %0, %%f27":: "m"(f_reg_save[27]));
+ asm volatile ("ld %0, %%f28":: "m"(f_reg_save[28]));
+ asm volatile ("ld %0, %%f29":: "m"(f_reg_save[29]));
+ asm volatile ("ld %0, %%f30":: "m"(f_reg_save[30]));
+ asm volatile ("ld %0, %%f31":: "m"(f_reg_save[31]));
+ */
+ asm volatile ("ldd %0, %%f32":: "m"(fd_reg_save[32/2-16]));
+ asm volatile ("ldd %0, %%f34":: "m"(fd_reg_save[34/2-16]));
+ asm volatile ("ldd %0, %%f36":: "m"(fd_reg_save[36/2-16]));
+ asm volatile ("ldd %0, %%f38":: "m"(fd_reg_save[38/2-16]));
+ asm volatile ("ldd %0, %%f40":: "m"(fd_reg_save[40/2-16]));
+ asm volatile ("ldd %0, %%f42":: "m"(fd_reg_save[42/2-16]));
+ asm volatile ("ldd %0, %%f44":: "m"(fd_reg_save[44/2-16]));
+ asm volatile ("ldd %0, %%f46":: "m"(fd_reg_save[46/2-16]));
+
+ asm volatile ("ldd %0, %%f48":: "m"(fd_reg_save[48/2-16]));
+ asm volatile ("ldd %0, %%f50":: "m"(fd_reg_save[50/2-16]));
+ asm volatile ("ldd %0, %%f52":: "m"(fd_reg_save[52/2-16]));
+ asm volatile ("ldd %0, %%f54":: "m"(fd_reg_save[54/2-16]));
+ asm volatile ("ldd %0, %%f56":: "m"(fd_reg_save[56/2-16]));
+ asm volatile ("ldd %0, %%f58":: "m"(fd_reg_save[58/2-16]));
+ asm volatile ("ldd %0, %%f60":: "m"(fd_reg_save[60/2-16]));
+ asm volatile ("ldd %0, %%f62":: "m"(fd_reg_save[62/2-16]));
+ asm volatile ("ldx %0, %%fsr":: "m"(fsr_reg));
+ }
+
+
+
+ void getPaths(std::vector<uint64_t> &paths,
+ std::map<uint64_t, int> *mMap, int total){
+ std::multimap<int, uint64_t> mulMap;
+ for(std::map<uint64_t, int>::iterator MI = mMap->begin(),
+ ME = mMap->end(); MI != ME; ++MI){
+ mulMap.insert(std::make_pair(MI->second, MI->first));
+ //std::cerr<<MI->first<<"\n";
+ }
+ int sum = 0;
+ for(std::multimap<int, uint64_t>::reverse_iterator RMI = mulMap.rbegin(),
+ RME = mulMap.rend(); RMI != RME; ++RMI){
+ sum += RMI->first;
+ //std::cerr<<(void *)RMI->second<<"\n";
+ paths.push_back(RMI->second);
+ if((sum*100)/total > THRESHOLD_PERCENTAGE)
+ break;
+ }
+
+ for(int i=0, e = paths.size(); i<e; i++){
+ int j;
+ uint64_t one = 1;
+ uint64_t temp = paths[i];
+ for(j=63; j>-1; j--){
+ if(temp & (one<<j))
+ break;
+ }
+
+ //reverse paths
+ uint64_t fin = 0;
+ for(int x = 0; x<j; x++)
+ fin |= ((((one<<(j-x-1))&temp)>>(j-x-1))<<(x));
+
+ //std::cerr<<"Fin: "<<(void *)fin<<"\n";
+ paths[i] = fin;
+ }
+ }
+
+ void countPath(){//unsigned int br){
+ uint64_t branchHist;
+ //save regs
+ uint64_t i_reg_save[6];
+ uint32_t f_reg_save[32];
+ uint64_t fd_reg_save[16];
+ uint64_t ccr_reg;
+ uint64_t fprs_reg;
+ uint64_t fsr_reg;
+ uint64_t g1_reg;
+ //#ifdef __sparc
+ asm volatile ("stx %%i0, %0": "=m"(i_reg_save[0]));
+ asm volatile ("stx %%i1, %0": "=m"(i_reg_save[1]));
+ asm volatile ("stx %%i2, %0": "=m"(i_reg_save[2]));
+ asm volatile ("stx %%i3, %0": "=m"(i_reg_save[3]));
+ asm volatile ("stx %%i4, %0": "=m"(i_reg_save[4]));
+ asm volatile ("stx %%i5, %0": "=m"(i_reg_save[5]));
+ asm volatile ("stx %%g1, %0": "=m"(branchHist));
+ asm volatile ("stx %%g1, %0": "=m"(g1_reg));
+
+ asm volatile ("st %%f0, %0": "=m"(f_reg_save[0]));
+ asm volatile ("st %%f1, %0": "=m"(f_reg_save[1]));
+ asm volatile ("st %%f2, %0": "=m"(f_reg_save[2]));
+ asm volatile ("st %%f3, %0": "=m"(f_reg_save[3]));
+ asm volatile ("st %%f4, %0": "=m"(f_reg_save[4]));
+ asm volatile ("st %%f5, %0": "=m"(f_reg_save[5]));
+ asm volatile ("st %%f6, %0": "=m"(f_reg_save[6]));
+ asm volatile ("st %%f7, %0": "=m"(f_reg_save[7]));
+ asm volatile ("st %%f8, %0": "=m"(f_reg_save[8]));
+ asm volatile ("st %%f9, %0": "=m"(f_reg_save[9]));
+ asm volatile ("st %%f10, %0": "=m"(f_reg_save[10]));
+ asm volatile ("st %%f11, %0": "=m"(f_reg_save[11]));
+ asm volatile ("st %%f12, %0": "=m"(f_reg_save[12]));
+ asm volatile ("st %%f13, %0": "=m"(f_reg_save[13]));
+ asm volatile ("st %%f14, %0": "=m"(f_reg_save[14]));
+ asm volatile ("st %%f15, %0": "=m"(f_reg_save[15]));
+
+ /*
+ asm volatile ("st %%f16, %0": "=m"(f_reg_save[16]));
+ asm volatile ("st %%f17, %0": "=m"(f_reg_save[17]));
+ asm volatile ("st %%f18, %0": "=m"(f_reg_save[18]));
+ asm volatile ("st %%f19, %0": "=m"(f_reg_save[19]));
+ asm volatile ("st %%f20, %0": "=m"(f_reg_save[20]));
+ asm volatile ("st %%f21, %0": "=m"(f_reg_save[21]));
+ asm volatile ("st %%f22, %0": "=m"(f_reg_save[22]));
+ asm volatile ("st %%f23, %0": "=m"(f_reg_save[23]));
+ asm volatile ("st %%f24, %0": "=m"(f_reg_save[24]));
+ asm volatile ("st %%f25, %0": "=m"(f_reg_save[25]));
+ asm volatile ("st %%f26, %0": "=m"(f_reg_save[26]));
+ asm volatile ("st %%f27, %0": "=m"(f_reg_save[27]));
+ asm volatile ("st %%f28, %0": "=m"(f_reg_save[28]));
+ asm volatile ("st %%f29, %0": "=m"(f_reg_save[29]));
+ asm volatile ("st %%f30, %0": "=m"(f_reg_save[30]));
+ asm volatile ("st %%f31, %0": "=m"(f_reg_save[31]));*/
+ asm volatile ("std %%f32, %0": "=m"(fd_reg_save[32/2-16]));
+ asm volatile ("std %%f34, %0": "=m"(fd_reg_save[34/2-16]));
+ asm volatile ("std %%f36, %0": "=m"(fd_reg_save[36/2-16]));
+ asm volatile ("std %%f38, %0": "=m"(fd_reg_save[38/2-16]));
+ asm volatile ("std %%f40, %0": "=m"(fd_reg_save[40/2-16]));
+ asm volatile ("std %%f42, %0": "=m"(fd_reg_save[42/2-16]));
+ asm volatile ("std %%f44, %0": "=m"(fd_reg_save[44/2-16]));
+ asm volatile ("std %%f46, %0": "=m"(fd_reg_save[46/2-16]));
+ //*/
+ asm volatile ("std %%f48, %0": "=m"(fd_reg_save[48/2-16]));
+ asm volatile ("std %%f50, %0": "=m"(fd_reg_save[50/2-16]));
+ asm volatile ("std %%f52, %0": "=m"(fd_reg_save[52/2-16]));
+ asm volatile ("std %%f54, %0": "=m"(fd_reg_save[54/2-16]));
+ asm volatile ("std %%f56, %0": "=m"(fd_reg_save[56/2-16]));
+ asm volatile ("std %%f58, %0": "=m"(fd_reg_save[58/2-16]));
+ asm volatile ("std %%f60, %0": "=m"(fd_reg_save[60/2-16]));
+ asm volatile ("std %%f62, %0": "=m"(fd_reg_save[62/2-16]));
+
+ asm volatile ("stx %%fsr, %0": "=m" (fsr_reg));
+ asm volatile ("rd %%fprs, %0": "=r"(fprs_reg));
+ asm volatile ("rd %%ccr, %0": "=r"(ccr_reg));
+
+ //static TraceCache2 *tr2 = new TraceCache2();
+
+ uint64_t pcAddr, startAddr, endAddr;
+
+ //get the PC address for call to trigger
+ #ifdef __sparc
+ asm volatile("add %%i7, %1, %0":"=r"(pcAddr):"i" (0));
+ #else
+ assert(false && "Case not handled for this processor architecture!");
+ #endif
+
+ unsigned int offst = 4;
+ unsigned int branchInstr;
+ do{
+ offst += 4;
+ branchInstr = vm->readInstrFrmVm(pcAddr+offst, tr, tr2);
+ }while(!isBranchInstr(branchInstr));
+
+ endAddr = pcAddr + offst+4; //until delay slot!
+
+ startAddr = getBranchTarget(branchInstr, pcAddr+offst);
+ uint64_t reverseAddr = tr->getOriginalAddress(startAddr);
+ //++iterationCounter[reverseAddr];
+
+ pcAddr = reverseAddr;
+
+ if(totalCount.find(pcAddr) != totalCount.end())
+ totalCount[pcAddr]++;
+ else
+ totalCount[pcAddr] = 1;
+
+ if(pathCounter.find(pcAddr) != pathCounter.end()){
+ std::map<uint64_t, int> *oldMap = pathCounter[pcAddr];
+ if(oldMap->size() > MAX_PATH_HISTORIES){
+
+ #ifdef GET_ALL_INFO
+ std::cerr<<"Removed-SLI-too-many\t"<<(void *)tr->getOriginalAddress(startAddr)<<"\t"<<(void *)endAddr<<"\t"<<oldMap->size()<<"\n";
+ #endif
+
+ //flush-everything, and do not cache!
+ assert(tr);
+
+ uint64_t startAddrforTrace = tr->getOriginalAddress(startAddr);
+ vm->writeBranchInstruction(startAddr, startAddrforTrace);
+ doFlush(startAddr-8, startAddr+8);
+
+ delete pathCounter[pcAddr];
+ pathCounter.erase(pcAddr);
+ totalCount[pcAddr] = 0;
+ //iterationCounter[reverseAddr] = 0;
+ exitCounter[reverseAddr] = 0;
+
+ tr->patchTrace(startAddr);
+ if(!backOffCounters[reverseAddr].second)
+ backOffCounters[reverseAddr].second = 1;
+
+ backOffCounters[reverseAddr].second *= 2;
+ assert(firstTriggerAddr.find(reverseAddr) != firstTriggerAddr.end());
+ insert_address_at(llvm_interval_counter +
+ backOffCounters[reverseAddr].second,
+ firstTriggerAddr[reverseAddr]);
+ }
+ else{
+ if(oldMap->find(branchHist) != oldMap->end()){
+ //std::cerr<<(void *)pcAddr<<"\t"<<branchHist<<"\n";
+ (*oldMap)[branchHist]++;
+
+ if(totalCount[pcAddr] > THRESHOLD_LEVEL_2){
+ //|| exitCounter[reverseAddr] > totalCount[pcAddr]){
+
+ if(exitCounter[reverseAddr] < (totalCount[pcAddr]*30)/100 &&
+ totalCount[pcAddr] > THRESHOLD_LEVEL_2){
+
+ int total = totalCount[pcAddr];
+
+ // iterationCounter[reverseAddr] = 0;
+ exitCounter[reverseAddr] = 0;
+ if(!backOffCounters[reverseAddr].first)
+ backOffCounters[reverseAddr].first = 1;
+
+ backOffCounters[reverseAddr].first *= 2;
+ //insert into queue with interval set
+ assert(firstTriggerAddr.find(reverseAddr) != firstTriggerAddr.end());
+
+ //DO NOT insert trace address if already optimized
+ //insert_address_at(llvm_interval_counter +
+ //backOffCounters[reverseAddr].first,
+ // firstTriggerAddr[reverseAddr]);
+
+ std::vector<uint64_t> tempVec;
+
+ getPaths(tempVec, oldMap, total);
+ uint64_t startAddrforTrace = tr->getOriginalAddress(startAddr);
+ assert(startAddr);
+ if(!tr2->hasTraceWithId(startAddrforTrace, tempVec[0]))
+ generateTraces(startAddrforTrace, endAddr,
+ tempVec, startAddr);
+ else{
+ //write a branch to the top
+ #ifdef GET_ALL_INFO
+ std::cerr<<"Trace-exists\t"<<
+ (void *)tr->getOriginalAddress(startAddr)<<
+ "\t"<<(void *)endAddr<<"\n";
+ #endif
+
+ uint64_t startAddrforTrace = tr->getOriginalAddress(startAddr);
+ vm->writeBranchInstruction(startAddrforTrace,
+ tr2->getAddr(startAddrforTrace));
+ doFlush(startAddrforTrace-8, startAddrforTrace+8);
+ }
+
+ delete pathCounter[pcAddr];
+ pathCounter.erase(pcAddr);
+ totalCount[pcAddr] = 0;
+ exitCounter[reverseAddr] = 0;
+ }
+ else{
+ #ifdef GET_ALL_INFO
+ std::cerr<<"No-trace-generated\t"
+ <<(void *)tr->getOriginalAddress(startAddr)<<
+ "\t"<<(void *)endAddr<<"\t"<<exitCounter[reverseAddr]<<"\t"<<
+ totalCount[pcAddr]<<"\t"<<THRESHOLD_LEVEL_2<<"\n";
+ #endif
+
+ uint64_t startAddrforTrace = tr->getOriginalAddress(startAddr);
+ vm->writeBranchInstruction(startAddr, startAddrforTrace);
+ doFlush(startAddr-8, startAddr+8);
+
+ delete pathCounter[pcAddr];
+ pathCounter.erase(pcAddr);
+ totalCount[pcAddr] = 0;
+ // iterationCounter[reverseAddr] = 0;
+ exitCounter[reverseAddr] = 0;
+
+ tr->patchTrace(startAddr);
+ if(!backOffCounters[reverseAddr].second)
+ backOffCounters[reverseAddr].second = 1;
+
+ backOffCounters[reverseAddr].second *= 2;
+ assert(firstTriggerAddr.find(reverseAddr) != firstTriggerAddr.end());
+
+ insert_address_at(llvm_interval_counter +
+ backOffCounters[reverseAddr].second,
+ firstTriggerAddr[reverseAddr]);
+
+ }
+ }
+ }
+ else
+ (*oldMap)[branchHist] = 1;
+ }
+ //increment counter!
+ }
+ else{
+ std::map<uint64_t, int> *newMap = new std::map<uint64_t, int>();
+ (*newMap)[branchHist]=1;
+ pathCounter[pcAddr] = newMap;
+ }
+
+ //#ifdef __sparc
+ fprs_reg ^= 0;
+ ccr_reg ^= 0;
+ asm volatile ("wr %0, 0, %%ccr":: "r"(ccr_reg));
+ asm volatile ("ldx %0, %%i0":: "m"(i_reg_save[0]));
+ asm volatile ("ldx %0, %%i1":: "m"(i_reg_save[1]));
+ asm volatile ("ldx %0, %%i2":: "m"(i_reg_save[2]));
+ asm volatile ("ldx %0, %%i3":: "m"(i_reg_save[3]));
+ asm volatile ("ldx %0, %%i4":: "m"(i_reg_save[4]));
+ asm volatile ("ldx %0, %%i5":: "m"(i_reg_save[5]));
+ asm volatile ("ldx %0, %%g1":: "m"(g1_reg));
+
+ asm volatile ("wr %0, 0, %%fprs":: "r"(fprs_reg));
+ asm volatile ("ld %0, %%f0":: "m"(f_reg_save[0]));
+ asm volatile ("ld %0, %%f1":: "m"(f_reg_save[1]));
+ asm volatile ("ld %0, %%f2":: "m"(f_reg_save[2]));
+ asm volatile ("ld %0, %%f3":: "m"(f_reg_save[3]));
+ asm volatile ("ld %0, %%f4":: "m"(f_reg_save[4]));
+ asm volatile ("ld %0, %%f5":: "m"(f_reg_save[5]));
+ asm volatile ("ld %0, %%f6":: "m"(f_reg_save[6]));
+ asm volatile ("ld %0, %%f7":: "m"(f_reg_save[7]));
+ asm volatile ("ld %0, %%f8":: "m"(f_reg_save[8]));
+ asm volatile ("ld %0, %%f9":: "m"(f_reg_save[9]));
+ asm volatile ("ld %0, %%f10":: "m"(f_reg_save[10]));
+ asm volatile ("ld %0, %%f11":: "m"(f_reg_save[11]));
+ asm volatile ("ld %0, %%f12":: "m"(f_reg_save[12]));
+ asm volatile ("ld %0, %%f13":: "m"(f_reg_save[13]));
+ asm volatile ("ld %0, %%f14":: "m"(f_reg_save[14]));
+ asm volatile ("ld %0, %%f15":: "m"(f_reg_save[15]));
+
+ /*
+ asm volatile ("ld %0, %%f16":: "m"(f_reg_save[16]));
+ asm volatile ("ld %0, %%f17":: "m"(f_reg_save[17]));
+ asm volatile ("ld %0, %%f18":: "m"(f_reg_save[18]));
+ asm volatile ("ld %0, %%f19":: "m"(f_reg_save[19]));
+ asm volatile ("ld %0, %%f20":: "m"(f_reg_save[20]));
+ asm volatile ("ld %0, %%f21":: "m"(f_reg_save[21]));
+ asm volatile ("ld %0, %%f22":: "m"(f_reg_save[22]));
+ asm volatile ("ld %0, %%f23":: "m"(f_reg_save[23]));
+ asm volatile ("ld %0, %%f24":: "m"(f_reg_save[24]));
+ asm volatile ("ld %0, %%f25":: "m"(f_reg_save[25]));
+ asm volatile ("ld %0, %%f26":: "m"(f_reg_save[26]));
+ asm volatile ("ld %0, %%f27":: "m"(f_reg_save[27]));
+ asm volatile ("ld %0, %%f28":: "m"(f_reg_save[28]));
+ asm volatile ("ld %0, %%f29":: "m"(f_reg_save[29]));
+ asm volatile ("ld %0, %%f30":: "m"(f_reg_save[30]));
+ asm volatile ("ld %0, %%f31":: "m"(f_reg_save[31]));*/
+ asm volatile ("ldd %0, %%f32":: "m"(fd_reg_save[32/2-16]));
+ asm volatile ("ldd %0, %%f34":: "m"(fd_reg_save[34/2-16]));
+ asm volatile ("ldd %0, %%f36":: "m"(fd_reg_save[36/2-16]));
+ asm volatile ("ldd %0, %%f38":: "m"(fd_reg_save[38/2-16]));
+ asm volatile ("ldd %0, %%f40":: "m"(fd_reg_save[40/2-16]));
+ asm volatile ("ldd %0, %%f42":: "m"(fd_reg_save[42/2-16]));
+ asm volatile ("ldd %0, %%f44":: "m"(fd_reg_save[44/2-16]));
+ asm volatile ("ldd %0, %%f46":: "m"(fd_reg_save[46/2-16]));
+ //*/
+ asm volatile ("ldd %0, %%f48":: "m"(fd_reg_save[48/2-16]));
+ asm volatile ("ldd %0, %%f50":: "m"(fd_reg_save[50/2-16]));
+ asm volatile ("ldd %0, %%f52":: "m"(fd_reg_save[52/2-16]));
+ asm volatile ("ldd %0, %%f54":: "m"(fd_reg_save[54/2-16]));
+ asm volatile ("ldd %0, %%f56":: "m"(fd_reg_save[56/2-16]));
+ asm volatile ("ldd %0, %%f58":: "m"(fd_reg_save[58/2-16]));
+ asm volatile ("ldd %0, %%f60":: "m"(fd_reg_save[60/2-16]));
+ asm volatile ("ldd %0, %%f62":: "m"(fd_reg_save[62/2-16]));
+
+ asm volatile ("ldx %0, %%fsr":: "m"(fsr_reg));
+
+ //#endif
+ }
+
+ void getBranchExitCode(std::vector<unsigned int> &instVec,
+ std::map<int, uint64_t> &branchMap,
+ std::map<int, uint64_t> &targetMap,
+ std::map<int, uint64_t> &callMap);
+
+ void getIndexToStart(std::pair<int,int> &prtoret, int pathNumber,
+ std::vector<uint64_t> &paths ){
+
+ int toRet = 0;
+ int pathChosen = 0;
+ uint64_t one = 1;
+
+ for(int i=0; i<pathNumber; i++){
+ uint64_t temp = (paths[pathNumber]^paths[i]);
+ int x=0;
+ for(x=0; x<64; x++)
+ if(temp & (one<<x))
+ break;
+ if(x>toRet){
+ toRet = x;
+ pathChosen = i;
+ }
+ }
+
+ prtoret.first = toRet;//x;//toRet
+ prtoret.second = pathChosen;//0;//pathChosen;
+ }
+
+ //Note: end addr is superfluous. The *only* way to work is to form loops,
+ //and that is done by checking if start addr is reached again!
+ void getPathIntersections(std::map<int, std::map<int, int> > &myMap,
+ std::vector<uint64_t> &paths){
+ //from this trace -> conditional branch number, dest trace
+ for(int pathNumber=1, e = paths.size(); pathNumber<e; pathNumber++){
+ std::pair<int, int> a;
+ getIndexToStart(a, pathNumber, paths);
+ (myMap[a.second])[a.first]=pathNumber;
+ }
+ }
+
+ int getIndexToStart(int pathNumber, std::vector<uint64_t> &paths ){
+ int toRet = 0;
+ uint64_t one = 1;
+ for(int i=0; i<pathNumber; i++){
+ uint64_t temp = (paths[pathNumber]^paths[i]);
+ int x=0;
+ for(x=0; x<64; x++)
+ if(temp & (one<<x))
+ break;
+ if(x>toRet)
+ toRet = x;
+ }
+
+ return toRet;
+ }
+
+ void printBinary(uint64_t n){
+ uint64_t one = 1;
+ for(int i=31; i>=0; i--)
+ std::cerr<<((n&(one<<i))>>i);
+ std::cerr<<"\n";
+ }
+
+ //#define FOR_DEBUG
+ #if 0
+ void doTrigger(unsigned int path, uint64_t start,
+ uint64_t firstLevelTraceStartAddr){
+ vector<BasicBlock *> vBB;
+ BasicBlock *startBB, *bb;
+
+ //std::cerr<<"FINAL TRACE ---------------------------------\n";
+
+ assert(getReverseBBMap(start, M, startBB) && "No BB found");
+
+ vBB.push_back(startBB);
+ //std::cerr<<startBB;
+
+ TerminatorInst *TI = startBB->getTerminator();
+ BranchInst *BI = dyn_cast<BranchInst>(TI);
+ assert(BI && "Must be a branch!");
+
+ if(BI->isConditional()){
+ if(path & 1)
+ bb = BI->getSuccessor(0);
+ else
+ bb = BI->getSuccessor(1);
+ path = path >> 1;
+ }
+ else
+ bb = BI->getSuccessor(0);
+
+ while(bb != startBB){
+ vBB.push_back(bb);
+ //std::cerr<<bb;
+
+ TI = bb->getTerminator();
+ BI = dyn_cast<BranchInst>(TI);
+ assert(BI && "Must be a branch!");
+
+ if(BI->isConditional()){
+ if(path & 1)
+ bb = BI->getSuccessor(0);
+ else
+ bb = BI->getSuccessor(1);
+
+ path = path >> 1;
+ }
+ else{
+ bb = BI->getSuccessor(0);
+ }
+ }
+
+ triggerBB(vBB, vm, tr, tr2, firstLevelTraceStartAddr);
+ }
+ #endif
+
+
+ //Create traces, stich them together, and add them to tracecache
+ void generateTraces(uint64_t start, uint64_t end,
+ std::vector<uint64_t> &paths,
+ uint64_t firstLevelTraceStartAddr){
+
+ if(paths.size() > MAX_ALLOWED_PATHS){
+ #ifdef GET_ALL_INFO
+ std::cerr<<"More-than-allowed-paths\t"<<(void *)start<<"\t"<<(void *)(tr->getEndAddress(start))
+ <<"\t"<<paths.size()<<"\n";
+ #endif
+
+ tr->patchTrace(firstLevelTraceStartAddr);
+ return;
+ }
+
+
+ #ifdef FOR_DEBUG
+ std::cerr<<"Start: "<<(void *)start<<"\t End: "<<(void *)end<<"\n";
+ std::cerr<<"Paths------\n";
+ for(std::vector<uint64_t>::iterator VI = paths.begin(), VE = paths.end();
+ VI != VE; ++VI)
+ printBinary(*VI);
+ std::cerr<<"-----------\n";
+ #endif
+
+ uint64_t one = 1; //the constant 1
+
+ //branch map and call map
+ //map of call instructions
+ std::map<int, uint64_t> callMap;
+
+ //branch target map!
+ std::map<int, uint64_t> targetMap;
+
+ //map of <trace number, index in traces>
+ std::map<int, int> targetTraceMap;
+
+ //map of branches
+ std::map<int, int> branchMap; //branch at index, was located at PC
+
+ //map of <from this trace, <conditional branch number, destination trace#> >
+ std::map<int, std::map<int, int> > pathIntersections;
+ getPathIntersections(pathIntersections, paths);
+
+ //use path 0 to form vBB
+ //doTrigger(paths[0], start, firstLevelTraceStartAddr);
+ //return;
+
+ #ifdef FOR_DEBUG
+ std::cerr<<"Path Intersections------\n";
+ for(std::map<int, std::map<int, int> >::iterator MI =
+ pathIntersections.begin(), ME = pathIntersections.end(); MI != ME;
+ ++MI){
+ std::cerr<<"From path:\t"<<MI->first<<"\n";
+ std::map<int, int> &toMap = MI->second;
+ for(std::map<int, int>::iterator MMI = toMap.begin(), MME = toMap.end();
+ MMI != MME; ++MMI)
+ std::cerr<<"Branch number: "<<MMI->first<<"\t Trace: "<<MMI->second<<"\n";
+ }
+ std::cerr<<"------------------------\n";
+ #endif
+
+ //do not include the backward branch yet!
+ //do it for the first element of the vector
+
+ std::vector<unsigned int> traces;
+ int index = 0;
+
+ #ifdef GET_ALL_INFO
+ int numberOfFunctions = 0;
+ #endif
+
+ #ifdef GET_COVERAGE
+ traces.push_back(0xde77a7ef);//save o7
+ traces.push_back(CALL);
+ traces.push_back(NOP);
+ traces.push_back(0xde5fa7ef);//restore o7
+ callMap[index+1] = (uint64_t)(intptr_t)&llvm_time_start;
+ index += 4;
+ #endif
+
+ uint64_t pc = start;
+
+ //use a call stack to recursively inline functions
+ std::vector<uint64_t> callStack;
+ std::vector<uint64_t> calledStack;
+
+ //int pathCounter = 0;
+ int pathNumber = 0;
+ for(std::vector<uint64_t>::iterator PI = paths.begin(), PE = paths.end();
+ PI != PE; ++PI, pathNumber++){
+
+ uint64_t firstPath = *PI;
+
+ std::map<int, int> *myIntersections = NULL;
+
+ int pathIndex = 0;
+ uint64_t pc = start;
+
+ if(pathIntersections.find(pathNumber) != pathIntersections.end())
+ myIntersections = &pathIntersections[pathNumber];
+
+ int indexToStart = getIndexToStart(pathNumber, paths);
+ bool insertCode = false;
+
+ if(pathNumber == 0)
+ insertCode = true;
+
+ bool seenStartPC = false;
+ uint64_t lastPC = pc;
+ bool sawUnconditional = false;
+
+ while(!(seenStartPC && pc==start)){///while
+ lastPC = pc;
+
+ //so in the end, if we end the loop through second
+ //while condition, we'd know which PC was branch.
+ seenStartPC = true;
+ sawUnconditional = false;
+
+ #ifdef FOR_DEBUG
+ std::cerr<<"PC:\t"<<(void *)pc<<"\n";
+ #endif
+
+ if(!insertCode && indexToStart == pathIndex-1){
+ insertCode = true;
+ if(pathNumber != 0){
+ assert(targetTraceMap.find(pathNumber) != targetTraceMap.end());
+ branchMap[targetTraceMap[pathNumber] ] = index;
+ }
+ }
+
+
+ unsigned int instr = vm->readInstrFrmVm(pc, tr, tr2);//, tr2);//, tr2);
+
+ //case: unconditional jump
+ //neglect the branch, copy the delay slot
+ assert(! isBranchNever(instr));
+ if(isBranchInstr(instr) && (isBranchAlways(instr) ) ){
+ //push in the delay slot
+ if(insertCode){
+ unsigned dslot = vm->readInstrFrmVm(pc+4, tr, tr2);
+ if(dslot != NOP){
+ traces.push_back(dslot);//, tr2));
+ index++;
+ }
+ }
+ pc = getBranchTarget(instr, pc);
+ sawUnconditional = true;
+ continue;
+ }
+
+ //case: call instruction
+ //just rewrite the target later. Right now, just store the index
+ if(isReturn(instr)){
+ //assert(callStack.size() && "Stack empty and a return is found!");
+ if(!callStack.size()){
+ tr->patchTrace(firstLevelTraceStartAddr);
+ assert(0 && "Found return");
+ #ifdef GET_ALL_INFO
+ std::cerr<<"Found-return\n";
+ #endif
+ return;
+ }
+
+ #ifdef GET_ALL_INFO
+ numberOfFunctions++;
+ #endif
+
+ if(insertCode){
+ //insert DS
+ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));
+ index++;
+ }
+ pc = callStack[callStack.size()-1];
+ callStack.pop_back();
+ calledStack.pop_back();
+ }
+ else if(isIndirectCall(instr)){
+ if(insertCode){
+ #ifdef GET_COVERAGE
+ traces.push_back(0xde77a7ef);//save o7
+ traces.push_back(CALL);
+ traces.push_back(NOP);
+ traces.push_back(0xde5fa7ef);//restore o7
+ callMap[index+1] = (uint64_t)(intptr_t)&llvm_time_end2;
+ index += 4;
+ #endif
+ traces.push_back(instr);
+ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));
+ index += 2;
+
+ #ifdef GET_COVERAGE
+ traces.push_back(0xde77a7ef);//save o7
+ traces.push_back(CALL);
+ traces.push_back(NOP);
+ traces.push_back(0xde5fa7ef);//restore o7
+ callMap[index+1] = (uint64_t)(intptr_t)&llvm_time_start;
+ index += 4;
+ #endif
+ }
+ pc += 8;
+ }
+
+ else if(isCallInstr(instr)){
+ uint64_t callTarget = getCallTarget(instr, pc);
+
+ Function *callFunc = getRevFunction(M, callTarget);
+
+ //inline the function if its just one basic block
+ //avoid recursion
+
+ if(callFunc && isInlinable(callFunc) &&
+ (callFunc->size() == 1 || tr->hasTraceAddr(callTarget)) &&
+ std::find(calledStack.begin(), calledStack.end(), callTarget)
+ == calledStack.end()){
+
+ //push DS, and set PC to new target
+ if(insertCode){
+ //std::cerr<<"Inlining function\n";
+ //std::cerr<<callFunc;
+ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));
+ index++;
+ //if(callFunc->size() > 1)
+ getReturnCode(traces, index, pc);
+ }
+
+ callStack.push_back(pc+8); //return address
+ calledStack.push_back(callTarget);
+ pc = callTarget;
+
+ }
+ else{
+
+ if(callTarget != (uint64_t)llvm_first_trigger && callTarget !=
+ (uint64_t)countPath){
+ if(insertCode){
+
+ #ifdef GET_COVERAGE
+ traces.push_back(0xde77a7ef);//save o7
+ traces.push_back(CALL);
+ traces.push_back(NOP);
+ traces.push_back(0xde5fa7ef);//restore o7
+ callMap[index+1] = (uint64_t)(intptr_t)&llvm_time_end2;
+ index += 4;
+ #endif
+ traces.push_back(instr);
+ callMap[index] = getCallTarget(instr, pc);
+ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));
+ index += 2;
+
+ #ifdef GET_COVERAGE
+ traces.push_back(0xde77a7ef);//save o7
+ traces.push_back(CALL);
+ traces.push_back(NOP);
+ traces.push_back(0xde5fa7ef);//restore o7
+ callMap[index+1] = (uint64_t)(intptr_t)&llvm_time_start;
+ index += 4;
+ #endif
+ }
+ }
+ else{
+ if(insertCode){
+ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));
+ index += 1;
+ }
+ }
+
+ pc += 8;
+ }
+ }
+
+ //case: conditional branch
+ else if(isBranchInstr(instr)){
+
+ int nextTrace = -1;
+ if(myIntersections && myIntersections->find(pathIndex) !=
+ myIntersections->end())// && pathNumber==0)
+ nextTrace = (*myIntersections)[pathIndex];
+
+ //is it taken?
+ if(firstPath & (one<<pathIndex)){
+
+ #ifdef FOR_DEBUG
+ std::cerr<<" taken \t";
+ #endif
+
+ if(insertCode){
+ //invert the branch, and use the fall through as the target
+ assert(!(instr & 0x20000000));
+ unsigned brInstr = vm->getInvertedBranch(instr);
+ if(isNonDepJump(brInstr))
+ brInstr = (brInstr & 0xfff7ffff);
+ traces.push_back(brInstr);
+
+ if(nextTrace < 0){
+ targetMap[index] = pc+8;
+ }
+ else{//make it point to next trace
+ assert(targetTraceMap.find(nextTrace) == targetTraceMap.end()
+ && "a given trace can have only one entry");
+ targetTraceMap[nextTrace] = index;
+ }
+
+ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));;//, tr2));
+ index +=2;
+ }
+ //continue pc from the target of the branch
+ pc = getBranchTarget(instr, pc);
+ }
+ else{
+ if(insertCode){
+ //just copy the branch
+ if(isNonDepJump(instr))
+ instr = instr & 0xfff7ffff;
+
+ traces.push_back(instr);
+
+ if(nextTrace < 0){
+ targetMap[index] = getBranchTarget(instr, pc);
+ }
+ else{
+ targetTraceMap[nextTrace] = index;
+ }
+
+
+ traces.push_back(vm->readInstrFrmVm(pc+4, tr, tr2));//, tr2));
+ index +=2;
+ }
+
+ pc += 8;
+ }
+
+ //increment pathIndex
+
+ pathIndex++;
+ }
+ else if((instr & 0x81c70000) == 0x81c70000){
+ assert(0);
+ }
+ //just copy the instruction
+ else{
+ if(insertCode){
+ if(instr!=NOP){
+ traces.push_back(instr);
+ index++;
+ }
+ }
+ pc += 4;
+ }
+ }
+
+ if(sawUnconditional){
+ //insert branch back to top!
+ unsigned int br = vm->readInstrFrmVm(lastPC, tr, tr2);//, tr2);
+ assert(isBranchInstr(br));
+ unsigned int ds = vm->readInstrFrmVm(lastPC+4, tr, tr2);//, tr2);
+
+ if(ds == NOP){
+ traces.push_back(NOP);
+ index++;
+ }
+
+ #ifdef GET_COVERAGE
+ // std::cerr<<"YYYYYYYYYYYYYYY\n";
+ traces[index-1] = getBranchInst(br, (uint64_t)(&traces[4]),
+ (uint64_t)(&traces[index-1]));
+ #else
+ traces[index-1] = getBranchInst(br, (uint64_t)(&traces[0]),
+ (uint64_t)(&traces[index-1]));
+ #endif
+ traces.push_back(ds);
+ index++;
+ }
+ else if(pc == start){
+ //insert branch back to top!
+ unsigned int br = vm->readInstrFrmVm(lastPC, tr, tr2);
+ unsigned int ds = vm->readInstrFrmVm(lastPC+4, tr, tr2);
+ traces[index-2] = getBranchInst(br, (uint64_t)(&traces[0]),
+ (uint64_t)(&traces[index-2]));
+ traces[index-1] = ds;
+ }
+ else{
+ //insert branch back to top!
+ unsigned int br = vm->readInstrFrmVm(pc, tr, tr2);
+ unsigned int ds = vm->readInstrFrmVm(pc+4, tr, tr2);
+ traces.push_back(getBranchInst(br, (uint64_t)(&traces[0]),
+ (uint64_t)(&traces[index])));
+ traces.push_back(ds);
+ index += 2;
+ }
+ }
+
+ std::map<int, uint64_t> myBranchMap;
+ getBranchExitCode(traces, myBranchMap, targetMap, callMap);
+
+ assert(tr->getEndAddress(start));
+
+ //tr->patchTrace(firstLevelTraceStartAddr);
+
+ if(!tr2->addTrace(start, tr->getEndAddress(start), traces, paths[0], callMap,
+ myBranchMap, branchMap, firstLevelTraceStartAddr, tr)){
+
+ std::cerr<<"^^^^^^^^^^************** Trace could not be added!!!\n";
+ }
+ #ifdef GET_ALL_INFO
+ std::cerr<<"Added-trace\t"<<(void *)start<<"\t"
+ <<(void *)(tr->getEndAddress(start))
+ <<"\t"<<traces.size()<<"\t"<<paths.size()<<"\t"
+ <<numberOfFunctions<<"\n";
+ #endif
+
+ }
+
+ void getBranchExitCode(std::vector<unsigned int> &instVec,
+ std::map<int, uint64_t> &branchMap,
+ std::map<int, uint64_t> &targetMap,
+ std::map<int, uint64_t> &callMap){
+
+ //for each branch, insert code!
+ int instIndex = instVec.size();
+
+ for(std::map<int, uint64_t>::iterator MI = targetMap.begin(),
+ ME = targetMap.end();
+ MI != ME; ++MI){
+ unsigned int instr = instVec[MI->first];
+ uint64_t pc = MI->second;
+
+ #ifdef GET_COVERAGE
+ instVec.push_back(0xde77a7ef);//save o7
+ instVec.push_back(CALL);
+ callMap[instIndex+1] = (uint64_t)&llvm_time_end2;
+ instVec.push_back(NOP);
+ instVec.push_back(0xde77a7ef);//restore o7
+ //end call_inst!
+ #endif
+
+ uint64_t target = targetMap[MI->first];
+
+ instVec.push_back(0x10800000);//BA
+ instVec.push_back(NOP);
+
+ uint64_t newInst = getBranchInst(instr, (uint64_t)(&instVec[instIndex]),
+ (uint64_t)(&instVec[MI->first]));
+ instVec[MI->first] = newInst;
+
+ #ifdef GET_COVERAGE
+ instIndex += 4;
+ #endif
+ branchMap[instIndex] = target;
+ //change original call map to point to new PC
+ //branchMap.erase(MI->first);
+ //branchMap[MI->first] = instIndex;
+
+ instIndex += 2;
+ }
+ }
+
+ void getReturnCode(vector<unsigned int> &traces, int &index, uint64_t ret){
+ //sethi1
+ unsigned int r1 = ((ret>>32)&(0xfffff000))>>10;
+ unsigned int r2 = (ret>>32)&(0xfff);
+ unsigned int sethi1 = 0x03000000 | r1;
+
+ //or %g1, r2, %g1
+ unsigned int or1 = 0x82106000|r2;
+
+ //sllx %g1, 32, %g5
+ unsigned int sllx = 0x8b287020;
+
+ //sethi2
+ unsigned int r11 = ((ret)&(0xfffff000))>>10;
+ unsigned int r22 = (ret)&(0xfff);
+ unsigned int sethi2 = 0x03000000 | r11;
+
+ //or %g1, r22, %g1
+ unsigned int or2 = 0x82106000|r22;
+
+ //add %g1, %g5, %07
+ unsigned int add = 0x9e014001;
+
+ traces.push_back(sethi1);
+ traces.push_back(or1);
+ traces.push_back(sllx);
+ traces.push_back(sethi2);
+ traces.push_back(or2);
+ traces.push_back(add);
+
+ index += 6;
+ }
+
+
+
More information about the llvm-commits
mailing list