Skip to content

Commit 93a83d3

Browse files
committed
IRGen: reuse linker directives collected from tbd gen to emit these symbols to IR
1 parent fdcd506 commit 93a83d3

File tree

9 files changed

+80
-35
lines changed

9 files changed

+80
-35
lines changed

include/swift/Subsystems.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/ArrayRef.h"
2626
#include "llvm/ADT/Optional.h"
2727
#include "llvm/ADT/StringRef.h"
28+
#include "llvm/ADT/StringSet.h"
2829
#include "llvm/Support/Mutex.h"
2930

3031
#include <memory>
@@ -276,7 +277,8 @@ namespace swift {
276277
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
277278
llvm::LLVMContext &LLVMContext,
278279
ArrayRef<std::string> parallelOutputFilenames,
279-
llvm::GlobalVariable **outModuleHash = nullptr);
280+
llvm::GlobalVariable **outModuleHash = nullptr,
281+
llvm::StringSet<> *LinkerDirectives = nullptr);
280282

281283
/// Turn the given Swift module into either LLVM IR or native code
282284
/// and return the generated LLVM IR module.
@@ -286,7 +288,8 @@ namespace swift {
286288
std::unique_ptr<SILModule> SILMod,
287289
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
288290
llvm::LLVMContext &LLVMContext,
289-
llvm::GlobalVariable **outModuleHash = nullptr);
291+
llvm::GlobalVariable **outModuleHash = nullptr,
292+
llvm::StringSet<> *LinkerDirectives = nullptr);
290293

291294
/// Given an already created LLVM module, construct a pass pipeline and run
292295
/// the Swift LLVM Pipeline upon it. This does not cause the module to be

include/swift/TBDGen/TBDGen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ struct TBDGenOptions {
3333
/// Whether this compilation is producing a TBD for InstallAPI.
3434
bool IsInstallAPI;
3535

36+
/// Only collect linker directive symbols.
37+
bool LinkerDirectivesOnly = false;
38+
3639
/// The install_name to use in the TBD file.
3740
std::string InstallName;
3841

lib/FrontendTool/FrontendTool.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,18 +1347,20 @@ static void generateIR(IRGenOptions &IRGenOpts, std::unique_ptr<SILModule> SM,
13471347
StringRef OutputFilename, ModuleOrSourceFile MSF,
13481348
std::unique_ptr<llvm::Module> &IRModule,
13491349
llvm::GlobalVariable *&HashGlobal,
1350-
ArrayRef<std::string> parallelOutputFilenames) {
1350+
ArrayRef<std::string> parallelOutputFilenames,
1351+
llvm::StringSet<> &LinkerDirectives) {
13511352
// FIXME: We shouldn't need to use the global context here, but
13521353
// something is persisting across calls to performIRGeneration.
13531354
auto &LLVMContext = getGlobalLLVMContext();
13541355
IRModule = MSF.is<SourceFile *>()
13551356
? performIRGeneration(IRGenOpts, *MSF.get<SourceFile *>(),
13561357
std::move(SM), OutputFilename, PSPs,
1357-
LLVMContext, &HashGlobal)
1358+
LLVMContext, &HashGlobal,
1359+
&LinkerDirectives)
13581360
: performIRGeneration(IRGenOpts, MSF.get<ModuleDecl *>(),
13591361
std::move(SM), OutputFilename, PSPs,
13601362
LLVMContext, parallelOutputFilenames,
1361-
&HashGlobal);
1363+
&HashGlobal, &LinkerDirectives);
13621364
}
13631365

13641366
static bool processCommandLineAndRunImmediately(CompilerInvocation &Invocation,
@@ -1457,6 +1459,17 @@ static bool generateCode(CompilerInvocation &Invocation,
14571459
EffectiveLanguageVersion, OutputFilename, Stats);
14581460
}
14591461

1462+
static void collectLinkerDirectives(CompilerInvocation &Invocation,
1463+
ModuleOrSourceFile MSF,
1464+
llvm::StringSet<> &Symbols) {
1465+
auto tbdOpts = Invocation.getTBDGenOptions();
1466+
tbdOpts.LinkerDirectivesOnly = true;
1467+
if (MSF.is<SourceFile*>())
1468+
enumeratePublicSymbols(MSF.get<SourceFile*>(), Symbols, tbdOpts);
1469+
else
1470+
enumeratePublicSymbols(MSF.get<ModuleDecl*>(), Symbols, tbdOpts);
1471+
}
1472+
14601473
static bool performCompileStepsPostSILGen(
14611474
CompilerInstance &Instance, CompilerInvocation &Invocation,
14621475
std::unique_ptr<SILModule> SM, bool astGuaranteedToCorrespondToSIL,
@@ -1585,14 +1598,16 @@ static bool performCompileStepsPostSILGen(
15851598
return processCommandLineAndRunImmediately(
15861599
Invocation, Instance, std::move(SM), MSF, observer, ReturnValue);
15871600

1601+
llvm::StringSet<> LinkerDirectives;
1602+
collectLinkerDirectives(Invocation, MSF, LinkerDirectives);
15881603
StringRef OutputFilename = PSPs.OutputFilename;
15891604
std::vector<std::string> ParallelOutputFilenames =
15901605
Invocation.getFrontendOptions().InputsAndOutputs.copyOutputFilenames();
15911606
std::unique_ptr<llvm::Module> IRModule;
15921607
llvm::GlobalVariable *HashGlobal;
15931608
generateIR(
15941609
IRGenOpts, std::move(SM), PSPs, OutputFilename, MSF, IRModule, HashGlobal,
1595-
ParallelOutputFilenames);
1610+
ParallelOutputFilenames, LinkerDirectives);
15961611

15971612
// Walk the AST for indexing after IR generation. Walking it before seems
15981613
// to cause miscompilation issues.

lib/IRGen/GenDecl.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ static bool hasCodeCoverageInstrumentation(SILFunction &f, SILModule &m) {
998998
return f.getProfiler() && m.getOptions().EmitProfileCoverageMapping;
999999
}
10001000

1001-
void IRGenerator::emitGlobalTopLevel() {
1001+
void IRGenerator::emitGlobalTopLevel(llvm::StringSet<> *linkerDirectives) {
10021002
// Generate order numbers for the functions in the SIL module that
10031003
// correspond to definitions in the LLVM module.
10041004
unsigned nextOrderNumber = 0;
@@ -1018,7 +1018,11 @@ void IRGenerator::emitGlobalTopLevel() {
10181018
CurrentIGMPtr IGM = getGenModule(wt.getProtocol()->getDeclContext());
10191019
ensureRelativeSymbolCollocation(wt);
10201020
}
1021-
1021+
if (linkerDirectives) {
1022+
for (auto &entry: *linkerDirectives) {
1023+
createLinkerDirectiveVariable(*PrimaryIGM, entry.getKey());
1024+
}
1025+
}
10221026
for (SILGlobalVariable &v : PrimaryIGM->getSILModule().getSILGlobals()) {
10231027
Decl *decl = v.getDecl();
10241028
CurrentIGMPtr IGM = getGenModule(decl ? decl->getDeclContext() : nullptr);

lib/IRGen/IRGen.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,8 @@ performIRGeneration(IRGenOptions &Opts, ModuleDecl *M,
858858
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
859859
const PrimarySpecificPaths &PSPs,
860860
llvm::LLVMContext &LLVMContext, SourceFile *SF = nullptr,
861-
llvm::GlobalVariable **outModuleHash = nullptr) {
861+
llvm::GlobalVariable **outModuleHash = nullptr,
862+
llvm::StringSet<> *linkerDirectives = nullptr) {
862863
auto &Ctx = M->getASTContext();
863864
assert(!Ctx.hadError());
864865

@@ -879,8 +880,9 @@ performIRGeneration(IRGenOptions &Opts, ModuleDecl *M,
879880

880881
{
881882
FrontendStatsTracer tracer(Ctx.Stats, "IRGen");
883+
882884
// Emit the module contents.
883-
irgen.emitGlobalTopLevel();
885+
irgen.emitGlobalTopLevel(linkerDirectives);
884886

885887
if (SF) {
886888
IGM.emitSourceFile(*SF);
@@ -1068,7 +1070,8 @@ struct LLVMCodeGenThreads {
10681070
static void performParallelIRGeneration(
10691071
IRGenOptions &Opts, swift::ModuleDecl *M, std::unique_ptr<SILModule> SILMod,
10701072
StringRef ModuleName, int numThreads,
1071-
ArrayRef<std::string> outputFilenames) {
1073+
ArrayRef<std::string> outputFilenames,
1074+
llvm::StringSet<> *linkerDirectives) {
10721075

10731076
IRGenerator irgen(Opts, *SILMod);
10741077

@@ -1134,7 +1137,7 @@ static void performParallelIRGeneration(
11341137
}
11351138

11361139
// Emit the module contents.
1137-
irgen.emitGlobalTopLevel();
1140+
irgen.emitGlobalTopLevel(linkerDirectives);
11381141

11391142
for (auto *File : M->getFiles()) {
11401143
if (auto *SF = dyn_cast<SourceFile>(File)) {
@@ -1262,29 +1265,33 @@ std::unique_ptr<llvm::Module> swift::performIRGeneration(
12621265
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
12631266
llvm::LLVMContext &LLVMContext,
12641267
ArrayRef<std::string> parallelOutputFilenames,
1265-
llvm::GlobalVariable **outModuleHash) {
1268+
llvm::GlobalVariable **outModuleHash,
1269+
llvm::StringSet<> *LinkerDirectives) {
12661270
if (SILMod->getOptions().shouldPerformIRGenerationInParallel() &&
12671271
!parallelOutputFilenames.empty()) {
12681272
auto NumThreads = SILMod->getOptions().NumThreads;
12691273
::performParallelIRGeneration(Opts, M, std::move(SILMod), ModuleName,
1270-
NumThreads, parallelOutputFilenames);
1274+
NumThreads, parallelOutputFilenames,
1275+
LinkerDirectives);
12711276
// TODO: Parallel LLVM compilation cannot be used if a (single) module is
12721277
// needed as return value.
12731278
return nullptr;
12741279
}
12751280
return ::performIRGeneration(Opts, M, std::move(SILMod), ModuleName, PSPs,
1276-
LLVMContext, nullptr, outModuleHash);
1281+
LLVMContext, nullptr, outModuleHash,
1282+
LinkerDirectives);
12771283
}
12781284

12791285
std::unique_ptr<llvm::Module> swift::
12801286
performIRGeneration(IRGenOptions &Opts, SourceFile &SF,
12811287
std::unique_ptr<SILModule> SILMod,
12821288
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
12831289
llvm::LLVMContext &LLVMContext,
1284-
llvm::GlobalVariable **outModuleHash) {
1290+
llvm::GlobalVariable **outModuleHash,
1291+
llvm::StringSet<> *LinkerDirectives) {
12851292
return ::performIRGeneration(Opts, SF.getParentModule(), std::move(SILMod),
12861293
ModuleName, PSPs, LLVMContext, &SF,
1287-
outModuleHash);
1294+
outModuleHash, LinkerDirectives);
12881295
}
12891296

12901297
void

lib/IRGen/IRGenModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ class IRGenerator {
331331

332332
/// Emit functions, variables and tables which are needed anyway, e.g. because
333333
/// they are externally visible.
334-
void emitGlobalTopLevel();
334+
void emitGlobalTopLevel(llvm::StringSet<> *LinkerDirectives);
335335

336336
/// Emit references to each of the protocol descriptors defined in this
337337
/// IR module.

lib/TBDGen/TBDGen.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ static bool isGlobalOrStaticVar(VarDecl *VD) {
5757
}
5858

5959
void TBDGenVisitor::addSymbolInternal(StringRef name,
60-
llvm::MachO::SymbolKind kind) {
60+
llvm::MachO::SymbolKind kind,
61+
bool isLinkerDirective) {
62+
if (!isLinkerDirective && Opts.LinkerDirectivesOnly)
63+
return;
6164
Symbols.addSymbol(kind, name, Targets);
6265
if (StringSymbols && kind == SymbolKind::GlobalSymbol) {
6366
auto isNewValue = StringSymbols->insert(name).second;
@@ -102,7 +105,8 @@ void TBDGenVisitor::addLinkerDirectiveSymbols(StringRef name,
102105
llvm::SmallString<64> Buffer;
103106
llvm::raw_svector_ostream OS(Buffer);
104107
OS << "$ld$hide$os" << CurMaj << "." << CurMin << "$" << name;
105-
addSymbolInternal(OS.str(), llvm::MachO::SymbolKind::GlobalSymbol);
108+
addSymbolInternal(OS.str(), llvm::MachO::SymbolKind::GlobalSymbol,
109+
/*LinkerDirective*/true);
106110
}
107111
}
108112
}
@@ -686,6 +690,12 @@ static bool isApplicationExtensionSafe(const LangOptions &LangOpts) {
686690
llvm::sys::Process::GetEnv("LD_APPLICATION_EXTENSION_SAFE");
687691
}
688692

693+
static bool hasLinkerDirective(Decl *D) {
694+
if (D->getAttrs().hasAttribute<OriginallyDefinedInAttr>())
695+
return true;
696+
return false;
697+
}
698+
689699
static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
690700
StringSet *symbols,
691701
llvm::raw_ostream *os,
@@ -734,6 +744,8 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
734744
visitor.addMainIfNecessary(file);
735745

736746
for (auto d : decls) {
747+
if (opts.LinkerDirectivesOnly && !hasLinkerDirective(d))
748+
continue;
737749
visitor.TopLevelDecl = d;
738750
SWIFT_DEFER { visitor.TopLevelDecl = nullptr; };
739751
visitor.visit(d);

lib/TBDGen/TBDGenVisitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
5757
Decl* TopLevelDecl = nullptr;
5858

5959
private:
60-
void addSymbolInternal(StringRef name, llvm::MachO::SymbolKind kind);
60+
void addSymbolInternal(StringRef name, llvm::MachO::SymbolKind kind,
61+
bool isLinkerDirective = false);
6162
void addLinkerDirectiveSymbols(StringRef name, llvm::MachO::SymbolKind kind);
6263
void addSymbol(StringRef name, llvm::MachO::SymbolKind kind =
6364
llvm::MachO::SymbolKind::GlobalSymbol);

test/attr/Inputs/SymbolMove/LowLevel.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,52 @@
1-
@available(OSX 10.8, *)
2-
@_originallyDefinedIn(module: "HighLevel", OSX 10.10)
1+
@available(OSX 10.7, *)
2+
@_originallyDefinedIn(module: "HighLevel", OSX 10.9)
33
public func printMessageMoved() {
44
print("Hello from LowLevel")
55
}
66

7-
@available(OSX 10.8, *)
8-
@_originallyDefinedIn(module: "HighLevel", OSX 10.10)
7+
@available(OSX 10.7, *)
8+
@_originallyDefinedIn(module: "HighLevel", OSX 10.9)
99
public struct Entity {
1010
public let value = "LowLevel"
1111
public init() {}
1212
public func location() -> String { return "Entity from " + value }
1313
}
1414

1515
// =================== Move protocol =================================//
16-
@available(OSX 10.8, *)
17-
@_originallyDefinedIn(module: "HighLevel", OSX 10.10)
16+
@available(OSX 10.7, *)
17+
@_originallyDefinedIn(module: "HighLevel", OSX 10.9)
1818
public protocol Box {
1919
associatedtype Item
2020
var ItemKind: String { get }
2121
func getItem() -> Item
2222
func shape() -> String
2323
}
2424

25-
@available(OSX 10.8, *)
26-
@_originallyDefinedIn(module: "HighLevel", OSX 10.10)
25+
@available(OSX 10.7, *)
26+
@_originallyDefinedIn(module: "HighLevel", OSX 10.9)
2727
extension Box {
2828
public func shape() -> String { return "round"}
2929
}
3030

31-
@available(OSX 10.8, *)
32-
@_originallyDefinedIn(module: "HighLevel", OSX 10.10)
31+
@available(OSX 10.7, *)
32+
@_originallyDefinedIn(module: "HighLevel", OSX 10.9)
3333
public struct Candy {
3434
public var kind = "candy"
3535
public init() {}
3636
}
3737

3838
// =================== Move enum ============================ //
39-
@available(OSX 10.8, *)
40-
@_originallyDefinedIn(module: "HighLevel", OSX 10.10)
39+
@available(OSX 10.7, *)
40+
@_originallyDefinedIn(module: "HighLevel", OSX 10.9)
4141
public enum LanguageKind: Int {
4242
case Cpp = 1
4343
case Swift = 2
4444
case ObjC = 3
4545
}
4646

4747
// =================== Move class ============================ //
48-
@available(OSX 10.8, *)
49-
@_originallyDefinedIn(module: "HighLevel", OSX 10.10)
48+
@available(OSX 10.7, *)
49+
@_originallyDefinedIn(module: "HighLevel", OSX 10.9)
5050
open class Vehicle {
5151
public init() {}
5252
public var currentSpeed = 40.0

0 commit comments

Comments
 (0)