LLVM API Documentation
00001 //===-- EdgeCode.cpp - generate LLVM instrumentation code -----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 //It implements the class EdgeCode: which provides 00010 //support for inserting "appropriate" instrumentation at 00011 //designated points in the graph 00012 // 00013 //It also has methods to insert initialization code in 00014 //top block of cfg 00015 //===----------------------------------------------------------------------===// 00016 00017 #include "Graph.h" 00018 #include "llvm/Constants.h" 00019 #include "llvm/DerivedTypes.h" 00020 #include "llvm/Instructions.h" 00021 #include "llvm/Module.h" 00022 00023 #define INSERT_LOAD_COUNT 00024 #define INSERT_STORE 00025 00026 00027 using std::vector; 00028 00029 namespace llvm { 00030 00031 static void getTriggerCode(Module *M, BasicBlock *BB, int MethNo, Value *pathNo, 00032 Value *cnt, Instruction *rInst){ 00033 00034 vector<Value *> tmpVec; 00035 tmpVec.push_back(Constant::getNullValue(Type::LongTy)); 00036 tmpVec.push_back(Constant::getNullValue(Type::LongTy)); 00037 Instruction *Idx = new GetElementPtrInst(cnt, tmpVec, "");//, 00038 BB->getInstList().push_back(Idx); 00039 00040 const Type *PIntTy = PointerType::get(Type::IntTy); 00041 Function *trigMeth = M->getOrInsertFunction("trigger", Type::VoidTy, 00042 Type::IntTy, Type::IntTy, 00043 PIntTy, PIntTy, 0); 00044 assert(trigMeth && "trigger method could not be inserted!"); 00045 00046 vector<Value *> trargs; 00047 00048 trargs.push_back(ConstantSInt::get(Type::IntTy,MethNo)); 00049 trargs.push_back(pathNo); 00050 trargs.push_back(Idx); 00051 trargs.push_back(rInst); 00052 00053 Instruction *callInst=new CallInst(trigMeth, trargs, "");//, BB->begin()); 00054 BB->getInstList().push_back(callInst); 00055 //triggerInst = new CallInst(trigMeth, trargs, "");//, InsertPos); 00056 } 00057 00058 00059 //get the code to be inserted on the edge 00060 //This is determined from cond (1-6) 00061 void getEdgeCode::getCode(Instruction *rInst, Value *countInst, 00062 Function *M, BasicBlock *BB, 00063 vector<Value *> &retVec){ 00064 00065 //Instruction *InsertPos = BB->getInstList().begin(); 00066 00067 //now check for cdIn and cdOut 00068 //first put cdOut 00069 if(cdOut!=NULL){ 00070 cdOut->getCode(rInst, countInst, M, BB, retVec); 00071 } 00072 00073 if(cdIn!=NULL){ 00074 cdIn->getCode(rInst, countInst, M, BB, retVec); 00075 } 00076 00077 //case: r=k code to be inserted 00078 switch(cond){ 00079 case 1:{ 00080 Value *val=ConstantSInt::get(Type::IntTy,inc); 00081 #ifdef INSERT_STORE 00082 Instruction *stInst=new StoreInst(val, rInst);//, InsertPos); 00083 BB->getInstList().push_back(stInst); 00084 #endif 00085 break; 00086 } 00087 00088 //case: r=0 to be inserted 00089 case 2:{ 00090 #ifdef INSERT_STORE 00091 Instruction *stInst = new StoreInst(ConstantSInt::getNullValue(Type::IntTy), rInst);//, InsertPos); 00092 BB->getInstList().push_back(stInst); 00093 #endif 00094 break; 00095 } 00096 00097 //r+=k 00098 case 3:{ 00099 Instruction *ldInst = new LoadInst(rInst, "ti1");//, InsertPos); 00100 BB->getInstList().push_back(ldInst); 00101 Value *val = ConstantSInt::get(Type::IntTy,inc); 00102 Instruction *addIn = BinaryOperator::create(Instruction::Add, ldInst, val, 00103 "ti2");//, InsertPos); 00104 BB->getInstList().push_back(addIn); 00105 #ifdef INSERT_STORE 00106 Instruction *stInst = new StoreInst(addIn, rInst);//, InsertPos); 00107 BB->getInstList().push_back(stInst); 00108 #endif 00109 break; 00110 } 00111 00112 //count[inc]++ 00113 case 4:{ 00114 vector<Value *> tmpVec; 00115 tmpVec.push_back(Constant::getNullValue(Type::LongTy)); 00116 tmpVec.push_back(ConstantSInt::get(Type::LongTy, inc)); 00117 Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//, 00118 00119 //Instruction *Idx = new GetElementPtrInst(countInst, 00120 // vector<Value*>(1,ConstantSInt::get(Type::LongTy, inc)), 00121 // "");//, InsertPos); 00122 BB->getInstList().push_back(Idx); 00123 00124 Instruction *ldInst=new LoadInst(Idx, "ti1");//, InsertPos); 00125 BB->getInstList().push_back(ldInst); 00126 00127 Value *val = ConstantSInt::get(Type::IntTy, 1); 00128 //Instruction *addIn = 00129 Instruction *newCount = 00130 BinaryOperator::create(Instruction::Add, ldInst, val,"ti2"); 00131 BB->getInstList().push_back(newCount); 00132 00133 00134 #ifdef INSERT_STORE 00135 //Instruction *stInst=new StoreInst(addIn, Idx, InsertPos); 00136 Instruction *stInst=new StoreInst(newCount, Idx);//, InsertPos); 00137 BB->getInstList().push_back(stInst); 00138 #endif 00139 00140 Value *trAddIndex = ConstantSInt::get(Type::IntTy,inc); 00141 00142 retVec.push_back(newCount); 00143 retVec.push_back(trAddIndex); 00144 //insert trigger 00145 //getTriggerCode(M->getParent(), BB, MethNo, 00146 // ConstantSInt::get(Type::IntTy,inc), newCount, triggerInst); 00147 //end trigger code 00148 00149 assert(inc>=0 && "IT MUST BE POSITIVE NOW"); 00150 break; 00151 } 00152 00153 //case: count[r+inc]++ 00154 case 5:{ 00155 00156 //ti1=inc+r 00157 Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos); 00158 BB->getInstList().push_back(ldIndex); 00159 00160 Value *val=ConstantSInt::get(Type::IntTy,inc); 00161 Instruction *addIndex=BinaryOperator:: 00162 create(Instruction::Add, ldIndex, val,"ti2");//, InsertPos); 00163 BB->getInstList().push_back(addIndex); 00164 00165 //now load count[addIndex] 00166 Instruction *castInst=new CastInst(addIndex, 00167 Type::LongTy,"ctin");//, InsertPos); 00168 BB->getInstList().push_back(castInst); 00169 00170 vector<Value *> tmpVec; 00171 tmpVec.push_back(Constant::getNullValue(Type::LongTy)); 00172 tmpVec.push_back(castInst); 00173 Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//, 00174 // InsertPos); 00175 BB->getInstList().push_back(Idx); 00176 00177 Instruction *ldInst=new LoadInst(Idx, "ti3");//, InsertPos); 00178 BB->getInstList().push_back(ldInst); 00179 00180 Value *cons=ConstantSInt::get(Type::IntTy,1); 00181 //count[addIndex]++ 00182 //std::cerr<<"Type ldInst:"<<ldInst->getType()<<"\t cons:"<<cons->getType()<<"\n"; 00183 Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst, 00184 cons,""); 00185 BB->getInstList().push_back(newCount); 00186 00187 #ifdef INSERT_STORE 00188 Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos); 00189 BB->getInstList().push_back(stInst); 00190 #endif 00191 00192 retVec.push_back(newCount); 00193 retVec.push_back(addIndex); 00194 //insert trigger 00195 //getTriggerCode(M->getParent(), BB, MethNo, addIndex, newCount, triggerInst); 00196 //end trigger code 00197 00198 break; 00199 } 00200 00201 //case: count[r]+ 00202 case 6:{ 00203 //ti1=inc+r 00204 Instruction *ldIndex=new LoadInst(rInst, "ti1");//, InsertPos); 00205 BB->getInstList().push_back(ldIndex); 00206 00207 //now load count[addIndex] 00208 Instruction *castInst2=new CastInst(ldIndex, Type::LongTy,"ctin"); 00209 BB->getInstList().push_back(castInst2); 00210 00211 vector<Value *> tmpVec; 00212 tmpVec.push_back(Constant::getNullValue(Type::LongTy)); 00213 tmpVec.push_back(castInst2); 00214 Instruction *Idx = new GetElementPtrInst(countInst, tmpVec, "");//, 00215 00216 //Instruction *Idx = new GetElementPtrInst(countInst, 00217 // vector<Value*>(1,castInst2), ""); 00218 00219 BB->getInstList().push_back(Idx); 00220 00221 Instruction *ldInst=new LoadInst(Idx, "ti2");//, InsertPos); 00222 BB->getInstList().push_back(ldInst); 00223 00224 Value *cons=ConstantSInt::get(Type::IntTy,1); 00225 00226 //count[addIndex]++ 00227 Instruction *newCount = BinaryOperator::create(Instruction::Add, ldInst, 00228 cons,"ti3"); 00229 BB->getInstList().push_back(newCount); 00230 00231 #ifdef INSERT_STORE 00232 Instruction *stInst = new StoreInst(newCount, Idx);//, InsertPos); 00233 BB->getInstList().push_back(stInst); 00234 #endif 00235 00236 retVec.push_back(newCount); 00237 retVec.push_back(ldIndex); 00238 break; 00239 } 00240 00241 } 00242 } 00243 00244 00245 00246 //Insert the initialization code in the top BB 00247 //this includes initializing r, and count 00248 //r is like an accumulator, that 00249 //keeps on adding increments as we traverse along a path 00250 //and at the end of the path, r contains the path 00251 //number of that path 00252 //Count is an array, where Count[k] represents 00253 //the number of executions of path k 00254 void insertInTopBB(BasicBlock *front, 00255 int k, 00256 Instruction *rVar, Value *threshold){ 00257 //rVar is variable r, 00258 //countVar is count[] 00259 00260 Value *Int0 = ConstantInt::get(Type::IntTy, 0); 00261 00262 //now push all instructions in front of the BB 00263 BasicBlock::iterator here=front->begin(); 00264 front->getInstList().insert(here, rVar); 00265 //front->getInstList().insert(here,countVar); 00266 00267 //Initialize Count[...] with 0 00268 00269 //for (int i=0;i<k; i++){ 00270 //Value *GEP2 = new GetElementPtrInst(countVar, 00271 // vector<Value *>(1,ConstantSInt::get(Type::LongTy, i)), 00272 // "", here); 00273 //new StoreInst(Int0, GEP2, here); 00274 //} 00275 00276 //store uint 0, uint *%R 00277 new StoreInst(Int0, rVar, here); 00278 } 00279 00280 00281 //insert a basic block with appropriate code 00282 //along a given edge 00283 void insertBB(Edge ed, 00284 getEdgeCode *edgeCode, 00285 Instruction *rInst, 00286 Value *countInst, 00287 int numPaths, int Methno, Value *threshold){ 00288 00289 BasicBlock* BB1=ed.getFirst()->getElement(); 00290 BasicBlock* BB2=ed.getSecond()->getElement(); 00291 00292 #ifdef DEBUG_PATH_PROFILES 00293 //debugging info 00294 cerr<<"Edges with codes ######################\n"; 00295 cerr<<BB1->getName()<<"->"<<BB2->getName()<<"\n"; 00296 cerr<<"########################\n"; 00297 #endif 00298 00299 //We need to insert a BB between BB1 and BB2 00300 TerminatorInst *TI=BB1->getTerminator(); 00301 BasicBlock *newBB=new BasicBlock("counter", BB1->getParent()); 00302 00303 //get code for the new BB 00304 vector<Value *> retVec; 00305 00306 edgeCode->getCode(rInst, countInst, BB1->getParent(), newBB, retVec); 00307 00308 BranchInst *BI = cast<BranchInst>(TI); 00309 00310 //Is terminator a branch instruction? 00311 //then we need to change branch destinations to include new BB 00312 00313 if(BI->isUnconditional()){ 00314 BI->setUnconditionalDest(newBB); 00315 } 00316 else{ 00317 if(BI->getSuccessor(0)==BB2) 00318 BI->setSuccessor(0, newBB); 00319 00320 if(BI->getSuccessor(1)==BB2) 00321 BI->setSuccessor(1, newBB); 00322 } 00323 00324 BasicBlock *triggerBB = NULL; 00325 if(retVec.size()>0){ 00326 triggerBB = new BasicBlock("trigger", BB1->getParent()); 00327 getTriggerCode(BB1->getParent()->getParent(), triggerBB, Methno, 00328 retVec[1], countInst, rInst);//retVec[0]); 00329 00330 //Instruction *castInst = new CastInst(retVec[0], Type::IntTy, ""); 00331 Instruction *etr = new LoadInst(threshold, "threshold"); 00332 00333 //std::cerr<<"type1: "<<etr->getType()<<" type2: "<<retVec[0]->getType()<<"\n"; 00334 Instruction *cmpInst = new SetCondInst(Instruction::SetLE, etr, 00335 retVec[0], ""); 00336 Instruction *newBI2 = new BranchInst(triggerBB, BB2, cmpInst); 00337 //newBB->getInstList().push_back(castInst); 00338 newBB->getInstList().push_back(etr); 00339 newBB->getInstList().push_back(cmpInst); 00340 newBB->getInstList().push_back(newBI2); 00341 00342 //triggerBB->getInstList().push_back(triggerInst); 00343 new BranchInst(BB2, 0, 0, triggerBB); 00344 } 00345 else{ 00346 new BranchInst(BB2, 0, 0, newBB); 00347 } 00348 00349 //now iterate over BB2, and set its Phi nodes right 00350 for(BasicBlock::iterator BB2Inst = BB2->begin(), BBend = BB2->end(); 00351 BB2Inst != BBend; ++BB2Inst){ 00352 00353 if(PHINode *phiInst=dyn_cast<PHINode>(BB2Inst)){ 00354 int bbIndex=phiInst->getBasicBlockIndex(BB1); 00355 assert(bbIndex>=0); 00356 phiInst->setIncomingBlock(bbIndex, newBB); 00357 00358 ///check if trigger!=null, then add value corresponding to it too! 00359 if(retVec.size()>0){ 00360 assert(triggerBB && "BasicBlock with trigger should not be null!"); 00361 Value *vl = phiInst->getIncomingValue((unsigned int)bbIndex); 00362 phiInst->addIncoming(vl, triggerBB); 00363 } 00364 } 00365 } 00366 } 00367 00368 } // End llvm namespace