diff options
author | Juergen Ributzka <juergen@apple.com> | 2014-05-16 02:33:15 +0000 |
---|---|---|
committer | Juergen Ributzka <juergen@apple.com> | 2014-05-16 02:33:15 +0000 |
commit | 9bc1b73c9e30197d18b64fb9cf09dd45eaef256b (patch) | |
tree | 19301c341258da0cf14012dbb4c947c50cfc7415 /lib/IR | |
parent | 6d81fc75c495e8ed20f1508042bcd2edba1a8058 (diff) | |
download | llvm-9bc1b73c9e30197d18b64fb9cf09dd45eaef256b.tar.gz llvm-9bc1b73c9e30197d18b64fb9cf09dd45eaef256b.tar.bz2 llvm-9bc1b73c9e30197d18b64fb9cf09dd45eaef256b.tar.xz |
Add C API for thread yielding callback.
Sometimes a LLVM compilation may take more time then a client would like to
wait for. The problem is that it is not possible to safely suspend the LLVM
thread from the outside. When the timing is bad it might be possible that the
LLVM thread holds a global mutex and this would block any progress in any other
thread.
This commit adds a new yield callback function that can be registered with a
context. LLVM will try to yield by calling this callback function, but there is
no guaranteed frequency. LLVM will only do so if it can guarantee that
suspending the thread won't block any forward progress in other LLVM contexts
in the same process.
Once the client receives the call back it can suspend the thread safely and
resume it at another time.
Related to <rdar://problem/16728690>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208945 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/Core.cpp | 7 | ||||
-rw-r--r-- | lib/IR/LLVMContext.cpp | 11 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.cpp | 2 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 3 | ||||
-rw-r--r-- | lib/IR/LegacyPassManager.cpp | 9 | ||||
-rw-r--r-- | lib/IR/PassManager.cpp | 5 |
6 files changed, 35 insertions, 2 deletions
diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index b1b0abb9ef..81d137edfe 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -89,6 +89,13 @@ void LLVMContextSetDiagnosticHandler(LLVMContextRef C, DiagnosticContext); } +void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback, + void *OpaqueHandle) { + auto YieldCallback = + LLVM_EXTENSION reinterpret_cast<LLVMContext::YieldCallbackTy>(Callback); + unwrap(C)->setYieldCallback(YieldCallback, OpaqueHandle); +} + void LLVMContextDispose(LLVMContextRef C) { delete unwrap(C); } diff --git a/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp index 588e1217bd..5f94dca1eb 100644 --- a/lib/IR/LLVMContext.cpp +++ b/lib/IR/LLVMContext.cpp @@ -115,6 +115,17 @@ void *LLVMContext::getDiagnosticContext() const { return pImpl->DiagnosticContext; } +void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) +{ + pImpl->YieldCallback = Callback; + pImpl->YieldOpaqueHandle = OpaqueHandle; +} + +void LLVMContext::yield() { + if (pImpl->YieldCallback) + pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); +} + void LLVMContext::emitError(const Twine &ErrorStr) { diagnose(DiagnosticInfoInlineAsm(ErrorStr)); } diff --git a/lib/IR/LLVMContextImpl.cpp b/lib/IR/LLVMContextImpl.cpp index 78a3c2d304..2042374647 100644 --- a/lib/IR/LLVMContextImpl.cpp +++ b/lib/IR/LLVMContextImpl.cpp @@ -41,6 +41,8 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) InlineAsmDiagContext = nullptr; DiagnosticHandler = nullptr; DiagnosticContext = nullptr; + YieldCallback = nullptr; + YieldOpaqueHandle = nullptr; NamedStructTypesUniqueID = 0; } diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index a6a65e6cac..b1ad9ff4a5 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -242,6 +242,9 @@ public: LLVMContext::DiagnosticHandlerTy DiagnosticHandler; void *DiagnosticContext; + LLVMContext::YieldCallbackTy YieldCallback; + void *YieldOpaqueHandle; + typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt *, DenseMapAPIntKeyInfo> IntMapTy; IntMapTy IntConstants; diff --git a/lib/IR/LegacyPassManager.cpp b/lib/IR/LegacyPassManager.cpp index b6d75b483f..d3f3482dc0 100644 --- a/lib/IR/LegacyPassManager.cpp +++ b/lib/IR/LegacyPassManager.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassManagers.h" @@ -1489,8 +1490,10 @@ bool FunctionPassManagerImpl::run(Function &F) { TimingInfo::createTheTimeInfo(); initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { Changed |= getContainedManager(Index)->runOnFunction(F); + F.getContext().yield(); + } for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) getContainedManager(Index)->cleanup(); @@ -1723,8 +1726,10 @@ bool PassManagerImpl::run(Module &M) { } initializeAllAnalysisInfo(); - for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) + for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) { Changed |= getContainedManager(Index)->runOnModule(M); + M.getContext().yield(); + } for (SmallVectorImpl<ImmutablePass *>::const_iterator I = IPV.begin(), E = IPV.end(); I != E; ++I) { diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index 3344b09953..0defb6ab3e 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/IR/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -32,6 +33,8 @@ PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) { if (AM) AM->invalidate(M, PassPA); PA.intersect(std::move(PassPA)); + + M->getContext().yield(); } if (DebugPM) @@ -92,6 +95,8 @@ PreservedAnalyses FunctionPassManager::run(Function *F, if (AM) AM->invalidate(F, PassPA); PA.intersect(std::move(PassPA)); + + F->getContext().yield(); } if (DebugPM) |