blob: 8668be1590599412914135c1a42c437dcbf78248 [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
Chris Lattnerb9d9e0f2002-09-11 01:21:29 +000058 //vector<Value *> elargs;
59 //elargs.push_back(ConstantSInt::get(Type::LongTy, 0));
60 //elargs.push_back(ConstantSInt::get(Type::LongTy, 0));
Anand Shukla21906892002-06-25 21:14:58 +000061
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 Lattnerb9d9e0f2002-09-11 01:21:29 +0000122 vector<Value*>(1,ConstantSInt::get(Type::LongTy, inc)),
Chris Lattner5c447862002-09-10 17:03:06 +0000123 "", 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 Lattnerb9d9e0f2002-09-11 01:21:29 +0000157 Type::LongTy,"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 Lattnerb9d9e0f2002-09-11 01:21:29 +0000187 Instruction *castInst2=new CastInst(ldIndex, Type::LongTy,"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
Anand Shuklad0f8c882002-02-26 18:59:46 +0000239 //now push all instructions in front of the BB
Chris Lattner5c447862002-09-10 17:03:06 +0000240 BasicBlock::iterator here=front->begin();
241 front->getInstList().insert(here, rVar);
242 front->getInstList().insert(here,countVar);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000243
244 //Initialize Count[...] with 0
Anand Shukla21906892002-06-25 21:14:58 +0000245
Chris Lattner5c447862002-09-10 17:03:06 +0000246 for (int i=0;i<k; i++){
247 Value *GEP2 = new GetElementPtrInst(countVar,
Chris Lattnerb9d9e0f2002-09-11 01:21:29 +0000248 vector<Value *>(1,ConstantSInt::get(Type::LongTy, i)),
Chris Lattner5c447862002-09-10 17:03:06 +0000249 "", here);
250 new StoreInst(Int0, GEP2, here);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000251 }
Anand Shukla21906892002-06-25 21:14:58 +0000252
Chris Lattnerb9d9e0f2002-09-11 01:21:29 +0000253 //store uint 0, uint *%R
254 new StoreInst(Int0, rVar, here);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000255}
256
257
258//insert a basic block with appropriate code
259//along a given edge
260void insertBB(Edge ed,
261 getEdgeCode *edgeCode,
262 Instruction *rInst,
Anand Shukla21906892002-06-25 21:14:58 +0000263 Instruction *countInst,
264 int numPaths, int Methno){
265 static int i=-1;
266 i++;
Anand Shuklad0f8c882002-02-26 18:59:46 +0000267 BasicBlock* BB1=ed.getFirst()->getElement();
268 BasicBlock* BB2=ed.getSecond()->getElement();
269
Anand Shukla21906892002-06-25 21:14:58 +0000270#ifdef DEBUG_PATH_PROFILES
271 //debugging info
272 cerr<<"Edges with codes ######################\n";
273 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
274 cerr<<"########################\n";
275#endif
276
277 char counterstr[100];
278 sprintf(counterstr,"counter%d",i);
279 std::string ctr=counterstr;
Anand Shuklad0f8c882002-02-26 18:59:46 +0000280
281 //We need to insert a BB between BB1 and BB2
282 TerminatorInst *TI=BB1->getTerminator();
Anand Shukla21906892002-06-25 21:14:58 +0000283 BasicBlock *newBB=new BasicBlock(ctr, BB1->getParent());
Anand Shuklad0f8c882002-02-26 18:59:46 +0000284
Anand Shuklad0f8c882002-02-26 18:59:46 +0000285 //Is terminator a branch instruction?
286 //then we need to change branch destinations to include new BB
287
Anand Shuklaff72c792002-07-08 19:36:39 +0000288 //std::cerr<<"before cast!\n";
Anand Shukla2a786332002-07-21 09:41:18 +0000289 //std::cerr<<"Method no in Edgecode:"<<Methno<<"\n";
290 //std::cerr<<"Instruction\n";
291 //std::cerr<<*TI;
Anand Shuklaff72c792002-07-08 19:36:39 +0000292 BranchInst *BI = cast<BranchInst>(TI);
293
Anand Shuklad0f8c882002-02-26 18:59:46 +0000294 if(BI->isUnconditional()){
295 BI->setUnconditionalDest(newBB);
296 Instruction *newBI2=new BranchInst(BB2);
297 newBB->getInstList().push_back(newBI2);
298 }
299 else{
Anand Shukla21906892002-06-25 21:14:58 +0000300 if(BI->getSuccessor(0)==BB2)
301 BI->setSuccessor(0, newBB);
302
303 if(BI->getSuccessor(1)==BB2)
304 BI->setSuccessor(1, newBB);
305
306 Instruction *newBI2=new BranchInst(BB2);
307 newBB->getInstList().push_back(newBI2);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000308 }
Chris Lattner154cf642002-09-14 19:33:16 +0000309
310 //get code for the new BB
311 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, numPaths, Methno);
312
Anand Shuklad0f8c882002-02-26 18:59:46 +0000313
Anand Shuklaff72c792002-07-08 19:36:39 +0000314 //std::cerr<<"After casting\n";
Anand Shukla21906892002-06-25 21:14:58 +0000315 //get code for the new BB
316 //now iterate over BB2, and set its Phi nodes right
Chris Lattner7076ff22002-06-25 16:13:21 +0000317 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end();
318 BB2Inst != BBend; ++BB2Inst){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000319
Chris Lattner7076ff22002-06-25 16:13:21 +0000320 if(PHINode *phiInst=dyn_cast<PHINode>(&*BB2Inst)){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000321 int bbIndex=phiInst->getBasicBlockIndex(BB1);
Anand Shukla21906892002-06-25 21:14:58 +0000322 assert(bbIndex>=0);
323 phiInst->setIncomingBlock(bbIndex, newBB);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000324 }
325 }
326}
Anand Shukla21906892002-06-25 21:14:58 +0000327