1 //===-- EdgeCode.cpp - generate LLVM instrumentation code --------*- C++ -*--=//
2 //It implements the class EdgeCode: which provides
3 //support for inserting "appropriate" instrumentation at
4 //designated points in the graph
6 //It also has methods to insert initialization code in
8 //===----------------------------------------------------------------------===//
11 #include "llvm/ConstantVals.h"
12 #include "llvm/DerivedTypes.h"
13 #include "llvm/iMemory.h"
14 #include "llvm/iTerminators.h"
15 #include "llvm/iOther.h"
16 #include "llvm/iOperators.h"
17 #include "llvm/iPHINode.h"
21 //get the code to be inserted on the edge
22 //This is determined from cond (1-6)
23 void getEdgeCode::getCode(Instruction *rInst,
24 Instruction *countInst,
28 BasicBlock::InstListType& instList=BB->getInstList();
29 BasicBlock::iterator here=instList.begin();
31 //case: r=k code to be inserted
34 Value *val=ConstantSInt::get(Type::IntTy,inc);
35 Instruction *stInst=new StoreInst(val, rInst);
36 here=instList.insert(here,stInst)+1;
40 //case: r=0 to be inserted
42 Value *val=ConstantSInt::get(Type::IntTy,0);
43 Instruction *stInst=new StoreInst(val, rInst);
44 here=instList.insert(here,stInst)+1;
50 Instruction *ldInst=new LoadInst(rInst, "ti1");
51 Value *val=ConstantSInt::get(Type::IntTy,inc);
52 Instruction *addIn=BinaryOperator::
53 create(Instruction::Add, ldInst, val,"ti2");
55 Instruction *stInst=new StoreInst(addIn, rInst);
56 here=instList.insert(here,ldInst)+1;
57 here=instList.insert(here,addIn)+1;
58 here=instList.insert(here,stInst)+1;
64 Instruction *ldInst=new
65 LoadInst(countInst,vector<Value *>
66 (1,ConstantUInt::get(Type::UIntTy, inc)), "ti1");
67 Value *val=ConstantSInt::get(Type::IntTy,1);
68 Instruction *addIn=BinaryOperator::
69 create(Instruction::Add, ldInst, val,"ti2");
71 assert(inc>=0 && "IT MUST BE POSITIVE NOW");
72 Instruction *stInst=new
73 StoreInst(addIn, countInst, vector<Value *>
74 (1, ConstantUInt::get(Type::UIntTy,inc)));
76 here=instList.insert(here,ldInst)+1;
77 here=instList.insert(here,addIn)+1;
78 here=instList.insert(here,stInst)+1;
82 //case: count[r+inc]++
85 Instruction *ldIndex=new LoadInst(rInst, "ti1");
86 Value *val=ConstantSInt::get(Type::IntTy,inc);
87 Instruction *addIndex=BinaryOperator::
88 create(Instruction::Add, ldIndex, val,"ti2");
90 //now load count[addIndex]
91 Instruction *castInst=new CastInst(addIndex,
93 Instruction *ldInst=new
94 LoadInst(countInst, vector<Value *>(1,castInst), "ti3");
95 Value *cons=ConstantSInt::get(Type::IntTy,1);
98 Instruction *addIn=BinaryOperator::
99 create(Instruction::Add, ldInst, cons,"ti4");
100 Instruction *stInst=new
101 StoreInst(addIn, countInst,
102 vector<Value *>(1,castInst));
104 here=instList.insert(here,ldIndex)+1;
105 here=instList.insert(here,addIndex)+1;
106 here=instList.insert(here,castInst)+1;
107 here=instList.insert(here,ldInst)+1;
108 here=instList.insert(here,addIn)+1;
109 here=instList.insert(here,stInst)+1;
116 Instruction *ldIndex=new LoadInst(rInst, "ti1");
118 //now load count[addIndex]
119 Instruction *castInst2=new
120 CastInst(ldIndex, Type::UIntTy,"ctin");
121 Instruction *ldInst=new
122 LoadInst(countInst, vector<Value *>(1,castInst2), "ti2");
123 Value *cons=ConstantSInt::get(Type::IntTy,1);
126 Instruction *addIn=BinaryOperator::
127 create(Instruction::Add, ldInst, cons,"ti3");
128 Instruction *stInst=new
129 StoreInst(addIn, countInst, vector<Value *>(1,castInst2));
131 here=instList.insert(here,ldIndex)+1;
132 here=instList.insert(here,castInst2)+1;
133 here=instList.insert(here,ldInst)+1;
134 here=instList.insert(here,addIn)+1;
135 here=instList.insert(here,stInst)+1;
140 //now check for cdIn and cdOut
143 cdOut->getCode(rInst, countInst, M, BB);
146 cdIn->getCode(rInst, countInst, M, BB);
153 //Insert the initialization code in the top BB
154 //this includes initializing r, and count
155 //r is like an accumulator, that
156 //keeps on adding increments as we traverse along a path
157 //and at the end of the path, r contains the path
158 //number of that path
159 //Count is an array, where Count[k] represents
160 //the number of executions of path k
161 void insertInTopBB(BasicBlock *front,
164 Instruction *countVar){
165 //rVar is variable r,
166 //countVar is array Count, and these are allocatted outside
168 //store uint 0, uint *%R, uint 0
170 idx.push_back(ConstantUInt::get(Type::UIntTy, 0));
171 Instruction *stInstr=new StoreInst(ConstantInt::get(Type::IntTy, 0), rVar,
174 //now push all instructions in front of the BB
175 BasicBlock::InstListType& instList=front->getInstList();
176 BasicBlock::iterator here=instList.begin();
177 here=front->getInstList().insert(here, rVar)+1;
178 here=front->getInstList().insert(here,countVar)+1;
180 //Initialize Count[...] with 0
181 for(int i=0;i<k; i++){
182 Instruction *stInstrC=new
183 StoreInst(ConstantInt::get(Type::IntTy, 0),
184 countVar, std::vector<Value *>
185 (1,ConstantUInt::get(Type::UIntTy, i)));
186 here=front->getInstList().insert(here,stInstrC)+1;
189 here=front->getInstList().insert(here,stInstr)+1;
193 //insert a basic block with appropriate code
195 void insertBB(Edge ed,
196 getEdgeCode *edgeCode,
198 Instruction *countInst){
200 BasicBlock* BB1=ed.getFirst()->getElement();
201 BasicBlock* BB2=ed.getSecond()->getElement();
203 #ifdef DEBUG_PATH_PROFILES
205 cerr<<"Edges with codes ######################\n";
206 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
207 cerr<<"########################\n";
210 //We need to insert a BB between BB1 and BB2
211 TerminatorInst *TI=BB1->getTerminator();
212 BasicBlock *newBB=new BasicBlock("counter", BB1->getParent());
214 //get code for the new BB
215 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB);
217 //Is terminator a branch instruction?
218 //then we need to change branch destinations to include new BB
220 BranchInst *BI=cast<BranchInst>(TI);
222 if(BI->isUnconditional()){
223 BI->setUnconditionalDest(newBB);
224 Instruction *newBI2=new BranchInst(BB2);
225 newBB->getInstList().push_back(newBI2);
228 Value *cond=BI->getCondition();
231 if(BI->getSuccessor(0)==BB2){
233 fB=BI->getSuccessor(1);
237 tB=BI->getSuccessor(0);
240 delete BB1->getInstList().pop_back();
241 Instruction *newBI=new BranchInst(tB,fB,cond);
242 Instruction *newBI2=new BranchInst(BB2);
243 BB1->getInstList().push_back(newBI);
244 newBB->getInstList().push_back(newBI2);
247 //now iterate over BB2, and set its Phi nodes right
248 for(BasicBlock::iterator BB2Inst=BB2->begin(), BBend=BB2->end();
249 BB2Inst!=BBend; ++BB2Inst){
251 if(PHINode *phiInst=dyn_cast<PHINode>(*BB2Inst)){
252 #ifdef DEBUG_PATH_PROFILES
253 cerr<<"YYYYYYYYYYYYYYYYY\n";
256 int bbIndex=phiInst->getBasicBlockIndex(BB1);
258 phiInst->setIncomingBlock(bbIndex, newBB);