mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	Initial checkin: helper file to insert instrumentation code along edges
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1804 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		
							
								
								
									
										262
									
								
								lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,262 @@
 | 
				
			|||||||
 | 
					//===-- EdgeCode.cpp - generate LLVM instrumentation code --------*- C++ -*--=//
 | 
				
			||||||
 | 
					//It implements the class EdgeCode: which provides 
 | 
				
			||||||
 | 
					//support for inserting "appropriate" instrumentation at
 | 
				
			||||||
 | 
					//designated points in the graph
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//It also has methods to insert initialization code in 
 | 
				
			||||||
 | 
					//top block of cfg
 | 
				
			||||||
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Graph.h"
 | 
				
			||||||
 | 
					#include "llvm/ConstantVals.h"
 | 
				
			||||||
 | 
					#include "llvm/DerivedTypes.h"
 | 
				
			||||||
 | 
					#include "llvm/iMemory.h"
 | 
				
			||||||
 | 
					#include "llvm/iTerminators.h"
 | 
				
			||||||
 | 
					#include "llvm/iOther.h"
 | 
				
			||||||
 | 
					#include "llvm/iOperators.h"
 | 
				
			||||||
 | 
					#include "llvm/iPHINode.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Method;
 | 
				
			||||||
 | 
					using std::vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//get the code to be inserted on the edge
 | 
				
			||||||
 | 
					//This is determined from cond (1-6)
 | 
				
			||||||
 | 
					void getEdgeCode::getCode(Instruction *rInst, 
 | 
				
			||||||
 | 
								  Instruction *countInst, 
 | 
				
			||||||
 | 
								  Method *M, 
 | 
				
			||||||
 | 
								  BasicBlock *BB){
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  BasicBlock::InstListType& instList=BB->getInstList();
 | 
				
			||||||
 | 
					  BasicBlock::iterator here=instList.begin();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //case: r=k code to be inserted
 | 
				
			||||||
 | 
					  switch(cond){
 | 
				
			||||||
 | 
					  case 1:{
 | 
				
			||||||
 | 
					    Value *val=ConstantSInt::get(Type::IntTy,inc);
 | 
				
			||||||
 | 
					    Instruction *stInst=new StoreInst(val, rInst);
 | 
				
			||||||
 | 
					    here=instList.insert(here,stInst)+1;
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //case: r=0 to be inserted
 | 
				
			||||||
 | 
					  case 2:{
 | 
				
			||||||
 | 
					    Value *val=ConstantSInt::get(Type::IntTy,0);
 | 
				
			||||||
 | 
					    Instruction *stInst=new StoreInst(val, rInst);
 | 
				
			||||||
 | 
					    here=instList.insert(here,stInst)+1;
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  //r+=k
 | 
				
			||||||
 | 
					  case 3:{
 | 
				
			||||||
 | 
					    Instruction *ldInst=new LoadInst(rInst, "ti1");
 | 
				
			||||||
 | 
					    Value *val=ConstantSInt::get(Type::IntTy,inc);
 | 
				
			||||||
 | 
					    Instruction *addIn=BinaryOperator::
 | 
				
			||||||
 | 
					      create(Instruction::Add, ldInst, val,"ti2");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Instruction *stInst=new StoreInst(addIn, rInst);
 | 
				
			||||||
 | 
					    here=instList.insert(here,ldInst)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,addIn)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,stInst)+1;
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //count[inc]++
 | 
				
			||||||
 | 
					  case 4:{
 | 
				
			||||||
 | 
					    Instruction *ldInst=new 
 | 
				
			||||||
 | 
					      LoadInst(countInst,vector<Value *>
 | 
				
			||||||
 | 
						       (1,ConstantUInt::get(Type::UIntTy, inc)), "ti1");
 | 
				
			||||||
 | 
					    Value *val=ConstantSInt::get(Type::IntTy,1);
 | 
				
			||||||
 | 
					    Instruction *addIn=BinaryOperator::
 | 
				
			||||||
 | 
					      create(Instruction::Add, ldInst, val,"ti2");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(inc>=0 && "IT MUST BE POSITIVE NOW");
 | 
				
			||||||
 | 
					    Instruction *stInst=new 
 | 
				
			||||||
 | 
					      StoreInst(addIn, countInst, vector<Value *>
 | 
				
			||||||
 | 
							(1, ConstantUInt::get(Type::UIntTy,inc)));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    here=instList.insert(here,ldInst)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,addIn)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,stInst)+1;
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //case: count[r+inc]++
 | 
				
			||||||
 | 
					  case 5:{
 | 
				
			||||||
 | 
					    //ti1=inc+r
 | 
				
			||||||
 | 
					    Instruction *ldIndex=new LoadInst(rInst, "ti1");
 | 
				
			||||||
 | 
					    Value *val=ConstantSInt::get(Type::IntTy,inc);
 | 
				
			||||||
 | 
					    Instruction *addIndex=BinaryOperator::
 | 
				
			||||||
 | 
					      create(Instruction::Add, ldIndex, val,"ti2");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //now load count[addIndex]
 | 
				
			||||||
 | 
					    Instruction *castInst=new CastInst(addIndex, 
 | 
				
			||||||
 | 
									       Type::UIntTy,"ctin");
 | 
				
			||||||
 | 
					    Instruction *ldInst=new 
 | 
				
			||||||
 | 
					      LoadInst(countInst, vector<Value *>(1,castInst), "ti3");
 | 
				
			||||||
 | 
					    Value *cons=ConstantSInt::get(Type::IntTy,1);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //count[addIndex]++
 | 
				
			||||||
 | 
					    Instruction *addIn=BinaryOperator::
 | 
				
			||||||
 | 
					      create(Instruction::Add, ldInst, cons,"ti4");
 | 
				
			||||||
 | 
					    Instruction *stInst=new 
 | 
				
			||||||
 | 
					      StoreInst(addIn, countInst, 
 | 
				
			||||||
 | 
							vector<Value *>(1,castInst));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    here=instList.insert(here,ldIndex)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,addIndex)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,castInst)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,ldInst)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,addIn)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,stInst)+1;
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //case: count[r]+
 | 
				
			||||||
 | 
					  case 6:{
 | 
				
			||||||
 | 
					    //ti1=inc+r
 | 
				
			||||||
 | 
					    Instruction *ldIndex=new LoadInst(rInst, "ti1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //now load count[addIndex]
 | 
				
			||||||
 | 
					    Instruction *castInst2=new 
 | 
				
			||||||
 | 
					      CastInst(ldIndex, Type::UIntTy,"ctin");
 | 
				
			||||||
 | 
					    Instruction *ldInst=new 
 | 
				
			||||||
 | 
					      LoadInst(countInst, vector<Value *>(1,castInst2), "ti2");
 | 
				
			||||||
 | 
					    Value *cons=ConstantSInt::get(Type::IntTy,1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //count[addIndex]++
 | 
				
			||||||
 | 
					    Instruction *addIn=BinaryOperator::
 | 
				
			||||||
 | 
					      create(Instruction::Add, ldInst, cons,"ti3"); 
 | 
				
			||||||
 | 
					    Instruction *stInst=new 
 | 
				
			||||||
 | 
					      StoreInst(addIn, countInst, vector<Value *>(1,castInst2));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    here=instList.insert(here,ldIndex)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,castInst2)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,ldInst)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,addIn)+1;
 | 
				
			||||||
 | 
					    here=instList.insert(here,stInst)+1;
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  //now check for cdIn and cdOut
 | 
				
			||||||
 | 
					  //first put cdOut
 | 
				
			||||||
 | 
					  if(cdOut!=NULL){
 | 
				
			||||||
 | 
					    cdOut->getCode(rInst, countInst, M, BB);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(cdIn!=NULL){
 | 
				
			||||||
 | 
					    cdIn->getCode(rInst, countInst, M, BB);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Insert the initialization code in the top BB
 | 
				
			||||||
 | 
					//this includes initializing r, and count
 | 
				
			||||||
 | 
					//r is like an accumulator, that 
 | 
				
			||||||
 | 
					//keeps on adding increments as we traverse along a path
 | 
				
			||||||
 | 
					//and at the end of the path, r contains the path
 | 
				
			||||||
 | 
					//number of that path
 | 
				
			||||||
 | 
					//Count is an array, where Count[k] represents
 | 
				
			||||||
 | 
					//the number of executions of path k
 | 
				
			||||||
 | 
					void insertInTopBB(BasicBlock *front, 
 | 
				
			||||||
 | 
							   int k, 
 | 
				
			||||||
 | 
							   Instruction *rVar, 
 | 
				
			||||||
 | 
							   Instruction *countVar){
 | 
				
			||||||
 | 
					  //rVar is variable r, 
 | 
				
			||||||
 | 
					  //countVar is array Count, and these are allocatted outside
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //store uint 0, uint *%R, uint 0
 | 
				
			||||||
 | 
					  vector<Value *> idx;
 | 
				
			||||||
 | 
					  idx.push_back(ConstantUInt::get(Type::UIntTy, 0));
 | 
				
			||||||
 | 
					  Instruction *stInstr=new StoreInst(ConstantInt::get(Type::IntTy, 0), rVar, 
 | 
				
			||||||
 | 
									     idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //now push all instructions in front of the BB
 | 
				
			||||||
 | 
					  BasicBlock::InstListType& instList=front->getInstList();
 | 
				
			||||||
 | 
					  BasicBlock::iterator here=instList.begin();
 | 
				
			||||||
 | 
					  here=front->getInstList().insert(here, rVar)+1;
 | 
				
			||||||
 | 
					  here=front->getInstList().insert(here,countVar)+1;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //Initialize Count[...] with 0
 | 
				
			||||||
 | 
					  for(int i=0;i<k; i++){
 | 
				
			||||||
 | 
					    Instruction *stInstrC=new 
 | 
				
			||||||
 | 
					      StoreInst(ConstantInt::get(Type::IntTy, 0), 
 | 
				
			||||||
 | 
							countVar, std::vector<Value *>
 | 
				
			||||||
 | 
							(1,ConstantUInt::get(Type::UIntTy, i))); 
 | 
				
			||||||
 | 
					    here=front->getInstList().insert(here,stInstrC)+1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  here=front->getInstList().insert(here,stInstr)+1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//insert a basic block with appropriate code
 | 
				
			||||||
 | 
					//along a given edge
 | 
				
			||||||
 | 
					void insertBB(Edge ed,
 | 
				
			||||||
 | 
						      getEdgeCode *edgeCode, 
 | 
				
			||||||
 | 
						      Instruction *rInst, 
 | 
				
			||||||
 | 
						      Instruction *countInst){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BasicBlock* BB1=ed.getFirst()->getElement();
 | 
				
			||||||
 | 
					  BasicBlock* BB2=ed.getSecond()->getElement();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					#ifdef DEBUG_PATH_PROFILES
 | 
				
			||||||
 | 
					  //debugging info
 | 
				
			||||||
 | 
					  cerr<<"Edges with codes ######################\n";
 | 
				
			||||||
 | 
					  cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
 | 
				
			||||||
 | 
					  cerr<<"########################\n";
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //We need to insert a BB between BB1 and BB2 
 | 
				
			||||||
 | 
					  TerminatorInst *TI=BB1->getTerminator();
 | 
				
			||||||
 | 
					  BasicBlock *newBB=new BasicBlock("counter", BB1->getParent());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //get code for the new BB
 | 
				
			||||||
 | 
					  edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  //Is terminator a branch instruction?
 | 
				
			||||||
 | 
					  //then we need to change branch destinations to include new BB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  BranchInst *BI=cast<BranchInst>(TI);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  if(BI->isUnconditional()){
 | 
				
			||||||
 | 
					    BI->setUnconditionalDest(newBB);
 | 
				
			||||||
 | 
					    Instruction *newBI2=new BranchInst(BB2);
 | 
				
			||||||
 | 
					    newBB->getInstList().push_back(newBI2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else{
 | 
				
			||||||
 | 
					    Value *cond=BI->getCondition();
 | 
				
			||||||
 | 
					    BasicBlock *fB, *tB;
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    if(BI->getSuccessor(0)==BB2){
 | 
				
			||||||
 | 
					      tB=newBB;
 | 
				
			||||||
 | 
					      fB=BI->getSuccessor(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else{
 | 
				
			||||||
 | 
					      fB=newBB;
 | 
				
			||||||
 | 
					      tB=BI->getSuccessor(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    delete BB1->getInstList().pop_back();
 | 
				
			||||||
 | 
					    Instruction *newBI=new BranchInst(tB,fB,cond);
 | 
				
			||||||
 | 
					    Instruction *newBI2=new BranchInst(BB2);
 | 
				
			||||||
 | 
					    BB1->getInstList().push_back(newBI);
 | 
				
			||||||
 | 
					    newBB->getInstList().push_back(newBI2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //now iterate over BB2, and set its Phi nodes right
 | 
				
			||||||
 | 
					  for(BasicBlock::iterator BB2Inst=BB2->begin(), BBend=BB2->end(); 
 | 
				
			||||||
 | 
					      BB2Inst!=BBend; ++BB2Inst){
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    if(PHINode *phiInst=dyn_cast<PHINode>(*BB2Inst)){
 | 
				
			||||||
 | 
					#ifdef DEBUG_PATH_PROFILES
 | 
				
			||||||
 | 
					      cerr<<"YYYYYYYYYYYYYYYYY\n";
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					     
 | 
				
			||||||
 | 
					      int bbIndex=phiInst->getBasicBlockIndex(BB1);
 | 
				
			||||||
 | 
					      if(bbIndex>=0)
 | 
				
			||||||
 | 
						phiInst->setIncomingBlock(bbIndex, newBB);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user