diff options
Diffstat (limited to 'lib/VMCore')
| -rw-r--r-- | lib/VMCore/AutoUpgrade.cpp | 70 | ||||
| -rw-r--r-- | lib/VMCore/LLVMContext.cpp | 19 | ||||
| -rw-r--r-- | lib/VMCore/LLVMContextImpl.cpp | 3 | ||||
| -rw-r--r-- | lib/VMCore/LLVMContextImpl.h | 2 | ||||
| -rw-r--r-- | lib/VMCore/Pass.cpp | 20 |
5 files changed, 106 insertions, 8 deletions
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index b9aa5c34675b9..4d06b66681694 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -145,6 +145,54 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; + case 'm': { + // This upgrades the llvm.memcpy, llvm.memmove, and llvm.memset to the + // new format that allows overloading the pointer for different address + // space (e.g., llvm.memcpy.i16 => llvm.memcpy.p0i8.p0i8.i16) + const char* NewFnName = NULL; + if (Name.compare(5,8,"memcpy.i",8) == 0) { + if (Name[13] == '8') + NewFnName = "llvm.memcpy.p0i8.p0i8.i8"; + else if (Name.compare(13,2,"16") == 0) + NewFnName = "llvm.memcpy.p0i8.p0i8.i16"; + else if (Name.compare(13,2,"32") == 0) + NewFnName = "llvm.memcpy.p0i8.p0i8.i32"; + else if (Name.compare(13,2,"64") == 0) + NewFnName = "llvm.memcpy.p0i8.p0i8.i64"; + } else if (Name.compare(5,9,"memmove.i",9) == 0) { + if (Name[14] == '8') + NewFnName = "llvm.memmove.p0i8.p0i8.i8"; + else if (Name.compare(14,2,"16") == 0) + NewFnName = "llvm.memmove.p0i8.p0i8.i16"; + else if (Name.compare(14,2,"32") == 0) + NewFnName = "llvm.memmove.p0i8.p0i8.i32"; + else if (Name.compare(14,2,"64") == 0) + NewFnName = "llvm.memmove.p0i8.p0i8.i64"; + } + else if (Name.compare(5,8,"memset.i",8) == 0) { + if (Name[13] == '8') + NewFnName = "llvm.memset.p0i8.i8"; + else if (Name.compare(13,2,"16") == 0) + NewFnName = "llvm.memset.p0i8.i16"; + else if (Name.compare(13,2,"32") == 0) + NewFnName = "llvm.memset.p0i8.i32"; + else if (Name.compare(13,2,"64") == 0) + NewFnName = "llvm.memset.p0i8.i64"; + } + if (NewFnName) { + const FunctionType *FTy = F->getFunctionType(); + NewFn = cast<Function>(M->getOrInsertFunction(NewFnName, + FTy->getReturnType(), + FTy->getParamType(0), + FTy->getParamType(1), + FTy->getParamType(2), + FTy->getParamType(3), + Type::getInt1Ty(F->getContext()), + (Type *)0)); + return true; + } + break; + } case 'p': // This upgrades the llvm.part.select overloaded intrinsic names to only // use one type specifier in the name. We only care about the old format @@ -472,6 +520,28 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { CI->eraseFromParent(); } break; + case Intrinsic::memcpy: + case Intrinsic::memmove: + case Intrinsic::memset: { + // Add isVolatile + const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext()); + Value *Operands[5] = { CI->getOperand(1), CI->getOperand(2), + CI->getOperand(3), CI->getOperand(4), + llvm::ConstantInt::get(I1Ty, 0) }; + CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5, + CI->getName(), CI); + NewCI->setTailCall(CI->isTailCall()); + NewCI->setCallingConv(CI->getCallingConv()); + // Handle any uses of the old CallInst. + if (!CI->use_empty()) + // Replace all uses of the old call with the new cast which has the + // correct type. + CI->replaceAllUsesWith(NewCI); + + // Clean up the old call now that it has been completely upgraded. + CI->eraseFromParent(); + break; + } } } diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 2a870ec6cfd94..3244f2842c4fd 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -33,6 +33,23 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { } LLVMContext::~LLVMContext() { delete pImpl; } +void LLVMContext::setInlineAsmDiagnosticHandler(void *DiagHandler, + void *DiagContext) { + pImpl->InlineAsmDiagHandler = DiagHandler; + pImpl->InlineAsmDiagContext = DiagContext; +} + +/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by +/// setInlineAsmDiagnosticHandler. +void *LLVMContext::getInlineAsmDiagnosticHandler() const { + return pImpl->InlineAsmDiagHandler; +} + +/// getInlineAsmDiagnosticContext - Return the diagnostic context set by +/// setInlineAsmDiagnosticHandler. +void *LLVMContext::getInlineAsmDiagnosticContext() const { + return pImpl->InlineAsmDiagContext; +} #ifndef NDEBUG /// isValidName - Return true if Name is a valid custom metadata handler name. @@ -73,5 +90,3 @@ void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { // MD Handlers are numbered from 1. Names[I->second] = I->first(); } - - diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index b4553ddc1b9f4..e71157f44020c 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -30,6 +30,9 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) Int32Ty(C, 32), Int64Ty(C, 64), AlwaysOpaqueTy(new OpaqueType(C)) { + InlineAsmDiagHandler = 0; + InlineAsmDiagContext = 0; + // Make sure the AlwaysOpaqueTy stays alive as long as the Context. AlwaysOpaqueTy->addRef(); OpaqueTypes.insert(AlwaysOpaqueTy); diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index d4ebf8044d8b8..4876f5d5075a8 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -115,6 +115,8 @@ public: class LLVMContextImpl { public: + void *InlineAsmDiagHandler, *InlineAsmDiagContext; + typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, DenseMapAPIntKeyInfo> IntMapTy; IntMapTy IntConstants; diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index 6093750124809..6b941f34996e1 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -294,13 +294,8 @@ public: static std::vector<PassRegistrationListener*> *Listeners = 0; static sys::SmartMutex<true> ListenersLock; -// FIXME: This should use ManagedStatic to manage the pass registrar. -// Unfortunately, we can't do this, because passes are registered with static -// ctors, and having llvm_shutdown clear this map prevents successful -// ressurection after llvm_shutdown is run. +static PassRegistrar *PassRegistrarObj = 0; static PassRegistrar *getPassRegistrar() { - static PassRegistrar *PassRegistrarObj = 0; - // Use double-checked locking to safely initialize the registrar when // we're running in multithreaded mode. PassRegistrar* tmp = PassRegistrarObj; @@ -323,6 +318,19 @@ static PassRegistrar *getPassRegistrar() { return PassRegistrarObj; } +// FIXME: We use ManagedCleanup to erase the pass registrar on shutdown. +// Unfortunately, passes are registered with static ctors, and having +// llvm_shutdown clear this map prevents successful ressurection after +// llvm_shutdown is run. Ideally we should find a solution so that we don't +// leak the map, AND can still resurrect after shutdown. +void cleanupPassRegistrar(void*) { + if (PassRegistrarObj) { + delete PassRegistrarObj; + PassRegistrarObj = 0; + } +} +ManagedCleanup<&cleanupPassRegistrar> registrarCleanup; + // getPassInfo - Return the PassInfo data structure that corresponds to this // pass... const PassInfo *Pass::getPassInfo() const { |
