23
23
#include " swift/AST/ProtocolConformance.h"
24
24
#include " swift/AST/SILGenRequests.h"
25
25
#include " swift/AST/SILOptimizerRequests.h"
26
+ #include " swift/AST/TBDGenRequests.h"
26
27
#include " swift/Basic/Defer.h"
27
28
#include " swift/Basic/Dwarf.h"
28
29
#include " swift/Basic/Platform.h"
40
41
#include " swift/SILOptimizer/PassManager/PassPipeline.h"
41
42
#include " swift/SILOptimizer/PassManager/Passes.h"
42
43
#include " swift/Subsystems.h"
44
+ #include " swift/TBDGen/TBDGen.h"
43
45
#include " ../Serialization/ModuleFormat.h"
44
46
#include " clang/Basic/TargetInfo.h"
45
47
#include " clang/Frontend/CompilerInstance.h"
@@ -907,6 +909,52 @@ static void runIRGenPreparePasses(SILModule &Module,
907
909
executePassPipelinePlan (&Module, plan, /* isMandatory*/ true , &IRModule);
908
910
}
909
911
912
+ namespace {
913
+ using IREntitiesToEmit = SmallVector<LinkEntity, 1 >;
914
+
915
+ struct SymbolSourcesToEmit {
916
+ SILRefsToEmit silRefsToEmit;
917
+ IREntitiesToEmit irEntitiesToEmit;
918
+ };
919
+
920
+ static Optional<SymbolSourcesToEmit>
921
+ getSymbolSourcesToEmit (const IRGenDescriptor &desc) {
922
+ if (!desc.SymbolsToEmit )
923
+ return None;
924
+
925
+ assert (!desc.SILMod && " Already emitted SIL?" );
926
+
927
+ // First retrieve the symbol source map to figure out what we need to build,
928
+ // making sure to include non-public symbols.
929
+ auto &ctx = desc.getParentModule ()->getASTContext ();
930
+ auto tbdDesc = desc.getTBDGenDescriptor ();
931
+ tbdDesc.getOptions ().PublicSymbolsOnly = false ;
932
+ auto symbolMap =
933
+ llvm::cantFail (ctx.evaluator (SymbolSourceMapRequest{std::move (tbdDesc)}));
934
+
935
+ // Then split up the symbols so they can be emitted by the appropriate part
936
+ // of the pipeline.
937
+ SILRefsToEmit silRefsToEmit;
938
+ IREntitiesToEmit irEntitiesToEmit;
939
+ for (const auto &symbol : *desc.SymbolsToEmit ) {
940
+ auto source = symbolMap.find (symbol);
941
+ assert (source && " Couldn't find symbol" );
942
+ switch (source->kind ) {
943
+ case SymbolSource::Kind::SIL:
944
+ silRefsToEmit.push_back (source->getSILDeclRef ());
945
+ break ;
946
+ case SymbolSource::Kind::IR:
947
+ irEntitiesToEmit.push_back (source->getIRLinkEntity ());
948
+ break ;
949
+ case SymbolSource::Kind::LinkerDirective:
950
+ case SymbolSource::Kind::Unknown:
951
+ llvm_unreachable (" Not supported" );
952
+ }
953
+ }
954
+ return SymbolSourcesToEmit{silRefsToEmit, irEntitiesToEmit};
955
+ }
956
+ } // end of anonymous namespace
957
+
910
958
// / Generates LLVM IR, runs the LLVM passes and produces the output file.
911
959
// / All this is done in a single thread.
912
960
GeneratedModule IRGenRequest::evaluate (Evaluator &evaluator,
@@ -917,12 +965,17 @@ GeneratedModule IRGenRequest::evaluate(Evaluator &evaluator,
917
965
auto &Ctx = M->getASTContext ();
918
966
assert (!Ctx.hadError ());
919
967
968
+ auto symsToEmit = getSymbolSourcesToEmit (desc);
969
+ assert (!symsToEmit || symsToEmit->irEntitiesToEmit .empty () &&
970
+ " IR symbol emission not implemented yet" );
971
+
920
972
// If we've been provided a SILModule, use it. Otherwise request the lowered
921
973
// SIL for the file or module.
922
974
auto SILMod = std::unique_ptr<SILModule>(desc.SILMod );
923
975
if (!SILMod) {
924
- auto loweringDesc =
925
- ASTLoweringDescriptor{desc.Ctx , desc.Conv , desc.SILOpts };
976
+ auto loweringDesc = ASTLoweringDescriptor{
977
+ desc.Ctx , desc.Conv , desc.SILOpts ,
978
+ symsToEmit.map ([](const auto &x) { return x.silRefsToEmit ; })};
926
979
SILMod = llvm::cantFail (Ctx.evaluator (LoweredSILRequest{loweringDesc}));
927
980
928
981
// If there was an error, bail.
@@ -1334,7 +1387,8 @@ GeneratedModule swift::performIRGeneration(
1334
1387
const auto &SILOpts = SILModPtr->getOptions ();
1335
1388
auto desc = IRGenDescriptor::forWholeModule (
1336
1389
M, Opts, TBDOpts, SILOpts, SILModPtr->Types , std::move (SILMod),
1337
- ModuleName, PSPs, parallelOutputFilenames, outModuleHash);
1390
+ ModuleName, PSPs, /* symsToEmit*/ None, parallelOutputFilenames,
1391
+ outModuleHash);
1338
1392
1339
1393
if (Opts.shouldPerformIRGenerationInParallel () &&
1340
1394
!parallelOutputFilenames.empty ()) {
@@ -1358,7 +1412,8 @@ performIRGeneration(FileUnit *file, const IRGenOptions &Opts,
1358
1412
const auto &SILOpts = SILModPtr->getOptions ();
1359
1413
auto desc = IRGenDescriptor::forFile (
1360
1414
file, Opts, TBDOpts, SILOpts, SILModPtr->Types , std::move (SILMod),
1361
- ModuleName, PSPs, PrivateDiscriminator, outModuleHash);
1415
+ ModuleName, PSPs, PrivateDiscriminator, /* symsToEmit*/ None,
1416
+ outModuleHash);
1362
1417
return llvm::cantFail (file->getASTContext ().evaluator (IRGenRequest{desc}));
1363
1418
}
1364
1419
@@ -1458,3 +1513,23 @@ GeneratedModule OptimizedIRRequest::evaluate(Evaluator &evaluator,
1458
1513
irMod.getTargetMachine ());
1459
1514
return irMod;
1460
1515
}
1516
+
1517
+ StringRef SymbolObjectCodeRequest::evaluate (Evaluator &evaluator,
1518
+ IRGenDescriptor desc) const {
1519
+ auto &ctx = desc.getParentModule ()->getASTContext ();
1520
+ auto mod = cantFail (evaluator (OptimizedIRRequest{desc}));
1521
+ auto *targetMachine = mod.getTargetMachine ();
1522
+
1523
+ // Add the passes to emit the LLVM module as object code.
1524
+ // TODO: Use compileAndWriteLLVM.
1525
+ legacy::PassManager emitPasses;
1526
+ emitPasses.add (createTargetTransformInfoWrapperPass (
1527
+ targetMachine->getTargetIRAnalysis ()));
1528
+
1529
+ SmallString<0 > output;
1530
+ raw_svector_ostream os (output);
1531
+ targetMachine->addPassesToEmitFile (emitPasses, os, nullptr , CGFT_ObjectFile);
1532
+ emitPasses.run (*mod.getModule ());
1533
+ os << ' \0 ' ;
1534
+ return ctx.AllocateCopy (output.str ());
1535
+ }
0 commit comments