summaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorAnand Shukla <ashukla@cs.uiuc.edu>2002-02-26 18:59:46 +0000
committerAnand Shukla <ashukla@cs.uiuc.edu>2002-02-26 18:59:46 +0000
commit0b8066c14948b436f7ab488bb963c56cc4b02734 (patch)
tree62d3436e8d536966b81827fe1926e895f69cb5b8 /lib/Transforms
parentd940c7d1129da90419ba6e4342c8b6ed8b7596cb (diff)
downloadllvm-0b8066c14948b436f7ab488bb963c56cc4b02734.tar.gz
llvm-0b8066c14948b436f7ab488bb963c56cc4b02734.tar.bz2
llvm-0b8066c14948b436f7ab488bb963c56cc4b02734.tar.xz
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp262
1 files changed, 262 insertions, 0 deletions
diff --git a/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp b/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp
new file mode 100644
index 0000000000..4111c1002c
--- /dev/null
+++ b/lib/Transforms/Instrumentation/ProfilePaths/EdgeCode.cpp
@@ -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);
+ }
+ }
+}