1 //===-- EdgeCode.cpp - generate LLVM instrumentation code -----------------===//
2 //It implements the class EdgeCode: which provides
3 //support for inserting "appropriate" instrumentation at
4 //designated points in the graph
6 //It also has methods to insert initialization code in
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Transforms/Instrumentation/Graph.h"
11 #include "llvm/Constants.h"
12 #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"
18 #include "llvm/Module.h"
21 #define INSERT_LOAD_COUNT
27 static void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo,
28 Value *cnt, Instruction *InsertPos){
30 vector<const Type*> args;
31 //args.push_back(PointerType::get(Type::SByteTy));
32 args.push_back(Type::IntTy);
33 args.push_back(Type::IntTy);
34 args.push_back(Type::IntTy);
35 const FunctionType *MTy = FunctionType::get(Type::VoidTy, args, false);
37 Function *trigMeth = M->getOrInsertFunction("trigger", MTy);
38 assert(trigMeth && "trigger method could not be inserted!");
40 vector<Value *> trargs;
42 trargs.push_back(ConstantSInt::get(Type::IntTy,MethNo));
43 trargs.push_back(pathNo);
44 trargs.push_back(cnt);
46 Instruction *callInst=new CallInst(trigMeth, trargs, "", InsertPos);
50 //get the code to be inserted on the edge
51 //This is determined from cond (1-6)
52 void getEdgeCode::getCode(Instruction *rInst,
53 Instruction *countInst,
55 BasicBlock *BB, int numPaths, int MethNo){
57 Instruction *InsertPos = BB->getInstList().begin();
59 //case: r=k code to be inserted
62 Value *val=ConstantSInt::get(Type::IntTy,inc);
64 Instruction *stInst=new StoreInst(val, rInst, InsertPos);
69 //case: r=0 to be inserted
72 new StoreInst(ConstantSInt::getNullValue(Type::IntTy), rInst, InsertPos);
78 Instruction *ldInst = new LoadInst(rInst, "ti1", InsertPos);
79 Value *val = ConstantSInt::get(Type::IntTy,inc);
80 Value *addIn = BinaryOperator::create(Instruction::Add, ldInst, val,
83 new StoreInst(addIn, rInst, InsertPos);
90 assert(inc>=0 && inc<=numPaths && "inc out of bound!");
92 Instruction *Idx = new GetElementPtrInst(countInst,
93 vector<Value*>(1,ConstantSInt::get(Type::LongTy, inc)),
96 Instruction *ldInst=new LoadInst(Idx, "ti1", InsertPos);
98 Value *val = ConstantSInt::get(Type::IntTy, 1);
100 BinaryOperator::create(Instruction::Add, ldInst, val,"ti2", InsertPos);
103 Instruction *stInst=new StoreInst(addIn, Idx, InsertPos);
107 getTriggerCode(M->getParent(), BB, MethNo,
108 ConstantSInt::get(Type::IntTy,inc), addIn, InsertPos);
111 assert(inc>=0 && "IT MUST BE POSITIVE NOW");
115 //case: count[r+inc]++
119 Instruction *ldIndex=new LoadInst(rInst, "ti1", InsertPos);
120 Value *val=ConstantSInt::get(Type::IntTy,inc);
121 Instruction *addIndex=BinaryOperator::
122 create(Instruction::Add, ldIndex, val,"ti2", InsertPos);
124 //now load count[addIndex]
125 Instruction *castInst=new CastInst(addIndex,
126 Type::LongTy,"ctin", InsertPos);
127 Instruction *Idx = new GetElementPtrInst(countInst,
128 vector<Value*>(1,castInst), "",
131 Instruction *ldInst=new LoadInst(Idx, "ti3", InsertPos);
132 Value *cons=ConstantSInt::get(Type::IntTy,1);
134 Value *addIn = BinaryOperator::create(Instruction::Add, ldInst,
138 Instruction *stInst = new StoreInst(addIn, Idx, InsertPos);
142 getTriggerCode(M->getParent(), BB, MethNo, addIndex, addIn, InsertPos);
151 Instruction *ldIndex=new LoadInst(rInst, "ti1", InsertPos);
153 //now load count[addIndex]
154 Instruction *castInst2=new CastInst(ldIndex, Type::LongTy,"ctin",InsertPos);
155 Instruction *Idx = new GetElementPtrInst(countInst,
156 vector<Value*>(1,castInst2), "",
159 Instruction *ldInst=new LoadInst(Idx, "ti2", InsertPos);
160 Value *cons=ConstantSInt::get(Type::IntTy,1);
163 Instruction *addIn=BinaryOperator::create(Instruction::Add, ldInst,
164 cons,"ti3", InsertPos);
167 new StoreInst(addIn, Idx, InsertPos);
170 getTriggerCode(M->getParent(), BB, MethNo, ldIndex, addIn, InsertPos);
176 //now check for cdIn and cdOut
179 cdIn->getCode(rInst, countInst, M, BB, numPaths, MethNo);
182 cdOut->getCode(rInst, countInst, M, BB, numPaths, MethNo);
188 //Insert the initialization code in the top BB
189 //this includes initializing r, and count
190 //r is like an accumulator, that
191 //keeps on adding increments as we traverse along a path
192 //and at the end of the path, r contains the path
193 //number of that path
194 //Count is an array, where Count[k] represents
195 //the number of executions of path k
196 void insertInTopBB(BasicBlock *front,
199 Instruction *countVar){
200 //rVar is variable r,
201 //countVar is array Count, and these are allocatted outside
203 Value *Int0 = ConstantInt::get(Type::IntTy, 0);
205 //now push all instructions in front of the BB
206 BasicBlock::iterator here=front->begin();
207 front->getInstList().insert(here, rVar);
208 front->getInstList().insert(here,countVar);
210 //Initialize Count[...] with 0
212 for (int i=0;i<k; i++){
213 Value *GEP2 = new GetElementPtrInst(countVar,
214 vector<Value *>(1,ConstantSInt::get(Type::LongTy, i)),
216 new StoreInst(Int0, GEP2, here);
219 //store uint 0, uint *%R
220 new StoreInst(Int0, rVar, here);
222 if(front->getParent()->getName() == "main"){
224 //if its a main function, do the following!
225 //A global variable: %llvm_threshold
226 //%llvm_threshold = uninitialized global int
227 GlobalVariable *threshold = new GlobalVariable(Type::IntTy, false, true, 0,
230 front->getParent()->getParent()->getGlobalList().push_back(threshold);
232 vector<const Type*> initialize_args;
233 initialize_args.push_back(PointerType::get(Type::IntTy));
235 const FunctionType *Fty = FunctionType::get(Type::VoidTy, initialize_args,
237 Function *initialMeth = front->getParent()->getParent()->getOrInsertFunction("reoptimizerInitialize", Fty);
238 assert(initialMeth && "Initialize method could not be inserted!");
240 vector<Value *> trargs;
241 trargs.push_back(threshold);
243 new CallInst(initialMeth, trargs, "", front->begin());
248 //insert a basic block with appropriate code
250 void insertBB(Edge ed,
251 getEdgeCode *edgeCode,
253 Instruction *countInst,
254 int numPaths, int Methno){
256 BasicBlock* BB1=ed.getFirst()->getElement();
257 BasicBlock* BB2=ed.getSecond()->getElement();
259 #ifdef DEBUG_PATH_PROFILES
261 cerr<<"Edges with codes ######################\n";
262 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n";
263 cerr<<"########################\n";
266 //We need to insert a BB between BB1 and BB2
267 TerminatorInst *TI=BB1->getTerminator();
268 BasicBlock *newBB=new BasicBlock("counter", BB1->getParent());
270 //Is terminator a branch instruction?
271 //then we need to change branch destinations to include new BB
273 BranchInst *BI = cast<BranchInst>(TI);
275 if(BI->isUnconditional()){
276 BI->setUnconditionalDest(newBB);
277 Instruction *newBI2=new BranchInst(BB2);
278 newBB->getInstList().push_back(newBI2);
281 if(BI->getSuccessor(0)==BB2)
282 BI->setSuccessor(0, newBB);
284 if(BI->getSuccessor(1)==BB2)
285 BI->setSuccessor(1, newBB);
287 Instruction *newBI2=new BranchInst(BB2);
288 newBB->getInstList().push_back(newBI2);
291 //get code for the new BB
292 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, numPaths, Methno);
294 //get code for the new BB
295 //now iterate over BB2, and set its Phi nodes right
296 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end();
297 BB2Inst != BBend; ++BB2Inst){
299 if(PHINode *phiInst=dyn_cast<PHINode>(&*BB2Inst)){
300 int bbIndex=phiInst->getBasicBlockIndex(BB1);
302 phiInst->setIncomingBlock(bbIndex, newBB);