blob: 2e5c0e7ffe65b4ad2712122e52aa955de8a8d161 [file] [log] [blame]
Chris Lattner5c447862002-09-10 17:03:06 +00001//===-- EdgeCode.cpp - generate LLVM instrumentation code -----------------===//
Anand Shuklad0f8c882002-02-26 18:59:46 +00002//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 Lattnerca142372002-04-28 19:55:58 +000011#include "llvm/Constants.h"
Anand Shuklad0f8c882002-02-26 18:59:46 +000012#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"
Anand Shukla21906892002-06-25 21:14:58 +000018#include "llvm/Module.h"
Anand Shukla21906892002-06-25 21:14:58 +000019#include <string.h>
20#include <stdio.h>
Anand Shukla21906892002-06-25 21:14:58 +000021
22#define INSERT_LOAD_COUNT
23#define INSERT_STORE
Anand Shuklad0f8c882002-02-26 18:59:46 +000024
Anand Shuklad0f8c882002-02-26 18:59:46 +000025using std::vector;
26
Anand Shukla21906892002-06-25 21:14:58 +000027
Chris Lattner5c447862002-09-10 17:03:06 +000028static void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo,
29 Value *cnt, Instruction *InsertPos){
Anand Shukla21906892002-06-25 21:14:58 +000030 static int i=-1;
31 i++;
32 char gstr[100];
33 sprintf(gstr,"globalVar%d",i);
34 std::string globalVarName=gstr;
Anand Shukla21906892002-06-25 21:14:58 +000035 vector<const Type*> args;
Anand Shuklaff72c792002-07-08 19:36:39 +000036 //args.push_back(PointerType::get(Type::SByteTy));
Anand Shukla21906892002-06-25 21:14:58 +000037 args.push_back(Type::IntTy);
38 args.push_back(Type::IntTy);
39 args.push_back(Type::IntTy);
Chris Lattner5c447862002-09-10 17:03:06 +000040 const FunctionType *MTy = FunctionType::get(Type::VoidTy, args, false);
Anand Shukla21906892002-06-25 21:14:58 +000041
42 // Function *triggerMeth = M->getOrInsertFunction("trigger", MTy);
43 Function *trigMeth = M->getOrInsertFunction("trigger", MTy);
44 assert(trigMeth && "trigger method could not be inserted!");
45 //if (Value *triggerMeth = ST->lookup(PointerType::get(MTy), "trigger")) {
46 //Function *trigMeth = cast<Function>(triggerMeth);
47 vector<Value *> trargs;
48
49 //pred_iterator piter=BB->pred_begin();
Anand Shuklaff72c792002-07-08 19:36:39 +000050 //std::string predName = "uu";//BB->getName();
51 //Constant *bbName=ConstantArray::get(predName);//BB->getName());
52 //GlobalVariable *gbl=new GlobalVariable(ArrayType::get(Type::SByteTy,
53 // predName.size()+1),
54 // true, true, bbName, gstr);
55
56 //M->getGlobalList().push_back(gbl);
Anand Shukla21906892002-06-25 21:14:58 +000057
58 vector<Value *> elargs;
59 elargs.push_back(ConstantUInt::get(Type::UIntTy, 0));
60 elargs.push_back(ConstantUInt::get(Type::UIntTy, 0));
61
Anand Shuklaff72c792002-07-08 19:36:39 +000062 // commented out bb name frm which its called
63 //Instruction *getElmntInst=new GetElementPtrInst(gbl,elargs,"elmntInst");
64
Anand Shukla21906892002-06-25 21:14:58 +000065 //trargs.push_back(ConstantArray::get(BB->getName()));
Anand Shuklaff72c792002-07-08 19:36:39 +000066
67 //trargs.push_back(getElmntInst);
68 //trargs.push_back(bbName);
69
Anand Shukla21906892002-06-25 21:14:58 +000070 trargs.push_back(ConstantSInt::get(Type::IntTy,MethNo));
71
72 //trargs.push_back(ConstantSInt::get(Type::IntTy,-1));//erase this
73 trargs.push_back(pathNo);
74 trargs.push_back(cnt);
Chris Lattner5c447862002-09-10 17:03:06 +000075 Instruction *callInst=new CallInst(trigMeth, trargs, "", InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +000076}
77
78
Anand Shuklad0f8c882002-02-26 18:59:46 +000079//get the code to be inserted on the edge
80//This is determined from cond (1-6)
81void getEdgeCode::getCode(Instruction *rInst,
82 Instruction *countInst,
Chris Lattnerf8e4dc32002-04-08 22:03:00 +000083 Function *M,
Anand Shukla21906892002-06-25 21:14:58 +000084 BasicBlock *BB, int numPaths, int MethNo){
Anand Shuklad0f8c882002-02-26 18:59:46 +000085
Chris Lattner5c447862002-09-10 17:03:06 +000086 Instruction *InsertPos = BB->begin();
Anand Shuklad0f8c882002-02-26 18:59:46 +000087
88 //case: r=k code to be inserted
89 switch(cond){
90 case 1:{
91 Value *val=ConstantSInt::get(Type::IntTy,inc);
Anand Shukla21906892002-06-25 21:14:58 +000092#ifdef INSERT_STORE
Chris Lattner5c447862002-09-10 17:03:06 +000093 Instruction *stInst=new StoreInst(val, rInst, InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +000094#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +000095 break;
96 }
97
98 //case: r=0 to be inserted
Chris Lattner5c447862002-09-10 17:03:06 +000099 case 2:
Anand Shukla21906892002-06-25 21:14:58 +0000100#ifdef INSERT_STORE
Chris Lattner5c447862002-09-10 17:03:06 +0000101 new StoreInst(ConstantSInt::getNullValue(Type::IntTy), rInst, InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000102#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000103 break;
Anand Shuklad0f8c882002-02-26 18:59:46 +0000104
105 //r+=k
106 case 3:{
Chris Lattner5c447862002-09-10 17:03:06 +0000107 Instruction *ldInst = new LoadInst(rInst, "ti1", InsertPos);
108 Value *val = ConstantSInt::get(Type::IntTy,inc);
109 Value *addIn = BinaryOperator::create(Instruction::Add, ldInst, val,
110 "ti2", InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000111#ifdef INSERT_STORE
Chris Lattner5c447862002-09-10 17:03:06 +0000112 new StoreInst(addIn, rInst, InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000113#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000114 break;
115 }
116
117 //count[inc]++
118 case 4:{
Anand Shukla21906892002-06-25 21:14:58 +0000119 assert(inc>=0 && inc<=numPaths && "inc out of bound!");
120
Chris Lattnere49f2992002-08-21 22:11:33 +0000121 Instruction *Idx = new GetElementPtrInst(countInst,
Chris Lattner5c447862002-09-10 17:03:06 +0000122 vector<Value*>(1,ConstantUInt::get(Type::UIntTy, inc)),
123 "", InsertPos);
Chris Lattnere49f2992002-08-21 22:11:33 +0000124
Chris Lattner5c447862002-09-10 17:03:06 +0000125 Instruction *ldInst=new LoadInst(Idx, "ti1", InsertPos);
Chris Lattnere49f2992002-08-21 22:11:33 +0000126
127 Value *val = ConstantSInt::get(Type::IntTy, 1);
128 Instruction *addIn =
Chris Lattner5c447862002-09-10 17:03:06 +0000129 BinaryOperator::create(Instruction::Add, ldInst, val,"ti2", InsertPos);
130
131#ifdef INSERT_STORE
132 Instruction *stInst=new StoreInst(addIn, Idx, InsertPos);
133#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000134
Anand Shukla21906892002-06-25 21:14:58 +0000135 //insert trigger
136 getTriggerCode(M->getParent(), BB, MethNo,
Chris Lattner5c447862002-09-10 17:03:06 +0000137 ConstantSInt::get(Type::IntTy,inc), addIn, InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000138 //end trigger code
139
Anand Shuklad0f8c882002-02-26 18:59:46 +0000140 assert(inc>=0 && "IT MUST BE POSITIVE NOW");
Anand Shuklad0f8c882002-02-26 18:59:46 +0000141 break;
142 }
143
144 //case: count[r+inc]++
145 case 5:{
Chris Lattner5c447862002-09-10 17:03:06 +0000146
Anand Shuklad0f8c882002-02-26 18:59:46 +0000147 //ti1=inc+r
Chris Lattner5c447862002-09-10 17:03:06 +0000148 Instruction *ldIndex=new LoadInst(rInst, "ti1", InsertPos);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000149 Value *val=ConstantSInt::get(Type::IntTy,inc);
150 Instruction *addIndex=BinaryOperator::
Chris Lattner5c447862002-09-10 17:03:06 +0000151 create(Instruction::Add, ldIndex, val,"ti2", InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000152 //erase following 1 line
153 //Value *valtemp=ConstantSInt::get(Type::IntTy,999);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000154 //now load count[addIndex]
Anand Shukla21906892002-06-25 21:14:58 +0000155
Anand Shuklad0f8c882002-02-26 18:59:46 +0000156 Instruction *castInst=new CastInst(addIndex,
Chris Lattner5c447862002-09-10 17:03:06 +0000157 Type::UIntTy,"ctin", InsertPos);
Chris Lattnere49f2992002-08-21 22:11:33 +0000158 Instruction *Idx = new GetElementPtrInst(countInst,
Chris Lattner5c447862002-09-10 17:03:06 +0000159 vector<Value*>(1,castInst), "",
160 InsertPos);
Chris Lattnere49f2992002-08-21 22:11:33 +0000161
Chris Lattner5c447862002-09-10 17:03:06 +0000162 Instruction *ldInst=new LoadInst(Idx, "ti3", InsertPos);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000163 Value *cons=ConstantSInt::get(Type::IntTy,1);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000164 //count[addIndex]++
Chris Lattner5c447862002-09-10 17:03:06 +0000165 Value *addIn = BinaryOperator::create(Instruction::Add, ldInst, cons,
166 "ti4", InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000167
168#ifdef INSERT_STORE
169 ///*
Chris Lattner5c447862002-09-10 17:03:06 +0000170 new StoreInst(addIn, Idx, InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000171 //*/
172#endif
Chris Lattner5c447862002-09-10 17:03:06 +0000173
174 //insert trigger
175 getTriggerCode(M->getParent(), BB, MethNo, addIndex, addIn, InsertPos);
176 //end trigger code
177
Anand Shuklad0f8c882002-02-26 18:59:46 +0000178 break;
179 }
180
181 //case: count[r]+
182 case 6:{
183 //ti1=inc+r
Chris Lattner5c447862002-09-10 17:03:06 +0000184 Instruction *ldIndex=new LoadInst(rInst, "ti1", InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000185
Anand Shuklad0f8c882002-02-26 18:59:46 +0000186 //now load count[addIndex]
Chris Lattner5c447862002-09-10 17:03:06 +0000187 Instruction *castInst2=new CastInst(ldIndex, Type::UIntTy,"ctin",InsertPos);
Chris Lattnere49f2992002-08-21 22:11:33 +0000188 Instruction *Idx = new GetElementPtrInst(countInst,
Chris Lattner5c447862002-09-10 17:03:06 +0000189 vector<Value*>(1,castInst2), "",
190 InsertPos);
Chris Lattnere49f2992002-08-21 22:11:33 +0000191
Chris Lattner5c447862002-09-10 17:03:06 +0000192 Instruction *ldInst=new LoadInst(Idx, "ti2", InsertPos);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000193 Value *cons=ConstantSInt::get(Type::IntTy,1);
194
195 //count[addIndex]++
Chris Lattnere49f2992002-08-21 22:11:33 +0000196 Instruction *addIn=BinaryOperator::create(Instruction::Add, ldInst,
Chris Lattner5c447862002-09-10 17:03:06 +0000197 cons,"ti3", InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000198
Chris Lattner5c447862002-09-10 17:03:06 +0000199#ifdef INSERT_STORE
200 new StoreInst(addIn, Idx, InsertPos);
201#endif
Anand Shukla21906892002-06-25 21:14:58 +0000202 //insert trigger
Chris Lattner5c447862002-09-10 17:03:06 +0000203 getTriggerCode(M->getParent(), BB, MethNo, ldIndex, addIn, InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +0000204 //end trigger code
Chris Lattner5c447862002-09-10 17:03:06 +0000205
Anand Shuklad0f8c882002-02-26 18:59:46 +0000206 break;
207 }
208
209 }
210 //now check for cdIn and cdOut
211 //first put cdOut
Anand Shuklad0f8c882002-02-26 18:59:46 +0000212 if(cdIn!=NULL){
Anand Shukla21906892002-06-25 21:14:58 +0000213 cdIn->getCode(rInst, countInst, M, BB, numPaths, MethNo);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000214 }
Anand Shukla21906892002-06-25 21:14:58 +0000215 if(cdOut!=NULL){
216 cdOut->getCode(rInst, countInst, M, BB, numPaths, MethNo);
217 }
Anand Shuklad0f8c882002-02-26 18:59:46 +0000218}
219
220
221
222//Insert the initialization code in the top BB
223//this includes initializing r, and count
224//r is like an accumulator, that
225//keeps on adding increments as we traverse along a path
226//and at the end of the path, r contains the path
227//number of that path
228//Count is an array, where Count[k] represents
229//the number of executions of path k
230void insertInTopBB(BasicBlock *front,
231 int k,
232 Instruction *rVar,
233 Instruction *countVar){
234 //rVar is variable r,
235 //countVar is array Count, and these are allocatted outside
Chris Lattnere49f2992002-08-21 22:11:33 +0000236
237 Value *Int0 = ConstantInt::get(Type::IntTy, 0);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000238
239 //store uint 0, uint *%R, uint 0
240 vector<Value *> idx;
241 idx.push_back(ConstantUInt::get(Type::UIntTy, 0));
Chris Lattnere49f2992002-08-21 22:11:33 +0000242
Anand Shuklad0f8c882002-02-26 18:59:46 +0000243 //now push all instructions in front of the BB
Chris Lattner5c447862002-09-10 17:03:06 +0000244 BasicBlock::iterator here=front->begin();
245 front->getInstList().insert(here, rVar);
246 front->getInstList().insert(here,countVar);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000247
248 //Initialize Count[...] with 0
Anand Shukla21906892002-06-25 21:14:58 +0000249
Chris Lattner5c447862002-09-10 17:03:06 +0000250 for (int i=0;i<k; i++){
251 Value *GEP2 = new GetElementPtrInst(countVar,
252 vector<Value *>(1,ConstantUInt::get(Type::UIntTy, i)),
253 "", here);
254 new StoreInst(Int0, GEP2, here);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000255 }
Anand Shukla21906892002-06-25 21:14:58 +0000256
Chris Lattner5c447862002-09-10 17:03:06 +0000257 Instruction *GEP = new GetElementPtrInst(rVar, idx, "", here);
258 new StoreInst(Int0, GEP, here);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000259}
260
261
262//insert a basic block with appropriate code
263//along a given edge
264void insertBB(Edge ed,
265 getEdgeCode *edgeCode,
266 Instruction *rInst,
Anand Shukla21906892002-06-25 21:14:58 +0000267 Instruction *countInst,
268 int numPaths, int Methno){
269 static int i=-1;
270 i++;
Anand Shuklad0f8c882002-02-26 18:59:46 +0000271 BasicBlock* BB1=ed.getFirst()->getElement();
272 BasicBlock* BB2=ed.getSecond()->getElement();
273
Anand Shukla21906892002-06-25 21:14:58 +0000274#ifdef DEBUG_PATH_PROFILES
275 //debugging info
276 cerr<<"Edges with codes ######################\n";
277 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
278 cerr<<"########################\n";
279#endif
280
281 char counterstr[100];
282 sprintf(counterstr,"counter%d",i);
283 std::string ctr=counterstr;
Anand Shuklad0f8c882002-02-26 18:59:46 +0000284
285 //We need to insert a BB between BB1 and BB2
286 TerminatorInst *TI=BB1->getTerminator();
Anand Shukla21906892002-06-25 21:14:58 +0000287 BasicBlock *newBB=new BasicBlock(ctr, BB1->getParent());
Anand Shuklad0f8c882002-02-26 18:59:46 +0000288
289 //get code for the new BB
Anand Shukla21906892002-06-25 21:14:58 +0000290 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, numPaths, Methno);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000291
292 //Is terminator a branch instruction?
293 //then we need to change branch destinations to include new BB
294
Anand Shuklaff72c792002-07-08 19:36:39 +0000295 //std::cerr<<"before cast!\n";
Anand Shukla2a786332002-07-21 09:41:18 +0000296 //std::cerr<<"Method no in Edgecode:"<<Methno<<"\n";
297 //std::cerr<<"Instruction\n";
298 //std::cerr<<*TI;
Anand Shuklaff72c792002-07-08 19:36:39 +0000299 BranchInst *BI = cast<BranchInst>(TI);
300
Anand Shuklad0f8c882002-02-26 18:59:46 +0000301 if(BI->isUnconditional()){
302 BI->setUnconditionalDest(newBB);
303 Instruction *newBI2=new BranchInst(BB2);
304 newBB->getInstList().push_back(newBI2);
305 }
306 else{
Anand Shukla21906892002-06-25 21:14:58 +0000307 if(BI->getSuccessor(0)==BB2)
308 BI->setSuccessor(0, newBB);
309
310 if(BI->getSuccessor(1)==BB2)
311 BI->setSuccessor(1, newBB);
312
313 Instruction *newBI2=new BranchInst(BB2);
314 newBB->getInstList().push_back(newBI2);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000315 }
316
Anand Shuklaff72c792002-07-08 19:36:39 +0000317 //std::cerr<<"After casting\n";
Anand Shukla21906892002-06-25 21:14:58 +0000318 //get code for the new BB
319 //now iterate over BB2, and set its Phi nodes right
Chris Lattner7076ff22002-06-25 16:13:21 +0000320 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end();
321 BB2Inst != BBend; ++BB2Inst){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000322
Chris Lattner7076ff22002-06-25 16:13:21 +0000323 if(PHINode *phiInst=dyn_cast<PHINode>(&*BB2Inst)){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000324 int bbIndex=phiInst->getBasicBlockIndex(BB1);
Anand Shukla21906892002-06-25 21:14:58 +0000325 assert(bbIndex>=0);
326 phiInst->setIncomingBlock(bbIndex, newBB);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000327 }
328 }
329}
Anand Shukla21906892002-06-25 21:14:58 +0000330