summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2014-05-16 02:33:15 +0000
committerJuergen Ributzka <juergen@apple.com>2014-05-16 02:33:15 +0000
commit34390c70a5b00a03455675151d7346d99cd12f2c (patch)
tree8a40ed3f73157d4fecd404a3b23aee741d1ec3b3 /llvm/lib/IR
parentdebcd500a0e184cc17254622411a9cc8e9dcfaa0 (diff)
downloadbcm5719-llvm-34390c70a5b00a03455675151d7346d99cd12f2c.tar.gz
bcm5719-llvm-34390c70a5b00a03455675151d7346d99cd12f2c.zip
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> llvm-svn: 208945
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/Core.cpp7
-rw-r--r--llvm/lib/IR/LLVMContext.cpp11
-rw-r--r--llvm/lib/IR/LLVMContextImpl.cpp2
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h3
-rw-r--r--llvm/lib/IR/LegacyPassManager.cpp9
-rw-r--r--llvm/lib/IR/PassManager.cpp5
6 files changed, 35 insertions, 2 deletions
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index b1b0abb9eff..81d137edfe0 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/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/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index 588e1217bd4..5f94dca1eb9 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/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/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 78a3c2d304b..2042374647d 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/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/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index a6a65e6cacd..b1ad9ff4a5a 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/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/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index b6d75b483f8..d3f3482dc02 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/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/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp
index 3344b099537..0defb6ab3e4 100644
--- a/llvm/lib/IR/PassManager.cpp
+++ b/llvm/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)
OpenPOWER on IntegriCloud