Commit 1217ab96 by Nicolas Capens Committed by Nicolas Capens

Support JIT on a separate thread

On platforms where the calling thread has a very small stack, LLVM can overflow the stack. Work around it by creating a temporary thread for performing LLVM optimizations and codegen. Bug: b/149829034 Change-Id: I59edd0f7d02b4724ea30f9413ea3efbb4d200290 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/41389Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent 3cfba7f0
...@@ -632,55 +632,70 @@ Config Nucleus::getDefaultConfig() ...@@ -632,55 +632,70 @@ Config Nucleus::getDefaultConfig()
std::shared_ptr<Routine> Nucleus::acquireRoutine(const char *name, const Config::Edit &cfgEdit /* = Config::Edit::None */) std::shared_ptr<Routine> Nucleus::acquireRoutine(const char *name, const Config::Edit &cfgEdit /* = Config::Edit::None */)
{ {
auto cfg = cfgEdit.apply(jit->config); std::shared_ptr<Routine> routine;
if(jit->builder->GetInsertBlock()->empty() || !jit->builder->GetInsertBlock()->back().isTerminator()) auto acquire = [&]() {
{ auto cfg = cfgEdit.apply(jit->config);
llvm::Type *type = jit->function->getReturnType();
if(type->isVoidTy()) if(jit->builder->GetInsertBlock()->empty() || !jit->builder->GetInsertBlock()->back().isTerminator())
{
createRetVoid();
}
else
{ {
createRet(V(llvm::UndefValue::get(type))); llvm::Type *type = jit->function->getReturnType();
if(type->isVoidTy())
{
createRetVoid();
}
else
{
createRet(V(llvm::UndefValue::get(type)));
}
} }
}
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
if(jit->debugInfo != nullptr) if(jit->debugInfo != nullptr)
{ {
jit->debugInfo->Finalize(); jit->debugInfo->Finalize();
} }
#endif // ENABLE_RR_DEBUG_INFO #endif // ENABLE_RR_DEBUG_INFO
if(false) if(false)
{ {
std::error_code error; std::error_code error;
llvm::raw_fd_ostream file(std::string(name) + "-llvm-dump-unopt.txt", error); llvm::raw_fd_ostream file(std::string(name) + "-llvm-dump-unopt.txt", error);
jit->module->print(file, 0); jit->module->print(file, 0);
} }
#if defined(ENABLE_RR_LLVM_IR_VERIFICATION) || !defined(NDEBUG) #if defined(ENABLE_RR_LLVM_IR_VERIFICATION) || !defined(NDEBUG)
{ {
llvm::legacy::PassManager pm; llvm::legacy::PassManager pm;
pm.add(llvm::createVerifierPass()); pm.add(llvm::createVerifierPass());
pm.run(*jit->module); pm.run(*jit->module);
} }
#endif // defined(ENABLE_RR_LLVM_IR_VERIFICATION) || !defined(NDEBUG) #endif // defined(ENABLE_RR_LLVM_IR_VERIFICATION) || !defined(NDEBUG)
jit->optimize(cfg); jit->optimize(cfg);
if(false) if(false)
{ {
std::error_code error; std::error_code error;
llvm::raw_fd_ostream file(std::string(name) + "-llvm-dump-opt.txt", error); llvm::raw_fd_ostream file(std::string(name) + "-llvm-dump-opt.txt", error);
jit->module->print(file, 0); jit->module->print(file, 0);
} }
auto routine = jit->acquireRoutine(&jit->function, 1, cfg); routine = jit->acquireRoutine(&jit->function, 1, cfg);
jit.reset(); jit.reset();
};
#ifdef JIT_IN_SEPARATE_THREAD
// Perform optimizations and codegen in a separate thread to avoid stack overflow.
// FIXME(b/149829034): This is not a long-term solution. Reactor has no control
// over the threading and stack sizes of its users, so this should be addressed
// at a higher level instead.
std::thread thread(acquire);
thread.join();
#else
acquire();
#endif
return routine; return routine;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment