blob: 61b6af77aa7d54a950b93a4bce7cb051d9cc2d04 [file] [log] [blame]
Anand Shuklad0f8c882002-02-26 18:59:46 +00001//===-- 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
5//
6//It also has methods to insert initialization code in
7//top block of cfg
8//===----------------------------------------------------------------------===//
9
Anand Shukla21906892002-06-25 21:14:58 +000010#include "llvm/Transforms/Instrumentation/Graph.h"
Chris Lattnerd92b01c2002-04-09 18:37:46 +000011#include "llvm/BasicBlock.h"
Chris Lattnerca142372002-04-28 19:55:58 +000012#include "llvm/Constants.h"
Anand Shuklad0f8c882002-02-26 18:59:46 +000013#include "llvm/DerivedTypes.h"
14#include "llvm/iMemory.h"
15#include "llvm/iTerminators.h"
16#include "llvm/iOther.h"
17#include "llvm/iOperators.h"
18#include "llvm/iPHINode.h"
Anand Shukla21906892002-06-25 21:14:58 +000019#include "llvm/Module.h"
20#include "llvm/SymbolTable.h"
21#include "llvm/GlobalVariable.h"
Anand Shuklaff72c792002-07-08 19:36:39 +000022#include "llvm/Constants.h"
Anand Shukla21906892002-06-25 21:14:58 +000023#include "llvm/BasicBlock.h"
24#include "llvm/Function.h"
25#include <string.h>
26#include <stdio.h>
27#include <iostream>
28
29#define INSERT_LOAD_COUNT
30#define INSERT_STORE
Anand Shuklad0f8c882002-02-26 18:59:46 +000031
Anand Shuklad0f8c882002-02-26 18:59:46 +000032using std::vector;
33
Anand Shukla21906892002-06-25 21:14:58 +000034
35void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo,
Anand Shuklaff72c792002-07-08 19:36:39 +000036 Value *cnt){
Anand Shukla21906892002-06-25 21:14:58 +000037 static int i=-1;
38 i++;
39 char gstr[100];
40 sprintf(gstr,"globalVar%d",i);
41 std::string globalVarName=gstr;
42 SymbolTable *ST = M->getSymbolTable();
43 vector<const Type*> args;
Anand Shuklaff72c792002-07-08 19:36:39 +000044 //args.push_back(PointerType::get(Type::SByteTy));
Anand Shukla21906892002-06-25 21:14:58 +000045 args.push_back(Type::IntTy);
46 args.push_back(Type::IntTy);
47 args.push_back(Type::IntTy);
48 const FunctionType *MTy =
49 FunctionType::get(Type::VoidTy, args, false);
50
51 // Function *triggerMeth = M->getOrInsertFunction("trigger", MTy);
52 Function *trigMeth = M->getOrInsertFunction("trigger", MTy);
53 assert(trigMeth && "trigger method could not be inserted!");
54 //if (Value *triggerMeth = ST->lookup(PointerType::get(MTy), "trigger")) {
55 //Function *trigMeth = cast<Function>(triggerMeth);
56 vector<Value *> trargs;
57
58 //pred_iterator piter=BB->pred_begin();
Anand Shuklaff72c792002-07-08 19:36:39 +000059 //std::string predName = "uu";//BB->getName();
60 //Constant *bbName=ConstantArray::get(predName);//BB->getName());
61 //GlobalVariable *gbl=new GlobalVariable(ArrayType::get(Type::SByteTy,
62 // predName.size()+1),
63 // true, true, bbName, gstr);
64
65 //M->getGlobalList().push_back(gbl);
Anand Shukla21906892002-06-25 21:14:58 +000066
67 vector<Value *> elargs;
68 elargs.push_back(ConstantUInt::get(Type::UIntTy, 0));
69 elargs.push_back(ConstantUInt::get(Type::UIntTy, 0));
70
Anand Shuklaff72c792002-07-08 19:36:39 +000071 // commented out bb name frm which its called
72 //Instruction *getElmntInst=new GetElementPtrInst(gbl,elargs,"elmntInst");
73
Anand Shukla21906892002-06-25 21:14:58 +000074 //trargs.push_back(ConstantArray::get(BB->getName()));
Anand Shuklaff72c792002-07-08 19:36:39 +000075
76 //trargs.push_back(getElmntInst);
77 //trargs.push_back(bbName);
78
Anand Shukla21906892002-06-25 21:14:58 +000079 trargs.push_back(ConstantSInt::get(Type::IntTy,MethNo));
80
81 //trargs.push_back(ConstantSInt::get(Type::IntTy,-1));//erase this
82 trargs.push_back(pathNo);
83 trargs.push_back(cnt);
84 Instruction *callInst=new CallInst(trigMeth,trargs);
85
86 BasicBlock::InstListType& instList=BB->getInstList();
87 BasicBlock::iterator here=instList.begin();
Anand Shuklaff72c792002-07-08 19:36:39 +000088 //here = ++instList.insert(here, getElmntInst);
Anand Shukla21906892002-06-25 21:14:58 +000089 instList.insert(here,callInst);
Anand Shukla21906892002-06-25 21:14:58 +000090}
91
92
Anand Shuklad0f8c882002-02-26 18:59:46 +000093//get the code to be inserted on the edge
94//This is determined from cond (1-6)
95void getEdgeCode::getCode(Instruction *rInst,
96 Instruction *countInst,
Chris Lattnerf8e4dc32002-04-08 22:03:00 +000097 Function *M,
Anand Shukla21906892002-06-25 21:14:58 +000098 BasicBlock *BB, int numPaths, int MethNo){
Anand Shuklad0f8c882002-02-26 18:59:46 +000099
100 BasicBlock::InstListType& instList=BB->getInstList();
101 BasicBlock::iterator here=instList.begin();
102
103 //case: r=k code to be inserted
104 switch(cond){
105 case 1:{
106 Value *val=ConstantSInt::get(Type::IntTy,inc);
Anand Shukla21906892002-06-25 21:14:58 +0000107#ifdef INSERT_STORE
Anand Shuklad0f8c882002-02-26 18:59:46 +0000108 Instruction *stInst=new StoreInst(val, rInst);
Anand Shukla21906892002-06-25 21:14:58 +0000109 here = ++instList.insert(here,stInst);
110#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000111 break;
112 }
113
114 //case: r=0 to be inserted
115 case 2:{
116 Value *val=ConstantSInt::get(Type::IntTy,0);
Anand Shukla21906892002-06-25 21:14:58 +0000117#ifdef INSERT_STORE
Anand Shuklad0f8c882002-02-26 18:59:46 +0000118 Instruction *stInst=new StoreInst(val, rInst);
Anand Shukla21906892002-06-25 21:14:58 +0000119 here = ++instList.insert(here,stInst);
120#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000121 break;
122 }
123
124 //r+=k
125 case 3:{
Anand Shukla21906892002-06-25 21:14:58 +0000126
Anand Shuklad0f8c882002-02-26 18:59:46 +0000127 Instruction *ldInst=new LoadInst(rInst, "ti1");
128 Value *val=ConstantSInt::get(Type::IntTy,inc);
129 Instruction *addIn=BinaryOperator::
130 create(Instruction::Add, ldInst, val,"ti2");
Anand Shukla21906892002-06-25 21:14:58 +0000131#ifdef INSERT_STORE
Anand Shuklad0f8c882002-02-26 18:59:46 +0000132 Instruction *stInst=new StoreInst(addIn, rInst);
Anand Shukla21906892002-06-25 21:14:58 +0000133#endif
134 here = ++instList.insert(here,ldInst);
135 here = ++instList.insert(here,addIn);
136#ifdef INSERT_STORE
137 here = ++instList.insert(here,stInst);
138#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000139 break;
140 }
141
142 //count[inc]++
143 case 4:{
Anand Shukla21906892002-06-25 21:14:58 +0000144
145 assert(inc>=0 && inc<=numPaths && "inc out of bound!");
146
Chris Lattnere49f2992002-08-21 22:11:33 +0000147 Instruction *Idx = new GetElementPtrInst(countInst,
148 vector<Value*>(1,ConstantUInt::get(Type::UIntTy, inc)));
149
150 Instruction *ldInst=new LoadInst(Idx, "ti1");
151
152 Value *val = ConstantSInt::get(Type::IntTy, 1);
153 Instruction *addIn =
154 BinaryOperator::create(Instruction::Add, ldInst, val,"ti2");
Anand Shuklad0f8c882002-02-26 18:59:46 +0000155
Anand Shukla21906892002-06-25 21:14:58 +0000156 //insert trigger
157 getTriggerCode(M->getParent(), BB, MethNo,
158 ConstantSInt::get(Type::IntTy,inc), addIn);
159 here=instList.begin();
160 //end trigger code
161
Anand Shuklad0f8c882002-02-26 18:59:46 +0000162 assert(inc>=0 && "IT MUST BE POSITIVE NOW");
Anand Shukla21906892002-06-25 21:14:58 +0000163#ifdef INSERT_STORE
Chris Lattnere49f2992002-08-21 22:11:33 +0000164 Instruction *stInst=new StoreInst(addIn, Idx);
Anand Shukla21906892002-06-25 21:14:58 +0000165#endif
Chris Lattnere49f2992002-08-21 22:11:33 +0000166 here = ++instList.insert(here,Idx);
Anand Shukla21906892002-06-25 21:14:58 +0000167 here = ++instList.insert(here,ldInst);
168 here = ++instList.insert(here,addIn);
169#ifdef INSERT_STORE
170 here = ++instList.insert(here,stInst);
171#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000172 break;
173 }
174
175 //case: count[r+inc]++
176 case 5:{
Anand Shukla21906892002-06-25 21:14:58 +0000177
Anand Shuklad0f8c882002-02-26 18:59:46 +0000178 //ti1=inc+r
179 Instruction *ldIndex=new LoadInst(rInst, "ti1");
180 Value *val=ConstantSInt::get(Type::IntTy,inc);
181 Instruction *addIndex=BinaryOperator::
182 create(Instruction::Add, ldIndex, val,"ti2");
Anand Shukla21906892002-06-25 21:14:58 +0000183 //erase following 1 line
184 //Value *valtemp=ConstantSInt::get(Type::IntTy,999);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000185 //now load count[addIndex]
Anand Shukla21906892002-06-25 21:14:58 +0000186
Anand Shuklad0f8c882002-02-26 18:59:46 +0000187 Instruction *castInst=new CastInst(addIndex,
188 Type::UIntTy,"ctin");
Chris Lattnere49f2992002-08-21 22:11:33 +0000189 Instruction *Idx = new GetElementPtrInst(countInst,
190 vector<Value*>(1,castInst));
191
192 Instruction *ldInst=new LoadInst(Idx, "ti3");
Anand Shuklad0f8c882002-02-26 18:59:46 +0000193 Value *cons=ConstantSInt::get(Type::IntTy,1);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000194 //count[addIndex]++
195 Instruction *addIn=BinaryOperator::
196 create(Instruction::Add, ldInst, cons,"ti4");
Anand Shukla21906892002-06-25 21:14:58 +0000197
198 //insert trigger
199 getTriggerCode(M->getParent(), BB, MethNo, addIndex, addIn);
200 here=instList.begin();
201 //end trigger code
202
203#ifdef INSERT_STORE
204 ///*
Chris Lattnere49f2992002-08-21 22:11:33 +0000205 Instruction *stInst=new StoreInst(addIn, Idx);
206
Anand Shukla21906892002-06-25 21:14:58 +0000207 //*/
208#endif
209 here = ++instList.insert(here,ldIndex);
210 here = ++instList.insert(here,addIndex);
211 here = ++instList.insert(here,castInst);
Chris Lattnere49f2992002-08-21 22:11:33 +0000212 here = ++instList.insert(here,Idx);
Anand Shukla21906892002-06-25 21:14:58 +0000213 here = ++instList.insert(here,ldInst);
214 here = ++instList.insert(here,addIn);
215#ifdef INSERT_STORE
216 here = ++instList.insert(here,stInst);
217#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000218 break;
219 }
220
221 //case: count[r]+
222 case 6:{
Anand Shukla21906892002-06-25 21:14:58 +0000223
Anand Shuklad0f8c882002-02-26 18:59:46 +0000224 //ti1=inc+r
225 Instruction *ldIndex=new LoadInst(rInst, "ti1");
Anand Shukla21906892002-06-25 21:14:58 +0000226
Anand Shuklad0f8c882002-02-26 18:59:46 +0000227 //now load count[addIndex]
Chris Lattnere49f2992002-08-21 22:11:33 +0000228 Instruction *castInst2=new CastInst(ldIndex, Type::UIntTy,"ctin");
229 Instruction *Idx = new GetElementPtrInst(countInst,
230 vector<Value*>(1,castInst2));
231
232 Instruction *ldInst=new LoadInst(Idx, "ti2");
Anand Shuklad0f8c882002-02-26 18:59:46 +0000233 Value *cons=ConstantSInt::get(Type::IntTy,1);
234
235 //count[addIndex]++
Chris Lattnere49f2992002-08-21 22:11:33 +0000236 Instruction *addIn=BinaryOperator::create(Instruction::Add, ldInst,
237 cons,"ti3");
Anand Shukla21906892002-06-25 21:14:58 +0000238
239 //insert trigger
240 getTriggerCode(M->getParent(), BB, MethNo, ldIndex, addIn);
241 here=instList.begin();
242 //end trigger code
243#ifdef INSERT_STORE
Chris Lattnere49f2992002-08-21 22:11:33 +0000244 Instruction *stInst=new StoreInst(addIn, Idx);
Anand Shukla21906892002-06-25 21:14:58 +0000245#endif
246 here = ++instList.insert(here,ldIndex);
247 here = ++instList.insert(here,castInst2);
Chris Lattnere49f2992002-08-21 22:11:33 +0000248 here = ++instList.insert(here,Idx);
Anand Shukla21906892002-06-25 21:14:58 +0000249 here = instList.insert(here,ldInst);
250 here = instList.insert(here,addIn);
251#ifdef INSERT_STORE
252 here = instList.insert(here,stInst);
253#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000254 break;
255 }
256
257 }
258 //now check for cdIn and cdOut
259 //first put cdOut
Anand Shuklad0f8c882002-02-26 18:59:46 +0000260 if(cdIn!=NULL){
Anand Shukla21906892002-06-25 21:14:58 +0000261 cdIn->getCode(rInst, countInst, M, BB, numPaths, MethNo);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000262 }
Anand Shukla21906892002-06-25 21:14:58 +0000263 if(cdOut!=NULL){
264 cdOut->getCode(rInst, countInst, M, BB, numPaths, MethNo);
265 }
Anand Shuklad0f8c882002-02-26 18:59:46 +0000266}
267
268
269
270//Insert the initialization code in the top BB
271//this includes initializing r, and count
272//r is like an accumulator, that
273//keeps on adding increments as we traverse along a path
274//and at the end of the path, r contains the path
275//number of that path
276//Count is an array, where Count[k] represents
277//the number of executions of path k
278void insertInTopBB(BasicBlock *front,
279 int k,
280 Instruction *rVar,
281 Instruction *countVar){
282 //rVar is variable r,
283 //countVar is array Count, and these are allocatted outside
Chris Lattnere49f2992002-08-21 22:11:33 +0000284
285 Value *Int0 = ConstantInt::get(Type::IntTy, 0);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000286
287 //store uint 0, uint *%R, uint 0
288 vector<Value *> idx;
289 idx.push_back(ConstantUInt::get(Type::UIntTy, 0));
Chris Lattnere49f2992002-08-21 22:11:33 +0000290
291 Instruction *GEP = new GetElementPtrInst(rVar, idx);
292 Instruction *stInstr=new StoreInst(Int0, GEP);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000293
294 //now push all instructions in front of the BB
295 BasicBlock::InstListType& instList=front->getInstList();
296 BasicBlock::iterator here=instList.begin();
Chris Lattner7076ff22002-06-25 16:13:21 +0000297 here=++front->getInstList().insert(here, rVar);
298 here=++front->getInstList().insert(here,countVar);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000299
300 //Initialize Count[...] with 0
Anand Shukla21906892002-06-25 21:14:58 +0000301
Anand Shuklad0f8c882002-02-26 18:59:46 +0000302 for(int i=0;i<k; i++){
Chris Lattnere49f2992002-08-21 22:11:33 +0000303 Instruction *GEP2 = new GetElementPtrInst(countVar,
304 std::vector<Value *>(1,ConstantUInt::get(Type::UIntTy, i)));
305 here=++front->getInstList().insert(here,GEP2);
306
307 Instruction *stInstrC=new StoreInst(Int0, GEP2);
Chris Lattner7076ff22002-06-25 16:13:21 +0000308 here=++front->getInstList().insert(here,stInstrC);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000309 }
Anand Shukla21906892002-06-25 21:14:58 +0000310
Chris Lattnere49f2992002-08-21 22:11:33 +0000311 here = ++front->getInstList().insert(here,GEP);
Anand Shukla21906892002-06-25 21:14:58 +0000312 here = ++front->getInstList().insert(here,stInstr);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000313}
314
315
316//insert a basic block with appropriate code
317//along a given edge
318void insertBB(Edge ed,
319 getEdgeCode *edgeCode,
320 Instruction *rInst,
Anand Shukla21906892002-06-25 21:14:58 +0000321 Instruction *countInst,
322 int numPaths, int Methno){
323 static int i=-1;
324 i++;
Anand Shuklad0f8c882002-02-26 18:59:46 +0000325 BasicBlock* BB1=ed.getFirst()->getElement();
326 BasicBlock* BB2=ed.getSecond()->getElement();
327
Anand Shukla21906892002-06-25 21:14:58 +0000328#ifdef DEBUG_PATH_PROFILES
329 //debugging info
330 cerr<<"Edges with codes ######################\n";
331 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
332 cerr<<"########################\n";
333#endif
334
335 char counterstr[100];
336 sprintf(counterstr,"counter%d",i);
337 std::string ctr=counterstr;
Anand Shuklad0f8c882002-02-26 18:59:46 +0000338
339 //We need to insert a BB between BB1 and BB2
340 TerminatorInst *TI=BB1->getTerminator();
Anand Shukla21906892002-06-25 21:14:58 +0000341 BasicBlock *newBB=new BasicBlock(ctr, BB1->getParent());
Anand Shuklad0f8c882002-02-26 18:59:46 +0000342
343 //get code for the new BB
Anand Shukla21906892002-06-25 21:14:58 +0000344 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, numPaths, Methno);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000345
346 //Is terminator a branch instruction?
347 //then we need to change branch destinations to include new BB
348
Anand Shuklaff72c792002-07-08 19:36:39 +0000349 //std::cerr<<"before cast!\n";
Anand Shukla2a786332002-07-21 09:41:18 +0000350 //std::cerr<<"Method no in Edgecode:"<<Methno<<"\n";
351 //std::cerr<<"Instruction\n";
352 //std::cerr<<*TI;
Anand Shuklaff72c792002-07-08 19:36:39 +0000353 BranchInst *BI = cast<BranchInst>(TI);
354
Anand Shuklad0f8c882002-02-26 18:59:46 +0000355 if(BI->isUnconditional()){
356 BI->setUnconditionalDest(newBB);
357 Instruction *newBI2=new BranchInst(BB2);
358 newBB->getInstList().push_back(newBI2);
359 }
360 else{
Anand Shukla21906892002-06-25 21:14:58 +0000361 if(BI->getSuccessor(0)==BB2)
362 BI->setSuccessor(0, newBB);
363
364 if(BI->getSuccessor(1)==BB2)
365 BI->setSuccessor(1, newBB);
366
367 Instruction *newBI2=new BranchInst(BB2);
368 newBB->getInstList().push_back(newBI2);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000369 }
370
Anand Shuklaff72c792002-07-08 19:36:39 +0000371 //std::cerr<<"After casting\n";
Anand Shukla21906892002-06-25 21:14:58 +0000372 //get code for the new BB
373 //now iterate over BB2, and set its Phi nodes right
Chris Lattner7076ff22002-06-25 16:13:21 +0000374 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end();
375 BB2Inst != BBend; ++BB2Inst){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000376
Chris Lattner7076ff22002-06-25 16:13:21 +0000377 if(PHINode *phiInst=dyn_cast<PHINode>(&*BB2Inst)){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000378 int bbIndex=phiInst->getBasicBlockIndex(BB1);
Anand Shukla21906892002-06-25 21:14:58 +0000379 assert(bbIndex>=0);
380 phiInst->setIncomingBlock(bbIndex, newBB);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000381 }
382 }
383}
Anand Shukla21906892002-06-25 21:14:58 +0000384