1 #ifndef _PASS_COMMON_H
2 #define _PASS_COMMON_H
3 
4 #if LLVM_VERSION >= 33
5 #define ATTRIBUTE_SET_TY              AttributeSet
6 #include <llvm/IR/Function.h>
7 #include <llvm/IR/Module.h>
8 #include <llvm/IR/Instructions.h>
9 #include <llvm/IR/Type.h>
10 #include <llvm/IR/Constants.h>
11 #include <llvm/IR/Intrinsics.h>
12 #include <llvm/IR/DerivedTypes.h>
13 #include <llvm/IR/LLVMContext.h>
14 #include <llvm/IR/IntrinsicInst.h>
15 #include <llvm/IR/DataLayout.h>
16 #include <llvm/IR/IRBuilder.h>
17 #else /* LLVM_VERSION < 33 */
18 #define ATTRIBUTE_SET_TY              AttrListPtr
19 #include <llvm/Function.h>
20 #include <llvm/Module.h>
21 #include <llvm/Instructions.h>
22 #include <llvm/Type.h>
23 #include <llvm/Constants.h>
24 #include <llvm/Intrinsics.h>
25 #include <llvm/DerivedTypes.h>
26 #include <llvm/LLVMContext.h>
27 #include <llvm/IntrinsicInst.h>
28 #endif /* LLVM_VERSION >= 33 */
29 
30 #if LLVM_VERSION >= 32
31 #define DATA_LAYOUT_TY 		      DataLayout
32 #define ATTRIBUTE_SET_RET_IDX         ATTRIBUTE_SET_TY::ReturnIndex
33 #define ATTRIBUTE_SET_FN_IDX          ATTRIBUTE_SET_TY::FunctionIndex
34 #include <llvm/IR/DebugInfo.h>
35 #if LLVM_VERSION == 32
36 #include <llvm/DataLayout.h>
37 #include <llvm/IRBuilder.h>
38 #endif
39 #else /* LLVM_VERSION < 32 */
40 #define DATA_LAYOUT_TY 		      TargetData
41 #define ATTRIBUTE_SET_RET_IDX         0
42 #define ATTRIBUTE_SET_FN_IDX          (~0U)
43 #include <llvm/Target/TargetData.h>
44 #include <llvm/Analysis/DebugInfo.h>
45 #include <llvm/Support/IRBuilder.h>
46 #endif /* LLVM_VERSION >= 32 */
47 
48 #if LLVM_VERSION >= 31
49 /* XXX Check. */
50 #define CONSTANT_ARRAY_INITIALIZER_TY ConstantDataArray
51 
52 #else /* LLVM_VERSION < 31 */
53 #define CONSTANT_ARRAY_INITIALIZER_TY ConstantArray
54 #endif /* LLVM_VERSION >= 31 */
55 
56 #if LLVM_VERSION >= 30
57 #define BASE_PARSER                   parser
58 
59 #define TYPECONST
60 #else /* LLVM_VERSION < 30 */
61 #define BASE_PARSER                   basic_parser
62 
63 #define TYPECONST const
64 #endif /* LLVM_VERSION >= 30 */
65 
66 #if LLVM_VERSION >= 29
67 #define VALUE_TO_VALUE_MAP_TY ValueToValueMapTy
68 #else  /* LLVM_VERSION < 29 */
69 #define VALUE_TO_VALUE_MAP_TY ValueMap<const Value*, Value*>
70 #endif /* LLVM_VERSION >= 29 */
71 
72 #define ZERO_CONSTANT_INT(M) ConstantInt::get((M).getContext(), APInt(32, 0, 10))
73 #define VOID_PTR_TY(M)       PointerType::get(IntegerType::get((M).getContext(), 8), 0)
74 #define VOID_PTR_PTR_TY(M)   PointerType::get(PointerType::get(IntegerType::get((M).getContext(), 8), 0), 0)
75 
76 #define FOREACH_FUNC(M, F, B) do { \
77     Module::FunctionListType &__FL = (M).getFunctionList(); \
78     for (Module::iterator __MI = __FL.begin(); __MI != __FL.end(); ++__MI) { \
79         const Function *F = __MI; \
80         if (F->isIntrinsic()) \
81             continue; \
82         B \
83     } \
84 } while(0)
85 
86 #define FOREACH_FUNC_INS(F, I, B) do { \
87     for (Function::const_iterator __FI = F->begin(), __FE = F->end(); __FI != __FE; ++__FI) { \
88         for (BasicBlock::const_iterator __BI = __FI->begin(), BE = __FI->end(); __BI != BE; ++__BI) { \
89             Instruction *I = (Instruction*) ((unsigned long) &(*__BI)); \
90             B \
91         } \
92     } \
93 } while(0)
94 
95 #define FOREACH_FUNC_CS(F, CS, B) do { \
96     FOREACH_FUNC_INS(F, I, \
97         CallSite CS = PassUtil::getCallSiteFromInstruction(I); \
98         if (!CS.getInstruction()) \
99             continue; \
100         B \
101     ); \
102 } while(0)
103 
104 #define DEBUG_LLVM_DEBUG_API 0
105 
106 typedef enum PassUtilLinkageTypeE {
107     PASS_UTIL_LINKAGE_NONE = 0,
108     PASS_UTIL_LINKAGE_WEAK,
109     PASS_UTIL_LINKAGE_COMMON,
110     PASS_UTIL_LINKAGE_EXTERNAL,
111     PASS_UTIL_LINKAGE_EXTERNAL_WEAK,
112     PASS_UTIL_LINKAGE_WEAK_POINTER,
113     PASS_UTIL_LINKAGE_PRIVATE,
114     __NUM_PASS_UTIL_LINKAGE_TYPES
115     /* Values here should only be appended at the end, external components (e.g., scripts) may be relying on them.*/
116 } PassUtilLinkageType;
117 
118 #define PASS_UTIL_LINKAGE_TYPE_STRINGS \
119     "NONE", \
120     "WEAK", \
121     "COMMON", \
122     "EXTERNAL", \
123     "EXTERNAL_WEAK", \
124     "WEAK_POINTER", \
125     "PRIVATE"
126 
127 typedef enum PassUtilPropE {
128     PASS_UTIL_PROP_NONE,
129     PASS_UTIL_PROP_NOINLINE,
130     PASS_UTIL_PROP_USED,
131     PASS_UTIL_PROP_PRESERVE,
132     __NUM_PASS_UTIL_PROPS
133 } PassUtilProp;
134 
135 #define PASS_UTIL_FLAG(F) (1 << F)
136 
137 #define PASS_COMMON_INIT_ONCE() \
138     Module *PassUtil::M = NULL; \
139 
140 using namespace llvm;
141 
142 namespace llvm {
143 
144 class PassUtil {
145   public:
146       static void writeTypeSymbolic(raw_string_ostream &OS, TYPECONST Type *type, const Module *M);
147       static const std::string getTypeDescription(TYPECONST Type* type);
148       static MDNode *findDbgGlobalDeclare(GlobalVariable *V);
149       static MDNode *findDbgSubprogramDeclare(const Function *F);
150       static void getDbgLocationInfoRelPath(const std::string &baseDir, const std::string &filename, const std::string &directory, std::string &relPath);
151       static void getDbgLocationInfo(DIDescriptor &DID, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath);
152       static bool getInstrDbgLocationInfo(Instruction *I, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath, unsigned int *lineNum, bool expand=true);
153       static unsigned getDbgSubrangeNumElements(const DISubrange &subrange);
154       static bool isDbgVectorTy(const DIType &type);
155       static DIType getDITypeDerivedFrom(const DIDerivedType &type);
156       static DIType getDITypeFromRef(const DITypeRef &ref);
157       static bool isOpaqueTy(TYPECONST Type *type);
158       static bool isPrimitiveTy(TYPECONST Type *type);
159       static Constant* getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes);
160       static GetElementPtrInst* createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr="", Instruction *InsertBefore=0);
161       static GetElementPtrInst* createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr="", BasicBlock *InsertAtEnd=0);
162       static CallInst* createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr="", Instruction *InsertBefore=0);
163       static CallInst* createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr="", BasicBlock *InsertAtEnd=0);
164       static Function* getIntrinsicFunction(Module &M, Intrinsic::ID id, TYPECONST Type** types=NULL, unsigned size=0);
165       static FunctionType* getFunctionType(TYPECONST Type* Result, std::vector<TYPECONST Type*> &argsTy, bool isVarArg=false);
166       static Function* setFunctionProperties(Function *F, unsigned long properties);
167       static Function* createFunctionWeakPtrWrapper(Module &M, StringRef Name, FunctionType *Ty);
168       static Function* getOrInsertFunction(Module &M, StringRef Name, FunctionType *Ty, PassUtilLinkageType insertLinkage, unsigned long properties);
169       static PassUtilLinkageType getFunctionPassUtilLinkageType(Function *F);
170       static std::string getPassUtilLinkageTypeString(PassUtilLinkageType linkageType);
171       static void getFunctionEntryExits(Function *F, BasicBlock **entryBlock, std::vector<BasicBlock*> *exitBlocks);
172       static bool isReturnedValue(Function *F, Value *V);
173       static CallSite getCallSiteFromInstruction(Instruction *I);
174       static CallSite getCallSiteFromUser(User *U);
175       static void getFunctionsInDirectBUCallgraph(Function* F, std::set<Function*> &funcs);
176       static void getAllocaInfo(Function *F, Instruction **allocaInsertionPoint, Instruction **firstNonAllocaInst);
177       static Constant* getStringConstantArray(Module &M, const std::string &string);
178       static GlobalVariable* getStringGlobalVariable(Module &M, const std::string &string, const std::string &varName = ".str.pu", const std::string &varSection = "", Constant **getElementPtrExpr=NULL, bool cacheable=false);
179       static ATTRIBUTE_SET_TY remapCallSiteAttributes(CallSite &CS, int argOffset);
180       static void parseStringListOpt(std::vector<std::string> &vector, const std::string &string, const std::string &separator = ":");
181       static void parseStringPairListOpt(std::set<std::pair<std::string, std::string> > &set, const std::string &string, const std::string &listSeparator = ":", const std::string &pairSeparator = ";");
182       static void parseRegexListOpt(std::vector<Regex*> &list, const std::string &string);
183       static bool matchRegexes(std::string string, std::vector<Regex*> &regexes);
184       static void setModule(Module *M);
185       static void getModuleName(Module &M, std::string *fullName, std::string *dirName, std::string *baseName);
186       static unsigned long getTypeHash(TYPECONST Type* type, unsigned maxLevel=11);
187   private:
188       static Module *M;
189 };
190 
writeTypeSymbolic(raw_string_ostream & OS,TYPECONST Type * type,const Module * M)191 inline void PassUtil::writeTypeSymbolic(raw_string_ostream &OS, TYPECONST Type *type, const Module *M) {
192 #if LLVM_VERSION >= 30
193     /* XXX Check. */
194     type->print(OS);
195     return;
196 #else
197     return WriteTypeSymbolic(OS, type, M);
198 #endif
199 }
200 
getTypeDescription(TYPECONST Type * type)201 inline const std::string PassUtil::getTypeDescription(TYPECONST Type* type) {
202     std::string string;
203 #if LLVM_VERSION >= 30
204     /* XXX Check. */
205     raw_string_ostream ostream(string);
206     type->print(ostream);
207     ostream.flush();
208 #else
209     string = type->getDescription();
210 #endif
211 
212     return string;
213 }
214 
findDbgGlobalDeclare(GlobalVariable * V)215 inline MDNode *PassUtil::findDbgGlobalDeclare(GlobalVariable *V) {
216 #if LLVM_VERSION >= 30
217   const Module *M = V->getParent();
218   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.cu");
219   if (!NMD)
220     return 0;
221 
222   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
223       DICompileUnit CU(NMD->getOperand(i));
224       DIArray GVs = CU.getGlobalVariables();
225       for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) {
226         DIDescriptor DIG(GVs.getElement(i));
227         if (DIGlobalVariable(DIG).getGlobal() == V)
228           return DIG;
229       }
230   }
231   return 0;
232 #else
233   const Module *M = V->getParent();
234   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
235   if (!NMD)
236     return 0;
237 
238   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
239     DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
240     if (!DIG.isGlobalVariable())
241       continue;
242     if (DIGlobalVariable(DIG).getGlobal() == V)
243       return DIG;
244   }
245   return 0;
246 #endif
247 }
248 
findDbgSubprogramDeclare(const Function * V)249 inline MDNode *PassUtil::findDbgSubprogramDeclare(const Function *V) {
250 #if LLVM_VERSION >= 30
251   const Module *M = V->getParent();
252   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.cu");
253   if (!NMD)
254     return 0;
255 
256   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
257       DICompileUnit CU(NMD->getOperand(i));
258       DIArray SPs = CU.getSubprograms();
259       for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
260            DISubprogram DIS(SPs.getElement(i));
261            if (DIS.getFunction() == V) {
262            	return DIS;
263            }
264       }
265   }
266   return 0;
267 #else
268   const Module *M = V->getParent();
269   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp");
270   if (!NMD)
271     return 0;
272 
273   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
274     DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
275     if (!DIG.isSubprogram())
276       continue;
277     if (DISubprogram(DIG).getFunction() == V)
278       return DIG;
279   }
280   return 0;
281 #endif
282 }
283 
getDbgLocationInfoRelPath(const std::string & baseDir,const std::string & filename,const std::string & directory,std::string & relPath)284 inline void PassUtil::getDbgLocationInfoRelPath(const std::string &baseDir, const std::string &filename, const std::string &directory, std::string &relPath) {
285     StringRef directoryRef(directory);
286     std::pair<StringRef, StringRef> stringPair = directoryRef.split(baseDir);
287     relPath = (stringPair.second.compare("") ? stringPair.second.str() : stringPair.first.str()) + "/" + filename;
288 #if DEBUG_LLVM_DEBUG_API
289     errs() << " - getDbgLocationInfoRelPath: Location Info is: " << directory << " | " << filename << " | " << relPath << "\n";
290 #endif
291 }
292 
getDbgLocationInfo(DIDescriptor & DID,const std::string & baseDir,std::string * filename,std::string * directory,std::string * relPath)293 inline void PassUtil::getDbgLocationInfo(DIDescriptor &DID, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath) {
294   StringRef _directory;
295   StringRef _filename;
296   if (DID.isGlobalVariable()) {
297 #if LLVM_VERSION >= 30
298     _directory = ((DIGlobalVariable*)&DID)->getDirectory();
299     _filename = ((DIGlobalVariable*)&DID)->getFilename();
300 #else
301     _directory = ((DIGlobalVariable*)&DID)->getCompileUnit().getDirectory();
302     _filename = ((DIGlobalVariable*)&DID)->getCompileUnit().getFilename();
303 #endif
304 #if DEBUG_LLVM_DEBUG_API
305     errs() << "DIGlobalVariable name is: " << ((DIGlobalVariable*)&DID)->getName() << "\n";
306 #endif
307   }
308   else if (DID.isSubprogram()) {
309     _directory = ((DISubprogram*)&DID)->getDirectory();
310     _filename = ((DISubprogram*)&DID)->getFilename();
311 #if DEBUG_LLVM_DEBUG_API
312     errs() << "DISubprogram name is: " << ((DISubprogram*)&DID)->getName() << "\n";
313 #endif
314   }
315   else {
316     DIScope DIS;
317     assert (DID.isVariable());
318     DIS = ((DIVariable*)&DID)->getContext();
319     if (DIS.isSubprogram()) {
320         _directory = ((DISubprogram*)&DIS)->getDirectory();
321         _filename = ((DISubprogram*)&DIS)->getFilename();
322 #if DEBUG_LLVM_DEBUG_API
323         errs() << "DIVariable (SP) name is: " << ((DIVariable*)&DID)->getName() << "\n";
324 #endif
325     }
326     else if (DIS.isLexicalBlock()) {
327         _directory = ((DILexicalBlock*)&DIS)->getDirectory();
328         _filename = ((DILexicalBlock*)&DIS)->getFilename();
329 #if DEBUG_LLVM_DEBUG_API
330         errs() << "DIVariable (LB) name is: " << ((DIVariable*)&DID)->getName() << "\n";
331 #endif
332     }
333     else {
334 #if LLVM_VERSION >= 30
335         assert(DIS.isLexicalBlockFile());
336         _directory = ((DILexicalBlockFile*)&DIS)->getDirectory();
337         _filename = ((DILexicalBlockFile*)&DIS)->getFilename();
338 #if DEBUG_LLVM_DEBUG_API
339         errs() << "DIVariable (LBF) name is: " << ((DIVariable*)&DID)->getName() << "\n";
340 #endif
341 #else
342 	assert(0 && "Unexpected DIScope instance!");
343 #endif
344     }
345   }
346   if (filename) {
347     *filename = _filename;
348   }
349   if (directory) {
350     *directory = _directory;
351   }
352   if (relPath) {
353     getDbgLocationInfoRelPath(baseDir, _filename, _directory, *relPath);
354   }
355 }
356 
getInstrDbgLocationInfo(Instruction * I,const std::string & baseDir,std::string * filename,std::string * directory,std::string * relPath,unsigned int * lineNum,bool expand)357 inline bool PassUtil::getInstrDbgLocationInfo(Instruction *I, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath, unsigned int *lineNum, bool expand) {
358     BasicBlock::iterator BI = I;
359     MDNode *N = BI->getMetadata("dbg");
360     if (!N && !expand) {
361         return false;
362     }
363     while(!N) {
364         if (BI->isTerminator()) {
365             BranchInst *BInst = dyn_cast<BranchInst>(BI);
366             if (BInst && BInst->isUnconditional()) {
367                 BI = BInst->getSuccessor(0)->front();
368                 N = BI->getMetadata("dbg");
369                 continue;
370             }
371             return false;
372         }
373         BI++;
374         N = BI->getMetadata("dbg");
375     }
376 
377     DILocation DIL(N);
378     StringRef _directory = DIL.getDirectory();
379     StringRef _filename = DIL.getFilename();
380     if (filename) {
381         *filename = _filename;
382     }
383     if (directory) {
384         *directory = _directory;
385     }
386     if (relPath) {
387       getDbgLocationInfoRelPath(baseDir, _filename, _directory, *relPath);
388     }
389     if (lineNum) {
390         *lineNum = DIL.getLineNumber();
391     }
392 
393     return true;
394 }
395 
getDbgSubrangeNumElements(const DISubrange & subrange)396 inline unsigned PassUtil::getDbgSubrangeNumElements(const DISubrange &subrange) {
397 #if LLVM_VERSION >= 33
398     const unsigned numElements = (unsigned) subrange.getCount();
399 #else
400     const unsigned low = (unsigned) subrange.getLo();
401     const unsigned high = (unsigned) subrange.getHi();
402     const unsigned numElements = high - low + 1;
403 #endif
404 
405     return numElements;
406 }
407 
isDbgVectorTy(const DIType & type)408 inline bool PassUtil::isDbgVectorTy(const DIType &type) {
409 #if LLVM_VERSION >= 33
410     return type.isVector();
411 #else
412     return type.getTag() == dwarf::DW_TAG_vector_type;
413 #endif
414 }
415 
getDITypeDerivedFrom(const DIDerivedType & type)416 inline DIType PassUtil::getDITypeDerivedFrom(const DIDerivedType &type) {
417 #if LLVM_VERSION >= 34
418     static DITypeIdentifierMap TypeIdentifierMap;
419     static bool TypeMapInitialized = false;
420     if (!TypeMapInitialized) {
421         assert(PassUtil::M && "Set module first!");
422         if (NamedMDNode *CU_Nodes = PassUtil::M->getNamedMetadata("llvm.dbg.cu")) {
423           TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
424           TypeMapInitialized = true;
425         }
426     }
427     return type.getTypeDerivedFrom().resolve(TypeIdentifierMap);
428 #else
429     return type.getTypeDerivedFrom();
430 #endif
431 }
432 
getDITypeFromRef(const DITypeRef & ref)433 inline DIType PassUtil::getDITypeFromRef(const DITypeRef &ref) {
434     static DITypeIdentifierMap TypeIdentifierMap;
435     static bool TypeMapInitialized = false;
436     if (!TypeMapInitialized) {
437         /* TODO: generate the type identifier map only once! */
438         assert(PassUtil::M && "Set module first!");
439         if (NamedMDNode *CU_Nodes = PassUtil::M->getNamedMetadata("llvm.dbg.cu")) {
440           TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
441           TypeMapInitialized = true;
442         }
443     }
444     return ref.resolve(TypeIdentifierMap);
445 }
446 
isOpaqueTy(TYPECONST Type * type)447 inline bool PassUtil::isOpaqueTy(TYPECONST Type *type) {
448 #if LLVM_VERSION >= 30
449     return type->isStructTy() && (((TYPECONST StructType*)type)->isOpaque() || type->getNumContainedTypes() == 0);
450 #else
451     return type->isOpaqueTy();
452 #endif
453 }
454 
isPrimitiveTy(TYPECONST Type * type)455 inline bool PassUtil::isPrimitiveTy(TYPECONST Type *type) {
456     return type->isVoidTy() || type->isFloatingPointTy() || type->isLabelTy() || type->isMetadataTy() || type->isX86_MMXTy();
457 }
458 
getGetElementPtrConstant(Constant * constant,std::vector<Value * > & indexes)459 inline Constant* PassUtil::getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes) {
460 #if LLVM_VERSION >= 30
461     ArrayRef<Value*> ref(indexes);
462     return ConstantExpr::getGetElementPtr(constant, ref);
463 #else
464     return ConstantExpr::getGetElementPtr(constant, &indexes[0], indexes.size());
465 #endif
466 }
467 
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,Instruction * InsertBefore)468 inline GetElementPtrInst* PassUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, Instruction *InsertBefore) {
469 #if LLVM_VERSION >= 30
470     ArrayRef<Value*> ref(indexes);
471     return GetElementPtrInst::Create(ptr, ref, NameStr, InsertBefore);
472 #else
473     return GetElementPtrInst::Create(ptr, indexes.begin(), indexes.end(), NameStr, InsertBefore);
474 #endif
475 }
476 
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,BasicBlock * InsertAtEnd)477 inline GetElementPtrInst* PassUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, BasicBlock *InsertAtEnd) {
478 #if LLVM_VERSION >= 30
479     ArrayRef<Value*> ref(indexes);
480     return GetElementPtrInst::Create(ptr, ref, NameStr, InsertAtEnd);
481 #else
482     return GetElementPtrInst::Create(ptr, indexes.begin(), indexes.end(), NameStr, InsertAtEnd);
483 #endif
484 }
485 
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,Instruction * InsertBefore)486 inline CallInst* PassUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, Instruction *InsertBefore) {
487 #if LLVM_VERSION >= 30
488     ArrayRef<Value*> ref(args);
489     return CallInst::Create(F, ref, NameStr, InsertBefore);
490 #else
491     return CallInst::Create(F, args.begin(), args.end(), NameStr, InsertBefore);
492 #endif
493 }
494 
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,BasicBlock * InsertAtEnd)495 inline CallInst* PassUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, BasicBlock *InsertAtEnd) {
496 #if LLVM_VERSION >= 30
497     ArrayRef<Value*> ref(args);
498     return CallInst::Create(F, ref, NameStr, InsertAtEnd);
499 #else
500     return CallInst::Create(F, args.begin(), args.end(), NameStr, InsertAtEnd);
501 #endif
502 }
503 
getIntrinsicFunction(Module & M,Intrinsic::ID id,TYPECONST Type ** types,unsigned size)504 inline Function* PassUtil::getIntrinsicFunction(Module &M, Intrinsic::ID id, TYPECONST Type** types, unsigned size) {
505 #if LLVM_VERSION >= 30
506     std::vector<TYPECONST Type*> typeVector;
507     for(unsigned i=0;i<size;i++) {
508         typeVector.push_back(types[i]);
509     }
510     ArrayRef<TYPECONST Type*> ref(typeVector);
511     return Intrinsic::getDeclaration(&M, id, ref);
512 #else
513     return Intrinsic::getDeclaration(&M, id, types, size);
514 #endif
515 }
516 
getFunctionType(TYPECONST Type * Result,std::vector<TYPECONST Type * > & argsTy,bool isVarArg)517 inline FunctionType* PassUtil::getFunctionType(TYPECONST Type* Result, std::vector<TYPECONST Type*> &argsTy, bool isVarArg)
518 {
519 #if LLVM_VERSION >= 30
520     ArrayRef<TYPECONST Type*> ref(argsTy);
521     return FunctionType::get(Result, ref, isVarArg);
522 #else
523     return FunctionType::get(Result, argsTy, isVarArg);
524 #endif
525 }
526 
setFunctionProperties(Function * F,unsigned long props)527 inline Function* PassUtil::setFunctionProperties(Function *F, unsigned long props)
528 {
529     assert(F);
530     bool preserve = props & (PASS_UTIL_FLAG(PASS_UTIL_PROP_NOINLINE)|PASS_UTIL_FLAG(PASS_UTIL_PROP_USED)|PASS_UTIL_FLAG(PASS_UTIL_PROP_PRESERVE));
531 
532     if (F->isDeclaration()) {
533         return F;
534     }
535     if (preserve) {
536         Instruction *I;
537         getAllocaInfo(F, NULL, &I);
538         assert(I);
539 
540         /* Add a volatile store to a new global variable to preserve it. */
541         PointerType* voidPointerTy = PointerType::get(IntegerType::get(F->getContext(), 8), 0);
542         GlobalVariable* volatileVar = new GlobalVariable(*F->getParent(),
543             voidPointerTy, false, GlobalValue::CommonLinkage,
544             0, F->getName() + "_llvm_propvar");
545         volatileVar->setInitializer(ConstantPointerNull::get(voidPointerTy));
546         new StoreInst(ConstantExpr::getCast(Instruction::BitCast, F, voidPointerTy), volatileVar, true, I);
547     }
548     return F;
549 }
550 
createFunctionWeakPtrWrapper(Module & M,StringRef Name,FunctionType * Ty)551 inline Function* PassUtil::createFunctionWeakPtrWrapper(Module &M, StringRef Name, FunctionType *Ty)
552 {
553     unsigned i;
554     Function *F = getOrInsertFunction(M, Name.str() + "_llvm_weakptrwrapper" , Ty, PASS_UTIL_LINKAGE_COMMON, 0);
555     TYPECONST Type *RetTy = Ty->getReturnType();
556     PointerType *FPtrTy = PointerType::get(Ty, 0);
557     Constant *FPtrNull = Constant::getNullValue(FPtrTy);
558 
559     /* Create the global function pointer variable. */
560     GlobalVariable* weakPtrVar = new GlobalVariable(M, FPtrTy, false,
561         GlobalValue::CommonLinkage, 0, Name);
562     weakPtrVar->setInitializer(FPtrNull);
563 
564     /* Create the wrapper function body. */
565     F->dropAllReferences();
566     BasicBlock* entryBB = BasicBlock::Create(M.getContext(), "entry",F,0);
567     BasicBlock* weakPtrOverridenBB = BasicBlock::Create(M.getContext(), "have." + Name.str(),F,0);
568     BasicBlock* endBB = BasicBlock::Create(M.getContext(), "end",F,0);
569     AllocaInst* retval = NULL;
570 
571     /* Parse arguments. */
572     std::vector<AllocaInst*> argsAllocaInsts;
573     for (Function::arg_iterator args = F->arg_begin(); args != F->arg_end(); args++) {
574         Value *argValue = args;
575         AllocaInst *allocaInst = new AllocaInst(argValue->getType(), ".llvm.pu.args", entryBB);
576         argsAllocaInsts.push_back(allocaInst);
577     }
578     if (!RetTy->isVoidTy()) {
579         retval = new AllocaInst(RetTy, "retval", entryBB);
580     }
581     i=0;
582     for (Function::arg_iterator args = F->arg_begin(); args != F->arg_end(); args++, i++) {
583         Value *argValue = args;
584         AllocaInst *allocaInst = argsAllocaInsts[i];
585         new StoreInst(argValue, allocaInst, true, entryBB);
586     }
587     if (retval) {
588         new StoreInst(Constant::getNullValue(RetTy), retval, true, entryBB);
589     }
590 
591     /* Build entry block. */
592     LoadInst* weakPtr = new LoadInst(weakPtrVar, "", true, entryBB);
593     ICmpInst* cmpInst = new ICmpInst(*entryBB, ICmpInst::ICMP_NE, weakPtr, FPtrNull, "");
594     BranchInst::Create(weakPtrOverridenBB, endBB, cmpInst, entryBB);
595 
596     /* Build weakPtrOverriden block, only executed with a non-NULL weakPtr */
597     std::vector<Value*> weakPtrCallParams;
598     i=0;
599     for (Function::arg_iterator args = F->arg_begin(); args != F->arg_end(); args++, i++) {
600         AllocaInst *allocaInst = argsAllocaInsts[i];
601         weakPtrCallParams.push_back(new LoadInst(allocaInst, "", true, weakPtrOverridenBB));
602     }
603     weakPtr = new LoadInst(weakPtrVar, "", true, weakPtrOverridenBB);
604     CallInst* weakPtrCall = createCallInstruction(weakPtr, weakPtrCallParams, "", weakPtrOverridenBB);
605     weakPtrCall->setCallingConv(CallingConv::C);
606 
607     if (retval) {
608         new StoreInst(weakPtrCall, retval, false, weakPtrOverridenBB);
609     }
610     BranchInst::Create(endBB, weakPtrOverridenBB);
611 
612     /* Build end block. */
613     if (!retval) {
614         ReturnInst::Create(M.getContext(), endBB);
615     }
616     else {
617         LoadInst* retvalValue = new LoadInst(retval, "", false, endBB);
618         ReturnInst::Create(M.getContext(), retvalValue, endBB);
619     }
620     return F;
621 }
622 
getOrInsertFunction(Module & M,StringRef Name,FunctionType * Ty,PassUtilLinkageType insertLinkage,unsigned long properties)623 inline Function* PassUtil::getOrInsertFunction(Module &M, StringRef Name, FunctionType *Ty, PassUtilLinkageType insertLinkage, unsigned long properties)
624 {
625     static std::map<std::string, Function *> functionMap;
626     std::map<std::string, Function *>::iterator functionMapIt;
627     Function *F = NULL;
628     bool needsEmptyBody = true;
629     bool needsProperties = true;
630     bool needsIncludsion = true;
631 
632     functionMapIt = functionMap.find(Name);
633     if (functionMapIt != functionMap.end()) {
634         return functionMapIt->second;
635     }
636     F = M.getFunction(Name);
637 
638     if (F) {
639         /* If the function exists, check the type and return it. */
640         if (F->getFunctionType() != Ty) {
641             return NULL;
642         }
643         functionMap.insert(std::pair<std::string, Function *>(Name, F));
644         setFunctionProperties(F, properties);
645         return F;
646     }
647 
648     /* Has the user requested creation of the function otherwise? */
649     if (insertLinkage == PASS_UTIL_LINKAGE_NONE) {
650         return NULL;
651     }
652     switch(insertLinkage) {
653     case PASS_UTIL_LINKAGE_WEAK:
654         /* Create empty function that can optionally be overriden at link time*/
655         F = Function::Create(Ty, GlobalVariable::WeakAnyLinkage, Name);
656     break;
657     case PASS_UTIL_LINKAGE_COMMON:
658         /* Creates empty function, non overridable. */
659         F = Function::Create(Ty, GlobalVariable::InternalLinkage, Name);
660     break;
661     case PASS_UTIL_LINKAGE_EXTERNAL:
662         /* Creates function declaration that must be defined at link time. */
663         F = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name);
664         needsEmptyBody = false;
665     break;
666     case PASS_UTIL_LINKAGE_EXTERNAL_WEAK:
667         /* Creates weak function declaration that can optionally be defined
668          * at link time (if undefined the linker will emit a NULL symbol).
669          */
670         F = Function::Create(Ty, GlobalVariable::ExternalWeakLinkage, Name);
671         needsEmptyBody = false;
672     break;
673     case PASS_UTIL_LINKAGE_WEAK_POINTER:
674         /* Creates function pointer initialized to NULL that can optionally
675          * be initialized at runtime. Invocations are wrapped to ensure that
676          * indirect call is performed on a NULL pointer. This is to emulate
677          * Mac OS' weak_pointer attribute, which allows weak symbols to be
678          * overriden in LD_PRELOADED libraries at runtime.
679          */
680         F = PassUtil::createFunctionWeakPtrWrapper(M, Name, Ty);
681         needsProperties = false;
682         needsIncludsion = false;
683     break;
684     default:
685         return NULL;
686     break;
687     }
688     if (needsIncludsion) {
689         M.getFunctionList().push_back(F);
690     }
691     if (needsEmptyBody) {
692         BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", F);
693         IRBuilder<> builder(block);
694         TYPECONST Type *RetTy = Ty->getReturnType();
695         if (RetTy->isVoidTy()) {
696             builder.CreateRetVoid();
697         }
698         else {
699             builder.CreateRet(Constant::getNullValue(RetTy));
700         }
701     }
702     functionMap.insert(std::pair<std::string, Function *>(Name, F));
703     if (needsProperties) {
704         setFunctionProperties(F, properties);
705     }
706     return F;
707 }
708 
getFunctionPassUtilLinkageType(Function * F)709 inline PassUtilLinkageType PassUtil::getFunctionPassUtilLinkageType(Function *F)
710 {
711     if (F->isDeclaration()) {
712         return PASS_UTIL_LINKAGE_EXTERNAL;
713     }
714     if (F->hasInternalLinkage()) {
715         return PASS_UTIL_LINKAGE_PRIVATE;
716     }
717     return PASS_UTIL_LINKAGE_COMMON;
718 }
719 
getPassUtilLinkageTypeString(PassUtilLinkageType linkageType)720 inline std::string PassUtil::getPassUtilLinkageTypeString(PassUtilLinkageType linkageType)
721 {
722     const char *strArray[] = { PASS_UTIL_LINKAGE_TYPE_STRINGS };
723     std::string str(strArray[linkageType]);
724     return str;
725 }
726 
getFunctionEntryExits(Function * F,BasicBlock ** entryBlock,std::vector<BasicBlock * > * exitBlocks)727 inline void PassUtil::getFunctionEntryExits(Function *F, BasicBlock **entryBlock, std::vector<BasicBlock*> *exitBlocks)
728 {
729     if (entryBlock) {
730         *entryBlock = &F->front();
731     }
732     if (exitBlocks) {
733         for(Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
734             if (isa<ReturnInst>(I->getTerminator()) || isa<UnreachableInst>(I->getTerminator()))
735                 exitBlocks->push_back(I);
736         }
737     }
738 }
739 
isReturnedValue(Function * F,Value * V)740 inline bool PassUtil::isReturnedValue(Function *F, Value *V)
741 {
742     std::vector<BasicBlock*> exitBlocks;
743     PassUtil::getFunctionEntryExits(F, NULL, &exitBlocks);
744     for (unsigned i=0;i<exitBlocks.size();i++) {
745         Instruction *I = exitBlocks[i]->getTerminator();
746         ReturnInst *RI = dyn_cast<ReturnInst>(I);
747         if (RI && RI->getReturnValue()) {
748             Value *RV = RI->getReturnValue();
749             if (RV == V) {
750                 return true;
751             }
752             if (LoadInst *LI = dyn_cast<LoadInst>(RV)) {
753                 if (LI->getPointerOperand() == V) {
754                     return true;
755                 }
756             }
757         }
758     }
759     return false;
760 }
761 
getCallSiteFromInstruction(Instruction * I)762 inline CallSite PassUtil::getCallSiteFromInstruction(Instruction *I)
763 {
764   return getCallSiteFromUser(I);
765 }
766 
getCallSiteFromUser(User * U)767 inline CallSite PassUtil::getCallSiteFromUser(User *U)
768 {
769   CallSite CS(U->stripPointerCasts());
770   CallSite emptyCS;
771   Instruction *I = CS.getInstruction();
772   if (!I)
773       return emptyCS;
774   if (isa<CallInst>(I) && dyn_cast<CallInst>(I)->isInlineAsm())
775       return emptyCS;
776   Function *F = CS.getCalledFunction();
777   if (F && F->isIntrinsic())
778       return emptyCS;
779   return CS;
780 }
781 
getFunctionsInDirectBUCallgraph(Function * F,std::set<Function * > & funcs)782 inline void PassUtil::getFunctionsInDirectBUCallgraph(Function* F, std::set<Function*> &funcs) {
783   if (funcs.find(F) != funcs.end())
784       return;
785   funcs.insert(F);
786   FOREACH_FUNC_CS(F, CS,
787       if (!CS.getCalledFunction())
788           continue;
789       getFunctionsInDirectBUCallgraph(CS.getCalledFunction(), funcs);
790   );
791 }
792 
getAllocaInfo(Function * F,Instruction ** allocaInsertionPoint,Instruction ** firstNonAllocaInst)793 inline void PassUtil::getAllocaInfo(Function *F, Instruction **allocaInsertionPoint, Instruction **firstNonAllocaInst)
794 {
795     assert(!F->isDeclaration());
796     BasicBlock::iterator allocaIP = F->front().begin();
797     while (isa<AllocaInst>(allocaIP)) ++allocaIP;
798     BasicBlock::iterator firstNonAI = allocaIP;
799     if (firstNonAI->getName().equals("alloca point")) {
800     	firstNonAI++;
801     }
802     if(allocaInsertionPoint) {
803     	*allocaInsertionPoint = allocaIP;
804     }
805     if(firstNonAllocaInst) {
806     	*firstNonAllocaInst = firstNonAI;
807     }
808 }
809 
getStringConstantArray(Module & M,const std::string & string)810 inline Constant* PassUtil::getStringConstantArray(Module &M, const std::string &string)
811 {
812   std::vector<Constant*> elements;
813   elements.reserve(string.size() + 1);
814   for (unsigned i = 0; i < string.size(); ++i)
815     elements.push_back(ConstantInt::get(Type::getInt8Ty(M.getContext()), string[i]));
816 
817   // Add a null terminator to the string...
818   elements.push_back(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0));
819 
820   ArrayType *ATy = ArrayType::get(Type::getInt8Ty(M.getContext()), elements.size());
821   return ConstantArray::get(ATy, elements);
822 }
823 
getStringGlobalVariable(Module & M,const std::string & string,const std::string & varName,const std::string & varSection,Constant ** getElementPtrExpr,bool cacheable)824 inline GlobalVariable* PassUtil::getStringGlobalVariable(Module &M, const std::string &string, const std::string &varName, const std::string &varSection, Constant **getElementPtrExpr, bool cacheable)
825 {
826     static std::map<std::string, GlobalVariable*> stringCache;
827     std::map<std::string, GlobalVariable*>::iterator stringCacheIt;
828     std::string stringCacheKey;
829     GlobalVariable *strGV = NULL;
830 
831     if (cacheable) {
832     	stringCacheKey = string + "~!~!" + varName + "~!~!" + varSection;
833         stringCacheIt = stringCache.find(stringCacheKey);
834         if (stringCacheIt != stringCache.end()) {
835             strGV = stringCacheIt->second;
836             cacheable = false;
837         }
838     }
839 
840     if (!strGV) {
841         //create a constant internal string reference
842         Constant *stringValue = PassUtil::getStringConstantArray(M, string);
843 
844         //create the global variable, cache it, and record it in the module
845         strGV = new GlobalVariable(M, stringValue->getType(), true,
846             GlobalValue::InternalLinkage, stringValue, varName);
847         if (varSection.compare("")) {
848             strGV->setSection(varSection);
849         }
850     }
851     if (getElementPtrExpr) {
852     	    std::vector<Value*> strConstantIndices;
853     	    strConstantIndices.push_back(ZERO_CONSTANT_INT(M));
854     	    strConstantIndices.push_back(ZERO_CONSTANT_INT(M));
855     	    *getElementPtrExpr = PassUtil::getGetElementPtrConstant(strGV, strConstantIndices);
856     }
857 
858     if (cacheable) {
859         stringCache.insert(std::pair<std::string, GlobalVariable*>(stringCacheKey, strGV));
860     }
861 
862     return strGV;
863 }
864 
remapCallSiteAttributes(CallSite & CS,int argOffset)865 inline ATTRIBUTE_SET_TY PassUtil::remapCallSiteAttributes(CallSite &CS, int argOffset)
866 {
867     ATTRIBUTE_SET_TY Attrs = CS.getAttributes();
868     ATTRIBUTE_SET_TY NewAttrs;
869 #if LLVM_VERSION >= 33
870     Instruction *I = CS.getInstruction();
871     NewAttrs.addAttributes(I->getContext(), ATTRIBUTE_SET_RET_IDX, Attrs.getRetAttributes());
872     NewAttrs.addAttributes(I->getContext(), ATTRIBUTE_SET_FN_IDX, Attrs.getFnAttributes());
873     for (unsigned i=1;i<=CS.arg_size();i++) {
874         NewAttrs.addAttributes(I->getContext(), i+argOffset, Attrs.getParamAttributes(i));
875     }
876 #elif LLVM_VERSION == 32
877     Instruction *I = CS.getInstruction();
878     NewAttrs.addAttr(I->getContext(), ATTRIBUTE_SET_RET_IDX, Attrs.getRetAttributes());
879     NewAttrs.addAttr(I->getContext(), ATTRIBUTE_SET_FN_IDX, Attrs.getFnAttributes());
880     for (unsigned i=1;i<=CS.arg_size();i++) {
881         NewAttrs.addAttr(I->getContext(), i+argOffset, Attrs.getParamAttributes(i));
882     }
883 #else
884     NewAttrs.addAttr(ATTRIBUTE_SET_RET_IDX, Attrs.getRetAttributes());
885     NewAttrs.addAttr(ATTRIBUTE_SET_FN_IDX, Attrs.getFnAttributes());
886     for (unsigned i=1;i<=CS.arg_size();i++) {
887         NewAttrs.addAttr(i+argOffset, Attrs.getParamAttributes(i));
888     }
889 #endif
890 
891     return NewAttrs;
892 }
893 
parseStringListOpt(std::vector<std::string> & list,const std::string & string,const std::string & separator)894 inline void PassUtil::parseStringListOpt(std::vector<std::string> &list, const std::string &string, const std::string &separator)
895 {
896     if(string.compare("")) {
897         SmallVector< StringRef, 8 > vector;
898         StringRef sref(string);
899         sref.split(vector, separator, -1, false);
900         list.insert(list.end(), vector.begin(), vector.end());
901     }
902 }
903 
parseStringPairListOpt(std::set<std::pair<std::string,std::string>> & set,const std::string & string,const std::string & listSeparator,const std::string & pairSeparator)904 inline void PassUtil::parseStringPairListOpt(std::set<std::pair<std::string, std::string> > &set, const std::string &string, const std::string &listSeparator, const std::string &pairSeparator)
905 {
906 	if(string.compare("")) {
907 		SmallVector< StringRef, 8 > vector;
908 		StringRef sref(string);
909 		sref.split(vector, listSeparator, -1, false);
910 		SmallVector< StringRef, 8 > parts;
911 		while(!vector.empty()) {
912 			StringRef token = vector.pop_back_val();
913 			parts.clear();
914 			token.split(parts, pairSeparator, -1, false);
915 			assert(parts.size() == 2 && "Two tokens were expected.");
916 			set.insert(std::pair<std::string, std::string>(parts.front(), parts.back()));
917 		}
918 	}
919 }
920 
parseRegexListOpt(std::vector<Regex * > & list,const std::string & string)921 inline void PassUtil::parseRegexListOpt(std::vector<Regex*> &list, const std::string &string)
922 {
923     std::vector<std::string> stringList;
924     std::vector<std::string>::iterator it;
925     PassUtil::parseStringListOpt(stringList, string);
926 
927     for (it = stringList.begin(); it != stringList.end(); ++it) {
928         Regex* regex = new Regex(*it, 0);
929         std::string error;
930         assert(regex->isValid(error));
931         list.push_back(regex);
932     }
933 }
934 
matchRegexes(std::string string,std::vector<Regex * > & regexes)935 inline bool PassUtil::matchRegexes(std::string string, std::vector<Regex*> &regexes)
936 {
937     for (std::vector<Regex*>::iterator it = regexes.begin(); it != regexes.end(); ++it) {
938     	Regex *regex = *it;
939     	if(regex->match(string, NULL)) {
940     	    return true;
941     	}
942     }
943 
944     return false;
945 }
946 
setModule(Module * M)947 inline void PassUtil::setModule(Module *M)
948 {
949     PassUtil::M = M;
950 }
951 
getModuleName(Module & M,std::string * fullName,std::string * dirName,std::string * baseName)952 inline void PassUtil::getModuleName(Module &M, std::string *fullName, std::string *dirName, std::string *baseName)
953 {
954     std::string _fullName, _dirName, _baseName;
955     _fullName = M.getModuleIdentifier();
956     SmallVector< StringRef, 8 > vector;
957     StringRef fullNameRef(_fullName);
958     fullNameRef.split(vector, "/", -1, false);
959     if (vector.size() > 1) {
960         _baseName = vector.pop_back_val();
961         for (unsigned i=0;i<vector.size();i++) {
962             _dirName.append("/");
963             _dirName.append(vector[i]);
964         }
965     }
966     else {
967         _baseName = _fullName;
968         _dirName = "/";
969     }
970     vector.clear();
971     StringRef baseNameRef(_baseName);
972     baseNameRef.split(vector, ".", -1, false);
973     if (vector.size() > 1) {
974         _baseName = vector[0];
975     }
976     if (fullName)
977         *fullName = _fullName;
978     if (dirName)
979         *dirName = _dirName;
980     if (baseName)
981         *baseName = _baseName;
982 }
983 
getTypeHash(TYPECONST Type * type,unsigned maxLevel)984 inline unsigned long PassUtil::getTypeHash(TYPECONST Type* type, unsigned maxLevel)
985 {
986     static std::vector<TYPECONST Type*> nestedTypes;
987     static unsigned level = 0;
988     static unsigned counter;
989     unsigned long hash = 7;
990     if(level == 0) {
991         counter = 0;
992     }
993     unsigned numContainedTypes = type->getNumContainedTypes();
994     unsigned nestedIndex = 0;
995     for(unsigned i=0;i<nestedTypes.size();i++) {
996         if(type == nestedTypes[i]) {
997             nestedIndex = i+1;
998             break;
999         }
1000     }
1001     hash = (13*hash) ^ level;
1002     hash = (13*hash) ^ counter++;
1003     hash = (13*hash) ^ type->getTypeID();
1004     hash = (13*hash) ^ nestedIndex;
1005     if(TYPECONST IntegerType *intType = dyn_cast<IntegerType>(type)) {
1006         hash = (13*hash) ^ intType->getBitWidth();
1007     }
1008     else if(TYPECONST PointerType *ptrType = dyn_cast<PointerType>(type)) {
1009         hash = (13*hash) ^ ptrType->getElementType()->getTypeID();
1010     }
1011     if(nestedIndex > 0 || level >= maxLevel) {
1012         return hash;
1013     }
1014     if(numContainedTypes == 0) {
1015         return hash;
1016     }
1017     level++;
1018     nestedTypes.push_back(type);
1019     hash = (13*hash) ^ numContainedTypes;
1020     for(unsigned i=0;i<numContainedTypes;i++) {
1021         hash = (13*hash) ^ getTypeHash(type->getContainedType(i), maxLevel);
1022     }
1023     nestedTypes.pop_back();
1024     level--;
1025 
1026     return hash;
1027 }
1028 
1029 }
1030 
1031 #endif /* _PASS_COMMON_H */
1032