23
23
#include " swift/AST/IRGenOptions.h"
24
24
#include " swift/AST/IRGenRequests.h"
25
25
#include " swift/AST/Module.h"
26
+ #include " swift/AST/SILGenRequests.h"
27
+ #include " swift/AST/TBDGenRequests.h"
26
28
#include " swift/Basic/LLVM.h"
27
29
#include " swift/Frontend/Frontend.h"
28
30
#include " swift/IRGen/IRGenPublic.h"
@@ -303,6 +305,7 @@ createLLJIT(const IRGenOptions &IRGenOpts, ASTContext &Ctx) {
303
305
}
304
306
305
307
class SILMaterializationUnit ;
308
+ class SwiftMaterializationUnit ;
306
309
307
310
// / Wraps an LLJIT instance, adds lazy compilation.
308
311
class SwiftJIT {
@@ -351,7 +354,7 @@ class SwiftJIT {
351
354
// / Register a the materialization unit `MU` with the `JITDylib``JD` and
352
355
// / create lazy reexports for all functions defined in the interface of `MU`
353
356
llvm::Error addSwift (llvm::orc::JITDylib &JD,
354
- std::unique_ptr<SILMaterializationUnit > MU);
357
+ std::unique_ptr<llvm::orc::MaterializationUnit > MU);
355
358
356
359
llvm::Error initialize (llvm::orc::JITDylib &JD) { return J->initialize (JD); }
357
360
@@ -374,6 +377,10 @@ class SwiftJIT {
374
377
return J->mangleAndIntern (Name);
375
378
}
376
379
380
+ llvm::orc::SymbolStringPtr intern (StringRef Name) {
381
+ return J->getExecutionSession ().intern (Name);
382
+ }
383
+
377
384
llvm::orc::IRCompileLayer &getIRCompileLayer () {
378
385
return J->getIRCompileLayer ();
379
386
}
@@ -489,13 +496,14 @@ static void dumpJIT(llvm::orc::LLJIT &JIT, const llvm::Module &Module,
489
496
// / IRGen the provided `SILModule` with the specified options.
490
497
// / Returns `std::nullopt` if a compiler error is encountered
491
498
static std::optional<GeneratedModule>
492
- generateModule (const CompilerInstance &CI, const IRGenOptions &IRGenOpts,
493
- std::unique_ptr<SILModule> SM) {
499
+ generateModule (const CompilerInstance &CI, std::unique_ptr<SILModule> SM) {
494
500
// TODO: Use OptimizedIRRequest for this.
495
501
const auto &Context = CI.getASTContext ();
496
502
auto *swiftModule = CI.getMainModule ();
497
503
const auto PSPs = CI.getPrimarySpecificPathsForAtMostOnePrimary ();
498
- const auto &TBDOpts = CI.getInvocation ().getTBDGenOptions ();
504
+ const auto &Invocation = CI.getInvocation ();
505
+ const auto &TBDOpts = Invocation.getTBDGenOptions ();
506
+ const auto &IRGenOpts = Invocation.getIRGenOptions ();
499
507
500
508
// Lower the SIL module to LLVM IR
501
509
auto GenModule = performIRGeneration (
@@ -527,6 +535,122 @@ static void logError(llvm::Error Err) {
527
535
logAllUnhandledErrors (std::move (Err), llvm::errs (), " " );
528
536
}
529
537
538
+ // / Allows lazy materialization of `SILDeclRef`s
539
+ class SwiftMaterializationUnit : public llvm ::orc::MaterializationUnit {
540
+ public:
541
+ static std::unique_ptr<SwiftMaterializationUnit>
542
+ Create (SwiftJIT &JIT, CompilerInstance &CI) {
543
+ auto *M = CI.getMainModule ();
544
+ TBDGenOptions Opts;
545
+ Opts.PublicSymbolsOnly = false ;
546
+ auto TBDDesc = TBDGenDescriptor::forModule (M, std::move (Opts));
547
+ SymbolSourceMapRequest SourceReq{TBDDesc};
548
+ auto Sources =
549
+ llvm::cantFail (M->getASTContext ().evaluator (std::move (SourceReq)));
550
+ llvm::orc::SymbolFlagsMap PublicInterface;
551
+ for (const auto &Entry : *Sources.storage ) {
552
+ const auto &Source = Entry.getValue ();
553
+ if (Source.kind != SymbolSource::Kind::SIL) {
554
+ continue ;
555
+ }
556
+ auto Ref = Source.getSILDeclRef ();
557
+ if (Ref.getDefinitionLinkage () != SILLinkage::Public)
558
+ continue ;
559
+ const auto &SymbolName = Entry.getKey ();
560
+ const auto Flags =
561
+ llvm::JITSymbolFlags::Exported | llvm::JITSymbolFlags::Callable;
562
+ PublicInterface[JIT.intern (SymbolName)] = Flags;
563
+ }
564
+ return std::unique_ptr<SwiftMaterializationUnit>(
565
+ new SwiftMaterializationUnit (JIT, CI, std::move (Sources),
566
+ std::move (PublicInterface)));
567
+ }
568
+
569
+ StringRef getName () const override { return " SwiftMaterializationUnit" ; }
570
+
571
+ private:
572
+ SwiftMaterializationUnit (SwiftJIT &JIT, CompilerInstance &CI,
573
+ SymbolSourceMap Sources,
574
+ llvm::orc::SymbolFlagsMap Symbols)
575
+ : MaterializationUnit({std::move (Symbols), nullptr }),
576
+ Sources (std::move(Sources)), JIT(JIT), CI(CI) {}
577
+
578
+ void addGlobal (llvm::orc::SymbolFlagsMap &Symbols,
579
+ const llvm::GlobalValue &Global,
580
+ const llvm::orc::MaterializationResponsibility &MR) {
581
+ // Ignore all symbols that will not appear in symbol table
582
+ if (Global.hasLocalLinkage () || Global.hasAppendingLinkage () ||
583
+ Global.isDeclaration ()) {
584
+ return ;
585
+ }
586
+ auto Name = Global.getName ();
587
+ auto MangledName = JIT.mangleAndIntern (Name);
588
+ if (MR.getRequestedSymbols ().contains (MangledName)) {
589
+ return ;
590
+ }
591
+ Symbols[MangledName] = llvm::JITSymbolFlags::fromGlobalValue (Global);
592
+ }
593
+
594
+ void materialize (
595
+ std::unique_ptr<llvm::orc::MaterializationResponsibility> R) override {
596
+ SILRefsToEmit Refs;
597
+ for (auto &Sym : R->getRequestedSymbols ()) {
598
+ const auto &Source = Sources.storage ->find (*Sym)->getValue ();
599
+ Refs.push_back (Source.getSILDeclRef ());
600
+ }
601
+ auto SM = performASTLowering (CI, std::move (Refs));
602
+ runSILDiagnosticPasses (*SM);
603
+ runSILLoweringPasses (*SM);
604
+ auto GM = generateModule (CI, std::move (SM));
605
+ if (!GM) {
606
+ R->failMaterialization ();
607
+ return ;
608
+ }
609
+ auto *Module = GM->getModule ();
610
+ // Now we must register all other public symbols defined by
611
+ // the module with the JIT
612
+ llvm::orc::SymbolFlagsMap LazilyDiscoveredSymbols;
613
+ // Register all global objects, including global
614
+ // variables and functions
615
+ for (const auto &Global : Module->global_objects ()) {
616
+ addGlobal (LazilyDiscoveredSymbols, Global, *R);
617
+ }
618
+ // Register all global aliases
619
+ for (const auto &Global : Module->aliases ()) {
620
+ addGlobal (LazilyDiscoveredSymbols, Global, *R);
621
+ }
622
+ llvm::orc::SymbolFlagsMap UnrequestedSymbols;
623
+ for (auto &[Sym, Flags] : R->getSymbols ()) {
624
+ if (!R->getRequestedSymbols ().contains (Sym) &&
625
+ !LazilyDiscoveredSymbols.count (Sym)) {
626
+ UnrequestedSymbols[Sym] = Flags;
627
+ }
628
+ }
629
+ std::unique_ptr<MaterializationUnit> UnrequestedMU (
630
+ new SwiftMaterializationUnit (JIT, CI, std::move (Sources),
631
+ std::move (UnrequestedSymbols)));
632
+ if (auto Err = R->replace (std::move (UnrequestedMU))) {
633
+ logError (std::move (Err));
634
+ R->failMaterialization ();
635
+ return ;
636
+ }
637
+ if (auto Err = R->defineMaterializing (std::move (LazilyDiscoveredSymbols))) {
638
+ logError (std::move (Err));
639
+ R->failMaterialization ();
640
+ return ;
641
+ }
642
+ auto TSM = std::move (*GM).intoThreadSafeContext ();
643
+ JIT.getIRCompileLayer ().emit (std::move (R), std::move (TSM));
644
+ }
645
+
646
+ void discard (const llvm::orc::JITDylib &JD,
647
+ const llvm::orc::SymbolStringPtr &Sym) override {}
648
+
649
+ SymbolSourceMap Sources;
650
+ SwiftJIT &JIT;
651
+ CompilerInstance &CI;
652
+ };
653
+
530
654
// / Lazily materializes an entire SIL module
531
655
class SILMaterializationUnit : public llvm ::orc::MaterializationUnit {
532
656
public:
@@ -539,7 +663,7 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
539
663
void materialize (
540
664
std::unique_ptr<llvm::orc::MaterializationResponsibility> R) override {
541
665
542
- auto GenModule = generateModule (CI, IRGenOpts, std::move (SM));
666
+ auto GenModule = generateModule (CI, std::move (SM));
543
667
544
668
if (!GenModule) {
545
669
R->failMaterialization ();
@@ -614,8 +738,9 @@ class SILMaterializationUnit : public llvm::orc::MaterializationUnit {
614
738
std::unique_ptr<SILModule> SM;
615
739
};
616
740
617
- llvm::Error SwiftJIT::addSwift (llvm::orc::JITDylib &JD,
618
- std::unique_ptr<SILMaterializationUnit> MU) {
741
+ llvm::Error
742
+ SwiftJIT::addSwift (llvm::orc::JITDylib &JD,
743
+ std::unique_ptr<llvm::orc::MaterializationUnit> MU) {
619
744
// Create stub map.
620
745
llvm::orc::SymbolAliasMap Stubs;
621
746
for (auto &[Name, Flags] : MU->getSymbols ()) {
@@ -749,7 +874,7 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
749
874
logError (std::move (Err));
750
875
return -1 ;
751
876
}
752
- auto GenModule = generateModule (CI, IRGenOpts, std::move (SM));
877
+ auto GenModule = generateModule (CI, std::move (SM));
753
878
if (!GenModule)
754
879
return -1 ;
755
880
auto *Module = GenModule->getModule ();
@@ -761,3 +886,85 @@ int swift::RunImmediately(CompilerInstance &CI, const ProcessCmdLine &CmdLine,
761
886
}
762
887
return runMain (**JIT, CmdLine);
763
888
}
889
+
890
+ int swift::RunImmediatelyFromAST (CompilerInstance &CI) {
891
+
892
+ auto &Context = CI.getASTContext ();
893
+
894
+ const auto &Invocation = CI.getInvocation ();
895
+ const auto &FrontendOpts = Invocation.getFrontendOptions ();
896
+
897
+ const ProcessCmdLine &CmdLine = ProcessCmdLine (
898
+ FrontendOpts.ImmediateArgv .begin (), FrontendOpts.ImmediateArgv .end ());
899
+
900
+ // Load libSwiftCore to setup process arguments.
901
+ //
902
+ // This must be done here, before any library loading has been done, to avoid
903
+ // racing with the static initializers in user code.
904
+ // Setup interpreted process arguments.
905
+ using ArgOverride = void (*SWIFT_CC (swift))(const char **, int );
906
+ #if defined(_WIN32)
907
+ auto stdlib = loadSwiftRuntime (Context.SearchPathOpts .RuntimeLibraryPaths );
908
+ if (!stdlib) {
909
+ CI.getDiags ().diagnose (SourceLoc (),
910
+ diag::error_immediate_mode_missing_stdlib);
911
+ return -1 ;
912
+ }
913
+ auto module = static_cast <HMODULE>(stdlib);
914
+ auto emplaceProcessArgs = reinterpret_cast <ArgOverride>(
915
+ GetProcAddress (module , " _swift_stdlib_overrideUnsafeArgvArgc" ));
916
+ if (emplaceProcessArgs == nullptr )
917
+ return -1 ;
918
+ #else
919
+ // In case the compiler is built with swift modules, it already has the stdlib
920
+ // linked to. First try to lookup the symbol with the standard library
921
+ // resolving.
922
+ auto emplaceProcessArgs =
923
+ (ArgOverride)dlsym (RTLD_DEFAULT, " _swift_stdlib_overrideUnsafeArgvArgc" );
924
+
925
+ if (dlerror ()) {
926
+ // If this does not work (= the Swift modules are not linked to the tool),
927
+ // we have to explicitly load the stdlib.
928
+ auto stdlib = loadSwiftRuntime (Context.SearchPathOpts .RuntimeLibraryPaths );
929
+ if (!stdlib) {
930
+ CI.getDiags ().diagnose (SourceLoc (),
931
+ diag::error_immediate_mode_missing_stdlib);
932
+ return -1 ;
933
+ }
934
+ dlerror ();
935
+ emplaceProcessArgs =
936
+ (ArgOverride)dlsym (stdlib, " _swift_stdlib_overrideUnsafeArgvArgc" );
937
+ if (dlerror ())
938
+ return -1 ;
939
+ }
940
+ #endif
941
+
942
+ SmallVector<const char *, 32 > argBuf;
943
+ for (size_t i = 0 ; i < CmdLine.size (); ++i) {
944
+ argBuf.push_back (CmdLine[i].c_str ());
945
+ }
946
+ argBuf.push_back (nullptr );
947
+
948
+ (*emplaceProcessArgs)(argBuf.data (), CmdLine.size ());
949
+
950
+ auto *swiftModule = CI.getMainModule ();
951
+ const auto &IRGenOpts = Invocation.getIRGenOptions ();
952
+ if (autolinkImportedModules (swiftModule, IRGenOpts))
953
+ return -1 ;
954
+
955
+ auto &Target = swiftModule->getASTContext ().LangOpts .Target ;
956
+ assert (Target.isMacOSX ());
957
+ auto JIT = SwiftJIT::Create (IRGenOpts, swiftModule->getASTContext ());
958
+ if (auto Err = JIT.takeError ()) {
959
+ logError (std::move (Err));
960
+ return -1 ;
961
+ }
962
+
963
+ auto MU = SwiftMaterializationUnit::Create (**JIT, CI);
964
+ if (auto Err = (*JIT)->addSwift ((*JIT)->getMainJITDylib (), std::move (MU))) {
965
+ logError (std::move (Err));
966
+ return -1 ;
967
+ }
968
+
969
+ return runMain ((*JIT)->getJIT (), CmdLine);
970
+ }
0 commit comments