1 //===-- EdgeCode.cpp - generate LLVM instrumentation code -----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 //It implements the class EdgeCode: which provides
10 //support for inserting "appropriate" instrumentation at
11 //designated points in the graph
13 //It also has methods to insert initialization code in
15 //===----------------------------------------------------------------------===//
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/iMemory.h"
21 #include "llvm/iTerminators.h"
22 #include "llvm/iOther.h"
23 #include "llvm/iOperators.h"
24 #include "llvm/iPHINode.h"
25 #include "llvm/Module.h"
27 #define INSERT_LOAD_COUNT
35 static void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo,
36 Value *cnt, Instruction *rInst){
38 vector<Value *> tmpVec;
39 tmpVec.push_back(Constant::getNullValue(Type::LongTy));
40 tmpVec.push_back(Constant::getNullValue(Type::LongTy));
41 Instruction *Idx = new GetElementPtrInst(cnt, tmpVec, "");//,
42 BB->getInstList().push_back(Idx);
44 const Type *PIntTy = PointerType::get(Type::IntTy);
45 Function *trigMeth = M->getOrInsertFunction("trigger", Type::VoidTy,
46 Type::IntTy, Type::IntTy,
48 assert(trigMeth && "trigger method could not be inserted!");
50 vector<Value *> trargs;
52 trargs.push_back(ConstantSInt::get(Type::IntTy,MethNo));
53 trargs.push_back(pathNo);
54 trargs.push_back(Idx);
55 trargs.push_back(rInst);
57 Instruction *callInst=new CallInst(trigMeth, trargs, "");//, BB->begin());
58 BB->getInstList().push_back(callInst);
59 //triggerInst = new CallInst(trigMeth, trargs, "");//, InsertPos);
63 //get the code to be inserted on the edge
64 //This is determined from cond (1-6)
65 void getEdgeCode::getCode(Instruction *rInst, Value *countInst,
66 Function *M, BasicBlock *BB,
67 vector<Value *> &retVec){
69 //Instruction *InsertPos = BB->getInstList().begin();
71 //now check for cdIn and cdOut
74 cdOut->getCode(rInst, countInst, M, BB, retVec);
78 cdIn->getCode(rInst, countInst, M, BB, retVec);
81 //case: r=k code to be inserted
84 Value *val=ConstantSInt::get(Type::IntTy,inc);
86 Instruction *stInst=new StoreInst(val, rInst);//, InsertPos);
87 BB->getInstList().push_back(stInst);
92 //case: r=0 to be inserted
95 Instruction *stInst = new StoreInst(ConstantSInt::getNullValue(Type::IntTy), rInst);//, InsertPos);
96 BB->getInstList().push_back(stInst);
103 Instruction *ldInst = new LoadInst(rInst, "ti1");//, InsertPos);
104 BB->getInstList().push_back(ldInst);
105 Value *val = ConstantSInt::get(Type::IntTy,inc);
106 Instruction *addIn = BinaryOperator::create(Instruction::Add, ldInst, val,
107 "ti2");//, InsertPos);
108 BB->getInstList().push_back(addIn);
110 Instruction *stInst = new StoreInst(addIn, rInst);//, InsertPos);
111 BB->getInstList().push_back(stInst);
118 vector<Value *> tmpVec;
119 tmpVec.push_back(Constant::getNullValue(Type::LongTy));
120 tmpVec.push_back(ConstantSInt::get(Type::LongTy, inc));
121 Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//,
123 //Instruction *Idx = new GetElementPtrInst(countInst,
124 // vector<Value*>(1,ConstantSInt::get(Type::LongTy, inc)),
125 // "");//, InsertPos);
126 BB->getInstList().push_back(Idx);
128 Instruction *ldInst=new LoadInst(Idx, "ti1");//, InsertPos);
129 BB->getInstList().push_back(ldInst);
131 Value *val = ConstantSInt::get(Type::IntTy, 1);
132 //Instruction *addIn =
133 Instruction *newCount =
134 BinaryOperator::create(Instruction::Add, ldInst, val,"ti2");
135 BB->getInstList().push_back(newCount);
139 //Instruction *stInst=new StoreInst(addIn, Idx, InsertPos);
140 Instruction *stInst=new StoreInst(newCount, Idx);//, InsertPos);
141 BB->getInstList().push_back(stInst);
144 Value *trAddIndex = ConstantSInt::get(Type::IntTy,inc);
146 retVec.push_back(newCount);
147 retVec.push_back(trAddIndex);
149 //getTriggerCode(M->getParent(), BB, MethNo,
150 // ConstantSInt::get(Type::IntTy,inc), newCount, triggerInst);
153 assert(inc>=0 && "IT MUST BE POSITIVE NOW");
157 //case: count[r+inc]++
161 Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos);
162 BB->getInstList().push_back(ldIndex);
164 Value *val=ConstantSInt::get(Type::IntTy,inc);
165 Instruction *addIndex=BinaryOperator::
166 create(Instruction::Add, ldIndex, val,"ti2");//, InsertPos);
167 BB->getInstList().push_back(addIndex);
169 //now load count[addIndex]
170 Instruction *castInst=new CastInst(addIndex,
171 Type::LongTy,"ctin");//, InsertPos);
172 BB->getInstList().push_back(castInst);
174 vector<Value *> tmpVec;
175 tmpVec.push_back(Constant::getNullValue(Type::LongTy));
176 tmpVec.push_back(castInst);
177 Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//,
179 BB->getInstList().push_back(Idx);
181 Instruction *ldInst=new LoadInst(Idx, "ti3");//, InsertPos);
182 BB->getInstList().push_back(ldInst);
184 Value *cons=ConstantSInt::get(Type::IntTy,1);
186 //std::cerr<<"Type ldInst:"<<ldInst->getType()<<"\t cons:"<<cons->getType()<<"\n";
187 Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst,
189 BB->getInstList().push_back(newCount);
192 Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos);
193 BB->getInstList().push_back(stInst);
196 retVec.push_back(newCount);
197 retVec.push_back(addIndex);
199 //getTriggerCode(M->getParent(), BB, MethNo, addIndex, newCount, triggerInst);
208 Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos);
209 BB->getInstList().push_back(ldIndex);
211 //now load count[addIndex]
212 Instruction *castInst2=new CastInst(ldIndex, Type::LongTy,"ctin");
213 BB->getInstList().push_back(castInst2);
215 vector<Value *> tmpVec;
216 tmpVec.push_back(Constant::getNullValue(Type::LongTy));
217 tmpVec.push_back(castInst2);
218 Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//,
220 //Instruction *Idx = new GetElementPtrInst(countInst,
221 // vector<Value*>(1,castInst2), "");
223 BB->getInstList().push_back(Idx);
225 Instruction *ldInst=new LoadInst(Idx, "ti2");//, InsertPos);
226 BB->getInstList().push_back(ldInst);
228 Value *cons=ConstantSInt::get(Type::IntTy,1);
231 Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst,
233 BB->getInstList().push_back(newCount);
236 Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos);
237 BB->getInstList().push_back(stInst);
240 retVec.push_back(newCount);
241 retVec.push_back(ldIndex);
250 //Insert the initialization code in the top BB
251 //this includes initializing r, and count
252 //r is like an accumulator, that
253 //keeps on adding increments as we traverse along a path
254 //and at the end of the path, r contains the path
255 //number of that path
256 //Count is an array, where Count[k] represents
257 //the number of executions of path k
258 void insertInTopBB(BasicBlock *front,
260 Instruction *rVar, Value *threshold){
261 //rVar is variable r,
262 //countVar is count[]
264 Value *Int0 = ConstantInt::get(Type::IntTy, 0);
266 //now push all instructions in front of the BB
267 BasicBlock::iterator here=front->begin();
268 front->getInstList().insert(here, rVar);
269 //front->getInstList().insert(here,countVar);
271 //Initialize Count[...] with 0
273 //for (int i=0;i<k; i++){
274 //Value *GEP2 = new GetElementPtrInst(countVar,
275 // vector<Value *>(1,ConstantSInt::get(Type::LongTy, i)),
277 //new StoreInst(Int0, GEP2, here);
280 //store uint 0, uint *%R
281 new StoreInst(Int0, rVar, here);
285 //insert a basic block with appropriate code
287 void insertBB(Edge ed,
288 getEdgeCode *edgeCode,
291 int numPaths, int Methno, Value *threshold){
293 BasicBlock* BB1=ed.getFirst()->getElement();
294 BasicBlock* BB2=ed.getSecond()->getElement();
296 #ifdef DEBUG_PATH_PROFILES
298 cerr<<"Edges with codes ######################\n";
299 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
300 cerr<<"########################\n";
303 //We need to insert a BB between BB1 and BB2
304 TerminatorInst *TI=BB1->getTerminator();
305 BasicBlock *newBB=new BasicBlock("counter", BB1->getParent());
307 //get code for the new BB
308 vector<Value *> retVec;
310 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, retVec);
312 BranchInst *BI = cast<BranchInst>(TI);
314 //Is terminator a branch instruction?
315 //then we need to change branch destinations to include new BB
317 if(BI->isUnconditional()){
318 BI->setUnconditionalDest(newBB);
321 if(BI->getSuccessor(0)==BB2)
322 BI->setSuccessor(0, newBB);
324 if(BI->getSuccessor(1)==BB2)
325 BI->setSuccessor(1, newBB);
328 BasicBlock *triggerBB = NULL;
330 triggerBB = new BasicBlock("trigger", BB1->getParent());
331 getTriggerCode(BB1->getParent()->getParent(), triggerBB, Methno,
332 retVec[1], countInst, rInst);//retVec[0]);
334 //Instruction *castInst = new CastInst(retVec[0], Type::IntTy, "");
335 Instruction *etr = new LoadInst(threshold, "threshold");
337 //std::cerr<<"type1: "<<etr->getType()<<" type2: "<<retVec[0]->getType()<<"\n";
338 Instruction *cmpInst = new SetCondInst(Instruction::SetLE, etr,
340 Instruction *newBI2 = new BranchInst(triggerBB, BB2, cmpInst);
341 //newBB->getInstList().push_back(castInst);
342 newBB->getInstList().push_back(etr);
343 newBB->getInstList().push_back(cmpInst);
344 newBB->getInstList().push_back(newBI2);
346 //triggerBB->getInstList().push_back(triggerInst);
347 Instruction *triggerBranch = new BranchInst(BB2);
348 triggerBB->getInstList().push_back(triggerBranch);
351 Instruction *newBI2=new BranchInst(BB2);
352 newBB->getInstList().push_back(newBI2);
355 //now iterate over BB2, and set its Phi nodes right
356 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end();
357 BB2Inst != BBend; ++BB2Inst){
359 if(PHINode *phiInst=dyn_cast<PHINode>(BB2Inst)){
360 int bbIndex=phiInst->getBasicBlockIndex(BB1);
362 phiInst->setIncomingBlock(bbIndex, newBB);
364 ///check if trigger!=null, then add value corresponding to it too!
366 assert(triggerBB && "BasicBlock with trigger should not be null!");
367 Value *vl = phiInst->getIncomingValue((unsigned int)bbIndex);
368 phiInst->addIncoming(vl, triggerBB);
374 } // End llvm namespace