blob: 6fa61d63f926099307f115e5d5bc739a0522b20e [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 Shukla77dca142002-09-20 16:44:35 +000019#include "llvm/Instruction.h"
Anand Shukla21906892002-06-25 21:14:58 +000020#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,
Anand Shukla77dca142002-09-20 16:44:35 +000029 Value *cnt){
Anand Shuklaf94ad682002-09-16 05:26:51 +000030
Anand Shukla21906892002-06-25 21:14:58 +000031 vector<const Type*> args;
Anand Shuklaff72c792002-07-08 19:36:39 +000032 //args.push_back(PointerType::get(Type::SByteTy));
Anand Shukla21906892002-06-25 21:14:58 +000033 args.push_back(Type::IntTy);
34 args.push_back(Type::IntTy);
Anand Shukla77dca142002-09-20 16:44:35 +000035 //args.push_back(Type::IntTy);
36 args.push_back(PointerType::get(Type::IntTy));
Chris Lattner5c447862002-09-10 17:03:06 +000037 const FunctionType *MTy = FunctionType::get(Type::VoidTy, args, false);
Anand Shukla21906892002-06-25 21:14:58 +000038
Anand Shukla21906892002-06-25 21:14:58 +000039 Function *trigMeth = M->getOrInsertFunction("trigger", MTy);
40 assert(trigMeth && "trigger method could not be inserted!");
Anand Shuklaf94ad682002-09-16 05:26:51 +000041
Anand Shukla21906892002-06-25 21:14:58 +000042 vector<Value *> trargs;
43
Anand Shukla21906892002-06-25 21:14:58 +000044 trargs.push_back(ConstantSInt::get(Type::IntTy,MethNo));
Anand Shukla21906892002-06-25 21:14:58 +000045 trargs.push_back(pathNo);
46 trargs.push_back(cnt);
Anand Shuklaf94ad682002-09-16 05:26:51 +000047
Anand Shukla77dca142002-09-20 16:44:35 +000048 Instruction *callInst=new CallInst(trigMeth, trargs, "");//, BB->begin());
49 BB->getInstList().push_back(callInst);
50 //triggerInst = new CallInst(trigMeth, trargs, "");//, InsertPos);
Anand Shukla21906892002-06-25 21:14:58 +000051}
52
53
Anand Shuklad0f8c882002-02-26 18:59:46 +000054//get the code to be inserted on the edge
55//This is determined from cond (1-6)
Anand Shukla77dca142002-09-20 16:44:35 +000056void getEdgeCode::getCode(Instruction *rInst, Instruction *countInst,
57 Function *M, BasicBlock *BB,
58 vector<Value *> &retVec){
Anand Shuklad0f8c882002-02-26 18:59:46 +000059
Anand Shukla77dca142002-09-20 16:44:35 +000060 //Instruction *InsertPos = BB->getInstList().begin();
Anand Shuklad0f8c882002-02-26 18:59:46 +000061
Anand Shukla77dca142002-09-20 16:44:35 +000062 //now check for cdIn and cdOut
63 //first put cdOut
64 if(cdOut!=NULL){
65 cdOut->getCode(rInst, countInst, M, BB, retVec);
66 }
67
68 if(cdIn!=NULL){
69 cdIn->getCode(rInst, countInst, M, BB, retVec);
70 }
71
Anand Shuklad0f8c882002-02-26 18:59:46 +000072 //case: r=k code to be inserted
73 switch(cond){
74 case 1:{
75 Value *val=ConstantSInt::get(Type::IntTy,inc);
Anand Shukla21906892002-06-25 21:14:58 +000076#ifdef INSERT_STORE
Anand Shukla77dca142002-09-20 16:44:35 +000077 Instruction *stInst=new StoreInst(val, rInst);//, InsertPos);
78 BB->getInstList().push_back(stInst);
Anand Shukla21906892002-06-25 21:14:58 +000079#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +000080 break;
81 }
82
83 //case: r=0 to be inserted
Anand Shukla77dca142002-09-20 16:44:35 +000084 case 2:{
Anand Shukla21906892002-06-25 21:14:58 +000085#ifdef INSERT_STORE
Anand Shukla77dca142002-09-20 16:44:35 +000086 Instruction *stInst = new StoreInst(ConstantSInt::getNullValue(Type::IntTy), rInst);//, InsertPos);
87 BB->getInstList().push_back(stInst);
Anand Shukla21906892002-06-25 21:14:58 +000088#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +000089 break;
Anand Shukla77dca142002-09-20 16:44:35 +000090 }
Anand Shuklad0f8c882002-02-26 18:59:46 +000091
92 //r+=k
93 case 3:{
Anand Shukla77dca142002-09-20 16:44:35 +000094 Instruction *ldInst = new LoadInst(rInst, "ti1");//, InsertPos);
95 BB->getInstList().push_back(ldInst);
Chris Lattner5c447862002-09-10 17:03:06 +000096 Value *val = ConstantSInt::get(Type::IntTy,inc);
Anand Shukla77dca142002-09-20 16:44:35 +000097 Instruction *addIn = BinaryOperator::create(Instruction::Add, ldInst, val,
98 "ti2");//, InsertPos);
99 BB->getInstList().push_back(addIn);
Anand Shukla21906892002-06-25 21:14:58 +0000100#ifdef INSERT_STORE
Anand Shukla77dca142002-09-20 16:44:35 +0000101 Instruction *stInst = new StoreInst(addIn, rInst);//, InsertPos);
102 BB->getInstList().push_back(stInst);
Anand Shukla21906892002-06-25 21:14:58 +0000103#endif
Anand Shuklad0f8c882002-02-26 18:59:46 +0000104 break;
105 }
106
107 //count[inc]++
108 case 4:{
Chris Lattnere49f2992002-08-21 22:11:33 +0000109 Instruction *Idx = new GetElementPtrInst(countInst,
Chris Lattnerb9d9e0f2002-09-11 01:21:29 +0000110 vector<Value*>(1,ConstantSInt::get(Type::LongTy, inc)),
Anand Shukla77dca142002-09-20 16:44:35 +0000111 "");//, InsertPos);
112 BB->getInstList().push_back(Idx);
Chris Lattnere49f2992002-08-21 22:11:33 +0000113
Anand Shukla77dca142002-09-20 16:44:35 +0000114 Instruction *ldInst=new LoadInst(Idx, "ti1");//, InsertPos);
115 BB->getInstList().push_back(ldInst);
Chris Lattnere49f2992002-08-21 22:11:33 +0000116
117 Value *val = ConstantSInt::get(Type::IntTy, 1);
Anand Shukla77dca142002-09-20 16:44:35 +0000118 //Instruction *addIn =
119 Instruction *newCount =
120 BinaryOperator::create(Instruction::Add, ldInst, val,"ti2");
121 BB->getInstList().push_back(newCount);
122
Chris Lattner5c447862002-09-10 17:03:06 +0000123
124#ifdef INSERT_STORE
Anand Shukla77dca142002-09-20 16:44:35 +0000125 //Instruction *stInst=new StoreInst(addIn, Idx, InsertPos);
126 Instruction *stInst=new StoreInst(newCount, Idx);//, InsertPos);
127 BB->getInstList().push_back(stInst);
Chris Lattner5c447862002-09-10 17:03:06 +0000128#endif
Anand Shukla77dca142002-09-20 16:44:35 +0000129
130 Value *trAddIndex = ConstantSInt::get(Type::IntTy,inc);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000131
Anand Shukla77dca142002-09-20 16:44:35 +0000132 retVec.push_back(newCount);
133 retVec.push_back(trAddIndex);
Anand Shukla21906892002-06-25 21:14:58 +0000134 //insert trigger
Anand Shukla77dca142002-09-20 16:44:35 +0000135 //getTriggerCode(M->getParent(), BB, MethNo,
136 // ConstantSInt::get(Type::IntTy,inc), newCount, triggerInst);
Anand Shukla21906892002-06-25 21:14:58 +0000137 //end trigger code
138
Anand Shuklad0f8c882002-02-26 18:59:46 +0000139 assert(inc>=0 && "IT MUST BE POSITIVE NOW");
Anand Shuklad0f8c882002-02-26 18:59:46 +0000140 break;
141 }
142
143 //case: count[r+inc]++
144 case 5:{
Chris Lattner5c447862002-09-10 17:03:06 +0000145
Anand Shuklad0f8c882002-02-26 18:59:46 +0000146 //ti1=inc+r
Anand Shukla77dca142002-09-20 16:44:35 +0000147 Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos);
148 BB->getInstList().push_back(ldIndex);
149
Anand Shuklad0f8c882002-02-26 18:59:46 +0000150 Value *val=ConstantSInt::get(Type::IntTy,inc);
151 Instruction *addIndex=BinaryOperator::
Anand Shukla77dca142002-09-20 16:44:35 +0000152 create(Instruction::Add, ldIndex, val,"ti2");//, InsertPos);
153 BB->getInstList().push_back(addIndex);
Anand Shukla21906892002-06-25 21:14:58 +0000154
Anand Shuklaf94ad682002-09-16 05:26:51 +0000155 //now load count[addIndex]
Anand Shuklad0f8c882002-02-26 18:59:46 +0000156 Instruction *castInst=new CastInst(addIndex,
Anand Shukla77dca142002-09-20 16:44:35 +0000157 Type::LongTy,"ctin");//, InsertPos);
158 BB->getInstList().push_back(castInst);
Chris Lattnere49f2992002-08-21 22:11:33 +0000159
Anand Shukla77dca142002-09-20 16:44:35 +0000160 Instruction *Idx = new GetElementPtrInst(countInst,
161 vector<Value*>(1,castInst), "");//,
162 // InsertPos);
163 BB->getInstList().push_back(Idx);
164
165 Instruction *ldInst=new LoadInst(Idx, "ti3");//, InsertPos);
166 BB->getInstList().push_back(ldInst);
167
Anand Shuklad0f8c882002-02-26 18:59:46 +0000168 Value *cons=ConstantSInt::get(Type::IntTy,1);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000169 //count[addIndex]++
Anand Shukla77dca142002-09-20 16:44:35 +0000170 Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst,
171 cons,"");
172 BB->getInstList().push_back(newCount);
Anand Shukla21906892002-06-25 21:14:58 +0000173
174#ifdef INSERT_STORE
Anand Shukla77dca142002-09-20 16:44:35 +0000175 Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos);
176 BB->getInstList().push_back(stInst);
Anand Shukla21906892002-06-25 21:14:58 +0000177#endif
Chris Lattner5c447862002-09-10 17:03:06 +0000178
Anand Shukla77dca142002-09-20 16:44:35 +0000179 retVec.push_back(newCount);
180 retVec.push_back(addIndex);
Chris Lattner5c447862002-09-10 17:03:06 +0000181 //insert trigger
Anand Shukla77dca142002-09-20 16:44:35 +0000182 //getTriggerCode(M->getParent(), BB, MethNo, addIndex, newCount, triggerInst);
Chris Lattner5c447862002-09-10 17:03:06 +0000183 //end trigger code
184
Anand Shuklad0f8c882002-02-26 18:59:46 +0000185 break;
186 }
187
188 //case: count[r]+
189 case 6:{
190 //ti1=inc+r
Anand Shukla77dca142002-09-20 16:44:35 +0000191 Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos);
192 BB->getInstList().push_back(ldIndex);
193
Anand Shuklad0f8c882002-02-26 18:59:46 +0000194 //now load count[addIndex]
Anand Shukla77dca142002-09-20 16:44:35 +0000195 Instruction *castInst2=new CastInst(ldIndex, Type::LongTy,"ctin");
196 BB->getInstList().push_back(castInst2);
197
Chris Lattnere49f2992002-08-21 22:11:33 +0000198 Instruction *Idx = new GetElementPtrInst(countInst,
Anand Shukla77dca142002-09-20 16:44:35 +0000199 vector<Value*>(1,castInst2), "");
200 BB->getInstList().push_back(Idx);
Chris Lattnere49f2992002-08-21 22:11:33 +0000201
Anand Shukla77dca142002-09-20 16:44:35 +0000202 Instruction *ldInst=new LoadInst(Idx, "ti2");//, InsertPos);
203 BB->getInstList().push_back(ldInst);
204
Anand Shuklad0f8c882002-02-26 18:59:46 +0000205 Value *cons=ConstantSInt::get(Type::IntTy,1);
206
207 //count[addIndex]++
Anand Shukla77dca142002-09-20 16:44:35 +0000208 Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst,
209 cons,"ti3");
210 BB->getInstList().push_back(newCount);
Anand Shukla21906892002-06-25 21:14:58 +0000211
Chris Lattner5c447862002-09-10 17:03:06 +0000212#ifdef INSERT_STORE
Anand Shukla77dca142002-09-20 16:44:35 +0000213 Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos);
214 BB->getInstList().push_back(stInst);
Chris Lattner5c447862002-09-10 17:03:06 +0000215#endif
Anand Shukla77dca142002-09-20 16:44:35 +0000216
217 retVec.push_back(newCount);
218 retVec.push_back(ldIndex);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000219 break;
220 }
221
222 }
Anand Shuklad0f8c882002-02-26 18:59:46 +0000223}
224
225
226
227//Insert the initialization code in the top BB
228//this includes initializing r, and count
229//r is like an accumulator, that
230//keeps on adding increments as we traverse along a path
231//and at the end of the path, r contains the path
232//number of that path
233//Count is an array, where Count[k] represents
234//the number of executions of path k
235void insertInTopBB(BasicBlock *front,
236 int k,
237 Instruction *rVar,
Anand Shukla77dca142002-09-20 16:44:35 +0000238 Instruction *countVar, Value *threshold){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000239 //rVar is variable r,
240 //countVar is array Count, and these are allocatted outside
Chris Lattnere49f2992002-08-21 22:11:33 +0000241
242 Value *Int0 = ConstantInt::get(Type::IntTy, 0);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000243
Anand Shuklad0f8c882002-02-26 18:59:46 +0000244 //now push all instructions in front of the BB
Chris Lattner5c447862002-09-10 17:03:06 +0000245 BasicBlock::iterator here=front->begin();
246 front->getInstList().insert(here, rVar);
247 front->getInstList().insert(here,countVar);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000248
249 //Initialize Count[...] with 0
Anand Shukla21906892002-06-25 21:14:58 +0000250
Anand Shukla77dca142002-09-20 16:44:35 +0000251 //for (int i=0;i<k; i++){
252 //Value *GEP2 = new GetElementPtrInst(countVar,
253 // vector<Value *>(1,ConstantSInt::get(Type::LongTy, i)),
254 // "", here);
255 //new StoreInst(Int0, GEP2, here);
256 //}
Anand Shukla21906892002-06-25 21:14:58 +0000257
Chris Lattnerb9d9e0f2002-09-11 01:21:29 +0000258 //store uint 0, uint *%R
259 new StoreInst(Int0, rVar, here);
Anand Shuklaf94ad682002-09-16 05:26:51 +0000260
Anand Shukla77dca142002-09-20 16:44:35 +0000261 //insert initialize function for initializing
262 vector<const Type*> inCountArgs;
263 inCountArgs.push_back(PointerType::get(Type::IntTy));
264 inCountArgs.push_back(Type::IntTy);
265
266 const FunctionType *cFty = FunctionType::get(Type::VoidTy, inCountArgs,
267 false);
268 Function *inCountMth = front->getParent()->getParent()->getOrInsertFunction("llvmInitializeCounter", cFty);
269 assert(inCountMth && "Initialize method could not be inserted!");
270
271 vector<Value *> iniArgs;
272 iniArgs.push_back(countVar);
273 iniArgs.push_back(ConstantSInt::get(Type::IntTy, k));
274 new CallInst(inCountMth, iniArgs, "", here);
275
276
Anand Shuklaf94ad682002-09-16 05:26:51 +0000277 if(front->getParent()->getName() == "main"){
Anand Shukla77dca142002-09-20 16:44:35 +0000278 //intialize threshold
Anand Shuklaf94ad682002-09-16 05:26:51 +0000279 vector<const Type*> initialize_args;
280 initialize_args.push_back(PointerType::get(Type::IntTy));
281
282 const FunctionType *Fty = FunctionType::get(Type::VoidTy, initialize_args,
283 false);
284 Function *initialMeth = front->getParent()->getParent()->getOrInsertFunction("reoptimizerInitialize", Fty);
285 assert(initialMeth && "Initialize method could not be inserted!");
286
287 vector<Value *> trargs;
288 trargs.push_back(threshold);
289
Anand Shukla77dca142002-09-20 16:44:35 +0000290 new CallInst(initialMeth, trargs, "", here);
Anand Shuklaf94ad682002-09-16 05:26:51 +0000291 }
Anand Shuklad0f8c882002-02-26 18:59:46 +0000292}
293
294
295//insert a basic block with appropriate code
296//along a given edge
297void insertBB(Edge ed,
298 getEdgeCode *edgeCode,
299 Instruction *rInst,
Anand Shukla21906892002-06-25 21:14:58 +0000300 Instruction *countInst,
Anand Shukla77dca142002-09-20 16:44:35 +0000301 int numPaths, int Methno, Value *threshold){
Anand Shuklaf94ad682002-09-16 05:26:51 +0000302
Anand Shuklad0f8c882002-02-26 18:59:46 +0000303 BasicBlock* BB1=ed.getFirst()->getElement();
304 BasicBlock* BB2=ed.getSecond()->getElement();
305
Anand Shukla21906892002-06-25 21:14:58 +0000306#ifdef DEBUG_PATH_PROFILES
307 //debugging info
308 cerr<<"Edges with codes ######################\n";
309 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
310 cerr<<"########################\n";
311#endif
312
Anand Shuklad0f8c882002-02-26 18:59:46 +0000313 //We need to insert a BB between BB1 and BB2
314 TerminatorInst *TI=BB1->getTerminator();
Anand Shuklaf94ad682002-09-16 05:26:51 +0000315 BasicBlock *newBB=new BasicBlock("counter", BB1->getParent());
Anand Shuklad0f8c882002-02-26 18:59:46 +0000316
Anand Shukla77dca142002-09-20 16:44:35 +0000317 //get code for the new BB
318 vector<Value *> retVec;
319
320 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, retVec);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000321
Anand Shuklaff72c792002-07-08 19:36:39 +0000322 BranchInst *BI = cast<BranchInst>(TI);
323
Anand Shukla77dca142002-09-20 16:44:35 +0000324 //Is terminator a branch instruction?
325 //then we need to change branch destinations to include new BB
326
Anand Shuklad0f8c882002-02-26 18:59:46 +0000327 if(BI->isUnconditional()){
328 BI->setUnconditionalDest(newBB);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000329 }
330 else{
Anand Shukla21906892002-06-25 21:14:58 +0000331 if(BI->getSuccessor(0)==BB2)
332 BI->setSuccessor(0, newBB);
333
334 if(BI->getSuccessor(1)==BB2)
335 BI->setSuccessor(1, newBB);
Anand Shukla77dca142002-09-20 16:44:35 +0000336 }
Anand Shukla21906892002-06-25 21:14:58 +0000337
Anand Shukla77dca142002-09-20 16:44:35 +0000338 BasicBlock *triggerBB = NULL;
339 if(retVec.size()>0){
340 triggerBB = new BasicBlock("trigger", BB1->getParent());
341 getTriggerCode(BB1->getParent()->getParent(), triggerBB, Methno,
342 retVec[1], countInst);//retVec[0]);
343
344 //Instruction *castInst = new CastInst(retVec[0], Type::IntTy, "");
345 Instruction *etr = new LoadInst(threshold, "threshold");
346
347 //std::cerr<<"type1: "<<etr->getType()<<" type2: "<<retVec[0]->getType()<<"\n";
348 Instruction *cmpInst = new SetCondInst(Instruction::SetLE, etr,
349 retVec[0], "");
350 Instruction *newBI2 = new BranchInst(triggerBB, BB2, cmpInst);
351 //newBB->getInstList().push_back(castInst);
352 newBB->getInstList().push_back(etr);
353 newBB->getInstList().push_back(cmpInst);
354 newBB->getInstList().push_back(newBI2);
355
356 //triggerBB->getInstList().push_back(triggerInst);
357 Instruction *triggerBranch = new BranchInst(BB2);
358 triggerBB->getInstList().push_back(triggerBranch);
359 }
360 else{
Anand Shukla21906892002-06-25 21:14:58 +0000361 Instruction *newBI2=new BranchInst(BB2);
362 newBB->getInstList().push_back(newBI2);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000363 }
Chris Lattner154cf642002-09-14 19:33:16 +0000364
Anand Shuklaf94ad682002-09-16 05:26:51 +0000365 //now iterate over BB2, and set its Phi nodes right
Chris Lattner7076ff22002-06-25 16:13:21 +0000366 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end();
367 BB2Inst != BBend; ++BB2Inst){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000368
Chris Lattner7076ff22002-06-25 16:13:21 +0000369 if(PHINode *phiInst=dyn_cast<PHINode>(&*BB2Inst)){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000370 int bbIndex=phiInst->getBasicBlockIndex(BB1);
Anand Shukla21906892002-06-25 21:14:58 +0000371 assert(bbIndex>=0);
372 phiInst->setIncomingBlock(bbIndex, newBB);
Anand Shukla77dca142002-09-20 16:44:35 +0000373
374 ///check if trigger!=null, then add value corresponding to it too!
375 if(retVec.size()>0){
376 assert(triggerBB && "BasicBlock with trigger should not be null!");
377 Value *vl = phiInst->getIncomingValue((unsigned int)bbIndex);
378 phiInst->addIncoming(vl, triggerBB);
379 }
Anand Shuklad0f8c882002-02-26 18:59:46 +0000380 }
381 }
382}
Anand Shukla21906892002-06-25 21:14:58 +0000383