18#include "llvm/ADT/StringExtras.h"
19#include "llvm/ExecutionEngine/ExecutionEngine.h"
20#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
21#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
22#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
23#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
24#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
25#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
26#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
27#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
28#include "llvm/ExecutionEngine/Orc/LLJIT.h"
29#include "llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h"
30#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
31#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
32#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
33#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
34#include "llvm/ExecutionEngine/SectionMemoryManager.h"
35#include "llvm/IR/Module.h"
36#include "llvm/Support/FileSystem.h"
37#include "llvm/Support/ManagedStatic.h"
38#include "llvm/Support/Path.h"
39#include "llvm/Support/TargetSelect.h"
40#include "llvm/TargetParser/Host.h"
44#include <netinet/in.h>
45#include <sys/socket.h>
51 llvm::errs() << (
void *)&llvm_orc_registerJITLoaderGDBWrapper
52 << (
void *)&llvm_orc_registerJITLoaderGDBAllocAction;
61 llvm::orc::JITTargetMachineBuilder JTMB) {
62 auto JITBuilder = std::make_unique<llvm::orc::LLJITBuilder>();
63 JITBuilder->setJITTargetMachineBuilder(std::move(JTMB));
64 JITBuilder->setPrePlatformSetup([](llvm::orc::LLJIT &J) {
67 consumeError(llvm::orc::enableDebuggerSupport(J));
68 return llvm::Error::success();
70 return std::move(JITBuilder);
74 llvm::orc::LLJITBuilder &JITBuilder,
77 : TSCtx(TSC), OutOfProcessChildPid(Config.ExecutorPID) {
79 llvm::ErrorAsOutParameter EAO(&Err);
81 if (
auto JitOrErr = JITBuilder.create())
82 Jit = std::move(*JitOrErr);
84 Err = JitOrErr.takeError();
92 llvm::orc::ResourceTrackerSP RT =
93 Jit->getMainJITDylib().createResourceTracker();
94 ResourceTrackers[&PTU] = RT;
96 return Jit->addIRModule(RT, {std::move(PTU.
TheModule), TSCtx});
101 llvm::orc::ResourceTrackerSP RT = std::move(ResourceTrackers[&PTU]);
103 return llvm::Error::success();
105 ResourceTrackers.erase(&PTU);
106 if (llvm::Error Err = RT->remove())
108 return llvm::Error::success();
114 return Jit->deinitialize(Jit->getMainJITDylib());
118 return Jit->initialize(Jit->getMainJITDylib());
125 auto SO = makeJITDylibSearchOrder({&Jit->getMainJITDylib(),
126 Jit->getPlatformJITDylib().get(),
127 Jit->getProcessSymbolsJITDylib().get()});
129 ExecutionSession &ES = Jit->getExecutionSession();
132 ES.lookup(SO, (NameKind ==
LinkerName) ? ES.intern(Name)
133 : Jit->mangleAndIntern(Name));
134 if (
auto Err = SymOrErr.takeError())
135 return std::move(Err);
136 return SymOrErr->getAddress();
141 unsigned SlabAllocateSize) {
142 llvm::orc::SharedMemoryMapper::SymbolAddrs SAs;
143 if (
auto Err = SREPC.getBootstrapSymbols(
145 llvm::orc::rt::ExecutorSharedMemoryMapperServiceInstanceName},
147 llvm::orc::rt::ExecutorSharedMemoryMapperServiceReserveWrapperName},
150 ExecutorSharedMemoryMapperServiceInitializeWrapperName},
153 ExecutorSharedMemoryMapperServiceDeinitializeWrapperName},
156 ExecutorSharedMemoryMapperServiceReleaseWrapperName}}))
157 return std::move(Err);
160 if (llvm::Triple(llvm::sys::getProcessTriple()).isOSWindows())
161 SlabSize = 1024 * 1024;
163 SlabSize = 1024 * 1024 * 1024;
165 if (SlabAllocateSize > 0)
166 SlabSize = SlabAllocateSize;
168 return llvm::orc::MapperJITLinkMemoryManager::CreateWithMapper<
169 llvm::orc::SharedMemoryMapper>(SlabSize, SREPC, SAs);
174 bool UseSharedMemory,
175 unsigned SlabAllocateSize,
179 return llvm::make_error<llvm::StringError>(
180 "-" + ExecutablePath +
" not supported on non-unix platforms",
181 llvm::inconvertibleErrorCode());
182#elif !LLVM_ENABLE_THREADS
184 return llvm::make_error<llvm::StringError>(
185 "-" + ExecutablePath +
186 " requires threads, but LLVM was built with "
187 "LLVM_ENABLE_THREADS=Off",
188 llvm::inconvertibleErrorCode());
191 if (!llvm::sys::fs::can_execute(ExecutablePath))
192 return llvm::make_error<llvm::StringError>(
193 llvm::formatv(
"Specified executor invalid: {0}", ExecutablePath),
194 llvm::inconvertibleErrorCode());
196 constexpr int ReadEnd = 0;
197 constexpr int WriteEnd = 1;
206 if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)
207 return llvm::make_error<llvm::StringError>(
208 "Unable to create pipe for executor", llvm::inconvertibleErrorCode());
216 close(ToExecutor[WriteEnd]);
217 close(FromExecutor[ReadEnd]);
223 std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
225 ExecutorPath = std::make_unique<char[]>(ExecutablePath.size() + 1);
226 strcpy(ExecutorPath.get(), ExecutablePath.data());
228 std::string FDSpecifierStr(
"filedescs=");
229 FDSpecifierStr += llvm::utostr(ToExecutor[ReadEnd]);
230 FDSpecifierStr +=
',';
231 FDSpecifierStr += llvm::utostr(FromExecutor[WriteEnd]);
232 FDSpecifier = std::make_unique<char[]>(FDSpecifierStr.size() + 1);
233 strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());
236 char *
const Args[] = {ExecutorPath.get(), FDSpecifier.get(),
nullptr};
237 int RC = execvp(ExecutorPath.get(), Args);
239 llvm::errs() <<
"unable to launch out-of-process executor \""
240 << ExecutorPath.get() <<
"\"\n";
247 close(ToExecutor[ReadEnd]);
248 close(FromExecutor[WriteEnd]);
250 llvm::orc::SimpleRemoteEPC::Setup S = llvm::orc::SimpleRemoteEPC::Setup();
252 S.CreateMemoryManager =
253 [SlabAllocateSize](llvm::orc::SimpleRemoteEPC &EPC) {
258 llvm::orc::SimpleRemoteEPC::Create<llvm::orc::FDSimpleRemoteEPCTransport>(
259 std::make_unique<llvm::orc::DynamicThreadPoolTaskDispatcher>(
261 std::move(S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
263 return EPCOrErr.takeError();
264 return std::make_pair(std::move(*EPCOrErr), ChildPID);
268#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS
271 std::string PortStr) {
274 Hints.ai_family = AF_INET;
275 Hints.ai_socktype = SOCK_STREAM;
276 Hints.ai_flags = AI_NUMERICSERV;
278 if (
int EC = getaddrinfo(Host.c_str(), PortStr.c_str(), &Hints, &AI))
279 return llvm::make_error<llvm::StringError>(
280 llvm::formatv(
"address resolution failed ({0})", strerror(EC)),
281 llvm::inconvertibleErrorCode());
286 for (Server = AI; Server !=
nullptr; Server = Server->ai_next) {
289 if ((SockFD = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0)
293 if (connect(SockFD, Server->ai_addr, Server->ai_addrlen) == 0)
302 if (Server ==
nullptr)
303 return llvm::make_error<llvm::StringError>(
"invalid hostname",
304 llvm::inconvertibleErrorCode());
310IncrementalExecutor::connectTCPSocket(llvm::StringRef NetworkAddress,
311 bool UseSharedMemory,
312 unsigned SlabAllocateSize) {
315 return llvm::make_error<llvm::StringError>(
316 "-" + NetworkAddress +
" not supported on non-unix platforms",
317 llvm::inconvertibleErrorCode());
318#elif !LLVM_ENABLE_THREADS
320 return llvm::make_error<llvm::StringError>(
321 "-" + NetworkAddress +
322 " requires threads, but LLVM was built with "
323 "LLVM_ENABLE_THREADS=Off",
324 llvm::inconvertibleErrorCode());
327 auto CreateErr = [NetworkAddress](Twine Details) {
328 return llvm::make_error<llvm::StringError>(
329 formatv(
"Failed to connect TCP socket '{0}': {1}", NetworkAddress,
331 llvm::inconvertibleErrorCode());
334 StringRef
Host, PortStr;
335 std::tie(Host, PortStr) = NetworkAddress.split(
':');
337 return CreateErr(
"Host name for -" + NetworkAddress +
" can not be empty");
339 return CreateErr(
"Port number in -" + NetworkAddress +
" can not be empty");
341 if (PortStr.getAsInteger(10, Port))
342 return CreateErr(
"Port number '" + PortStr +
"' is not a valid integer");
346 return SockFD.takeError();
348 llvm::orc::SimpleRemoteEPC::Setup S = llvm::orc::SimpleRemoteEPC::Setup();
350 S.CreateMemoryManager =
351 [SlabAllocateSize](llvm::orc::SimpleRemoteEPC &EPC) {
355 return llvm::orc::SimpleRemoteEPC::Create<
356 llvm::orc::FDSimpleRemoteEPCTransport>(
357 std::make_unique<llvm::orc::DynamicThreadPoolTaskDispatcher>(
359 std::move(S), *SockFD, *SockFD);
LLVM_ATTRIBUTE_USED void linkComponents()
Defines the clang::TargetOptions class.
static llvm::Expected< std::pair< std::unique_ptr< llvm::orc::SimpleRemoteEPC >, uint32_t > > launchExecutor(llvm::StringRef ExecutablePath, bool UseSharedMemory, unsigned SlabAllocateSize, std::function< void()> CustomizeFork=nullptr)
virtual llvm::Error runCtors() const
virtual llvm::Error addModule(PartialTranslationUnit &PTU)
virtual ~IncrementalExecutor()
virtual llvm::Expected< llvm::orc::ExecutorAddr > getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const
static llvm::Expected< std::unique_ptr< llvm::orc::LLJITBuilder > > createDefaultJITBuilder(llvm::orc::JITTargetMachineBuilder JTMB)
virtual llvm::Error removeModule(PartialTranslationUnit &PTU)
IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC)
virtual llvm::Error cleanUp()
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
Expected< std::unique_ptr< llvm::jitlink::JITLinkMemoryManager > > createSharedMemoryManager(llvm::orc::SimpleRemoteEPC &SREPC, unsigned SlabAllocateSize)
int const char * function
The class keeps track of various objects created as part of processing incremental inputs.
std::unique_ptr< llvm::Module > TheModule
The llvm IR produced for the input.