Initial checkin: helper file to insert instrumentation code along edges
authorAnand Shukla <ashukla@cs.uiuc.edu>
Tue, 26 Feb 2002 18:59:46 +0000 (18:59 +0000)
committerAnand Shukla <ashukla@cs.uiuc.edu>
Tue, 26 Feb 2002 18:59:46 +0000 (18:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1804 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp [new file with mode: 0644]

diff --git a/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp b/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp
new file mode 100644 (file)
index 0000000..4111c10
--- /dev/null
@@ -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);
+    }
+  }
+}