@@ -273,6 +273,35 @@ StringRef demangleFunctionBody(const StringRef Mangled) {
273273 return Mangled.drop_back (ManglingSuffix.size ());
274274}
275275
276+ // / Creates an `LLJIT` instance with the given target options and an
277+ // / attached generator that resolves symbols from the current process
278+ static llvm::Expected<std::unique_ptr<llvm::orc::LLJIT>>
279+ createLLJIT (const IRGenOptions &IRGenOpts, ASTContext &Ctx) {
280+ llvm::TargetOptions TargetOpt;
281+ std::string CPU;
282+ std::string Triple;
283+ std::vector<std::string> Features;
284+ std::tie (TargetOpt, CPU, Features, Triple) =
285+ getIRTargetOptions (IRGenOpts, Ctx);
286+ auto JTMB = llvm::orc::JITTargetMachineBuilder (llvm::Triple (Triple))
287+ .setRelocationModel (llvm::Reloc::PIC_)
288+ .setOptions (std::move (TargetOpt))
289+ .setCPU (std::move (CPU))
290+ .addFeatures (Features)
291+ .setCodeGenOptLevel (llvm::CodeGenOpt::Default);
292+ auto J = llvm::orc::LLJITBuilder ()
293+ .setJITTargetMachineBuilder (std::move (JTMB))
294+ .create ();
295+ if (!J)
296+ return J.takeError ();
297+ auto G = llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess (
298+ (*J)->getDataLayout ().getGlobalPrefix ());
299+ if (!G)
300+ return G.takeError ();
301+ (*J)->getMainJITDylib ().addGenerator (std::move (*G));
302+ return J;
303+ }
304+
276305class SILMaterializationUnit ;
277306
278307// / Wraps an LLJIT instance, adds lazy compilation.
@@ -288,30 +317,12 @@ class SwiftJIT {
288317 // / current process.
289318 static llvm::Expected<std::unique_ptr<SwiftJIT>>
290319 Create (const IRGenOptions &IRGenOpts, ASTContext &Ctx) {
291- llvm::TargetOptions TargetOpt;
292- std::string CPU;
293- std::string Triple;
294- std::vector<std::string> Features;
295- std::tie (TargetOpt, CPU, Features, Triple) =
296- getIRTargetOptions (IRGenOpts, Ctx);
297- auto JTMB = llvm::orc::JITTargetMachineBuilder (llvm::Triple (Triple))
298- .setRelocationModel (llvm::Reloc::PIC_)
299- .setOptions (std::move (TargetOpt))
300- .setCPU (std::move (CPU))
301- .addFeatures (Features)
302- .setCodeGenOptLevel (llvm::CodeGenOpt::Default);
303-
304- auto J =
305- getLLJITBuilder ().setJITTargetMachineBuilder (std::move (JTMB)).create ();
320+
321+ auto J = createLLJIT (IRGenOpts, Ctx);
306322 if (!J)
307323 return J.takeError ();
308324
309325 // Create generator to resolve symbols defined in current process
310- auto G = llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess (
311- (*J)->getDataLayout ().getGlobalPrefix ());
312- if (!G)
313- return G.takeError ();
314- (*J)->getMainJITDylib ().addGenerator (std::move (*G));
315326
316327 auto EPCIU = llvm::orc::EPCIndirectionUtils::Create (
317328 (*J)->getExecutionSession ().getExecutorProcessControl ());
@@ -333,6 +344,8 @@ class SwiftJIT {
333344 J->getExecutionSession ().reportError (std::move (Err));
334345 }
335346
347+ llvm::orc::LLJIT &getJIT () { return *J; }
348+
336349 llvm::orc::JITDylib &getMainJITDylib () { return J->getMainJITDylib (); }
337350
338351 // / Register a the materialization unit `MU` with the `JITDylib``JD` and
@@ -370,19 +383,6 @@ class SwiftJIT {
370383 }
371384
372385private:
373- // / Creates a `LLJITTargetBuilder` and configures its `ObjectLinkingLayer`
374- static llvm::orc::LLJITBuilder getLLJITBuilder () {
375- using ObjLayer = llvm::Expected<std::unique_ptr<llvm::orc::ObjectLayer>>;
376- return std::move (llvm::orc::LLJITBuilder ().setObjectLinkingLayerCreator (
377- [&](auto &ES, const auto &TargetTriple) -> ObjLayer {
378- auto MemMgr = llvm::jitlink::InProcessMemoryManager::Create ();
379- if (!MemMgr)
380- return MemMgr.takeError ();
381- return std::make_unique<llvm::orc::ObjectLinkingLayer>(
382- ES, std::move (*MemMgr));
383- }));
384- }
385-
386386 // / An ORC layer to rename the names of function bodies to support lazy
387387 // / reexports
388388 class SwiftJITPlugin : public llvm ::orc::ObjectLinkingLayer::Plugin {
@@ -470,6 +470,63 @@ class SwiftJIT {
470470 std::unique_ptr<llvm::orc::IndirectStubsManager> ISM;
471471};
472472
473+ // / Dump the contents of `Module` if requested
474+ static void dumpJIT (llvm::orc::LLJIT &JIT, const llvm::Module &Module,
475+ const IRGenOptions &IRGenOpts) {
476+ LLVM_DEBUG (llvm::dbgs () << " Module to be executed:\n " ; Module.dump ());
477+ switch (IRGenOpts.DumpJIT ) {
478+ case JITDebugArtifact::None:
479+ break ;
480+ case JITDebugArtifact::LLVMIR:
481+ DumpLLVMIR (Module);
482+ break ;
483+ case JITDebugArtifact::Object:
484+ JIT.getObjTransformLayer ().setTransform (llvm::orc::DumpObjects ());
485+ break ;
486+ }
487+ }
488+
489+ // / IRGen the provided `SILModule` with the specified options.
490+ // / Returns `std::nullopt` if a compiler error is encountered
491+ static std::optional<GeneratedModule>
492+ generateModule (const CompilerInstance &CI, const IRGenOptions &IRGenOpts,
493+ std::unique_ptr<SILModule> SM) {
494+ // TODO: Use OptimizedIRRequest for this.
495+ const auto &Context = CI.getASTContext ();
496+ auto *swiftModule = CI.getMainModule ();
497+ const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary ();
498+ const auto &TBDOpts = CI.getInvocation ().getTBDGenOptions ();
499+
500+ // Lower the SIL module to LLVM IR
501+ auto GenModule = performIRGeneration (
502+ swiftModule, IRGenOpts, TBDOpts, std::move (SM),
503+ swiftModule->getName ().str (), PSPs, ArrayRef<std::string>());
504+
505+ if (Context.hadError ()) {
506+ return std::nullopt ;
507+ }
508+
509+ assert (GenModule && " Emitted no diagnostics but IR generation failed?" );
510+ auto *Module = GenModule.getModule ();
511+
512+ // Run LLVM passes on the resulting module
513+ performLLVM (IRGenOpts, Context.Diags , /* diagMutex*/ nullptr ,
514+ /* hash*/ nullptr , Module, GenModule.getTargetMachine (),
515+ CI.getPrimarySpecificPathsForAtMostOnePrimary ().OutputFilename ,
516+ CI.getOutputBackend (), Context.Stats );
517+
518+ if (Context.hadError ()) {
519+ return std::nullopt ;
520+ }
521+
522+ return GenModule;
523+ }
524+
525+ // / Log a compilation error to standard error
526+ static void logError (llvm::Error Err) {
527+ logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
528+ }
529+
473530// / Lazily materializes an entire SIL module
474531class SILMaterializationUnit : public llvm ::orc::MaterializationUnit {
475532public:
@@ -482,33 +539,16 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
482539 void materialize (
483540 std::unique_ptr<llvm::orc::MaterializationResponsibility> R) override {
484541
485- // TODO: Use OptimizedIRRequest for this.
486- const auto &Context = CI.getASTContext ();
487- auto *swiftModule = CI.getMainModule ();
488- const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary ();
489- const auto &TBDOpts = CI.getInvocation ().getTBDGenOptions ();
490-
491- // Lower the SIL module to LLVM IR
492- auto GenModule = performIRGeneration (
493- swiftModule, IRGenOpts, TBDOpts, std::move (SM),
494- swiftModule->getName ().str (), PSPs, ArrayRef<std::string>());
542+ auto GenModule = generateModule (CI, IRGenOpts, std::move (SM));
495543
496- if (Context. hadError () ) {
544+ if (!GenModule ) {
497545 R->failMaterialization ();
498546 return ;
499547 }
500548
501- assert (GenModule && " Emitted no diagnostics but IR generation failed?" );
502- auto *Module = GenModule.getModule ();
503-
504- // Run LLVM passes on the resulting module
505- performLLVM (IRGenOpts, Context.Diags , /* diagMutex*/ nullptr ,
506- /* hash*/ nullptr , Module, GenModule.getTargetMachine (),
507- CI.getPrimarySpecificPathsForAtMostOnePrimary ().OutputFilename ,
508- CI.getOutputBackend (), Context.Stats );
549+ auto *Module = GenModule->getModule ();
509550
510551 // Dump IR if requested
511- LLVM_DEBUG (llvm::dbgs () << " Module to be executed:\n " ; Module->dump ());
512552 dumpJIT (*Module);
513553
514554 // Now we must register all other public symbols defined by
@@ -525,9 +565,9 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
525565 }
526566 // Register the symbols we have discovered with the JIT
527567 if (auto Err = R->defineMaterializing (Symbols)) {
528- logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
568+ logError (std::move (Err));
529569 }
530- auto TSM = std::move (GenModule).intoThreadSafeContext ();
570+ auto TSM = std::move (* GenModule).intoThreadSafeContext ();
531571 JIT.getIRCompileLayer ().emit (std::move (R), std::move (TSM));
532572 }
533573
@@ -536,16 +576,7 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
536576private:
537577 // / Dump the contents of `Module` if requested
538578 void dumpJIT (const llvm::Module &Module) {
539- switch (IRGenOpts.DumpJIT ) {
540- case JITDebugArtifact::None:
541- break ;
542- case JITDebugArtifact::LLVMIR:
543- DumpLLVMIR (Module);
544- break ;
545- case JITDebugArtifact::Object:
546- JIT.getObjTransformLayer ().setTransform (llvm::orc::DumpObjects ());
547- break ;
548- }
579+ ::dumpJIT (JIT.getJIT(), Module, IRGenOpts);
549580 }
550581
551582 // / All global value `Global` to `Symbols` if it is a public definition
@@ -608,17 +639,49 @@ llvm::Error SwiftJIT::addSwift(llvm::orc::JITDylib &JD,
608639 return JD.define (std::move (MU));
609640}
610641
642+ // / Lookup the entry point in `J` and run it with the given command line
643+ // / arguments `CmdLine`. Returns `-1` if failed to compile, or the status
644+ // / returned by the entry point following execution.
645+ static int runMain (llvm::orc::LLJIT &J, const ProcessCmdLine &CmdLine) {
646+ LLVM_DEBUG (llvm::dbgs () << " Running static constructors\n " );
647+ if (auto Err = J.initialize (J.getMainJITDylib ())) {
648+ logError (std::move (Err));
649+ return -1 ;
650+ }
651+
652+ auto MainSym = J.lookup (" main" );
653+ if (!MainSym) {
654+ logError (MainSym.takeError ());
655+ return -1 ;
656+ }
657+
658+ using MainFnTy = int (*)(int , char *[]);
659+ MainFnTy JITMain = MainSym->toPtr <MainFnTy>();
660+
661+ LLVM_DEBUG (llvm::dbgs () << " Running main\n " );
662+ int Result = llvm::orc::runAsMain (JITMain, CmdLine);
663+
664+ LLVM_DEBUG (llvm::dbgs () << " Running static destructors\n " );
665+ if (auto Err = J.deinitialize (J.getMainJITDylib ())) {
666+ logError (std::move (Err));
667+ return -1 ;
668+ }
669+
670+ return Result;
671+ }
672+
611673int swift::RunImmediately (CompilerInstance &CI, const ProcessCmdLine &CmdLine,
612674 const IRGenOptions &IRGenOpts,
613675 const SILOptions &SILOpts,
614676 std::unique_ptr<SILModule> &&SM) {
615- ASTContext &Context = CI.getASTContext ();
677+
678+ auto &Context = CI.getASTContext ();
679+
616680 // Load libSwiftCore to setup process arguments.
617681 //
618682 // This must be done here, before any library loading has been done, to avoid
619683 // racing with the static initializers in user code.
620684 // Setup interpreted process arguments.
621-
622685 using ArgOverride = void (* SWIFT_CC (swift))(const char **, int );
623686#if defined(_WIN32)
624687 auto stdlib = loadSwiftRuntime (Context.SearchPathOpts .RuntimeLibraryPaths );
@@ -656,8 +719,6 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
656719 }
657720#endif
658721
659- auto *swiftModule = CI.getMainModule ();
660-
661722 SmallVector<const char *, 32 > argBuf;
662723 for (size_t i = 0 ; i < CmdLine.size (); ++i) {
663724 argBuf.push_back (CmdLine[i].c_str ());
@@ -666,45 +727,41 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
666727
667728 (*emplaceProcessArgs)(argBuf.data (), CmdLine.size ());
668729
730+ auto *swiftModule = CI.getMainModule ();
669731 if (autolinkImportedModules (swiftModule, IRGenOpts))
670732 return -1 ;
671733
672- auto JIT = SwiftJIT::Create (IRGenOpts, swiftModule->getASTContext ());
673- if (auto Err = JIT.takeError ()) {
674- llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
675- return -1 ;
676- }
734+ auto &Target = swiftModule->getASTContext ().LangOpts .Target ;
735+ if (Target.isMacOSX ()) {
736+ auto JIT = SwiftJIT::Create (IRGenOpts, swiftModule->getASTContext ());
737+ if (auto Err = JIT.takeError ()) {
738+ logError (std::move (Err));
739+ return -1 ;
740+ }
677741
678- auto MU = std::make_unique<SILMaterializationUnit>(**JIT, CI, IRGenOpts,
679- std::move (SM));
680- if (auto Err = (*JIT)->addSwift ((*JIT)->getMainJITDylib (), std::move (MU))) {
681- llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
682- return -1 ;
683- }
742+ auto MU = std::make_unique<SILMaterializationUnit>(**JIT, CI, IRGenOpts,
743+ std::move (SM));
744+ if (auto Err = (*JIT)->addSwift ((*JIT)->getMainJITDylib (), std::move (MU))) {
745+ logError (std::move (Err));
746+ return -1 ;
747+ }
684748
685- LLVM_DEBUG (llvm::dbgs () << " Running static constructors\n " );
686- if (auto Err = (*JIT)->initialize ((*JIT)->getMainJITDylib ())) {
687- llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
688- return -1 ;
749+ return runMain ((*JIT)->getJIT (), CmdLine);
689750 }
690-
691- auto MainSym = (*JIT)->lookup (" main" );
692- if (!MainSym) {
693- llvm::logAllUnhandledErrors (MainSym.takeError (), llvm::errs (), " " );
751+ auto JIT = createLLJIT (IRGenOpts, swiftModule->getASTContext ());
752+ if (auto Err = JIT.takeError ()) {
753+ logError (std::move (Err));
694754 return -1 ;
695755 }
696-
697- using MainFnTy = int (*)(int , char *[]);
698- auto JITMain = MainSym->toPtr <MainFnTy>();
699-
700- LLVM_DEBUG (llvm::dbgs () << " Running main\n " );
701- int Result = llvm::orc::runAsMain (JITMain, CmdLine);
702-
703- LLVM_DEBUG (llvm::dbgs () << " Running static destructors\n " );
704- if (auto Err = (*JIT)->deinitialize ((*JIT)->getMainJITDylib ())) {
705- logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
756+ auto GenModule = generateModule (CI, IRGenOpts, std::move (SM));
757+ if (!GenModule)
758+ return -1 ;
759+ auto *Module = GenModule->getModule ();
760+ dumpJIT (**JIT, *Module, IRGenOpts);
761+ auto TSM = std::move (*GenModule).intoThreadSafeContext ();
762+ if (auto Err = (*JIT)->addIRModule (std::move (TSM))) {
763+ logError (std::move (Err));
706764 return -1 ;
707765 }
708-
709- return Result;
766+ return runMain (**JIT, CmdLine);
710767}
0 commit comments