================ @@ -347,20 +348,110 @@ const char *const Runtimes = R"( EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; +llvm::Expected<std::pair<std::unique_ptr<llvm::orc::LLJITBuilder>, uint32_t>> +Interpreter::outOfProcessJITBuilder(JITConfig Config) { + std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC; + uint32_t childPid = -1; + if (!Config.OOPExecutor.empty()) { + // Launch an out-of-process executor locally in a child process. + auto ResultOrErr = IncrementalExecutor::launchExecutor( + Config.OOPExecutor, Config.UseSharedMemory, + Config.SlabAllocateSizeString); + if (!ResultOrErr) + return ResultOrErr.takeError(); + childPid = ResultOrErr->second; + auto EPCOrErr = std::move(ResultOrErr->first); + EPC = std::move(EPCOrErr); + } else if (Config.OOPExecutorConnect != "") { + auto EPCOrErr = IncrementalExecutor::connectTCPSocket( + Config.OOPExecutorConnect, Config.UseSharedMemory, + Config.SlabAllocateSizeString); + if (!EPCOrErr) + return EPCOrErr.takeError(); + EPC = std::move(*EPCOrErr); + } + + std::unique_ptr<llvm::orc::LLJITBuilder> JB; + if (EPC) { + auto JBOrErr = clang::Interpreter::createLLJITBuilder( + std::move(EPC), Config.OrcRuntimePath); + if (!JBOrErr) + return JBOrErr.takeError(); + JB = std::move(*JBOrErr); + } + + return std::make_pair(std::move(JB), childPid); +} + +llvm::Expected<std::string> +Interpreter::getOrcRuntimePath(const driver::ToolChain &TC) { + std::optional<std::string> CompilerRTPath = TC.getCompilerRTPath(); + std::optional<std::string> ResourceDir = TC.getRuntimePath(); + + if (!CompilerRTPath) { + return llvm::make_error<llvm::StringError>("CompilerRT path not found", + std::error_code()); + } + + const std::array<const char *, 3> OrcRTLibNames = { + "liborc_rt.a", "liborc_rt_osx.a", "liborc_rt-x86_64.a"}; + + for (const char *LibName : OrcRTLibNames) { + llvm::SmallString<256> CandidatePath((*CompilerRTPath).c_str()); + llvm::sys::path::append(CandidatePath, LibName); + + if (llvm::sys::fs::exists(CandidatePath)) { + return CandidatePath.str().str(); + } + } + + return llvm::make_error<llvm::StringError>( + llvm::Twine("OrcRuntime library not found in: ") + (*CompilerRTPath), + std::error_code()); +} + llvm::Expected<std::unique_ptr<Interpreter>> -Interpreter::create(std::unique_ptr<CompilerInstance> CI, - std::unique_ptr<llvm::orc::LLJITBuilder> JB) { +Interpreter::create(std::unique_ptr<CompilerInstance> CI, JITConfig Config) { llvm::Error Err = llvm::Error::success(); - auto Interp = std::unique_ptr<Interpreter>( - new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr)); - if (Err) - return std::move(Err); + + std::unique_ptr<llvm::orc::LLJITBuilder> JB; + + if (Config.IsOutOfProcess) { + const TargetInfo &TI = CI->getTarget(); + const llvm::Triple &Triple = TI.getTriple(); + + DiagnosticsEngine &Diags = CI->getDiagnostics(); + std::string BinaryName = llvm::sys::fs::getMainExecutable(nullptr, nullptr); + driver::Driver Driver(BinaryName, Triple.str(), Diags); + std::vector<const char *> Args = {"clang", "--version"}; + std::unique_ptr<clang::driver::Compilation> C( + Driver.BuildCompilation(Args)); + if (!C) { + return llvm::make_error<llvm::StringError>( + "Failed to create driver compilation for out-of-process JIT", + std::error_code()); + } + if (Config.OrcRuntimePath == "") { + const clang::driver::ToolChain &TC = C->getDefaultToolChain(); + + auto OrcRuntimePathOrErr = getOrcRuntimePath(TC); + if (!OrcRuntimePathOrErr) { + return OrcRuntimePathOrErr.takeError(); + } + + Config.OrcRuntimePath = *OrcRuntimePathOrErr; + } ---------------- vgvassilev wrote:
This needs to happen on the existing compiler instance that we create and not on a fake one `clang --version`. https://github.com/llvm/llvm-project/pull/155140 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits