xref: /minix3/minix/llvm/passes/include/common/pass_common.h (revision bdb565187c0f1a04513dd488df843317b27f86c8)
13e457fe3SDavid van Moolenbroek #ifndef _PASS_COMMON_H
23e457fe3SDavid van Moolenbroek #define _PASS_COMMON_H
33e457fe3SDavid van Moolenbroek 
43e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 33
53e457fe3SDavid van Moolenbroek #define ATTRIBUTE_SET_TY              AttributeSet
63e457fe3SDavid van Moolenbroek #include <llvm/IR/Function.h>
73e457fe3SDavid van Moolenbroek #include <llvm/IR/Module.h>
83e457fe3SDavid van Moolenbroek #include <llvm/IR/Instructions.h>
93e457fe3SDavid van Moolenbroek #include <llvm/IR/Type.h>
103e457fe3SDavid van Moolenbroek #include <llvm/IR/Constants.h>
113e457fe3SDavid van Moolenbroek #include <llvm/IR/Intrinsics.h>
123e457fe3SDavid van Moolenbroek #include <llvm/IR/DerivedTypes.h>
133e457fe3SDavid van Moolenbroek #include <llvm/IR/LLVMContext.h>
143e457fe3SDavid van Moolenbroek #include <llvm/IR/IntrinsicInst.h>
153e457fe3SDavid van Moolenbroek #include <llvm/IR/DataLayout.h>
163e457fe3SDavid van Moolenbroek #include <llvm/IR/IRBuilder.h>
173e457fe3SDavid van Moolenbroek #else /* LLVM_VERSION < 33 */
183e457fe3SDavid van Moolenbroek #define ATTRIBUTE_SET_TY              AttrListPtr
193e457fe3SDavid van Moolenbroek #include <llvm/Function.h>
203e457fe3SDavid van Moolenbroek #include <llvm/Module.h>
213e457fe3SDavid van Moolenbroek #include <llvm/Instructions.h>
223e457fe3SDavid van Moolenbroek #include <llvm/Type.h>
233e457fe3SDavid van Moolenbroek #include <llvm/Constants.h>
243e457fe3SDavid van Moolenbroek #include <llvm/Intrinsics.h>
253e457fe3SDavid van Moolenbroek #include <llvm/DerivedTypes.h>
263e457fe3SDavid van Moolenbroek #include <llvm/LLVMContext.h>
273e457fe3SDavid van Moolenbroek #include <llvm/IntrinsicInst.h>
283e457fe3SDavid van Moolenbroek #endif /* LLVM_VERSION >= 33 */
293e457fe3SDavid van Moolenbroek 
303e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 32
313e457fe3SDavid van Moolenbroek #define DATA_LAYOUT_TY 		      DataLayout
323e457fe3SDavid van Moolenbroek #define ATTRIBUTE_SET_RET_IDX         ATTRIBUTE_SET_TY::ReturnIndex
333e457fe3SDavid van Moolenbroek #define ATTRIBUTE_SET_FN_IDX          ATTRIBUTE_SET_TY::FunctionIndex
34*bdb56518SDavid van Moolenbroek #include <llvm/IR/DebugInfo.h>
353e457fe3SDavid van Moolenbroek #if LLVM_VERSION == 32
363e457fe3SDavid van Moolenbroek #include <llvm/DataLayout.h>
373e457fe3SDavid van Moolenbroek #include <llvm/IRBuilder.h>
383e457fe3SDavid van Moolenbroek #endif
393e457fe3SDavid van Moolenbroek #else /* LLVM_VERSION < 32 */
403e457fe3SDavid van Moolenbroek #define DATA_LAYOUT_TY 		      TargetData
413e457fe3SDavid van Moolenbroek #define ATTRIBUTE_SET_RET_IDX         0
423e457fe3SDavid van Moolenbroek #define ATTRIBUTE_SET_FN_IDX          (~0U)
433e457fe3SDavid van Moolenbroek #include <llvm/Target/TargetData.h>
443e457fe3SDavid van Moolenbroek #include <llvm/Analysis/DebugInfo.h>
453e457fe3SDavid van Moolenbroek #include <llvm/Support/IRBuilder.h>
463e457fe3SDavid van Moolenbroek #endif /* LLVM_VERSION >= 32 */
473e457fe3SDavid van Moolenbroek 
483e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 31
493e457fe3SDavid van Moolenbroek /* XXX Check. */
503e457fe3SDavid van Moolenbroek #define CONSTANT_ARRAY_INITIALIZER_TY ConstantDataArray
513e457fe3SDavid van Moolenbroek 
523e457fe3SDavid van Moolenbroek #else /* LLVM_VERSION < 31 */
533e457fe3SDavid van Moolenbroek #define CONSTANT_ARRAY_INITIALIZER_TY ConstantArray
543e457fe3SDavid van Moolenbroek #endif /* LLVM_VERSION >= 31 */
553e457fe3SDavid van Moolenbroek 
563e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
573e457fe3SDavid van Moolenbroek #define BASE_PARSER                   parser
583e457fe3SDavid van Moolenbroek 
593e457fe3SDavid van Moolenbroek #define TYPECONST
603e457fe3SDavid van Moolenbroek #else /* LLVM_VERSION < 30 */
613e457fe3SDavid van Moolenbroek #define BASE_PARSER                   basic_parser
623e457fe3SDavid van Moolenbroek 
633e457fe3SDavid van Moolenbroek #define TYPECONST const
643e457fe3SDavid van Moolenbroek #endif /* LLVM_VERSION >= 30 */
653e457fe3SDavid van Moolenbroek 
663e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 29
673e457fe3SDavid van Moolenbroek #define VALUE_TO_VALUE_MAP_TY ValueToValueMapTy
683e457fe3SDavid van Moolenbroek #else  /* LLVM_VERSION < 29 */
693e457fe3SDavid van Moolenbroek #define VALUE_TO_VALUE_MAP_TY ValueMap<const Value*, Value*>
703e457fe3SDavid van Moolenbroek #endif /* LLVM_VERSION >= 29 */
713e457fe3SDavid van Moolenbroek 
723e457fe3SDavid van Moolenbroek #define ZERO_CONSTANT_INT(M) ConstantInt::get((M).getContext(), APInt(32, 0, 10))
733e457fe3SDavid van Moolenbroek #define VOID_PTR_TY(M)       PointerType::get(IntegerType::get((M).getContext(), 8), 0)
743e457fe3SDavid van Moolenbroek #define VOID_PTR_PTR_TY(M)   PointerType::get(PointerType::get(IntegerType::get((M).getContext(), 8), 0), 0)
753e457fe3SDavid van Moolenbroek 
763e457fe3SDavid van Moolenbroek #define FOREACH_FUNC(M, F, B) do { \
773e457fe3SDavid van Moolenbroek     Module::FunctionListType &__FL = (M).getFunctionList(); \
783e457fe3SDavid van Moolenbroek     for (Module::iterator __MI = __FL.begin(); __MI != __FL.end(); ++__MI) { \
793e457fe3SDavid van Moolenbroek         const Function *F = __MI; \
803e457fe3SDavid van Moolenbroek         if (F->isIntrinsic()) \
813e457fe3SDavid van Moolenbroek             continue; \
823e457fe3SDavid van Moolenbroek         B \
833e457fe3SDavid van Moolenbroek     } \
843e457fe3SDavid van Moolenbroek } while(0)
853e457fe3SDavid van Moolenbroek 
863e457fe3SDavid van Moolenbroek #define FOREACH_FUNC_INS(F, I, B) do { \
873e457fe3SDavid van Moolenbroek     for (Function::const_iterator __FI = F->begin(), __FE = F->end(); __FI != __FE; ++__FI) { \
883e457fe3SDavid van Moolenbroek         for (BasicBlock::const_iterator __BI = __FI->begin(), BE = __FI->end(); __BI != BE; ++__BI) { \
893e457fe3SDavid van Moolenbroek             Instruction *I = (Instruction*) ((unsigned long) &(*__BI)); \
903e457fe3SDavid van Moolenbroek             B \
913e457fe3SDavid van Moolenbroek         } \
923e457fe3SDavid van Moolenbroek     } \
933e457fe3SDavid van Moolenbroek } while(0)
943e457fe3SDavid van Moolenbroek 
953e457fe3SDavid van Moolenbroek #define FOREACH_FUNC_CS(F, CS, B) do { \
963e457fe3SDavid van Moolenbroek     FOREACH_FUNC_INS(F, I, \
973e457fe3SDavid van Moolenbroek         CallSite CS = PassUtil::getCallSiteFromInstruction(I); \
983e457fe3SDavid van Moolenbroek         if (!CS.getInstruction()) \
993e457fe3SDavid van Moolenbroek             continue; \
1003e457fe3SDavid van Moolenbroek         B \
1013e457fe3SDavid van Moolenbroek     ); \
1023e457fe3SDavid van Moolenbroek } while(0)
1033e457fe3SDavid van Moolenbroek 
1043e457fe3SDavid van Moolenbroek #define DEBUG_LLVM_DEBUG_API 0
1053e457fe3SDavid van Moolenbroek 
1063e457fe3SDavid van Moolenbroek typedef enum PassUtilLinkageTypeE {
1073e457fe3SDavid van Moolenbroek     PASS_UTIL_LINKAGE_NONE = 0,
1083e457fe3SDavid van Moolenbroek     PASS_UTIL_LINKAGE_WEAK,
1093e457fe3SDavid van Moolenbroek     PASS_UTIL_LINKAGE_COMMON,
1103e457fe3SDavid van Moolenbroek     PASS_UTIL_LINKAGE_EXTERNAL,
1113e457fe3SDavid van Moolenbroek     PASS_UTIL_LINKAGE_EXTERNAL_WEAK,
1123e457fe3SDavid van Moolenbroek     PASS_UTIL_LINKAGE_WEAK_POINTER,
1133e457fe3SDavid van Moolenbroek     PASS_UTIL_LINKAGE_PRIVATE,
1143e457fe3SDavid van Moolenbroek     __NUM_PASS_UTIL_LINKAGE_TYPES
1153e457fe3SDavid van Moolenbroek     /* Values here should only be appended at the end, external components (e.g., scripts) may be relying on them.*/
1163e457fe3SDavid van Moolenbroek } PassUtilLinkageType;
1173e457fe3SDavid van Moolenbroek 
1183e457fe3SDavid van Moolenbroek #define PASS_UTIL_LINKAGE_TYPE_STRINGS \
1193e457fe3SDavid van Moolenbroek     "NONE", \
1203e457fe3SDavid van Moolenbroek     "WEAK", \
1213e457fe3SDavid van Moolenbroek     "COMMON", \
1223e457fe3SDavid van Moolenbroek     "EXTERNAL", \
1233e457fe3SDavid van Moolenbroek     "EXTERNAL_WEAK", \
1243e457fe3SDavid van Moolenbroek     "WEAK_POINTER", \
1253e457fe3SDavid van Moolenbroek     "PRIVATE"
1263e457fe3SDavid van Moolenbroek 
1273e457fe3SDavid van Moolenbroek typedef enum PassUtilPropE {
1283e457fe3SDavid van Moolenbroek     PASS_UTIL_PROP_NONE,
1293e457fe3SDavid van Moolenbroek     PASS_UTIL_PROP_NOINLINE,
1303e457fe3SDavid van Moolenbroek     PASS_UTIL_PROP_USED,
1313e457fe3SDavid van Moolenbroek     PASS_UTIL_PROP_PRESERVE,
1323e457fe3SDavid van Moolenbroek     __NUM_PASS_UTIL_PROPS
1333e457fe3SDavid van Moolenbroek } PassUtilProp;
1343e457fe3SDavid van Moolenbroek 
1353e457fe3SDavid van Moolenbroek #define PASS_UTIL_FLAG(F) (1 << F)
1363e457fe3SDavid van Moolenbroek 
1373e457fe3SDavid van Moolenbroek #define PASS_COMMON_INIT_ONCE() \
1383e457fe3SDavid van Moolenbroek     Module *PassUtil::M = NULL; \
1393e457fe3SDavid van Moolenbroek 
1403e457fe3SDavid van Moolenbroek using namespace llvm;
1413e457fe3SDavid van Moolenbroek 
1423e457fe3SDavid van Moolenbroek namespace llvm {
1433e457fe3SDavid van Moolenbroek 
1443e457fe3SDavid van Moolenbroek class PassUtil {
1453e457fe3SDavid van Moolenbroek   public:
1463e457fe3SDavid van Moolenbroek       static void writeTypeSymbolic(raw_string_ostream &OS, TYPECONST Type *type, const Module *M);
1473e457fe3SDavid van Moolenbroek       static const std::string getTypeDescription(TYPECONST Type* type);
148*bdb56518SDavid van Moolenbroek       static MDNode *findDbgGlobalDeclare(GlobalVariable *V);
149*bdb56518SDavid van Moolenbroek       static MDNode *findDbgSubprogramDeclare(const Function *F);
1503e457fe3SDavid van Moolenbroek       static void getDbgLocationInfoRelPath(const std::string &baseDir, const std::string &filename, const std::string &directory, std::string &relPath);
1513e457fe3SDavid van Moolenbroek       static void getDbgLocationInfo(DIDescriptor &DID, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath);
1523e457fe3SDavid van Moolenbroek       static bool getInstrDbgLocationInfo(Instruction *I, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath, unsigned int *lineNum, bool expand=true);
1533e457fe3SDavid van Moolenbroek       static unsigned getDbgSubrangeNumElements(const DISubrange &subrange);
1543e457fe3SDavid van Moolenbroek       static bool isDbgVectorTy(const DIType &type);
1553e457fe3SDavid van Moolenbroek       static DIType getDITypeDerivedFrom(const DIDerivedType &type);
156*bdb56518SDavid van Moolenbroek       static DIType getDITypeFromRef(const DITypeRef &ref);
1573e457fe3SDavid van Moolenbroek       static bool isOpaqueTy(TYPECONST Type *type);
158*bdb56518SDavid van Moolenbroek       static bool isPrimitiveTy(TYPECONST Type *type);
1593e457fe3SDavid van Moolenbroek       static Constant* getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes);
1603e457fe3SDavid van Moolenbroek       static GetElementPtrInst* createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr="", Instruction *InsertBefore=0);
1613e457fe3SDavid van Moolenbroek       static GetElementPtrInst* createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr="", BasicBlock *InsertAtEnd=0);
1623e457fe3SDavid van Moolenbroek       static CallInst* createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr="", Instruction *InsertBefore=0);
1633e457fe3SDavid van Moolenbroek       static CallInst* createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr="", BasicBlock *InsertAtEnd=0);
1643e457fe3SDavid van Moolenbroek       static Function* getIntrinsicFunction(Module &M, Intrinsic::ID id, TYPECONST Type** types=NULL, unsigned size=0);
1653e457fe3SDavid van Moolenbroek       static FunctionType* getFunctionType(TYPECONST Type* Result, std::vector<TYPECONST Type*> &argsTy, bool isVarArg=false);
1663e457fe3SDavid van Moolenbroek       static Function* setFunctionProperties(Function *F, unsigned long properties);
1673e457fe3SDavid van Moolenbroek       static Function* createFunctionWeakPtrWrapper(Module &M, StringRef Name, FunctionType *Ty);
1683e457fe3SDavid van Moolenbroek       static Function* getOrInsertFunction(Module &M, StringRef Name, FunctionType *Ty, PassUtilLinkageType insertLinkage, unsigned long properties);
1693e457fe3SDavid van Moolenbroek       static PassUtilLinkageType getFunctionPassUtilLinkageType(Function *F);
1703e457fe3SDavid van Moolenbroek       static std::string getPassUtilLinkageTypeString(PassUtilLinkageType linkageType);
1713e457fe3SDavid van Moolenbroek       static void getFunctionEntryExits(Function *F, BasicBlock **entryBlock, std::vector<BasicBlock*> *exitBlocks);
1723e457fe3SDavid van Moolenbroek       static bool isReturnedValue(Function *F, Value *V);
1733e457fe3SDavid van Moolenbroek       static CallSite getCallSiteFromInstruction(Instruction *I);
1743e457fe3SDavid van Moolenbroek       static CallSite getCallSiteFromUser(User *U);
1753e457fe3SDavid van Moolenbroek       static void getFunctionsInDirectBUCallgraph(Function* F, std::set<Function*> &funcs);
1763e457fe3SDavid van Moolenbroek       static void getAllocaInfo(Function *F, Instruction **allocaInsertionPoint, Instruction **firstNonAllocaInst);
1773e457fe3SDavid van Moolenbroek       static Constant* getStringConstantArray(Module &M, const std::string &string);
1783e457fe3SDavid van Moolenbroek       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);
1793e457fe3SDavid van Moolenbroek       static ATTRIBUTE_SET_TY remapCallSiteAttributes(CallSite &CS, int argOffset);
1803e457fe3SDavid van Moolenbroek       static void parseStringListOpt(std::vector<std::string> &vector, const std::string &string, const std::string &separator = ":");
1813e457fe3SDavid van Moolenbroek       static void parseStringPairListOpt(std::set<std::pair<std::string, std::string> > &set, const std::string &string, const std::string &listSeparator = ":", const std::string &pairSeparator = ";");
1823e457fe3SDavid van Moolenbroek       static void parseRegexListOpt(std::vector<Regex*> &list, const std::string &string);
1833e457fe3SDavid van Moolenbroek       static bool matchRegexes(std::string string, std::vector<Regex*> &regexes);
1843e457fe3SDavid van Moolenbroek       static void setModule(Module *M);
1853e457fe3SDavid van Moolenbroek       static void getModuleName(Module &M, std::string *fullName, std::string *dirName, std::string *baseName);
1863e457fe3SDavid van Moolenbroek       static unsigned long getTypeHash(TYPECONST Type* type, unsigned maxLevel=11);
1873e457fe3SDavid van Moolenbroek   private:
1883e457fe3SDavid van Moolenbroek       static Module *M;
1893e457fe3SDavid van Moolenbroek };
1903e457fe3SDavid van Moolenbroek 
writeTypeSymbolic(raw_string_ostream & OS,TYPECONST Type * type,const Module * M)1913e457fe3SDavid van Moolenbroek inline void PassUtil::writeTypeSymbolic(raw_string_ostream &OS, TYPECONST Type *type, const Module *M) {
1923e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
1933e457fe3SDavid van Moolenbroek     /* XXX Check. */
1943e457fe3SDavid van Moolenbroek     type->print(OS);
1953e457fe3SDavid van Moolenbroek     return;
1963e457fe3SDavid van Moolenbroek #else
1973e457fe3SDavid van Moolenbroek     return WriteTypeSymbolic(OS, type, M);
1983e457fe3SDavid van Moolenbroek #endif
1993e457fe3SDavid van Moolenbroek }
2003e457fe3SDavid van Moolenbroek 
getTypeDescription(TYPECONST Type * type)2013e457fe3SDavid van Moolenbroek inline const std::string PassUtil::getTypeDescription(TYPECONST Type* type) {
2023e457fe3SDavid van Moolenbroek     std::string string;
2033e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
2043e457fe3SDavid van Moolenbroek     /* XXX Check. */
2053e457fe3SDavid van Moolenbroek     raw_string_ostream ostream(string);
2063e457fe3SDavid van Moolenbroek     type->print(ostream);
2073e457fe3SDavid van Moolenbroek     ostream.flush();
2083e457fe3SDavid van Moolenbroek #else
2093e457fe3SDavid van Moolenbroek     string = type->getDescription();
2103e457fe3SDavid van Moolenbroek #endif
2113e457fe3SDavid van Moolenbroek 
2123e457fe3SDavid van Moolenbroek     return string;
2133e457fe3SDavid van Moolenbroek }
2143e457fe3SDavid van Moolenbroek 
findDbgGlobalDeclare(GlobalVariable * V)215*bdb56518SDavid van Moolenbroek inline MDNode *PassUtil::findDbgGlobalDeclare(GlobalVariable *V) {
2163e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
2173e457fe3SDavid van Moolenbroek   const Module *M = V->getParent();
2183e457fe3SDavid van Moolenbroek   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.cu");
2193e457fe3SDavid van Moolenbroek   if (!NMD)
2203e457fe3SDavid van Moolenbroek     return 0;
2213e457fe3SDavid van Moolenbroek 
2223e457fe3SDavid van Moolenbroek   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2233e457fe3SDavid van Moolenbroek       DICompileUnit CU(NMD->getOperand(i));
2243e457fe3SDavid van Moolenbroek       DIArray GVs = CU.getGlobalVariables();
2253e457fe3SDavid van Moolenbroek       for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) {
2263e457fe3SDavid van Moolenbroek         DIDescriptor DIG(GVs.getElement(i));
2273e457fe3SDavid van Moolenbroek         if (DIGlobalVariable(DIG).getGlobal() == V)
2283e457fe3SDavid van Moolenbroek           return DIG;
2293e457fe3SDavid van Moolenbroek       }
2303e457fe3SDavid van Moolenbroek   }
2313e457fe3SDavid van Moolenbroek   return 0;
2323e457fe3SDavid van Moolenbroek #else
2333e457fe3SDavid van Moolenbroek   const Module *M = V->getParent();
2343e457fe3SDavid van Moolenbroek   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
2353e457fe3SDavid van Moolenbroek   if (!NMD)
2363e457fe3SDavid van Moolenbroek     return 0;
2373e457fe3SDavid van Moolenbroek 
2383e457fe3SDavid van Moolenbroek   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2393e457fe3SDavid van Moolenbroek     DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
2403e457fe3SDavid van Moolenbroek     if (!DIG.isGlobalVariable())
2413e457fe3SDavid van Moolenbroek       continue;
2423e457fe3SDavid van Moolenbroek     if (DIGlobalVariable(DIG).getGlobal() == V)
2433e457fe3SDavid van Moolenbroek       return DIG;
2443e457fe3SDavid van Moolenbroek   }
2453e457fe3SDavid van Moolenbroek   return 0;
2463e457fe3SDavid van Moolenbroek #endif
2473e457fe3SDavid van Moolenbroek }
2483e457fe3SDavid van Moolenbroek 
findDbgSubprogramDeclare(const Function * V)249*bdb56518SDavid van Moolenbroek inline MDNode *PassUtil::findDbgSubprogramDeclare(const Function *V) {
2503e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
2513e457fe3SDavid van Moolenbroek   const Module *M = V->getParent();
2523e457fe3SDavid van Moolenbroek   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.cu");
2533e457fe3SDavid van Moolenbroek   if (!NMD)
2543e457fe3SDavid van Moolenbroek     return 0;
2553e457fe3SDavid van Moolenbroek 
2563e457fe3SDavid van Moolenbroek   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2573e457fe3SDavid van Moolenbroek       DICompileUnit CU(NMD->getOperand(i));
2583e457fe3SDavid van Moolenbroek       DIArray SPs = CU.getSubprograms();
2593e457fe3SDavid van Moolenbroek       for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
2603e457fe3SDavid van Moolenbroek            DISubprogram DIS(SPs.getElement(i));
2613e457fe3SDavid van Moolenbroek            if (DIS.getFunction() == V) {
2623e457fe3SDavid van Moolenbroek            	return DIS;
2633e457fe3SDavid van Moolenbroek            }
2643e457fe3SDavid van Moolenbroek       }
2653e457fe3SDavid van Moolenbroek   }
2663e457fe3SDavid van Moolenbroek   return 0;
2673e457fe3SDavid van Moolenbroek #else
2683e457fe3SDavid van Moolenbroek   const Module *M = V->getParent();
2693e457fe3SDavid van Moolenbroek   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp");
2703e457fe3SDavid van Moolenbroek   if (!NMD)
2713e457fe3SDavid van Moolenbroek     return 0;
2723e457fe3SDavid van Moolenbroek 
2733e457fe3SDavid van Moolenbroek   for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2743e457fe3SDavid van Moolenbroek     DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
2753e457fe3SDavid van Moolenbroek     if (!DIG.isSubprogram())
2763e457fe3SDavid van Moolenbroek       continue;
2773e457fe3SDavid van Moolenbroek     if (DISubprogram(DIG).getFunction() == V)
2783e457fe3SDavid van Moolenbroek       return DIG;
2793e457fe3SDavid van Moolenbroek   }
2803e457fe3SDavid van Moolenbroek   return 0;
2813e457fe3SDavid van Moolenbroek #endif
2823e457fe3SDavid van Moolenbroek }
2833e457fe3SDavid van Moolenbroek 
getDbgLocationInfoRelPath(const std::string & baseDir,const std::string & filename,const std::string & directory,std::string & relPath)2843e457fe3SDavid van Moolenbroek inline void PassUtil::getDbgLocationInfoRelPath(const std::string &baseDir, const std::string &filename, const std::string &directory, std::string &relPath) {
2853e457fe3SDavid van Moolenbroek     StringRef directoryRef(directory);
2863e457fe3SDavid van Moolenbroek     std::pair<StringRef, StringRef> stringPair = directoryRef.split(baseDir);
2873e457fe3SDavid van Moolenbroek     relPath = (stringPair.second.compare("") ? stringPair.second.str() : stringPair.first.str()) + "/" + filename;
2883e457fe3SDavid van Moolenbroek #if DEBUG_LLVM_DEBUG_API
2893e457fe3SDavid van Moolenbroek     errs() << " - getDbgLocationInfoRelPath: Location Info is: " << directory << " | " << filename << " | " << relPath << "\n";
2903e457fe3SDavid van Moolenbroek #endif
2913e457fe3SDavid van Moolenbroek }
2923e457fe3SDavid van Moolenbroek 
getDbgLocationInfo(DIDescriptor & DID,const std::string & baseDir,std::string * filename,std::string * directory,std::string * relPath)2933e457fe3SDavid van Moolenbroek inline void PassUtil::getDbgLocationInfo(DIDescriptor &DID, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath) {
2943e457fe3SDavid van Moolenbroek   StringRef _directory;
2953e457fe3SDavid van Moolenbroek   StringRef _filename;
2963e457fe3SDavid van Moolenbroek   if (DID.isGlobalVariable()) {
2973e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
2983e457fe3SDavid van Moolenbroek     _directory = ((DIGlobalVariable*)&DID)->getDirectory();
2993e457fe3SDavid van Moolenbroek     _filename = ((DIGlobalVariable*)&DID)->getFilename();
3003e457fe3SDavid van Moolenbroek #else
3013e457fe3SDavid van Moolenbroek     _directory = ((DIGlobalVariable*)&DID)->getCompileUnit().getDirectory();
3023e457fe3SDavid van Moolenbroek     _filename = ((DIGlobalVariable*)&DID)->getCompileUnit().getFilename();
3033e457fe3SDavid van Moolenbroek #endif
3043e457fe3SDavid van Moolenbroek #if DEBUG_LLVM_DEBUG_API
3053e457fe3SDavid van Moolenbroek     errs() << "DIGlobalVariable name is: " << ((DIGlobalVariable*)&DID)->getName() << "\n";
3063e457fe3SDavid van Moolenbroek #endif
3073e457fe3SDavid van Moolenbroek   }
3083e457fe3SDavid van Moolenbroek   else if (DID.isSubprogram()) {
3093e457fe3SDavid van Moolenbroek     _directory = ((DISubprogram*)&DID)->getDirectory();
3103e457fe3SDavid van Moolenbroek     _filename = ((DISubprogram*)&DID)->getFilename();
3113e457fe3SDavid van Moolenbroek #if DEBUG_LLVM_DEBUG_API
3123e457fe3SDavid van Moolenbroek     errs() << "DISubprogram name is: " << ((DISubprogram*)&DID)->getName() << "\n";
3133e457fe3SDavid van Moolenbroek #endif
3143e457fe3SDavid van Moolenbroek   }
3153e457fe3SDavid van Moolenbroek   else {
3163e457fe3SDavid van Moolenbroek     DIScope DIS;
3173e457fe3SDavid van Moolenbroek     assert (DID.isVariable());
3183e457fe3SDavid van Moolenbroek     DIS = ((DIVariable*)&DID)->getContext();
3193e457fe3SDavid van Moolenbroek     if (DIS.isSubprogram()) {
3203e457fe3SDavid van Moolenbroek         _directory = ((DISubprogram*)&DIS)->getDirectory();
3213e457fe3SDavid van Moolenbroek         _filename = ((DISubprogram*)&DIS)->getFilename();
3223e457fe3SDavid van Moolenbroek #if DEBUG_LLVM_DEBUG_API
3233e457fe3SDavid van Moolenbroek         errs() << "DIVariable (SP) name is: " << ((DIVariable*)&DID)->getName() << "\n";
3243e457fe3SDavid van Moolenbroek #endif
3253e457fe3SDavid van Moolenbroek     }
3263e457fe3SDavid van Moolenbroek     else if (DIS.isLexicalBlock()) {
3273e457fe3SDavid van Moolenbroek         _directory = ((DILexicalBlock*)&DIS)->getDirectory();
3283e457fe3SDavid van Moolenbroek         _filename = ((DILexicalBlock*)&DIS)->getFilename();
3293e457fe3SDavid van Moolenbroek #if DEBUG_LLVM_DEBUG_API
3303e457fe3SDavid van Moolenbroek         errs() << "DIVariable (LB) name is: " << ((DIVariable*)&DID)->getName() << "\n";
3313e457fe3SDavid van Moolenbroek #endif
3323e457fe3SDavid van Moolenbroek     }
3333e457fe3SDavid van Moolenbroek     else {
3343e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
3353e457fe3SDavid van Moolenbroek         assert(DIS.isLexicalBlockFile());
3363e457fe3SDavid van Moolenbroek         _directory = ((DILexicalBlockFile*)&DIS)->getDirectory();
3373e457fe3SDavid van Moolenbroek         _filename = ((DILexicalBlockFile*)&DIS)->getFilename();
3383e457fe3SDavid van Moolenbroek #if DEBUG_LLVM_DEBUG_API
3393e457fe3SDavid van Moolenbroek         errs() << "DIVariable (LBF) name is: " << ((DIVariable*)&DID)->getName() << "\n";
3403e457fe3SDavid van Moolenbroek #endif
3413e457fe3SDavid van Moolenbroek #else
3423e457fe3SDavid van Moolenbroek 	assert(0 && "Unexpected DIScope instance!");
3433e457fe3SDavid van Moolenbroek #endif
3443e457fe3SDavid van Moolenbroek     }
3453e457fe3SDavid van Moolenbroek   }
3463e457fe3SDavid van Moolenbroek   if (filename) {
3473e457fe3SDavid van Moolenbroek     *filename = _filename;
3483e457fe3SDavid van Moolenbroek   }
3493e457fe3SDavid van Moolenbroek   if (directory) {
3503e457fe3SDavid van Moolenbroek     *directory = _directory;
3513e457fe3SDavid van Moolenbroek   }
3523e457fe3SDavid van Moolenbroek   if (relPath) {
3533e457fe3SDavid van Moolenbroek     getDbgLocationInfoRelPath(baseDir, _filename, _directory, *relPath);
3543e457fe3SDavid van Moolenbroek   }
3553e457fe3SDavid van Moolenbroek }
3563e457fe3SDavid van Moolenbroek 
getInstrDbgLocationInfo(Instruction * I,const std::string & baseDir,std::string * filename,std::string * directory,std::string * relPath,unsigned int * lineNum,bool expand)3573e457fe3SDavid van Moolenbroek inline bool PassUtil::getInstrDbgLocationInfo(Instruction *I, const std::string &baseDir, std::string *filename, std::string *directory, std::string *relPath, unsigned int *lineNum, bool expand) {
3583e457fe3SDavid van Moolenbroek     BasicBlock::iterator BI = I;
3593e457fe3SDavid van Moolenbroek     MDNode *N = BI->getMetadata("dbg");
3603e457fe3SDavid van Moolenbroek     if (!N && !expand) {
3613e457fe3SDavid van Moolenbroek         return false;
3623e457fe3SDavid van Moolenbroek     }
3633e457fe3SDavid van Moolenbroek     while(!N) {
3643e457fe3SDavid van Moolenbroek         if (BI->isTerminator()) {
3653e457fe3SDavid van Moolenbroek             BranchInst *BInst = dyn_cast<BranchInst>(BI);
3663e457fe3SDavid van Moolenbroek             if (BInst && BInst->isUnconditional()) {
3673e457fe3SDavid van Moolenbroek                 BI = BInst->getSuccessor(0)->front();
3683e457fe3SDavid van Moolenbroek                 N = BI->getMetadata("dbg");
3693e457fe3SDavid van Moolenbroek                 continue;
3703e457fe3SDavid van Moolenbroek             }
3713e457fe3SDavid van Moolenbroek             return false;
3723e457fe3SDavid van Moolenbroek         }
3733e457fe3SDavid van Moolenbroek         BI++;
3743e457fe3SDavid van Moolenbroek         N = BI->getMetadata("dbg");
3753e457fe3SDavid van Moolenbroek     }
3763e457fe3SDavid van Moolenbroek 
3773e457fe3SDavid van Moolenbroek     DILocation DIL(N);
3783e457fe3SDavid van Moolenbroek     StringRef _directory = DIL.getDirectory();
3793e457fe3SDavid van Moolenbroek     StringRef _filename = DIL.getFilename();
3803e457fe3SDavid van Moolenbroek     if (filename) {
3813e457fe3SDavid van Moolenbroek         *filename = _filename;
3823e457fe3SDavid van Moolenbroek     }
3833e457fe3SDavid van Moolenbroek     if (directory) {
3843e457fe3SDavid van Moolenbroek         *directory = _directory;
3853e457fe3SDavid van Moolenbroek     }
3863e457fe3SDavid van Moolenbroek     if (relPath) {
3873e457fe3SDavid van Moolenbroek       getDbgLocationInfoRelPath(baseDir, _filename, _directory, *relPath);
3883e457fe3SDavid van Moolenbroek     }
3893e457fe3SDavid van Moolenbroek     if (lineNum) {
3903e457fe3SDavid van Moolenbroek         *lineNum = DIL.getLineNumber();
3913e457fe3SDavid van Moolenbroek     }
3923e457fe3SDavid van Moolenbroek 
3933e457fe3SDavid van Moolenbroek     return true;
3943e457fe3SDavid van Moolenbroek }
3953e457fe3SDavid van Moolenbroek 
getDbgSubrangeNumElements(const DISubrange & subrange)3963e457fe3SDavid van Moolenbroek inline unsigned PassUtil::getDbgSubrangeNumElements(const DISubrange &subrange) {
3973e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 33
3983e457fe3SDavid van Moolenbroek     const unsigned numElements = (unsigned) subrange.getCount();
3993e457fe3SDavid van Moolenbroek #else
4003e457fe3SDavid van Moolenbroek     const unsigned low = (unsigned) subrange.getLo();
4013e457fe3SDavid van Moolenbroek     const unsigned high = (unsigned) subrange.getHi();
4023e457fe3SDavid van Moolenbroek     const unsigned numElements = high - low + 1;
4033e457fe3SDavid van Moolenbroek #endif
4043e457fe3SDavid van Moolenbroek 
4053e457fe3SDavid van Moolenbroek     return numElements;
4063e457fe3SDavid van Moolenbroek }
4073e457fe3SDavid van Moolenbroek 
isDbgVectorTy(const DIType & type)4083e457fe3SDavid van Moolenbroek inline bool PassUtil::isDbgVectorTy(const DIType &type) {
4093e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 33
4103e457fe3SDavid van Moolenbroek     return type.isVector();
4113e457fe3SDavid van Moolenbroek #else
4123e457fe3SDavid van Moolenbroek     return type.getTag() == dwarf::DW_TAG_vector_type;
4133e457fe3SDavid van Moolenbroek #endif
4143e457fe3SDavid van Moolenbroek }
4153e457fe3SDavid van Moolenbroek 
getDITypeDerivedFrom(const DIDerivedType & type)4163e457fe3SDavid van Moolenbroek inline DIType PassUtil::getDITypeDerivedFrom(const DIDerivedType &type) {
4173e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 34
4183e457fe3SDavid van Moolenbroek     static DITypeIdentifierMap TypeIdentifierMap;
4193e457fe3SDavid van Moolenbroek     static bool TypeMapInitialized = false;
4203e457fe3SDavid van Moolenbroek     if (!TypeMapInitialized) {
4213e457fe3SDavid van Moolenbroek         assert(PassUtil::M && "Set module first!");
4223e457fe3SDavid van Moolenbroek         if (NamedMDNode *CU_Nodes = PassUtil::M->getNamedMetadata("llvm.dbg.cu")) {
4233e457fe3SDavid van Moolenbroek           TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
4243e457fe3SDavid van Moolenbroek           TypeMapInitialized = true;
4253e457fe3SDavid van Moolenbroek         }
4263e457fe3SDavid van Moolenbroek     }
4273e457fe3SDavid van Moolenbroek     return type.getTypeDerivedFrom().resolve(TypeIdentifierMap);
4283e457fe3SDavid van Moolenbroek #else
4293e457fe3SDavid van Moolenbroek     return type.getTypeDerivedFrom();
4303e457fe3SDavid van Moolenbroek #endif
4313e457fe3SDavid van Moolenbroek }
4323e457fe3SDavid van Moolenbroek 
getDITypeFromRef(const DITypeRef & ref)433*bdb56518SDavid van Moolenbroek inline DIType PassUtil::getDITypeFromRef(const DITypeRef &ref) {
434*bdb56518SDavid van Moolenbroek     static DITypeIdentifierMap TypeIdentifierMap;
435*bdb56518SDavid van Moolenbroek     static bool TypeMapInitialized = false;
436*bdb56518SDavid van Moolenbroek     if (!TypeMapInitialized) {
437*bdb56518SDavid van Moolenbroek         /* TODO: generate the type identifier map only once! */
438*bdb56518SDavid van Moolenbroek         assert(PassUtil::M && "Set module first!");
439*bdb56518SDavid van Moolenbroek         if (NamedMDNode *CU_Nodes = PassUtil::M->getNamedMetadata("llvm.dbg.cu")) {
440*bdb56518SDavid van Moolenbroek           TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
441*bdb56518SDavid van Moolenbroek           TypeMapInitialized = true;
442*bdb56518SDavid van Moolenbroek         }
443*bdb56518SDavid van Moolenbroek     }
444*bdb56518SDavid van Moolenbroek     return ref.resolve(TypeIdentifierMap);
445*bdb56518SDavid van Moolenbroek }
446*bdb56518SDavid van Moolenbroek 
isOpaqueTy(TYPECONST Type * type)4473e457fe3SDavid van Moolenbroek inline bool PassUtil::isOpaqueTy(TYPECONST Type *type) {
4483e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
4493e457fe3SDavid van Moolenbroek     return type->isStructTy() && (((TYPECONST StructType*)type)->isOpaque() || type->getNumContainedTypes() == 0);
4503e457fe3SDavid van Moolenbroek #else
4513e457fe3SDavid van Moolenbroek     return type->isOpaqueTy();
4523e457fe3SDavid van Moolenbroek #endif
4533e457fe3SDavid van Moolenbroek }
4543e457fe3SDavid van Moolenbroek 
isPrimitiveTy(TYPECONST Type * type)455*bdb56518SDavid van Moolenbroek inline bool PassUtil::isPrimitiveTy(TYPECONST Type *type) {
456*bdb56518SDavid van Moolenbroek     return type->isVoidTy() || type->isFloatingPointTy() || type->isLabelTy() || type->isMetadataTy() || type->isX86_MMXTy();
457*bdb56518SDavid van Moolenbroek }
458*bdb56518SDavid van Moolenbroek 
getGetElementPtrConstant(Constant * constant,std::vector<Value * > & indexes)4593e457fe3SDavid van Moolenbroek inline Constant* PassUtil::getGetElementPtrConstant(Constant *constant, std::vector<Value*> &indexes) {
4603e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
4613e457fe3SDavid van Moolenbroek     ArrayRef<Value*> ref(indexes);
4623e457fe3SDavid van Moolenbroek     return ConstantExpr::getGetElementPtr(constant, ref);
4633e457fe3SDavid van Moolenbroek #else
4643e457fe3SDavid van Moolenbroek     return ConstantExpr::getGetElementPtr(constant, &indexes[0], indexes.size());
4653e457fe3SDavid van Moolenbroek #endif
4663e457fe3SDavid van Moolenbroek }
4673e457fe3SDavid van Moolenbroek 
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,Instruction * InsertBefore)4683e457fe3SDavid van Moolenbroek inline GetElementPtrInst* PassUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, Instruction *InsertBefore) {
4693e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
4703e457fe3SDavid van Moolenbroek     ArrayRef<Value*> ref(indexes);
4713e457fe3SDavid van Moolenbroek     return GetElementPtrInst::Create(ptr, ref, NameStr, InsertBefore);
4723e457fe3SDavid van Moolenbroek #else
4733e457fe3SDavid van Moolenbroek     return GetElementPtrInst::Create(ptr, indexes.begin(), indexes.end(), NameStr, InsertBefore);
4743e457fe3SDavid van Moolenbroek #endif
4753e457fe3SDavid van Moolenbroek }
4763e457fe3SDavid van Moolenbroek 
createGetElementPtrInstruction(Value * ptr,std::vector<Value * > & indexes,const Twine & NameStr,BasicBlock * InsertAtEnd)4773e457fe3SDavid van Moolenbroek inline GetElementPtrInst* PassUtil::createGetElementPtrInstruction(Value *ptr, std::vector<Value*> &indexes, const Twine &NameStr, BasicBlock *InsertAtEnd) {
4783e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
4793e457fe3SDavid van Moolenbroek     ArrayRef<Value*> ref(indexes);
4803e457fe3SDavid van Moolenbroek     return GetElementPtrInst::Create(ptr, ref, NameStr, InsertAtEnd);
4813e457fe3SDavid van Moolenbroek #else
4823e457fe3SDavid van Moolenbroek     return GetElementPtrInst::Create(ptr, indexes.begin(), indexes.end(), NameStr, InsertAtEnd);
4833e457fe3SDavid van Moolenbroek #endif
4843e457fe3SDavid van Moolenbroek }
4853e457fe3SDavid van Moolenbroek 
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,Instruction * InsertBefore)4863e457fe3SDavid van Moolenbroek inline CallInst* PassUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, Instruction *InsertBefore) {
4873e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
4883e457fe3SDavid van Moolenbroek     ArrayRef<Value*> ref(args);
4893e457fe3SDavid van Moolenbroek     return CallInst::Create(F, ref, NameStr, InsertBefore);
4903e457fe3SDavid van Moolenbroek #else
4913e457fe3SDavid van Moolenbroek     return CallInst::Create(F, args.begin(), args.end(), NameStr, InsertBefore);
4923e457fe3SDavid van Moolenbroek #endif
4933e457fe3SDavid van Moolenbroek }
4943e457fe3SDavid van Moolenbroek 
createCallInstruction(Value * F,std::vector<Value * > & args,const Twine & NameStr,BasicBlock * InsertAtEnd)4953e457fe3SDavid van Moolenbroek inline CallInst* PassUtil::createCallInstruction(Value *F, std::vector<Value*> &args, const Twine &NameStr, BasicBlock *InsertAtEnd) {
4963e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
4973e457fe3SDavid van Moolenbroek     ArrayRef<Value*> ref(args);
4983e457fe3SDavid van Moolenbroek     return CallInst::Create(F, ref, NameStr, InsertAtEnd);
4993e457fe3SDavid van Moolenbroek #else
5003e457fe3SDavid van Moolenbroek     return CallInst::Create(F, args.begin(), args.end(), NameStr, InsertAtEnd);
5013e457fe3SDavid van Moolenbroek #endif
5023e457fe3SDavid van Moolenbroek }
5033e457fe3SDavid van Moolenbroek 
getIntrinsicFunction(Module & M,Intrinsic::ID id,TYPECONST Type ** types,unsigned size)5043e457fe3SDavid van Moolenbroek inline Function* PassUtil::getIntrinsicFunction(Module &M, Intrinsic::ID id, TYPECONST Type** types, unsigned size) {
5053e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
5063e457fe3SDavid van Moolenbroek     std::vector<TYPECONST Type*> typeVector;
5073e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<size;i++) {
5083e457fe3SDavid van Moolenbroek         typeVector.push_back(types[i]);
5093e457fe3SDavid van Moolenbroek     }
5103e457fe3SDavid van Moolenbroek     ArrayRef<TYPECONST Type*> ref(typeVector);
5113e457fe3SDavid van Moolenbroek     return Intrinsic::getDeclaration(&M, id, ref);
5123e457fe3SDavid van Moolenbroek #else
5133e457fe3SDavid van Moolenbroek     return Intrinsic::getDeclaration(&M, id, types, size);
5143e457fe3SDavid van Moolenbroek #endif
5153e457fe3SDavid van Moolenbroek }
5163e457fe3SDavid van Moolenbroek 
getFunctionType(TYPECONST Type * Result,std::vector<TYPECONST Type * > & argsTy,bool isVarArg)5173e457fe3SDavid van Moolenbroek inline FunctionType* PassUtil::getFunctionType(TYPECONST Type* Result, std::vector<TYPECONST Type*> &argsTy, bool isVarArg)
5183e457fe3SDavid van Moolenbroek {
5193e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 30
5203e457fe3SDavid van Moolenbroek     ArrayRef<TYPECONST Type*> ref(argsTy);
5213e457fe3SDavid van Moolenbroek     return FunctionType::get(Result, ref, isVarArg);
5223e457fe3SDavid van Moolenbroek #else
5233e457fe3SDavid van Moolenbroek     return FunctionType::get(Result, argsTy, isVarArg);
5243e457fe3SDavid van Moolenbroek #endif
5253e457fe3SDavid van Moolenbroek }
5263e457fe3SDavid van Moolenbroek 
setFunctionProperties(Function * F,unsigned long props)5273e457fe3SDavid van Moolenbroek inline Function* PassUtil::setFunctionProperties(Function *F, unsigned long props)
5283e457fe3SDavid van Moolenbroek {
5293e457fe3SDavid van Moolenbroek     assert(F);
5303e457fe3SDavid van Moolenbroek     bool preserve = props & (PASS_UTIL_FLAG(PASS_UTIL_PROP_NOINLINE)|PASS_UTIL_FLAG(PASS_UTIL_PROP_USED)|PASS_UTIL_FLAG(PASS_UTIL_PROP_PRESERVE));
5313e457fe3SDavid van Moolenbroek 
5323e457fe3SDavid van Moolenbroek     if (F->isDeclaration()) {
5333e457fe3SDavid van Moolenbroek         return F;
5343e457fe3SDavid van Moolenbroek     }
5353e457fe3SDavid van Moolenbroek     if (preserve) {
5363e457fe3SDavid van Moolenbroek         Instruction *I;
5373e457fe3SDavid van Moolenbroek         getAllocaInfo(F, NULL, &I);
5383e457fe3SDavid van Moolenbroek         assert(I);
5393e457fe3SDavid van Moolenbroek 
5403e457fe3SDavid van Moolenbroek         /* Add a volatile store to a new global variable to preserve it. */
5413e457fe3SDavid van Moolenbroek         PointerType* voidPointerTy = PointerType::get(IntegerType::get(F->getContext(), 8), 0);
5423e457fe3SDavid van Moolenbroek         GlobalVariable* volatileVar = new GlobalVariable(*F->getParent(),
5433e457fe3SDavid van Moolenbroek             voidPointerTy, false, GlobalValue::CommonLinkage,
5443e457fe3SDavid van Moolenbroek             0, F->getName() + "_llvm_propvar");
5453e457fe3SDavid van Moolenbroek         volatileVar->setInitializer(ConstantPointerNull::get(voidPointerTy));
5463e457fe3SDavid van Moolenbroek         new StoreInst(ConstantExpr::getCast(Instruction::BitCast, F, voidPointerTy), volatileVar, true, I);
5473e457fe3SDavid van Moolenbroek     }
5483e457fe3SDavid van Moolenbroek     return F;
5493e457fe3SDavid van Moolenbroek }
5503e457fe3SDavid van Moolenbroek 
createFunctionWeakPtrWrapper(Module & M,StringRef Name,FunctionType * Ty)5513e457fe3SDavid van Moolenbroek inline Function* PassUtil::createFunctionWeakPtrWrapper(Module &M, StringRef Name, FunctionType *Ty)
5523e457fe3SDavid van Moolenbroek {
5533e457fe3SDavid van Moolenbroek     unsigned i;
5543e457fe3SDavid van Moolenbroek     Function *F = getOrInsertFunction(M, Name.str() + "_llvm_weakptrwrapper" , Ty, PASS_UTIL_LINKAGE_COMMON, 0);
5553e457fe3SDavid van Moolenbroek     TYPECONST Type *RetTy = Ty->getReturnType();
5563e457fe3SDavid van Moolenbroek     PointerType *FPtrTy = PointerType::get(Ty, 0);
5573e457fe3SDavid van Moolenbroek     Constant *FPtrNull = Constant::getNullValue(FPtrTy);
5583e457fe3SDavid van Moolenbroek 
5593e457fe3SDavid van Moolenbroek     /* Create the global function pointer variable. */
5603e457fe3SDavid van Moolenbroek     GlobalVariable* weakPtrVar = new GlobalVariable(M, FPtrTy, false,
5613e457fe3SDavid van Moolenbroek         GlobalValue::CommonLinkage, 0, Name);
5623e457fe3SDavid van Moolenbroek     weakPtrVar->setInitializer(FPtrNull);
5633e457fe3SDavid van Moolenbroek 
5643e457fe3SDavid van Moolenbroek     /* Create the wrapper function body. */
5653e457fe3SDavid van Moolenbroek     F->dropAllReferences();
5663e457fe3SDavid van Moolenbroek     BasicBlock* entryBB = BasicBlock::Create(M.getContext(), "entry",F,0);
5673e457fe3SDavid van Moolenbroek     BasicBlock* weakPtrOverridenBB = BasicBlock::Create(M.getContext(), "have." + Name.str(),F,0);
5683e457fe3SDavid van Moolenbroek     BasicBlock* endBB = BasicBlock::Create(M.getContext(), "end",F,0);
5693e457fe3SDavid van Moolenbroek     AllocaInst* retval = NULL;
5703e457fe3SDavid van Moolenbroek 
5713e457fe3SDavid van Moolenbroek     /* Parse arguments. */
5723e457fe3SDavid van Moolenbroek     std::vector<AllocaInst*> argsAllocaInsts;
5733e457fe3SDavid van Moolenbroek     for (Function::arg_iterator args = F->arg_begin(); args != F->arg_end(); args++) {
5743e457fe3SDavid van Moolenbroek         Value *argValue = args;
5753e457fe3SDavid van Moolenbroek         AllocaInst *allocaInst = new AllocaInst(argValue->getType(), ".llvm.pu.args", entryBB);
5763e457fe3SDavid van Moolenbroek         argsAllocaInsts.push_back(allocaInst);
5773e457fe3SDavid van Moolenbroek     }
5783e457fe3SDavid van Moolenbroek     if (!RetTy->isVoidTy()) {
5793e457fe3SDavid van Moolenbroek         retval = new AllocaInst(RetTy, "retval", entryBB);
5803e457fe3SDavid van Moolenbroek     }
5813e457fe3SDavid van Moolenbroek     i=0;
5823e457fe3SDavid van Moolenbroek     for (Function::arg_iterator args = F->arg_begin(); args != F->arg_end(); args++, i++) {
5833e457fe3SDavid van Moolenbroek         Value *argValue = args;
5843e457fe3SDavid van Moolenbroek         AllocaInst *allocaInst = argsAllocaInsts[i];
5853e457fe3SDavid van Moolenbroek         new StoreInst(argValue, allocaInst, true, entryBB);
5863e457fe3SDavid van Moolenbroek     }
5873e457fe3SDavid van Moolenbroek     if (retval) {
5883e457fe3SDavid van Moolenbroek         new StoreInst(Constant::getNullValue(RetTy), retval, true, entryBB);
5893e457fe3SDavid van Moolenbroek     }
5903e457fe3SDavid van Moolenbroek 
5913e457fe3SDavid van Moolenbroek     /* Build entry block. */
5923e457fe3SDavid van Moolenbroek     LoadInst* weakPtr = new LoadInst(weakPtrVar, "", true, entryBB);
5933e457fe3SDavid van Moolenbroek     ICmpInst* cmpInst = new ICmpInst(*entryBB, ICmpInst::ICMP_NE, weakPtr, FPtrNull, "");
5943e457fe3SDavid van Moolenbroek     BranchInst::Create(weakPtrOverridenBB, endBB, cmpInst, entryBB);
5953e457fe3SDavid van Moolenbroek 
5963e457fe3SDavid van Moolenbroek     /* Build weakPtrOverriden block, only executed with a non-NULL weakPtr */
5973e457fe3SDavid van Moolenbroek     std::vector<Value*> weakPtrCallParams;
5983e457fe3SDavid van Moolenbroek     i=0;
5993e457fe3SDavid van Moolenbroek     for (Function::arg_iterator args = F->arg_begin(); args != F->arg_end(); args++, i++) {
6003e457fe3SDavid van Moolenbroek         AllocaInst *allocaInst = argsAllocaInsts[i];
6013e457fe3SDavid van Moolenbroek         weakPtrCallParams.push_back(new LoadInst(allocaInst, "", true, weakPtrOverridenBB));
6023e457fe3SDavid van Moolenbroek     }
6033e457fe3SDavid van Moolenbroek     weakPtr = new LoadInst(weakPtrVar, "", true, weakPtrOverridenBB);
6043e457fe3SDavid van Moolenbroek     CallInst* weakPtrCall = createCallInstruction(weakPtr, weakPtrCallParams, "", weakPtrOverridenBB);
6053e457fe3SDavid van Moolenbroek     weakPtrCall->setCallingConv(CallingConv::C);
6063e457fe3SDavid van Moolenbroek 
6073e457fe3SDavid van Moolenbroek     if (retval) {
6083e457fe3SDavid van Moolenbroek         new StoreInst(weakPtrCall, retval, false, weakPtrOverridenBB);
6093e457fe3SDavid van Moolenbroek     }
6103e457fe3SDavid van Moolenbroek     BranchInst::Create(endBB, weakPtrOverridenBB);
6113e457fe3SDavid van Moolenbroek 
6123e457fe3SDavid van Moolenbroek     /* Build end block. */
6133e457fe3SDavid van Moolenbroek     if (!retval) {
6143e457fe3SDavid van Moolenbroek         ReturnInst::Create(M.getContext(), endBB);
6153e457fe3SDavid van Moolenbroek     }
6163e457fe3SDavid van Moolenbroek     else {
6173e457fe3SDavid van Moolenbroek         LoadInst* retvalValue = new LoadInst(retval, "", false, endBB);
6183e457fe3SDavid van Moolenbroek         ReturnInst::Create(M.getContext(), retvalValue, endBB);
6193e457fe3SDavid van Moolenbroek     }
6203e457fe3SDavid van Moolenbroek     return F;
6213e457fe3SDavid van Moolenbroek }
6223e457fe3SDavid van Moolenbroek 
getOrInsertFunction(Module & M,StringRef Name,FunctionType * Ty,PassUtilLinkageType insertLinkage,unsigned long properties)6233e457fe3SDavid van Moolenbroek inline Function* PassUtil::getOrInsertFunction(Module &M, StringRef Name, FunctionType *Ty, PassUtilLinkageType insertLinkage, unsigned long properties)
6243e457fe3SDavid van Moolenbroek {
6253e457fe3SDavid van Moolenbroek     static std::map<std::string, Function *> functionMap;
6263e457fe3SDavid van Moolenbroek     std::map<std::string, Function *>::iterator functionMapIt;
6273e457fe3SDavid van Moolenbroek     Function *F = NULL;
6283e457fe3SDavid van Moolenbroek     bool needsEmptyBody = true;
6293e457fe3SDavid van Moolenbroek     bool needsProperties = true;
6303e457fe3SDavid van Moolenbroek     bool needsIncludsion = true;
6313e457fe3SDavid van Moolenbroek 
6323e457fe3SDavid van Moolenbroek     functionMapIt = functionMap.find(Name);
6333e457fe3SDavid van Moolenbroek     if (functionMapIt != functionMap.end()) {
6343e457fe3SDavid van Moolenbroek         return functionMapIt->second;
6353e457fe3SDavid van Moolenbroek     }
6363e457fe3SDavid van Moolenbroek     F = M.getFunction(Name);
6373e457fe3SDavid van Moolenbroek 
6383e457fe3SDavid van Moolenbroek     if (F) {
6393e457fe3SDavid van Moolenbroek         /* If the function exists, check the type and return it. */
6403e457fe3SDavid van Moolenbroek         if (F->getFunctionType() != Ty) {
6413e457fe3SDavid van Moolenbroek             return NULL;
6423e457fe3SDavid van Moolenbroek         }
6433e457fe3SDavid van Moolenbroek         functionMap.insert(std::pair<std::string, Function *>(Name, F));
6443e457fe3SDavid van Moolenbroek         setFunctionProperties(F, properties);
6453e457fe3SDavid van Moolenbroek         return F;
6463e457fe3SDavid van Moolenbroek     }
6473e457fe3SDavid van Moolenbroek 
6483e457fe3SDavid van Moolenbroek     /* Has the user requested creation of the function otherwise? */
6493e457fe3SDavid van Moolenbroek     if (insertLinkage == PASS_UTIL_LINKAGE_NONE) {
6503e457fe3SDavid van Moolenbroek         return NULL;
6513e457fe3SDavid van Moolenbroek     }
6523e457fe3SDavid van Moolenbroek     switch(insertLinkage) {
6533e457fe3SDavid van Moolenbroek     case PASS_UTIL_LINKAGE_WEAK:
6543e457fe3SDavid van Moolenbroek         /* Create empty function that can optionally be overriden at link time*/
6553e457fe3SDavid van Moolenbroek         F = Function::Create(Ty, GlobalVariable::WeakAnyLinkage, Name);
6563e457fe3SDavid van Moolenbroek     break;
6573e457fe3SDavid van Moolenbroek     case PASS_UTIL_LINKAGE_COMMON:
6583e457fe3SDavid van Moolenbroek         /* Creates empty function, non overridable. */
6593e457fe3SDavid van Moolenbroek         F = Function::Create(Ty, GlobalVariable::InternalLinkage, Name);
6603e457fe3SDavid van Moolenbroek     break;
6613e457fe3SDavid van Moolenbroek     case PASS_UTIL_LINKAGE_EXTERNAL:
6623e457fe3SDavid van Moolenbroek         /* Creates function declaration that must be defined at link time. */
6633e457fe3SDavid van Moolenbroek         F = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name);
6643e457fe3SDavid van Moolenbroek         needsEmptyBody = false;
6653e457fe3SDavid van Moolenbroek     break;
6663e457fe3SDavid van Moolenbroek     case PASS_UTIL_LINKAGE_EXTERNAL_WEAK:
6673e457fe3SDavid van Moolenbroek         /* Creates weak function declaration that can optionally be defined
6683e457fe3SDavid van Moolenbroek          * at link time (if undefined the linker will emit a NULL symbol).
6693e457fe3SDavid van Moolenbroek          */
6703e457fe3SDavid van Moolenbroek         F = Function::Create(Ty, GlobalVariable::ExternalWeakLinkage, Name);
6713e457fe3SDavid van Moolenbroek         needsEmptyBody = false;
6723e457fe3SDavid van Moolenbroek     break;
6733e457fe3SDavid van Moolenbroek     case PASS_UTIL_LINKAGE_WEAK_POINTER:
6743e457fe3SDavid van Moolenbroek         /* Creates function pointer initialized to NULL that can optionally
6753e457fe3SDavid van Moolenbroek          * be initialized at runtime. Invocations are wrapped to ensure that
6763e457fe3SDavid van Moolenbroek          * indirect call is performed on a NULL pointer. This is to emulate
6773e457fe3SDavid van Moolenbroek          * Mac OS' weak_pointer attribute, which allows weak symbols to be
6783e457fe3SDavid van Moolenbroek          * overriden in LD_PRELOADED libraries at runtime.
6793e457fe3SDavid van Moolenbroek          */
6803e457fe3SDavid van Moolenbroek         F = PassUtil::createFunctionWeakPtrWrapper(M, Name, Ty);
6813e457fe3SDavid van Moolenbroek         needsProperties = false;
6823e457fe3SDavid van Moolenbroek         needsIncludsion = false;
6833e457fe3SDavid van Moolenbroek     break;
6843e457fe3SDavid van Moolenbroek     default:
6853e457fe3SDavid van Moolenbroek         return NULL;
6863e457fe3SDavid van Moolenbroek     break;
6873e457fe3SDavid van Moolenbroek     }
6883e457fe3SDavid van Moolenbroek     if (needsIncludsion) {
6893e457fe3SDavid van Moolenbroek         M.getFunctionList().push_back(F);
6903e457fe3SDavid van Moolenbroek     }
6913e457fe3SDavid van Moolenbroek     if (needsEmptyBody) {
6923e457fe3SDavid van Moolenbroek         BasicBlock* block = BasicBlock::Create(M.getContext(), "entry", F);
6933e457fe3SDavid van Moolenbroek         IRBuilder<> builder(block);
6943e457fe3SDavid van Moolenbroek         TYPECONST Type *RetTy = Ty->getReturnType();
6953e457fe3SDavid van Moolenbroek         if (RetTy->isVoidTy()) {
6963e457fe3SDavid van Moolenbroek             builder.CreateRetVoid();
6973e457fe3SDavid van Moolenbroek         }
6983e457fe3SDavid van Moolenbroek         else {
6993e457fe3SDavid van Moolenbroek             builder.CreateRet(Constant::getNullValue(RetTy));
7003e457fe3SDavid van Moolenbroek         }
7013e457fe3SDavid van Moolenbroek     }
7023e457fe3SDavid van Moolenbroek     functionMap.insert(std::pair<std::string, Function *>(Name, F));
7033e457fe3SDavid van Moolenbroek     if (needsProperties) {
7043e457fe3SDavid van Moolenbroek         setFunctionProperties(F, properties);
7053e457fe3SDavid van Moolenbroek     }
7063e457fe3SDavid van Moolenbroek     return F;
7073e457fe3SDavid van Moolenbroek }
7083e457fe3SDavid van Moolenbroek 
getFunctionPassUtilLinkageType(Function * F)7093e457fe3SDavid van Moolenbroek inline PassUtilLinkageType PassUtil::getFunctionPassUtilLinkageType(Function *F)
7103e457fe3SDavid van Moolenbroek {
7113e457fe3SDavid van Moolenbroek     if (F->isDeclaration()) {
7123e457fe3SDavid van Moolenbroek         return PASS_UTIL_LINKAGE_EXTERNAL;
7133e457fe3SDavid van Moolenbroek     }
7143e457fe3SDavid van Moolenbroek     if (F->hasInternalLinkage()) {
7153e457fe3SDavid van Moolenbroek         return PASS_UTIL_LINKAGE_PRIVATE;
7163e457fe3SDavid van Moolenbroek     }
7173e457fe3SDavid van Moolenbroek     return PASS_UTIL_LINKAGE_COMMON;
7183e457fe3SDavid van Moolenbroek }
7193e457fe3SDavid van Moolenbroek 
getPassUtilLinkageTypeString(PassUtilLinkageType linkageType)7203e457fe3SDavid van Moolenbroek inline std::string PassUtil::getPassUtilLinkageTypeString(PassUtilLinkageType linkageType)
7213e457fe3SDavid van Moolenbroek {
7223e457fe3SDavid van Moolenbroek     const char *strArray[] = { PASS_UTIL_LINKAGE_TYPE_STRINGS };
7233e457fe3SDavid van Moolenbroek     std::string str(strArray[linkageType]);
7243e457fe3SDavid van Moolenbroek     return str;
7253e457fe3SDavid van Moolenbroek }
7263e457fe3SDavid van Moolenbroek 
getFunctionEntryExits(Function * F,BasicBlock ** entryBlock,std::vector<BasicBlock * > * exitBlocks)7273e457fe3SDavid van Moolenbroek inline void PassUtil::getFunctionEntryExits(Function *F, BasicBlock **entryBlock, std::vector<BasicBlock*> *exitBlocks)
7283e457fe3SDavid van Moolenbroek {
7293e457fe3SDavid van Moolenbroek     if (entryBlock) {
7303e457fe3SDavid van Moolenbroek         *entryBlock = &F->front();
7313e457fe3SDavid van Moolenbroek     }
7323e457fe3SDavid van Moolenbroek     if (exitBlocks) {
7333e457fe3SDavid van Moolenbroek         for(Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
7343e457fe3SDavid van Moolenbroek             if (isa<ReturnInst>(I->getTerminator()) || isa<UnreachableInst>(I->getTerminator()))
7353e457fe3SDavid van Moolenbroek                 exitBlocks->push_back(I);
7363e457fe3SDavid van Moolenbroek         }
7373e457fe3SDavid van Moolenbroek     }
7383e457fe3SDavid van Moolenbroek }
7393e457fe3SDavid van Moolenbroek 
isReturnedValue(Function * F,Value * V)7403e457fe3SDavid van Moolenbroek inline bool PassUtil::isReturnedValue(Function *F, Value *V)
7413e457fe3SDavid van Moolenbroek {
7423e457fe3SDavid van Moolenbroek     std::vector<BasicBlock*> exitBlocks;
7433e457fe3SDavid van Moolenbroek     PassUtil::getFunctionEntryExits(F, NULL, &exitBlocks);
7443e457fe3SDavid van Moolenbroek     for (unsigned i=0;i<exitBlocks.size();i++) {
7453e457fe3SDavid van Moolenbroek         Instruction *I = exitBlocks[i]->getTerminator();
7463e457fe3SDavid van Moolenbroek         ReturnInst *RI = dyn_cast<ReturnInst>(I);
7473e457fe3SDavid van Moolenbroek         if (RI && RI->getReturnValue()) {
7483e457fe3SDavid van Moolenbroek             Value *RV = RI->getReturnValue();
7493e457fe3SDavid van Moolenbroek             if (RV == V) {
7503e457fe3SDavid van Moolenbroek                 return true;
7513e457fe3SDavid van Moolenbroek             }
7523e457fe3SDavid van Moolenbroek             if (LoadInst *LI = dyn_cast<LoadInst>(RV)) {
7533e457fe3SDavid van Moolenbroek                 if (LI->getPointerOperand() == V) {
7543e457fe3SDavid van Moolenbroek                     return true;
7553e457fe3SDavid van Moolenbroek                 }
7563e457fe3SDavid van Moolenbroek             }
7573e457fe3SDavid van Moolenbroek         }
7583e457fe3SDavid van Moolenbroek     }
7593e457fe3SDavid van Moolenbroek     return false;
7603e457fe3SDavid van Moolenbroek }
7613e457fe3SDavid van Moolenbroek 
getCallSiteFromInstruction(Instruction * I)7623e457fe3SDavid van Moolenbroek inline CallSite PassUtil::getCallSiteFromInstruction(Instruction *I)
7633e457fe3SDavid van Moolenbroek {
7643e457fe3SDavid van Moolenbroek   return getCallSiteFromUser(I);
7653e457fe3SDavid van Moolenbroek }
7663e457fe3SDavid van Moolenbroek 
getCallSiteFromUser(User * U)7673e457fe3SDavid van Moolenbroek inline CallSite PassUtil::getCallSiteFromUser(User *U)
7683e457fe3SDavid van Moolenbroek {
7693e457fe3SDavid van Moolenbroek   CallSite CS(U->stripPointerCasts());
7703e457fe3SDavid van Moolenbroek   CallSite emptyCS;
7713e457fe3SDavid van Moolenbroek   Instruction *I = CS.getInstruction();
7723e457fe3SDavid van Moolenbroek   if (!I)
7733e457fe3SDavid van Moolenbroek       return emptyCS;
7743e457fe3SDavid van Moolenbroek   if (isa<CallInst>(I) && dyn_cast<CallInst>(I)->isInlineAsm())
7753e457fe3SDavid van Moolenbroek       return emptyCS;
7763e457fe3SDavid van Moolenbroek   Function *F = CS.getCalledFunction();
7773e457fe3SDavid van Moolenbroek   if (F && F->isIntrinsic())
7783e457fe3SDavid van Moolenbroek       return emptyCS;
7793e457fe3SDavid van Moolenbroek   return CS;
7803e457fe3SDavid van Moolenbroek }
7813e457fe3SDavid van Moolenbroek 
getFunctionsInDirectBUCallgraph(Function * F,std::set<Function * > & funcs)7823e457fe3SDavid van Moolenbroek inline void PassUtil::getFunctionsInDirectBUCallgraph(Function* F, std::set<Function*> &funcs) {
7833e457fe3SDavid van Moolenbroek   if (funcs.find(F) != funcs.end())
7843e457fe3SDavid van Moolenbroek       return;
7853e457fe3SDavid van Moolenbroek   funcs.insert(F);
7863e457fe3SDavid van Moolenbroek   FOREACH_FUNC_CS(F, CS,
7873e457fe3SDavid van Moolenbroek       if (!CS.getCalledFunction())
7883e457fe3SDavid van Moolenbroek           continue;
7893e457fe3SDavid van Moolenbroek       getFunctionsInDirectBUCallgraph(CS.getCalledFunction(), funcs);
7903e457fe3SDavid van Moolenbroek   );
7913e457fe3SDavid van Moolenbroek }
7923e457fe3SDavid van Moolenbroek 
getAllocaInfo(Function * F,Instruction ** allocaInsertionPoint,Instruction ** firstNonAllocaInst)7933e457fe3SDavid van Moolenbroek inline void PassUtil::getAllocaInfo(Function *F, Instruction **allocaInsertionPoint, Instruction **firstNonAllocaInst)
7943e457fe3SDavid van Moolenbroek {
7953e457fe3SDavid van Moolenbroek     assert(!F->isDeclaration());
7963e457fe3SDavid van Moolenbroek     BasicBlock::iterator allocaIP = F->front().begin();
7973e457fe3SDavid van Moolenbroek     while (isa<AllocaInst>(allocaIP)) ++allocaIP;
7983e457fe3SDavid van Moolenbroek     BasicBlock::iterator firstNonAI = allocaIP;
7993e457fe3SDavid van Moolenbroek     if (firstNonAI->getName().equals("alloca point")) {
8003e457fe3SDavid van Moolenbroek     	firstNonAI++;
8013e457fe3SDavid van Moolenbroek     }
8023e457fe3SDavid van Moolenbroek     if(allocaInsertionPoint) {
8033e457fe3SDavid van Moolenbroek     	*allocaInsertionPoint = allocaIP;
8043e457fe3SDavid van Moolenbroek     }
8053e457fe3SDavid van Moolenbroek     if(firstNonAllocaInst) {
8063e457fe3SDavid van Moolenbroek     	*firstNonAllocaInst = firstNonAI;
8073e457fe3SDavid van Moolenbroek     }
8083e457fe3SDavid van Moolenbroek }
8093e457fe3SDavid van Moolenbroek 
getStringConstantArray(Module & M,const std::string & string)8103e457fe3SDavid van Moolenbroek inline Constant* PassUtil::getStringConstantArray(Module &M, const std::string &string)
8113e457fe3SDavid van Moolenbroek {
8123e457fe3SDavid van Moolenbroek   std::vector<Constant*> elements;
8133e457fe3SDavid van Moolenbroek   elements.reserve(string.size() + 1);
8143e457fe3SDavid van Moolenbroek   for (unsigned i = 0; i < string.size(); ++i)
8153e457fe3SDavid van Moolenbroek     elements.push_back(ConstantInt::get(Type::getInt8Ty(M.getContext()), string[i]));
8163e457fe3SDavid van Moolenbroek 
8173e457fe3SDavid van Moolenbroek   // Add a null terminator to the string...
8183e457fe3SDavid van Moolenbroek   elements.push_back(ConstantInt::get(Type::getInt8Ty(M.getContext()), 0));
8193e457fe3SDavid van Moolenbroek 
8203e457fe3SDavid van Moolenbroek   ArrayType *ATy = ArrayType::get(Type::getInt8Ty(M.getContext()), elements.size());
8213e457fe3SDavid van Moolenbroek   return ConstantArray::get(ATy, elements);
8223e457fe3SDavid van Moolenbroek }
8233e457fe3SDavid van Moolenbroek 
getStringGlobalVariable(Module & M,const std::string & string,const std::string & varName,const std::string & varSection,Constant ** getElementPtrExpr,bool cacheable)8243e457fe3SDavid van Moolenbroek inline GlobalVariable* PassUtil::getStringGlobalVariable(Module &M, const std::string &string, const std::string &varName, const std::string &varSection, Constant **getElementPtrExpr, bool cacheable)
8253e457fe3SDavid van Moolenbroek {
8263e457fe3SDavid van Moolenbroek     static std::map<std::string, GlobalVariable*> stringCache;
8273e457fe3SDavid van Moolenbroek     std::map<std::string, GlobalVariable*>::iterator stringCacheIt;
8283e457fe3SDavid van Moolenbroek     std::string stringCacheKey;
8293e457fe3SDavid van Moolenbroek     GlobalVariable *strGV = NULL;
8303e457fe3SDavid van Moolenbroek 
8313e457fe3SDavid van Moolenbroek     if (cacheable) {
8323e457fe3SDavid van Moolenbroek     	stringCacheKey = string + "~!~!" + varName + "~!~!" + varSection;
8333e457fe3SDavid van Moolenbroek         stringCacheIt = stringCache.find(stringCacheKey);
8343e457fe3SDavid van Moolenbroek         if (stringCacheIt != stringCache.end()) {
8353e457fe3SDavid van Moolenbroek             strGV = stringCacheIt->second;
8363e457fe3SDavid van Moolenbroek             cacheable = false;
8373e457fe3SDavid van Moolenbroek         }
8383e457fe3SDavid van Moolenbroek     }
8393e457fe3SDavid van Moolenbroek 
8403e457fe3SDavid van Moolenbroek     if (!strGV) {
8413e457fe3SDavid van Moolenbroek         //create a constant internal string reference
8423e457fe3SDavid van Moolenbroek         Constant *stringValue = PassUtil::getStringConstantArray(M, string);
8433e457fe3SDavid van Moolenbroek 
8443e457fe3SDavid van Moolenbroek         //create the global variable, cache it, and record it in the module
8453e457fe3SDavid van Moolenbroek         strGV = new GlobalVariable(M, stringValue->getType(), true,
8463e457fe3SDavid van Moolenbroek             GlobalValue::InternalLinkage, stringValue, varName);
8473e457fe3SDavid van Moolenbroek         if (varSection.compare("")) {
8483e457fe3SDavid van Moolenbroek             strGV->setSection(varSection);
8493e457fe3SDavid van Moolenbroek         }
8503e457fe3SDavid van Moolenbroek     }
8513e457fe3SDavid van Moolenbroek     if (getElementPtrExpr) {
8523e457fe3SDavid van Moolenbroek     	    std::vector<Value*> strConstantIndices;
8533e457fe3SDavid van Moolenbroek     	    strConstantIndices.push_back(ZERO_CONSTANT_INT(M));
8543e457fe3SDavid van Moolenbroek     	    strConstantIndices.push_back(ZERO_CONSTANT_INT(M));
8553e457fe3SDavid van Moolenbroek     	    *getElementPtrExpr = PassUtil::getGetElementPtrConstant(strGV, strConstantIndices);
8563e457fe3SDavid van Moolenbroek     }
8573e457fe3SDavid van Moolenbroek 
8583e457fe3SDavid van Moolenbroek     if (cacheable) {
8593e457fe3SDavid van Moolenbroek         stringCache.insert(std::pair<std::string, GlobalVariable*>(stringCacheKey, strGV));
8603e457fe3SDavid van Moolenbroek     }
8613e457fe3SDavid van Moolenbroek 
8623e457fe3SDavid van Moolenbroek     return strGV;
8633e457fe3SDavid van Moolenbroek }
8643e457fe3SDavid van Moolenbroek 
remapCallSiteAttributes(CallSite & CS,int argOffset)8653e457fe3SDavid van Moolenbroek inline ATTRIBUTE_SET_TY PassUtil::remapCallSiteAttributes(CallSite &CS, int argOffset)
8663e457fe3SDavid van Moolenbroek {
8673e457fe3SDavid van Moolenbroek     ATTRIBUTE_SET_TY Attrs = CS.getAttributes();
8683e457fe3SDavid van Moolenbroek     ATTRIBUTE_SET_TY NewAttrs;
8693e457fe3SDavid van Moolenbroek #if LLVM_VERSION >= 33
8703e457fe3SDavid van Moolenbroek     Instruction *I = CS.getInstruction();
8713e457fe3SDavid van Moolenbroek     NewAttrs.addAttributes(I->getContext(), ATTRIBUTE_SET_RET_IDX, Attrs.getRetAttributes());
8723e457fe3SDavid van Moolenbroek     NewAttrs.addAttributes(I->getContext(), ATTRIBUTE_SET_FN_IDX, Attrs.getFnAttributes());
8733e457fe3SDavid van Moolenbroek     for (unsigned i=1;i<=CS.arg_size();i++) {
8743e457fe3SDavid van Moolenbroek         NewAttrs.addAttributes(I->getContext(), i+argOffset, Attrs.getParamAttributes(i));
8753e457fe3SDavid van Moolenbroek     }
8763e457fe3SDavid van Moolenbroek #elif LLVM_VERSION == 32
8773e457fe3SDavid van Moolenbroek     Instruction *I = CS.getInstruction();
8783e457fe3SDavid van Moolenbroek     NewAttrs.addAttr(I->getContext(), ATTRIBUTE_SET_RET_IDX, Attrs.getRetAttributes());
8793e457fe3SDavid van Moolenbroek     NewAttrs.addAttr(I->getContext(), ATTRIBUTE_SET_FN_IDX, Attrs.getFnAttributes());
8803e457fe3SDavid van Moolenbroek     for (unsigned i=1;i<=CS.arg_size();i++) {
8813e457fe3SDavid van Moolenbroek         NewAttrs.addAttr(I->getContext(), i+argOffset, Attrs.getParamAttributes(i));
8823e457fe3SDavid van Moolenbroek     }
8833e457fe3SDavid van Moolenbroek #else
8843e457fe3SDavid van Moolenbroek     NewAttrs.addAttr(ATTRIBUTE_SET_RET_IDX, Attrs.getRetAttributes());
8853e457fe3SDavid van Moolenbroek     NewAttrs.addAttr(ATTRIBUTE_SET_FN_IDX, Attrs.getFnAttributes());
8863e457fe3SDavid van Moolenbroek     for (unsigned i=1;i<=CS.arg_size();i++) {
8873e457fe3SDavid van Moolenbroek         NewAttrs.addAttr(i+argOffset, Attrs.getParamAttributes(i));
8883e457fe3SDavid van Moolenbroek     }
8893e457fe3SDavid van Moolenbroek #endif
8903e457fe3SDavid van Moolenbroek 
8913e457fe3SDavid van Moolenbroek     return NewAttrs;
8923e457fe3SDavid van Moolenbroek }
8933e457fe3SDavid van Moolenbroek 
parseStringListOpt(std::vector<std::string> & list,const std::string & string,const std::string & separator)8943e457fe3SDavid van Moolenbroek inline void PassUtil::parseStringListOpt(std::vector<std::string> &list, const std::string &string, const std::string &separator)
8953e457fe3SDavid van Moolenbroek {
8963e457fe3SDavid van Moolenbroek     if(string.compare("")) {
8973e457fe3SDavid van Moolenbroek         SmallVector< StringRef, 8 > vector;
8983e457fe3SDavid van Moolenbroek         StringRef sref(string);
8993e457fe3SDavid van Moolenbroek         sref.split(vector, separator, -1, false);
9003e457fe3SDavid van Moolenbroek         list.insert(list.end(), vector.begin(), vector.end());
9013e457fe3SDavid van Moolenbroek     }
9023e457fe3SDavid van Moolenbroek }
9033e457fe3SDavid van Moolenbroek 
parseStringPairListOpt(std::set<std::pair<std::string,std::string>> & set,const std::string & string,const std::string & listSeparator,const std::string & pairSeparator)9043e457fe3SDavid van Moolenbroek 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)
9053e457fe3SDavid van Moolenbroek {
9063e457fe3SDavid van Moolenbroek 	if(string.compare("")) {
9073e457fe3SDavid van Moolenbroek 		SmallVector< StringRef, 8 > vector;
9083e457fe3SDavid van Moolenbroek 		StringRef sref(string);
9093e457fe3SDavid van Moolenbroek 		sref.split(vector, listSeparator, -1, false);
9103e457fe3SDavid van Moolenbroek 		SmallVector< StringRef, 8 > parts;
9113e457fe3SDavid van Moolenbroek 		while(!vector.empty()) {
9123e457fe3SDavid van Moolenbroek 			StringRef token = vector.pop_back_val();
9133e457fe3SDavid van Moolenbroek 			parts.clear();
9143e457fe3SDavid van Moolenbroek 			token.split(parts, pairSeparator, -1, false);
9153e457fe3SDavid van Moolenbroek 			assert(parts.size() == 2 && "Two tokens were expected.");
9163e457fe3SDavid van Moolenbroek 			set.insert(std::pair<std::string, std::string>(parts.front(), parts.back()));
9173e457fe3SDavid van Moolenbroek 		}
9183e457fe3SDavid van Moolenbroek 	}
9193e457fe3SDavid van Moolenbroek }
9203e457fe3SDavid van Moolenbroek 
parseRegexListOpt(std::vector<Regex * > & list,const std::string & string)9213e457fe3SDavid van Moolenbroek inline void PassUtil::parseRegexListOpt(std::vector<Regex*> &list, const std::string &string)
9223e457fe3SDavid van Moolenbroek {
9233e457fe3SDavid van Moolenbroek     std::vector<std::string> stringList;
9243e457fe3SDavid van Moolenbroek     std::vector<std::string>::iterator it;
9253e457fe3SDavid van Moolenbroek     PassUtil::parseStringListOpt(stringList, string);
9263e457fe3SDavid van Moolenbroek 
9273e457fe3SDavid van Moolenbroek     for (it = stringList.begin(); it != stringList.end(); ++it) {
9283e457fe3SDavid van Moolenbroek         Regex* regex = new Regex(*it, 0);
9293e457fe3SDavid van Moolenbroek         std::string error;
9303e457fe3SDavid van Moolenbroek         assert(regex->isValid(error));
9313e457fe3SDavid van Moolenbroek         list.push_back(regex);
9323e457fe3SDavid van Moolenbroek     }
9333e457fe3SDavid van Moolenbroek }
9343e457fe3SDavid van Moolenbroek 
matchRegexes(std::string string,std::vector<Regex * > & regexes)9353e457fe3SDavid van Moolenbroek inline bool PassUtil::matchRegexes(std::string string, std::vector<Regex*> &regexes)
9363e457fe3SDavid van Moolenbroek {
9373e457fe3SDavid van Moolenbroek     for (std::vector<Regex*>::iterator it = regexes.begin(); it != regexes.end(); ++it) {
9383e457fe3SDavid van Moolenbroek     	Regex *regex = *it;
9393e457fe3SDavid van Moolenbroek     	if(regex->match(string, NULL)) {
9403e457fe3SDavid van Moolenbroek     	    return true;
9413e457fe3SDavid van Moolenbroek     	}
9423e457fe3SDavid van Moolenbroek     }
9433e457fe3SDavid van Moolenbroek 
9443e457fe3SDavid van Moolenbroek     return false;
9453e457fe3SDavid van Moolenbroek }
9463e457fe3SDavid van Moolenbroek 
setModule(Module * M)9473e457fe3SDavid van Moolenbroek inline void PassUtil::setModule(Module *M)
9483e457fe3SDavid van Moolenbroek {
9493e457fe3SDavid van Moolenbroek     PassUtil::M = M;
9503e457fe3SDavid van Moolenbroek }
9513e457fe3SDavid van Moolenbroek 
getModuleName(Module & M,std::string * fullName,std::string * dirName,std::string * baseName)9523e457fe3SDavid van Moolenbroek inline void PassUtil::getModuleName(Module &M, std::string *fullName, std::string *dirName, std::string *baseName)
9533e457fe3SDavid van Moolenbroek {
9543e457fe3SDavid van Moolenbroek     std::string _fullName, _dirName, _baseName;
9553e457fe3SDavid van Moolenbroek     _fullName = M.getModuleIdentifier();
9563e457fe3SDavid van Moolenbroek     SmallVector< StringRef, 8 > vector;
9573e457fe3SDavid van Moolenbroek     StringRef fullNameRef(_fullName);
9583e457fe3SDavid van Moolenbroek     fullNameRef.split(vector, "/", -1, false);
9593e457fe3SDavid van Moolenbroek     if (vector.size() > 1) {
9603e457fe3SDavid van Moolenbroek         _baseName = vector.pop_back_val();
9613e457fe3SDavid van Moolenbroek         for (unsigned i=0;i<vector.size();i++) {
9623e457fe3SDavid van Moolenbroek             _dirName.append("/");
9633e457fe3SDavid van Moolenbroek             _dirName.append(vector[i]);
9643e457fe3SDavid van Moolenbroek         }
9653e457fe3SDavid van Moolenbroek     }
9663e457fe3SDavid van Moolenbroek     else {
9673e457fe3SDavid van Moolenbroek         _baseName = _fullName;
9683e457fe3SDavid van Moolenbroek         _dirName = "/";
9693e457fe3SDavid van Moolenbroek     }
9703e457fe3SDavid van Moolenbroek     vector.clear();
9713e457fe3SDavid van Moolenbroek     StringRef baseNameRef(_baseName);
9723e457fe3SDavid van Moolenbroek     baseNameRef.split(vector, ".", -1, false);
9733e457fe3SDavid van Moolenbroek     if (vector.size() > 1) {
9743e457fe3SDavid van Moolenbroek         _baseName = vector[0];
9753e457fe3SDavid van Moolenbroek     }
9763e457fe3SDavid van Moolenbroek     if (fullName)
9773e457fe3SDavid van Moolenbroek         *fullName = _fullName;
9783e457fe3SDavid van Moolenbroek     if (dirName)
9793e457fe3SDavid van Moolenbroek         *dirName = _dirName;
9803e457fe3SDavid van Moolenbroek     if (baseName)
9813e457fe3SDavid van Moolenbroek         *baseName = _baseName;
9823e457fe3SDavid van Moolenbroek }
9833e457fe3SDavid van Moolenbroek 
getTypeHash(TYPECONST Type * type,unsigned maxLevel)9843e457fe3SDavid van Moolenbroek inline unsigned long PassUtil::getTypeHash(TYPECONST Type* type, unsigned maxLevel)
9853e457fe3SDavid van Moolenbroek {
9863e457fe3SDavid van Moolenbroek     static std::vector<TYPECONST Type*> nestedTypes;
9873e457fe3SDavid van Moolenbroek     static unsigned level = 0;
9883e457fe3SDavid van Moolenbroek     static unsigned counter;
9893e457fe3SDavid van Moolenbroek     unsigned long hash = 7;
9903e457fe3SDavid van Moolenbroek     if(level == 0) {
9913e457fe3SDavid van Moolenbroek         counter = 0;
9923e457fe3SDavid van Moolenbroek     }
9933e457fe3SDavid van Moolenbroek     unsigned numContainedTypes = type->getNumContainedTypes();
9943e457fe3SDavid van Moolenbroek     unsigned nestedIndex = 0;
9953e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<nestedTypes.size();i++) {
9963e457fe3SDavid van Moolenbroek         if(type == nestedTypes[i]) {
9973e457fe3SDavid van Moolenbroek             nestedIndex = i+1;
9983e457fe3SDavid van Moolenbroek             break;
9993e457fe3SDavid van Moolenbroek         }
10003e457fe3SDavid van Moolenbroek     }
10013e457fe3SDavid van Moolenbroek     hash = (13*hash) ^ level;
10023e457fe3SDavid van Moolenbroek     hash = (13*hash) ^ counter++;
10033e457fe3SDavid van Moolenbroek     hash = (13*hash) ^ type->getTypeID();
10043e457fe3SDavid van Moolenbroek     hash = (13*hash) ^ nestedIndex;
10053e457fe3SDavid van Moolenbroek     if(TYPECONST IntegerType *intType = dyn_cast<IntegerType>(type)) {
10063e457fe3SDavid van Moolenbroek         hash = (13*hash) ^ intType->getBitWidth();
10073e457fe3SDavid van Moolenbroek     }
10083e457fe3SDavid van Moolenbroek     else if(TYPECONST PointerType *ptrType = dyn_cast<PointerType>(type)) {
10093e457fe3SDavid van Moolenbroek         hash = (13*hash) ^ ptrType->getElementType()->getTypeID();
10103e457fe3SDavid van Moolenbroek     }
10113e457fe3SDavid van Moolenbroek     if(nestedIndex > 0 || level >= maxLevel) {
10123e457fe3SDavid van Moolenbroek         return hash;
10133e457fe3SDavid van Moolenbroek     }
10143e457fe3SDavid van Moolenbroek     if(numContainedTypes == 0) {
10153e457fe3SDavid van Moolenbroek         return hash;
10163e457fe3SDavid van Moolenbroek     }
10173e457fe3SDavid van Moolenbroek     level++;
10183e457fe3SDavid van Moolenbroek     nestedTypes.push_back(type);
10193e457fe3SDavid van Moolenbroek     hash = (13*hash) ^ numContainedTypes;
10203e457fe3SDavid van Moolenbroek     for(unsigned i=0;i<numContainedTypes;i++) {
10213e457fe3SDavid van Moolenbroek         hash = (13*hash) ^ getTypeHash(type->getContainedType(i), maxLevel);
10223e457fe3SDavid van Moolenbroek     }
10233e457fe3SDavid van Moolenbroek     nestedTypes.pop_back();
10243e457fe3SDavid van Moolenbroek     level--;
10253e457fe3SDavid van Moolenbroek 
10263e457fe3SDavid van Moolenbroek     return hash;
10273e457fe3SDavid van Moolenbroek }
10283e457fe3SDavid van Moolenbroek 
10293e457fe3SDavid van Moolenbroek }
10303e457fe3SDavid van Moolenbroek 
10313e457fe3SDavid van Moolenbroek #endif /* _PASS_COMMON_H */
1032