blob: 1c0970537a7e9a4a3d21be53a6e2bb3ff20d567c [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
10#include "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"
19
Anand Shuklad0f8c882002-02-26 18:59:46 +000020using std::vector;
21
22//get the code to be inserted on the edge
23//This is determined from cond (1-6)
24void getEdgeCode::getCode(Instruction *rInst,
25 Instruction *countInst,
Chris Lattnerf8e4dc32002-04-08 22:03:00 +000026 Function *M,
Anand Shuklad0f8c882002-02-26 18:59:46 +000027 BasicBlock *BB){
28
29 BasicBlock::InstListType& instList=BB->getInstList();
30 BasicBlock::iterator here=instList.begin();
31
32 //case: r=k code to be inserted
33 switch(cond){
34 case 1:{
35 Value *val=ConstantSInt::get(Type::IntTy,inc);
36 Instruction *stInst=new StoreInst(val, rInst);
Chris Lattner7076ff22002-06-25 16:13:21 +000037 here=++instList.insert(here,stInst);
Anand Shuklad0f8c882002-02-26 18:59:46 +000038 break;
39 }
40
41 //case: r=0 to be inserted
42 case 2:{
43 Value *val=ConstantSInt::get(Type::IntTy,0);
44 Instruction *stInst=new StoreInst(val, rInst);
Chris Lattner7076ff22002-06-25 16:13:21 +000045 here=++instList.insert(here,stInst);
Anand Shuklad0f8c882002-02-26 18:59:46 +000046 break;
47 }
48
49 //r+=k
50 case 3:{
51 Instruction *ldInst=new LoadInst(rInst, "ti1");
52 Value *val=ConstantSInt::get(Type::IntTy,inc);
53 Instruction *addIn=BinaryOperator::
54 create(Instruction::Add, ldInst, val,"ti2");
55
56 Instruction *stInst=new StoreInst(addIn, rInst);
Chris Lattner7076ff22002-06-25 16:13:21 +000057 here=++instList.insert(here,ldInst);
58 here=++instList.insert(here,addIn);
59 here=++instList.insert(here,stInst);
Anand Shuklad0f8c882002-02-26 18:59:46 +000060 break;
61 }
62
63 //count[inc]++
64 case 4:{
65 Instruction *ldInst=new
66 LoadInst(countInst,vector<Value *>
67 (1,ConstantUInt::get(Type::UIntTy, inc)), "ti1");
68 Value *val=ConstantSInt::get(Type::IntTy,1);
69 Instruction *addIn=BinaryOperator::
70 create(Instruction::Add, ldInst, val,"ti2");
71
72 assert(inc>=0 && "IT MUST BE POSITIVE NOW");
73 Instruction *stInst=new
74 StoreInst(addIn, countInst, vector<Value *>
75 (1, ConstantUInt::get(Type::UIntTy,inc)));
76
Chris Lattner7076ff22002-06-25 16:13:21 +000077 here=++instList.insert(here,ldInst);
78 here=++instList.insert(here,addIn);
79 here=++instList.insert(here,stInst);
Anand Shuklad0f8c882002-02-26 18:59:46 +000080 break;
81 }
82
83 //case: count[r+inc]++
84 case 5:{
85 //ti1=inc+r
86 Instruction *ldIndex=new LoadInst(rInst, "ti1");
87 Value *val=ConstantSInt::get(Type::IntTy,inc);
88 Instruction *addIndex=BinaryOperator::
89 create(Instruction::Add, ldIndex, val,"ti2");
90
91 //now load count[addIndex]
92 Instruction *castInst=new CastInst(addIndex,
93 Type::UIntTy,"ctin");
94 Instruction *ldInst=new
95 LoadInst(countInst, vector<Value *>(1,castInst), "ti3");
96 Value *cons=ConstantSInt::get(Type::IntTy,1);
97
98 //count[addIndex]++
99 Instruction *addIn=BinaryOperator::
100 create(Instruction::Add, ldInst, cons,"ti4");
101 Instruction *stInst=new
102 StoreInst(addIn, countInst,
103 vector<Value *>(1,castInst));
104
Chris Lattner7076ff22002-06-25 16:13:21 +0000105 here=++instList.insert(here,ldIndex);
106 here=++instList.insert(here,addIndex);
107 here=++instList.insert(here,castInst);
108 here=++instList.insert(here,ldInst);
109 here=++instList.insert(here,addIn);
110 here=++instList.insert(here,stInst);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000111 break;
112 }
113
114 //case: count[r]+
115 case 6:{
116 //ti1=inc+r
117 Instruction *ldIndex=new LoadInst(rInst, "ti1");
118
119 //now load count[addIndex]
120 Instruction *castInst2=new
121 CastInst(ldIndex, Type::UIntTy,"ctin");
122 Instruction *ldInst=new
123 LoadInst(countInst, vector<Value *>(1,castInst2), "ti2");
124 Value *cons=ConstantSInt::get(Type::IntTy,1);
125
126 //count[addIndex]++
127 Instruction *addIn=BinaryOperator::
128 create(Instruction::Add, ldInst, cons,"ti3");
129 Instruction *stInst=new
130 StoreInst(addIn, countInst, vector<Value *>(1,castInst2));
131
Chris Lattner7076ff22002-06-25 16:13:21 +0000132 here=++instList.insert(here,ldIndex);
133 here=++instList.insert(here,castInst2);
134 here=++instList.insert(here,ldInst);
135 here=++instList.insert(here,addIn);
136 here=++instList.insert(here,stInst);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000137 break;
138 }
139
140 }
141 //now check for cdIn and cdOut
142 //first put cdOut
143 if(cdOut!=NULL){
144 cdOut->getCode(rInst, countInst, M, BB);
145 }
146 if(cdIn!=NULL){
147 cdIn->getCode(rInst, countInst, M, BB);
148 }
149
150}
151
152
153
154//Insert the initialization code in the top BB
155//this includes initializing r, and count
156//r is like an accumulator, that
157//keeps on adding increments as we traverse along a path
158//and at the end of the path, r contains the path
159//number of that path
160//Count is an array, where Count[k] represents
161//the number of executions of path k
162void insertInTopBB(BasicBlock *front,
163 int k,
164 Instruction *rVar,
165 Instruction *countVar){
166 //rVar is variable r,
167 //countVar is array Count, and these are allocatted outside
168
169 //store uint 0, uint *%R, uint 0
170 vector<Value *> idx;
171 idx.push_back(ConstantUInt::get(Type::UIntTy, 0));
172 Instruction *stInstr=new StoreInst(ConstantInt::get(Type::IntTy, 0), rVar,
173 idx);
174
175 //now push all instructions in front of the BB
176 BasicBlock::InstListType& instList=front->getInstList();
177 BasicBlock::iterator here=instList.begin();
Chris Lattner7076ff22002-06-25 16:13:21 +0000178 here=++front->getInstList().insert(here, rVar);
179 here=++front->getInstList().insert(here,countVar);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000180
181 //Initialize Count[...] with 0
182 for(int i=0;i<k; i++){
183 Instruction *stInstrC=new
184 StoreInst(ConstantInt::get(Type::IntTy, 0),
185 countVar, std::vector<Value *>
186 (1,ConstantUInt::get(Type::UIntTy, i)));
Chris Lattner7076ff22002-06-25 16:13:21 +0000187 here=++front->getInstList().insert(here,stInstrC);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000188 }
189
Chris Lattner7076ff22002-06-25 16:13:21 +0000190 here=++front->getInstList().insert(here,stInstr);
Anand Shuklad0f8c882002-02-26 18:59:46 +0000191}
192
193
194//insert a basic block with appropriate code
195//along a given edge
196void insertBB(Edge ed,
197 getEdgeCode *edgeCode,
198 Instruction *rInst,
199 Instruction *countInst){
200
201 BasicBlock* BB1=ed.getFirst()->getElement();
202 BasicBlock* BB2=ed.getSecond()->getElement();
203
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000204 DEBUG(cerr << "Edges with codes ######################\n";
205 cerr << BB1->getName() << "->" << BB2->getName() << "\n";
206 cerr << "########################\n");
Anand Shuklad0f8c882002-02-26 18:59:46 +0000207
208 //We need to insert a BB between BB1 and BB2
209 TerminatorInst *TI=BB1->getTerminator();
210 BasicBlock *newBB=new BasicBlock("counter", BB1->getParent());
211
212 //get code for the new BB
213 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB);
214
215 //Is terminator a branch instruction?
216 //then we need to change branch destinations to include new BB
217
218 BranchInst *BI=cast<BranchInst>(TI);
219
220 if(BI->isUnconditional()){
221 BI->setUnconditionalDest(newBB);
222 Instruction *newBI2=new BranchInst(BB2);
223 newBB->getInstList().push_back(newBI2);
224 }
225 else{
226 Value *cond=BI->getCondition();
227 BasicBlock *fB, *tB;
228
Chris Lattner7076ff22002-06-25 16:13:21 +0000229 if (BI->getSuccessor(0) == BB2){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000230 tB=newBB;
231 fB=BI->getSuccessor(1);
Chris Lattner7076ff22002-06-25 16:13:21 +0000232 } else {
Anand Shuklad0f8c882002-02-26 18:59:46 +0000233 fB=newBB;
234 tB=BI->getSuccessor(0);
235 }
236
Chris Lattner7076ff22002-06-25 16:13:21 +0000237 BB1->getInstList().pop_back();
238 BB1->getInstList().push_back(new BranchInst(tB,fB,cond));
239 newBB->getInstList().push_back(new BranchInst(BB2));
Anand Shuklad0f8c882002-02-26 18:59:46 +0000240 }
241
242 //now iterate over BB2, and set its Phi nodes right
Chris Lattner7076ff22002-06-25 16:13:21 +0000243 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end();
244 BB2Inst != BBend; ++BB2Inst){
Anand Shuklad0f8c882002-02-26 18:59:46 +0000245
Chris Lattner7076ff22002-06-25 16:13:21 +0000246 if(PHINode *phiInst=dyn_cast<PHINode>(&*BB2Inst)){
Chris Lattnere1fc2d92002-05-22 21:56:32 +0000247 DEBUG(cerr<<"YYYYYYYYYYYYYYYYY\n");
248
Anand Shuklad0f8c882002-02-26 18:59:46 +0000249 int bbIndex=phiInst->getBasicBlockIndex(BB1);
250 if(bbIndex>=0)
251 phiInst->setIncomingBlock(bbIndex, newBB);
252 }
253 }
254}