[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