diff --git a/opts/ClassIMPCache.cpp b/opts/ClassIMPCache.cpp index a407bf6..43a5a33 100644 --- a/opts/ClassIMPCache.cpp +++ b/opts/ClassIMPCache.cpp @@ -12,6 +12,7 @@ #include "ObjectiveCOpts.h" #include "IMPCacher.h" #include +#include "LLVMCompat.h" using namespace GNUstep; using namespace llvm; @@ -21,7 +22,7 @@ namespace { class ClassIMPCachePass : public ModulePass { - const IntegerType *IntTy; + LLVMIntegerType *IntTy; public: static char ID; @@ -68,7 +69,7 @@ namespace for (SmallVectorImpl >::iterator i=Lookups.begin(), e=Lookups.end() ; e!=i ; i++) { Instruction *call = i->first.getInstruction(); - const Type *SlotPtrTy = call->getType(); + LLVMType *SlotPtrTy = call->getType(); Value *slot = new GlobalVariable(M, SlotPtrTy, false, GlobalValue::PrivateLinkage, Constant::getNullValue(SlotPtrTy), @@ -86,15 +87,6 @@ namespace char ClassIMPCachePass::ID = 0; RegisterPass X("gnu-class-imp-cache", "Cache IMPs for class messages"); -#if LLVM_MAJOR > 2 - StandardPass::RegisterStandardPass D( - StandardPass::Module, &NonfragileIvarID, - StandardPass::OptimzationFlags(2, 0, 0, StandardPass::OptimizeSize), - &ClassIMPCacheID); - StandardPass::RegisterStandardPass L(StandardPass::LTO, - &NonfragileIvarID, StandardPass::OptimzationFlags(0), - &ClassIMPCacheID); -#endif } ModulePass *createClassIMPCachePass(void) diff --git a/opts/ClassLookupCache.cpp b/opts/ClassLookupCache.cpp index 648d71b..6bdc8ff 100644 --- a/opts/ClassLookupCache.cpp +++ b/opts/ClassLookupCache.cpp @@ -72,7 +72,7 @@ namespace e=Lookups.end() ; e!=i ; i++) { llvm::Instruction *lookup = i->first; std::string &cls = i->second; - const llvm::Type *clsTy = lookup->getType(); + LLVMType *clsTy = lookup->getType(); Value *global = M->getGlobalVariable(("_OBJC_CLASS_" + i->second).c_str(), true); global = 0; // If we can see the class reference for this, then reference it @@ -147,15 +147,6 @@ namespace char ClassLookupCachePass::ID = 0; RegisterPass X("gnu-class-lookup-cache", "Cache class lookups"); -#if LLVM_MAJOR > 2 - StandardPass::RegisterStandardPass D( - StandardPass::Module, &LoopIMPCacheID, - StandardPass::OptimzationFlags(1, 0, 0, StandardPass::OptimizeSize), - &ClassLookupCacheID); - StandardPass::RegisterStandardPass L(StandardPass::LTO, - &LoopIMPCacheID, StandardPass::OptimzationFlags(0), - &ClassLookupCacheID); -#endif } ModulePass *createClassLookupCachePass(void) diff --git a/opts/ClassMethodInliner.cpp b/opts/ClassMethodInliner.cpp index 7319081..fb1c293 100644 --- a/opts/ClassMethodInliner.cpp +++ b/opts/ClassMethodInliner.cpp @@ -101,15 +101,6 @@ namespace char ClassMethodInliner::ID = 0; RegisterPass X("gnu-class-method-inline", "Inline class methods and message sends to super"); -#if LLVM_MAJOR > 2 - StandardPass::RegisterStandardPass D( - StandardPass::Module, &ClassLookupCacheID, - StandardPass::OptimzationFlags(3, 0, 0, StandardPass::OptimizeSize), - &ClassMethodInlinerID); - StandardPass::RegisterStandardPass L(StandardPass::LTO, - &ClassLookupCacheID, StandardPass::OptimzationFlags(0), - &ClassMethodInlinerID); -#endif } ModulePass *createClassMethodInliner(void) diff --git a/opts/IMPCacher.cpp b/opts/IMPCacher.cpp index bd699ac..2bce45e 100644 --- a/opts/IMPCacher.cpp +++ b/opts/IMPCacher.cpp @@ -20,7 +20,7 @@ GNUstep::IMPCacher::IMPCacher(LLVMContext &C, Pass *owner) : Context(C), IntTy = (sizeof(int) == 4 ) ? Type::getInt32Ty(C) : Type::getInt64Ty(C); IdTy = PointerType::getUnqual(PtrTy); Value *AlreadyCachedFlagValue = MDString::get(C, "IMPCached"); - AlreadyCachedFlag = CreateMDNode(C, AlreadyCachedFlagValue); + AlreadyCachedFlag = CreateMDNode(C, &AlreadyCachedFlagValue); IMPCacheFlagKind = Context.getMDKindID("IMPCache"); } @@ -149,8 +149,8 @@ void GNUstep::IMPCacher::SpeculativelyInline(Instruction *call, Function if (calleeTy != FTy) { for (unsigned i=0 ; igetNumParams() ; i++) { - const Type *callType = calleeTy->getParamType(i); - const Type *argType = FTy->getParamType(i); + LLVMType *callType = calleeTy->getParamType(i); + LLVMType *argType = FTy->getParamType(i); if (callType != argType) { inlineCall->setOperand(i, new BitCastInst(inlineCall->getOperand(i), argType, "", inlineCall)); diff --git a/opts/IMPCacher.h b/opts/IMPCacher.h index 702bd05..4f76810 100644 --- a/opts/IMPCacher.h +++ b/opts/IMPCacher.h @@ -1,3 +1,4 @@ +#include "LLVMCompat.h" namespace llvm { class BasicBlock; @@ -23,9 +24,9 @@ namespace GNUstep MDNode *AlreadyCachedFlag; unsigned IMPCacheFlagKind; Pass *Owner; - const PointerType *PtrTy; - const PointerType *IdTy; - const IntegerType *IntTy; + LLVMPointerType *PtrTy; + LLVMPointerType *IdTy; + LLVMIntegerType *IntTy; public: IMPCacher(LLVMContext &C, Pass *owner); void CacheLookup(Instruction *lookup, Value *slot, Value *version, bool diff --git a/opts/IvarPass.cpp b/opts/IvarPass.cpp index 420793c..c56d9d4 100644 --- a/opts/IvarPass.cpp +++ b/opts/IvarPass.cpp @@ -10,7 +10,6 @@ #include "ObjectiveCOpts.h" #include -using namespace GNUstep; using namespace llvm; using std::string; @@ -147,14 +146,6 @@ namespace { char GNUNonfragileIvarPass::ID = 0; RegisterPass X("gnu-nonfragile-ivar", "Ivar fragility pass"); -#if LLVM_MAJOR > 2 - StandardPass::RegisterStandardPass D( - StandardPass::Module, &DefaultStandardPasses::LoopUnrollID, - StandardPass::OptimzationFlags(1), &NonfragileIvarID); - StandardPass::RegisterStandardPass L(StandardPass::LTO, - &DefaultStandardPasses::JumpThreadingID, - StandardPass::OptimzationFlags(0), &NonfragileIvarID); -#endif } FunctionPass *createGNUNonfragileIvarPass(void) diff --git a/opts/LLVMCompat.h b/opts/LLVMCompat.h index c78712a..85f472c 100644 --- a/opts/LLVMCompat.h +++ b/opts/LLVMCompat.h @@ -1,33 +1,115 @@ /** * Compatibility header that wraps LLVM API breakage and lets us compile with * old and new versions of LLVM. + * + * First LLVM version supported is 2.9. */ +#ifndef __LANGUAGEKIT_LLVM_HACKS__ +#define __LANGUAGEKIT_LLVM_HACKS__ +#include +#include +#include +#include + + +// Only preserve names in a debug build. This simplifies the +// IR in a release build, but makes it much harder to debug. +#ifndef DEBUG + typedef llvm::IRBuilder CGBuilder; +#else + typedef llvm::IRBuilder<> CGBuilder; +#endif + __attribute((unused)) static inline -PHINode* CreatePHI(const Type *Ty, - unsigned NumReservedValues, - const Twine &NameStr="", - Instruction *InsertBefore=0) { +llvm::PHINode* CreatePHI(llvm::Type *Ty, + unsigned NumReservedValues, + const llvm::Twine &NameStr="", + llvm::Instruction *InsertBefore=0) { #if LLVM_MAJOR < 3 - PHINode *phi = PHINode::Create(Ty, NameStr, InsertBefore); + llvm::PHINode *phi = llvm::PHINode::Create(Ty, NameStr, InsertBefore); phi->reserveOperandSpace(NumReservedValues); return phi; #else - return PHINode::Create(Ty, NumReservedValues, NameStr, InsertBefore); + return llvm::PHINode::Create(Ty, NumReservedValues, NameStr, InsertBefore); #endif } __attribute((unused)) static inline -MDNode* CreateMDNode(LLVMContext &C, - Value *V) { +llvm::PHINode* IRBuilderCreatePHI(CGBuilder *Builder, + llvm::Type *Ty, + unsigned NumReservedValues, + const llvm::Twine &NameStr="") +{ #if LLVM_MAJOR < 3 - return MDNode::get(C, &V, 1); + llvm::PHINode *phi = Builder->CreatePHI(Ty, NameStr); + phi->reserveOperandSpace(NumReservedValues); + return phi; #else - ArrayRef val(V); - return MDNode::get(C, val); + return Builder->CreatePHI(Ty, NumReservedValues, NameStr); #endif } + + +__attribute((unused)) static inline +llvm::MDNode* CreateMDNode(llvm::LLVMContext &C, + llvm::Value **V, + unsigned length=1) { +#if LLVM_MAJOR < 3 + return llvm::MDNode::get(C, V, length); +#else + llvm::ArrayRef val(V, length); + return llvm::MDNode::get(C, val); +#endif +} + +template +static inline +llvm::InvokeInst* IRBuilderCreateInvoke(CGBuilder *Builder, + llvm::Value *callee, + llvm::BasicBlock *dest, + llvm::BasicBlock *dest2, + T values, + const llvm::Twine &NameStr="") +{ +#if LLVM_MAJOR < 3 + return Builder->CreateInvoke(callee, dest, dest2, values.begin(), values.end(), NameStr); +#else + return Builder->CreateInvoke(callee, dest, dest2, values, NameStr); +#endif +} + +template +static inline +llvm::CallInst* IRBuilderCreateCall(CGBuilder *Builder, + llvm::Value *callee, + T values, + const llvm::Twine &NameStr="") +{ +#if LLVM_MAJOR < 3 + return Builder->CreateCall(callee, values.begin(), values.end(), NameStr); +#else + return Builder->CreateCall(callee, values, NameStr); +#endif +} + +template +static inline +llvm::CallInst* CreateCall(llvm::Value *callee, + T values, + const llvm::Twine &NameStr, + llvm::Instruction *before) +{ +#if LLVM_MAJOR < 3 + return llvm::CallInst::Create(callee, values.begin(), values.end(), NameStr, before); +#else + return llvm::CallInst::Create(callee, values, NameStr, before); +#endif +} + + + #if LLVM_MAJOR < 3 #define GetStructType(context, ...) StructType::get(context, __VA_ARGS__) #else @@ -35,11 +117,28 @@ MDNode* CreateMDNode(LLVMContext &C, #endif __attribute((unused)) static inline -Constant* GetConstantStruct(LLVMContext &C, const std::vector +llvm::Constant* GetConstantStruct(llvm::LLVMContext &C, const std::vector &V, bool Packed) { #if LLVM_MAJOR < 3 - return ConstantStruct::get(C, V, Packed); + return llvm::ConstantStruct::get(C, V, Packed); #else - return ConstantStruct::getAnon(C, V, Packed); + return llvm::ConstantStruct::getAnon(C, V, Packed); #endif } + + +#if LLVM_MAJOR < 3 +typedef const llvm::Type LLVMType; +typedef const llvm::StructType LLVMStructType; +typedef const llvm::ArrayType LLVMArrayType; +typedef const llvm::PointerType LLVMPointerType; +typedef const llvm::IntegerType LLVMIntegerType; +#else +typedef llvm::Type LLVMType; +typedef llvm::StructType LLVMStructType; +typedef llvm::ArrayType LLVMArrayType; +typedef llvm::PointerType LLVMPointerType; +typedef llvm::IntegerType LLVMIntegerType; +#endif + +#endif diff --git a/opts/LoopIMPCachePass.cpp b/opts/LoopIMPCachePass.cpp index fba2f39..b41f555 100644 --- a/opts/LoopIMPCachePass.cpp +++ b/opts/LoopIMPCachePass.cpp @@ -21,7 +21,7 @@ namespace class GNULoopIMPCachePass : public FunctionPass { GNUstep::IMPCacher *cacher; - const IntegerType *IntTy; + LLVMIntegerType *IntTy; Module *M; public: @@ -68,7 +68,7 @@ namespace IRBuilder<> B = IRBuilder<>(entry); for (SmallVectorImpl::iterator i=Lookups.begin(), e=Lookups.end() ; e!=i ; i++) { - const Type *SlotPtrTy = (*i)->getType(); + LLVMType *SlotPtrTy = (*i)->getType(); B.SetInsertPoint(entry, entry->begin()); Value *slot = B.CreateAlloca(SlotPtrTy, 0, "slot"); Value *version = B.CreateAlloca(IntTy, 0, "slot_version"); @@ -87,15 +87,6 @@ namespace char GNULoopIMPCachePass::ID = 0; RegisterPass X("gnu-loop-imp-cache", "Cache IMPs in loops pass"); -#if LLVM_MAJOR > 2 - StandardPass::RegisterStandardPass D( - StandardPass::Module, &ClassIMPCacheID, - StandardPass::OptimzationFlags(2, 0, 0, StandardPass::OptimizeSize), - &LoopIMPCacheID); - StandardPass::RegisterStandardPass L(StandardPass::LTO, - &ClassIMPCacheID, StandardPass::OptimzationFlags(0), - &LoopIMPCacheID); -#endif } FunctionPass *createGNULoopIMPCachePass(void) diff --git a/opts/ObjectiveCOpts.cpp b/opts/ObjectiveCOpts.cpp index bd82276..99d8e5b 100644 --- a/opts/ObjectiveCOpts.cpp +++ b/opts/ObjectiveCOpts.cpp @@ -53,9 +53,3 @@ namespace "Run all of the GNUstep Objective-C runtimm optimisations"); } - -unsigned char GNUstep::ClassIMPCacheID; -unsigned char GNUstep::ClassMethodInlinerID; -unsigned char GNUstep::ClassLookupCacheID; -unsigned char GNUstep::LoopIMPCacheID; -unsigned char GNUstep::NonfragileIvarID; diff --git a/opts/ObjectiveCOpts.h b/opts/ObjectiveCOpts.h index 332e914..c90452d 100644 --- a/opts/ObjectiveCOpts.h +++ b/opts/ObjectiveCOpts.h @@ -5,11 +5,3 @@ llvm::FunctionPass *createGNUNonfragileIvarPass(void); llvm::FunctionPass *createGNULoopIMPCachePass(void); llvm::ModulePass *createTypeFeedbackPass(void); llvm::ModulePass *createTypeFeedbackDrivenInlinerPass(void); - -namespace GNUstep { - extern unsigned char ClassIMPCacheID; - extern unsigned char ClassMethodInlinerID; - extern unsigned char ClassLookupCacheID; - extern unsigned char LoopIMPCacheID; - extern unsigned char NonfragileIvarID; -} diff --git a/opts/TypeFeedback.cpp b/opts/TypeFeedback.cpp index 25e0883..09709d9 100644 --- a/opts/TypeFeedback.cpp +++ b/opts/TypeFeedback.cpp @@ -18,7 +18,7 @@ namespace { typedef std::vector replacementVector; static char ID; uint32_t callsiteCount; - const IntegerType *Int32Ty; + LLVMIntegerType *Int32Ty; GNUObjCTypeFeedback() : ModulePass(ID), callsiteCount(0) {} void profileFunction(Function &F, Constant *ModuleID) { @@ -32,14 +32,17 @@ namespace { CallSite call(b); if (call.getInstruction() && !call.getCalledFunction()) { - llvm::Value *args[] = { call->getOperand(1), call->getOperand(0), - ModuleID, ConstantInt::get(Int32Ty, callsiteCount++) }; + llvm::SmallVector args; + args.push_back(call->getOperand(1)); + args.push_back(call->getOperand(0)), + args.push_back(ModuleID); + args.push_back(ConstantInt::get(Int32Ty, callsiteCount++)); Constant *profile = M->getOrInsertFunction("objc_msg_profile", Type::getVoidTy(M->getContext()), args[0]->getType(), args[1]->getType(), args[2]->getType(), args[3]->getType(), NULL); - CallInst::Create(profile, args, args+4, "", call.getInstruction()); + CreateCall(profile, args, "", call.getInstruction()); } } } @@ -50,7 +53,7 @@ namespace { { LLVMContext &VMContext = M.getContext(); Int32Ty = IntegerType::get(VMContext, 32); - const PointerType *PtrTy = Type::getInt8PtrTy(VMContext); + LLVMPointerType *PtrTy = Type::getInt8PtrTy(VMContext); Constant *moduleName = ConstantArray::get(VMContext, M.getModuleIdentifier(), true); moduleName = new GlobalVariable(M, moduleName->getType(), true, @@ -108,7 +111,7 @@ namespace { } // Type of one ctor - const Type *ctorTy = + LLVMType *ctorTy = cast(GCL->getType()->getElementType())->getElementType(); // Add the std::vector CSVals;