@@ -273,6 +273,35 @@ StringRef demangleFunctionBody(const StringRef Mangled) {
273
273
return Mangled.drop_back (ManglingSuffix.size ());
274
274
}
275
275
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
+
276
305
class SILMaterializationUnit ;
277
306
278
307
// / Wraps an LLJIT instance, adds lazy compilation.
@@ -288,30 +317,12 @@ class SwiftJIT {
288
317
// / current process.
289
318
static llvm::Expected<std::unique_ptr<SwiftJIT>>
290
319
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);
306
322
if (!J)
307
323
return J.takeError ();
308
324
309
325
// 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));
315
326
316
327
auto EPCIU = llvm::orc::EPCIndirectionUtils::Create (
317
328
(*J)->getExecutionSession ().getExecutorProcessControl ());
@@ -333,6 +344,8 @@ class SwiftJIT {
333
344
J->getExecutionSession ().reportError (std::move (Err));
334
345
}
335
346
347
+ llvm::orc::LLJIT &getJIT () { return *J; }
348
+
336
349
llvm::orc::JITDylib &getMainJITDylib () { return J->getMainJITDylib (); }
337
350
338
351
// / Register a the materialization unit `MU` with the `JITDylib``JD` and
@@ -370,19 +383,6 @@ class SwiftJIT {
370
383
}
371
384
372
385
private:
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
-
386
386
// / An ORC layer to rename the names of function bodies to support lazy
387
387
// / reexports
388
388
class SwiftJITPlugin : public llvm ::orc::ObjectLinkingLayer::Plugin {
@@ -470,6 +470,63 @@ class SwiftJIT {
470
470
std::unique_ptr<llvm::orc::IndirectStubsManager> ISM;
471
471
};
472
472
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
+
473
530
// / Lazily materializes an entire SIL module
474
531
class SILMaterializationUnit : public llvm ::orc::MaterializationUnit {
475
532
public:
@@ -482,33 +539,16 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
482
539
void materialize (
483
540
std::unique_ptr<llvm::orc::MaterializationResponsibility> R) override {
484
541
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));
495
543
496
- if (Context. hadError () ) {
544
+ if (!GenModule ) {
497
545
R->failMaterialization ();
498
546
return ;
499
547
}
500
548
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 ();
509
550
510
551
// Dump IR if requested
511
- LLVM_DEBUG (llvm::dbgs () << " Module to be executed:\n " ; Module->dump ());
512
552
dumpJIT (*Module);
513
553
514
554
// Now we must register all other public symbols defined by
@@ -525,9 +565,9 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
525
565
}
526
566
// Register the symbols we have discovered with the JIT
527
567
if (auto Err = R->defineMaterializing (Symbols)) {
528
- logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
568
+ logError (std::move (Err));
529
569
}
530
- auto TSM = std::move (GenModule).intoThreadSafeContext ();
570
+ auto TSM = std::move (* GenModule).intoThreadSafeContext ();
531
571
JIT.getIRCompileLayer ().emit (std::move (R), std::move (TSM));
532
572
}
533
573
@@ -536,16 +576,7 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
536
576
private:
537
577
// / Dump the contents of `Module` if requested
538
578
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);
549
580
}
550
581
551
582
// / All global value `Global` to `Symbols` if it is a public definition
@@ -608,17 +639,49 @@ llvm::Error SwiftJIT::addSwift(llvm::orc::JITDylib &JD,
608
639
return JD.define (std::move (MU));
609
640
}
610
641
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
+
611
673
int swift::RunImmediately (CompilerInstance &CI, const ProcessCmdLine &CmdLine,
612
674
const IRGenOptions &IRGenOpts,
613
675
const SILOptions &SILOpts,
614
676
std::unique_ptr<SILModule> &&SM) {
615
- ASTContext &Context = CI.getASTContext ();
677
+
678
+ auto &Context = CI.getASTContext ();
679
+
616
680
// Load libSwiftCore to setup process arguments.
617
681
//
618
682
// This must be done here, before any library loading has been done, to avoid
619
683
// racing with the static initializers in user code.
620
684
// Setup interpreted process arguments.
621
-
622
685
using ArgOverride = void (* SWIFT_CC (swift))(const char **, int );
623
686
#if defined(_WIN32)
624
687
auto stdlib = loadSwiftRuntime (Context.SearchPathOpts .RuntimeLibraryPaths );
@@ -656,8 +719,6 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
656
719
}
657
720
#endif
658
721
659
- auto *swiftModule = CI.getMainModule ();
660
-
661
722
SmallVector<const char *, 32 > argBuf;
662
723
for (size_t i = 0 ; i < CmdLine.size (); ++i) {
663
724
argBuf.push_back (CmdLine[i].c_str ());
@@ -666,45 +727,41 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
666
727
667
728
(*emplaceProcessArgs)(argBuf.data (), CmdLine.size ());
668
729
730
+ auto *swiftModule = CI.getMainModule ();
669
731
if (autolinkImportedModules (swiftModule, IRGenOpts))
670
732
return -1 ;
671
733
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
+ }
677
741
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
+ }
684
748
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);
689
750
}
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));
694
754
return -1 ;
695
755
}
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));
706
764
return -1 ;
707
765
}
708
-
709
- return Result;
766
+ return runMain (**JIT, CmdLine);
710
767
}
0 commit comments