[llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp

Anand Shukla ashukla at cs.uiuc.edu
Fri Jul 18 11:04:01 PDT 2003


Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger:

SLI.cpp added (r1.1)

---
Log message:

Major revision for runtime tracing framework

---
Diffs of the changes:

Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp
diff -c /dev/null llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp:1.1
*** /dev/null	Fri Jul 18 11:03:55 2003
--- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SLI.cpp	Fri Jul 18 11:03:45 2003
***************
*** 0 ****
--- 1,763 ----
+ #include "llvm/Reoptimizer/Mapping/LLVMinfo.h"
+ #include "llvm/Reoptimizer/InstrUtils.h"
+ #include "llvm/Reoptimizer/TraceCache.h"
+ #include "llvm/Reoptimizer/VirtualMem.h"
+ #include "llvm/Bytecode/Reader.h"
+ #include "llvm/iTerminators.h"
+ #include "Support/DataTypes.h"
+ #include "llvm/Support/CFG.h"
+ #include "llvm/Module.h"
+ #include "GetTimer.h"
+ #include <algorithm>
+ #include <iostream>
+ #include <vector>
+ #include <map>
+ 
+ using namespace std;
+ 
+ extern TraceCache *tr;
+ extern TraceCache *tr2;
+ extern int llvm_length;
+ extern const unsigned char LLVMBytecode[];
+ extern "C" void llvm_time_end();
+ extern void countPath();//unsigned int path);
+ extern "C" void llvm_first_trigger();
+ Module *M;
+ static bool initialized = false;
+ 
+ enum Color{
+   WHITE,
+   GREY,
+   BLACK
+ };
+ 
+ #define BRANCH_ALWAYS   0x10800000
+ #define CALL 0x40000000
+ 
+ void doInlining(uint64_t addr1, vector<Function *> &stack, VirtualMem *vm);
+ 
+ Module *initModules(){
+   Module *M;
+   
+   //BytecodeParser Parser;
+   std::string err;
+   M = ParseBytecodeBuffer(LLVMBytecode, llvm_length, "NOFILENAME", &err);
+   assert(M && "Module parsing failed!");
+ 
+   return M;
+ }
+ 
+ void doBackEdgeDFS(BasicBlock *node, map<BasicBlock*, BasicBlock *> &backedges,
+ 		   map<BasicBlock *, Color> &color){
+   color[node] = GREY;
+   for(BasicBlock::succ_iterator s=succ_begin(node), se=succ_end(node); 
+       s!=se; ++s){
+     if(color[*s] == GREY){
+       //backedge node->*s
+       assert(backedges.find(node) == backedges.end() && 
+ 	     "Multiple backedges starting at same basic block");
+       backedges[node] = *s;
+     }
+     else if(color[*s] != BLACK){
+       //must be white
+       doBackEdgeDFS(*s, backedges, color);
+     }
+   }
+   color[node] = BLACK;
+ }
+ 
+ void getBackEdges(map<BasicBlock*, BasicBlock *> &backedges, Function *F){
+   BasicBlock &root = F->front();
+   map<BasicBlock *, Color> color;
+   doBackEdgeDFS(&root, backedges, color);
+ }
+ 
+ void doForwardDFS(BasicBlock *node,BasicBlock *end, 
+ 		  map<BasicBlock*, BasicBlock *> &backEdges, 
+ 		  map<BasicBlock *, unsigned long> &forward, 
+ 		  map<BasicBlock *, Color> &color){
+   color[node] = GREY;
+   //std::cerr<<"Forward--------------\n";
+   //std::cerr<<node;
+   forward[node] = 1;
+   if(node != end){
+    for(BasicBlock::succ_iterator s=succ_begin(node), se=succ_end(node); 
+       s!=se; ++s){
+      //if node -> *s is a backedge, neglect
+      if(backEdges[node] == *s)
+        continue;
+      if(color[*s] != GREY && color[*s] != BLACK){
+        doForwardDFS(*s, end, backEdges, forward, color);
+      }
+    }
+   }
+   color[node] = BLACK;
+ }
+ 
+ void getForward(BasicBlock *root, BasicBlock *end, 
+ 		map<BasicBlock*, BasicBlock *> &backEdges,
+ 		map<BasicBlock *, unsigned long> &forward){
+   //do DFS, avoid backedges, don't go beyond end
+   map<BasicBlock *, Color> color;
+   doForwardDFS(root, end, backEdges, forward, color);
+ }
+ 
+ void doBackwardDFS(BasicBlock *node, BasicBlock *start,
+ 		   map<BasicBlock*, BasicBlock *> &backEdges,
+ 		   map<BasicBlock *, unsigned long> &forward,
+ 		   map<BasicBlock *, unsigned long> &backward,
+ 		   map<BasicBlock *, Color> &color){
+   color[node] = GREY;
+   backward[node] = 1;
+   //std::cerr<<"Backward----------\n";
+   //std::cerr<<node;
+   if(node != start){
+     for(BasicBlock::pred_iterator p=pred_begin(node), pe=pred_end(node); 
+ 	p!=pe; ++p){
+       if(forward[*p]){
+         //std::cerr<<"Color: "<<color[*p]<<"\n";
+         //std::cerr<<*p;
+ 	if(backEdges[*p] == node){
+ 	  continue;
+           //std::cerr<<"Has BE----------\n"; 
+         }
+ 	if(color[*p] != GREY && color[*p] != BLACK){
+ 	  doBackwardDFS(*p, start, backEdges, forward, backward, color);
+ 	}
+       }
+     }
+   }
+   color[node] = BLACK;
+ }
+ 
+ void getBackward(BasicBlock *node, BasicBlock *start,
+ 		 map<BasicBlock*, BasicBlock *> &backEdges,
+ 		 map<BasicBlock *, unsigned long> &forward,
+ 		 map<BasicBlock *, unsigned long> &backward){
+   //do DFS, avoid backedges, consider only forward edges
+   map<BasicBlock *, Color> color;
+   doBackwardDFS(node, start, backEdges, forward, backward, color);
+   backward[start] = 1;
+ }
+ 
+ void getExit(map<BasicBlock *, unsigned long> &backward,
+ 	     map<BasicBlock *, unsigned long> &exitBBs){
+   vector<BasicBlock *> toPush;
+   for(map<BasicBlock *, unsigned long>::iterator MI = backward.begin(),
+ 	ME = backward.end(); MI != ME; ++MI){
+     for(BasicBlock::succ_iterator s=succ_begin(MI->first), 
+ 	  se=succ_end(MI->first); s != se; ++s){
+       if(backward.find(*s) == backward.end()){
+ 	exitBBs[*s] = 1;
+ 	toPush.push_back(*s);
+ 	//std::cerr<<"Exit-----------\n";
+ 	//std::cerr<<*s;
+       }
+     }
+   }
+ 
+   for(vector<BasicBlock *>::iterator VI = toPush.begin(), VE = toPush.end();
+       VI != VE; ++VI){
+     backward[*VI] = 1;
+   }
+ }
+ 
+ void doTraceDFS(BasicBlock *node, vector<BasicBlock *> &trace, 
+ 		map<BasicBlock *, unsigned long> &backward,
+ 		map<BasicBlock *, Color> &color){
+   //std::cerr<<node;
+   color[node] = GREY;
+   trace.push_back(node);
+   for(BasicBlock::succ_iterator s=succ_begin(node), 
+ 	se=succ_end(node); s != se; ++s){
+     if(backward.find(*s) != backward.end()){
+       if(color[*s] != GREY && color[*s] != BLACK){
+ 	doTraceDFS(*s, trace, backward, color);
+       }
+     }
+   }
+ 
+   color[node] = BLACK;
+ }
+ 
+ void getTrace(BasicBlock *root, vector<BasicBlock *> &trace, 
+ 	      map<BasicBlock *, unsigned long> &backward){
+   //do a DFS from root ONLY on nodes in backward
+   map<BasicBlock *, Color> color;
+   doTraceDFS(root, trace, backward, color);
+ }
+ 
+ 
+ void doTraceDFSForFunction(BasicBlock *node, vector<BasicBlock *> &trace, 
+ 			   map<BasicBlock *, Color> &color){
+ 
+   color[node] = GREY;
+   trace.push_back(node);
+   for(BasicBlock::succ_iterator s=succ_begin(node), 
+ 	se=succ_end(node); s != se; ++s){
+     if(color[*s] != GREY && color[*s] != BLACK){
+       doTraceDFSForFunction(*s, trace, color);
+     }
+   }
+   color[node] = BLACK;
+ }
+ 
+ 
+ //Inlining algorithm
+ //
+ //For the TOP loop
+ //  seen;
+ //  For all calls x {
+ //   
+ //     if(!seen[x] && (x is inlinable)){
+ //       if(x not in tracache)
+ //         inline(x, stack{this function});
+ //       seen[x] = true;
+ //     }
+ //  else{
+ //     generate save/restore g1
+ //  }
+ 
+ // For inlinable functions
+ // 
+ // inline(x, stack){
+ //     stack.push(x);
+ //     seen;
+ //     for all calls y in x {
+ //       if(!seen[y] && y is inlinable && y not in stack){
+ //         if(y not in tracecache)
+ //           inline(y, stack);
+ //         seen[y] = true;
+ //       }
+ //       else{
+ //         generate save/restore for y
+ //       }
+ //     }
+ 
+ void doInstrumentation(uint64_t addr1, uint64_t addr2, VirtualMem *vm){
+  
+   //static Module *M;
+   
+   uint64_t endAddr = addr2;
+ 
+   //get LLVM module
+   if(!initialized){
+     M = initModules();
+     //std::cerr<<M;
+     initialized = true;
+   }
+   
+   assert(M && "Module unparsed!");
+   
+   //get BB address
+   BasicBlock *root=NULL, *end=NULL;
+   assert(getReverseBBMap(addr1, M, root) && "Not found root");
+   while(!getReverseBBMap(addr2, M, end))
+     addr2 -= 4;
+ 
+   assert(root && end && "No root or end found");
+ 
+   /*
+   std::cerr<<root->getParent();
+   std::cerr<<"root---------------------------\n";
+   std::cerr<<root;
+   std::cerr<<"exit---------------------------\n";
+   std::cerr<<end;
+   std::cerr<<"trace---------------------------\n";
+   */
+ 
+   //find backedges
+   map<BasicBlock*, BasicBlock*> backEdges; //edge from key->value
+   getBackEdges(backEdges, root->getParent());
+ 
+   //end node
+   assert(backEdges.find(end) != backEdges.end() && 
+ 	 "No backedge with end found");
+ 
+   //get forward edges
+   map<BasicBlock *, unsigned long> forward;
+   getForward(root, end, backEdges, forward);
+   
+   //get backward edges
+   map<BasicBlock *, unsigned long> backward;
+   getBackward(end, root, backEdges, forward, backward);
+ 
+   //for BBs in backward, find exit nodes
+   map<BasicBlock *, unsigned long> exitBBs;
+   getExit(backward, exitBBs);
+ 
+   //std::cerr<<"Trace------------------\n";
+   //get a vector of trace
+   vector<BasicBlock *> vBB;
+   getTrace(root, vBB, backward);
+ 
+   //std::cerr<<"END---------------------------\n";
+ 
+   unsigned int initial_code[] = {0x83663001};//0x82102001//move 1 to g1
+   unsigned int call_code[] = {0xc277a7ef, 0xc25fa7ef, 0xde77a7f7, 0xde5fa7f7}; 
+   //save g1, restore g1, save o7, restore o7
+   unsigned int succ0_code[] = {0x83286001, 0x82106001}; //shift g1, or g1 with 1
+   unsigned int succ1_code[] = {0x83286001, NOP}; //shift g1
+   unsigned int loop_top_code[] = {CALL, NOP};
+   //{0xd077A7F7, 0x91661001, CALL, 0xd05fA7F7};
+   //spill o0, g7->o0, call, unspill o0 0x90104000
+   unsigned int exit_code[] = {CALL, NOP};//call llvm_time_end
+ 
+   map<int, uint64_t> callMap;
+   map<int, uint64_t> branchMap;
+   map<BasicBlock *, int> bbPlacement;
+   map<int, BasicBlock *> branchStub; 
+   map<uint64_t, int> toInline;
+ 
+   int index = 0;
+   vector<unsigned int> trace; 
+   //generate a vector of instructions
+   trace.push_back(initial_code[0]);
+   //trace.push_back(initial_code[1]);
+   index += 1; 
+   //assume: succ[0] is 0, succ[1] is 1
+   for(vector<BasicBlock *>::iterator VBI = vBB.begin(), VBE = vBB.end();
+       VBI != VBE; ++VBI){//loop on vBB
+     
+     std::pair<uint64_t, uint64_t> bbInst = getBasicBlockInfo(*VBI);
+     uint64_t bbStart = bbInst.first;
+     uint64_t bbEnd = bbInst.second;
+ 
+     if(exitBBs.find(*VBI) != exitBBs.end()){ //is an exit BB
+       bbPlacement[*VBI] = index;
+       trace.push_back(call_code[2]);
+       trace.push_back(exit_code[0]);
+       trace.push_back(exit_code[1]);
+       trace.push_back(call_code[3]);
+       //trace.push_back(exit_code[2]);
+       trace.push_back(BRANCH_ALWAYS);
+       trace.push_back(NOP);
+       branchMap[index + 4] = bbStart;
+       callMap[index+1] = (uint64_t)(intptr_t)(&llvm_time_end);
+       index += 6;
+     }
+     else{ //This is not an exit BB
+       
+       bbPlacement[*VBI] = index;
+ 
+       bool isCondBranch = false;
+       int fillLater = 0;
+       bool isSucc0 = false;
+ 
+       uint64_t succ0=0, succ1=0;
+       BasicBlock *taken=NULL, *ntaken=NULL;
+       TerminatorInst *TI = (*VBI)->getTerminator();
+       if(isa<BranchInst>(TI)){
+ 	BranchInst *BI = cast<BranchInst>(TI);
+ 	if(BI->isConditional()){
+ 	  isCondBranch = true;
+ 	  taken = BI->getSuccessor(0);
+ 	  ntaken = BI->getSuccessor(1);
+ 	  succ0 = getBasicBlockInfo(taken).first;
+ 	  succ1 = getBasicBlockInfo(ntaken).first;
+ 	}
+       }
+ 
+       
+       for(uint64_t addr = bbStart; addr <= bbEnd; addr+=4){//loop on BB
+ 	unsigned instr = vm->readInstrFrmVm(addr, tr, tr2);
+       
+ 	if(isIndirectCall(instr)){
+ 	  trace.push_back(call_code[0]);
+ 	  trace.push_back(instr);
+ 	  //trace.push_back(NOP);
+ 	  trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	  trace.push_back(call_code[1]);
+ 	  index += 4;
+ 	  addr += 4;
+ 	}
+ 	else if(isCallInstr(instr)){
+ 	  uint64_t callTarget = getCallTarget(instr, addr);
+ 	  if(callTarget != (uint64_t)(intptr_t)&llvm_first_trigger){
+ 	   
+ 	    if(isInlinable(getRevFunction(M, callTarget))){
+ 	      trace.push_back(instr);
+ 	      trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	      callMap[index] = getCallTarget(instr, addr);
+ 	      toInline[callTarget] = 1;
+ 	      index += 2;
+ 	      addr += 4;
+ 	    }
+ 	    else{
+ 	   
+ 	      trace.push_back(call_code[0]);
+ 	      trace.push_back(instr);
+ 	      //trace.push_back(NOP);
+ 	      trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	      trace.push_back(call_code[1]);
+ 	      callMap[index+1] = getCallTarget(instr, addr);
+ 	      index += 4;
+ 	      addr += 4;
+ 	    }
+ 	  }
+ 	  else{
+ 	    trace.push_back(call_code[2]); //save o7
+ 	    trace.push_back(loop_top_code[0]);
+ 	    trace.push_back(loop_top_code[1]);
+ 	    trace.push_back(call_code[3]); //restore o7
+ 	    callMap[index+1] = (uint64_t)(intptr_t)&countPath;
+ 	    index += 4;
+ 	  }
+ 	}
+ 	else if(isBranchInstr(instr)){//is branch
+ 	  assert(!isBranchNever(instr) && "Branch never not handled!");
+ 	  if(isBranchAlways(instr)){
+ 	    uint64_t target = getBranchTarget(instr, addr);
+ 	    if(target == addr1){
+ 
+ 	      trace.push_back(instr);
+ 	      trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	      trace[index] = getBranchInst(instr, 
+ 					   (uint64_t)(intptr_t)&trace[0], 
+ 					   (uint64_t)(intptr_t)&trace[index]);
+ 	      index += 2;
+ 	    }
+ 	    else{
+ 	      trace.push_back(instr);
+ 	      trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	      
+ 	      BasicBlock *targetBB=NULL;
+ 	      assert(getReverseBBMap(getBranchTarget(instr, addr), M, targetBB));
+ 	      branchStub[index] = targetBB;
+ 	      index += 2;
+ 	    }
+ 	    
+ 	    addr += 4;
+ 	  }
+ 	  else{
+ 	    if(isCondBranch){
+ 	      uint64_t target = getBranchTarget(instr, addr);
+ 	      if(target == succ0){
+ 		isSucc0 = true;
+ 		fillLater = index;
+ 		trace.push_back(instr);
+ 		trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 		trace.push_back(succ1_code[0]);
+ 		trace.push_back(succ1_code[1]);
+ 		index += 4;
+ 		addr += 4;
+ 	      }
+ 	      else{
+ 		fillLater = index;
+ 		trace.push_back(instr);
+ 		trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 		trace.push_back(succ0_code[0]);
+ 		trace.push_back(succ0_code[1]);
+ 		index += 4;
+ 		addr += 4; 
+ 	      }
+ 	    }
+ 	    else{
+ 	      assert(false && "Should not be here!");
+ 	    }
+ 	  }
+ 	}
+ 	else{
+ 	  trace.push_back(instr);
+ 	  index++;
+ 	}
+       }
+     
+       if(isCondBranch){
+ 	trace.push_back(0);//dummy
+ 
+ 	unsigned int newBranch = getBranchInst(trace[fillLater], 
+ 					       (uint64_t)(intptr_t)&trace[index],
+ 					       (uint64_t)(intptr_t)&trace[fillLater]);
+       
+ 	trace[fillLater] = newBranch;
+ 
+ 	if(isSucc0){
+ 	  trace[index] = succ0_code[0];
+ 	  trace.push_back(succ0_code[1]);
+ 	  trace.push_back(BRANCH_ALWAYS);
+ 	  trace.push_back(NOP);
+ 
+ 	  if(taken == vBB[0]){
+ 	    assert(false && "Conditional branch to top!");
+ 	  }
+ 	  branchStub[index+2] = taken;
+ 	  index += 4;
+ 	}
+ 	else{
+ 	  trace[index] = succ1_code[0];
+ 	  trace.push_back(succ1_code[1]);
+ 	  trace.push_back(BRANCH_ALWAYS);
+ 	  if(ntaken == vBB[0]){
+ 	    assert(false && "Conditional branch to top!");
+ 	  }
+ 	  branchStub[index+2] = ntaken;
+ 	  trace.push_back(NOP);
+ 	  index += 4;
+ 	}
+       }
+     }
+   }
+ 
+   for(map<int, BasicBlock *>::iterator MI = branchStub.begin(),
+ 	ME = branchStub.end(); MI != ME; ++MI){
+     trace[MI->first] = getBranchInst(trace[MI->first], 
+ 				     (uint64_t)(intptr_t)&trace[bbPlacement[MI->second]],
+ 				     (uint64_t)(intptr_t)&trace[MI->first]);
+   }
+   
+ 
+   if(!tr->addTrace(addr1, endAddr, trace, 0, callMap, branchMap, tr2)){
+     std::cerr<<"Could not add!\n";
+   }
+ 
+ #ifdef GET_ALL_INFO
+   std::cerr<<"Added-SLI-trace\t"<<(void *)addr1<<"\t"<<(void *)endAddr
+ 	   <<"\t"<<trace.size()<<"\n";
+ #endif
+ 
+   for(map<uint64_t, int>::iterator MI = toInline.begin(), ME = toInline.end();
+       MI != ME; ++MI){
+     if(!tr->hasTraceAddr(MI->first)){
+       vector<Function *> stack;
+       stack.push_back(root->getParent());
+       doInlining(MI->first, stack, vm);
+     }
+   }
+ 
+ }
+ 
+ void doInlining(uint64_t addr1, vector<Function *> &stack, VirtualMem *vm){
+   static bool initialized = false;
+ 
+   assert(M && "No module!");
+   Function *F = getRevFunction(M, addr1); 
+ 
+   stack.push_back(F); //the functions inlined so far are in stack
+ 
+   //get LLVM module
+   if(!initialized){
+     M = initModules();
+     initialized = true;
+   }
+   
+   assert(M && "Module unparsed!");
+   
+   //get BB address
+   BasicBlock *root = &F->front();
+   //BasicBlock *end = &F->back();
+ 
+   //std::cerr<<F;
+ 
+   //check that end has ret
+   //assert(isa<ReturnInst>(end->getTerminator()) && "Not the terminal BB");
+   
+   //get a vector of trace
+   vector<BasicBlock *> vBB;
+   map<BasicBlock *, Color> color;
+   doTraceDFSForFunction(root, vBB, color);
+ 
+   unsigned int initial_code[] = {0x83663001};//0x82102001//move 1 to g1
+   unsigned int call_code[] = {0xc277a7ef, 0xc25fa7ef, 0xde77a7f7, 0xde5fa7f7}; 
+   //save g1, restore g1, save o7, restore o7
+   unsigned int succ0_code[] = {0x83286001, 0x82106001}; //shift g1, or g1 with 1
+   unsigned int succ1_code[] = {0x83286001, NOP}; //shift g1
+   unsigned int loop_top_code[] = {CALL, NOP};
+   //{0xd077A7F7, 0x91661001, CALL, 0xd05fA7F7};
+   //spill o0, g7->o0, call, unspill o0 0x90104000
+   unsigned int exit_code[] = {CALL, NOP};//call llvm_time_end
+ 
+   map<int, uint64_t> callMap;
+   map<int, uint64_t> branchMap;
+   map<BasicBlock *, int> bbPlacement;
+   map<int, BasicBlock *> branchStub; 
+   map<uint64_t, int> toInline;
+ 
+   int index = 0;
+   vector<unsigned int> trace; 
+   //generate a vector of instructions
+   
+   //assume: succ[0] is 0, succ[1] is 1
+   for(vector<BasicBlock *>::iterator VBI = vBB.begin(), VBE = vBB.end();
+       VBI != VBE; ++VBI){//loop on vBB
+     
+     std::pair<uint64_t, uint64_t> bbInst = getBasicBlockInfo(*VBI);
+     uint64_t bbStart = bbInst.first;
+     uint64_t bbEnd = bbInst.second;
+ 
+     bbPlacement[*VBI] = index;
+ 
+     bool isCondBranch = false;
+     int fillLater = 0;
+     bool isSucc0 = false;
+ 
+     uint64_t succ0=0 , succ1=0;
+     BasicBlock *taken=NULL, *ntaken=NULL;
+     TerminatorInst *TI = (*VBI)->getTerminator();
+     if(isa<BranchInst>(TI)){
+       BranchInst *BI = cast<BranchInst>(TI);
+       if(BI->isConditional()){
+ 	isCondBranch = true;
+ 	taken = BI->getSuccessor(0);
+ 	ntaken = BI->getSuccessor(1);
+ 	succ0 = getBasicBlockInfo(taken).first;
+ 	succ1 = getBasicBlockInfo(ntaken).first;
+       }
+     }
+ 
+       
+     for(uint64_t addr = bbStart; addr <= bbEnd; addr+=4){//loop on BB
+       unsigned instr = vm->readInstrFrmVm(addr, tr, tr2);
+       
+       if(isIndirectCall(instr)){
+ 	trace.push_back(call_code[0]);
+ 	trace.push_back(instr);
+ 	//trace.push_back(NOP);
+ 	trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	trace.push_back(call_code[1]);
+ 	index += 4;
+ 	addr += 4;
+       }
+       else if(isCallInstr(instr)){
+ 	uint64_t callTarget = getCallTarget(instr, addr);
+ 	if(callTarget != (uint64_t)(intptr_t)&llvm_first_trigger){
+ 	  if(isInlinable(getRevFunction(M, callTarget)) &&
+ 	     find(stack.begin(), stack.end(), 
+ 		  getRevFunction(M, callTarget)) == stack.end()){
+ 	    trace.push_back(instr);
+ 	    trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	    callMap[index] = getCallTarget(instr, addr);
+ 	    toInline[callTarget] = 1;
+ 	    index += 2;
+ 	    addr += 4;
+ 	  }
+ 	  else{
+ 	    trace.push_back(call_code[0]);
+ 	    trace.push_back(instr);
+ 	    //trace.push_back(NOP);
+ 	    trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	    trace.push_back(call_code[1]);
+ 	    callMap[index+1] = getCallTarget(instr, addr);
+ 	    index += 4;
+ 	    addr += 4;
+ 	  }
+ 	}
+ 	else{
+ 	  trace.push_back(call_code[2]); //save o7
+ 	  trace.push_back(loop_top_code[0]);
+ 	  trace.push_back(loop_top_code[1]);
+ 	  trace.push_back(call_code[3]); //restore o7
+ 	  callMap[index+1] = (uint64_t)(intptr_t)&countPath;
+ 	  index += 4;
+ 	}
+       }
+       else if(isBranchInstr(instr)){//is branch
+ 	assert(!isBranchNever(instr) && "Branch never not handled!");
+ 	if(isBranchAlways(instr)){
+ 	  uint64_t target = getBranchTarget(instr, addr);
+ 	  trace.push_back(instr);
+ 	  trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	  
+ 	  BasicBlock *targetBB=NULL;
+ 	  assert(getReverseBBMap(getBranchTarget(instr, addr), M, targetBB));
+ 	  branchStub[index] = targetBB;
+ 	  index += 2;
+ 	  addr += 4;
+ 	}
+ 	else{
+ 	  if(isCondBranch){
+ 	    uint64_t target = getBranchTarget(instr, addr);
+ 	    if(target == succ0){
+ 	      isSucc0 = true;
+ 	      fillLater = index;
+ 	      trace.push_back(instr);
+ 	      trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	      trace.push_back(succ1_code[0]);
+ 	      trace.push_back(succ1_code[1]);
+ 	      index += 4;
+ 	      addr += 4;
+ 	    }
+ 	    else{
+ 	      fillLater = index;
+ 	      trace.push_back(instr);
+ 	      trace.push_back(vm->readInstrFrmVm(addr+4, tr, tr2));
+ 	      trace.push_back(succ0_code[0]);
+ 	      trace.push_back(succ0_code[1]);
+ 	      index += 4;
+ 	      addr += 4; 
+ 	    }
+ 	  }
+ 	  else{
+ 	    assert(false && "Should not be here!");
+ 	  }
+ 	}
+       }
+       else{
+ 	trace.push_back(instr);
+ 	index++;
+       }
+     }
+     
+     if(isCondBranch){
+       trace.push_back(0);//dummy
+ 
+       unsigned int newBranch = getBranchInst(trace[fillLater], 
+ 					     (uint64_t)(intptr_t)&trace[index],
+ 					     (uint64_t)(intptr_t)&trace[fillLater]);
+       
+       trace[fillLater] = newBranch;
+ 
+       if(isSucc0){
+ 	trace[index] = succ0_code[0];
+ 	trace.push_back(succ0_code[1]);
+ 	trace.push_back(BRANCH_ALWAYS);
+ 	trace.push_back(NOP);
+ 
+ 	if(taken == vBB[0]){
+ 	  assert(false && "Conditional branch to top!");
+ 	}
+ 	branchStub[index+2] = taken;
+ 	index += 4;
+       }
+       else{
+ 	trace[index] = succ1_code[0];
+ 	trace.push_back(succ1_code[1]);
+ 	trace.push_back(BRANCH_ALWAYS);
+ 	if(ntaken == vBB[0]){
+ 	  assert(false && "Conditional branch to top!");
+ 	}
+ 	branchStub[index+2] = ntaken;
+ 	trace.push_back(NOP);
+ 	index += 4;
+       }
+     }
+     
+   }
+ 
+   for(map<int, BasicBlock *>::iterator MI = branchStub.begin(),
+ 	ME = branchStub.end(); MI != ME; ++MI){
+     trace[MI->first] = getBranchInst(trace[MI->first], 
+ 				     (uint64_t)(intptr_t)&trace[bbPlacement[MI->second]],
+ 				     (uint64_t)(intptr_t)&trace[MI->first]);
+   }
+   
+   uint64_t fakeEnd = 0;
+   if(F->size() > 1){
+     if(!tr->addTrace(addr1, fakeEnd, trace, 0, callMap, branchMap, tr2)){
+       std::cerr<<"Could not add!\n";
+     }
+   }
+ 
+ #ifdef GET_ALL_INFO
+   std::cerr<<"Added-SLI-inline\t"<<(void *)addr1<<"\t"<<trace.size()<<"\n";
+ #endif
+   //}
+ 
+   for(map<uint64_t, int>::iterator MI = toInline.begin(), ME = toInline.end();
+       MI != ME; ++MI){
+     if(!tr->hasTraceAddr(MI->first)){
+       stack.push_back(root->getParent());
+       doInlining(MI->first, stack, vm);
+     }
+   }
+ }





More information about the llvm-commits mailing list