Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 1 | //===-- 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 Lattner | d92b01c | 2002-04-09 18:37:46 +0000 | [diff] [blame] | 11 | #include "llvm/BasicBlock.h" |
Chris Lattner | ca14237 | 2002-04-28 19:55:58 +0000 | [diff] [blame] | 12 | #include "llvm/Constants.h" |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 13 | #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 Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 20 | using std::vector; |
| 21 | |
| 22 | //get the code to be inserted on the edge |
| 23 | //This is determined from cond (1-6) |
| 24 | void getEdgeCode::getCode(Instruction *rInst, |
| 25 | Instruction *countInst, |
Chris Lattner | f8e4dc3 | 2002-04-08 22:03:00 +0000 | [diff] [blame] | 26 | Function *M, |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 27 | 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 37 | here=++instList.insert(here,stInst); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 38 | 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 45 | here=++instList.insert(here,stInst); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 46 | 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 57 | here=++instList.insert(here,ldInst); |
| 58 | here=++instList.insert(here,addIn); |
| 59 | here=++instList.insert(here,stInst); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 60 | 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 77 | here=++instList.insert(here,ldInst); |
| 78 | here=++instList.insert(here,addIn); |
| 79 | here=++instList.insert(here,stInst); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 80 | 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 105 | 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 Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 111 | 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 132 | 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 Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 137 | 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 |
| 162 | void 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 178 | here=++front->getInstList().insert(here, rVar); |
| 179 | here=++front->getInstList().insert(here,countVar); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 180 | |
| 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 187 | here=++front->getInstList().insert(here,stInstrC); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 188 | } |
| 189 | |
Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 190 | here=++front->getInstList().insert(here,stInstr); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | |
| 194 | //insert a basic block with appropriate code |
| 195 | //along a given edge |
| 196 | void 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 Lattner | e1fc2d9 | 2002-05-22 21:56:32 +0000 | [diff] [blame] | 204 | DEBUG(cerr << "Edges with codes ######################\n"; |
| 205 | cerr << BB1->getName() << "->" << BB2->getName() << "\n"; |
| 206 | cerr << "########################\n"); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 207 | |
| 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 Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 229 | if (BI->getSuccessor(0) == BB2){ |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 230 | tB=newBB; |
| 231 | fB=BI->getSuccessor(1); |
Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 232 | } else { |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 233 | fB=newBB; |
| 234 | tB=BI->getSuccessor(0); |
| 235 | } |
| 236 | |
Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 237 | BB1->getInstList().pop_back(); |
| 238 | BB1->getInstList().push_back(new BranchInst(tB,fB,cond)); |
| 239 | newBB->getInstList().push_back(new BranchInst(BB2)); |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 240 | } |
| 241 | |
| 242 | //now iterate over BB2, and set its Phi nodes right |
Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 243 | for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end(); |
| 244 | BB2Inst != BBend; ++BB2Inst){ |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 245 | |
Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 246 | if(PHINode *phiInst=dyn_cast<PHINode>(&*BB2Inst)){ |
Chris Lattner | e1fc2d9 | 2002-05-22 21:56:32 +0000 | [diff] [blame] | 247 | DEBUG(cerr<<"YYYYYYYYYYYYYYYYY\n"); |
| 248 | |
Anand Shukla | d0f8c88 | 2002-02-26 18:59:46 +0000 | [diff] [blame] | 249 | int bbIndex=phiInst->getBasicBlockIndex(BB1); |
| 250 | if(bbIndex>=0) |
| 251 | phiInst->setIncomingBlock(bbIndex, newBB); |
| 252 | } |
| 253 | } |
| 254 | } |