Skip to content

Commit 4446e0b

Browse files
Merge remote-tracking branch 'katei/katei/prototype-thin-lto' into katei/wasm-thin-lto
2 parents fa38512 + af4ffc1 commit 4446e0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+3345
-60
lines changed

include/swift/AST/SILOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ class SILOptions {
153153
/// Enable large loadable types IRGen pass.
154154
bool EnableLargeLoadableTypes = true;
155155

156+
/// The path to combined module summary file
157+
std::string ModuleSummaryPath;
158+
156159
/// The name of the file to which the backend should save optimization
157160
/// records.
158161
std::string OptRecordFile;

include/swift/Basic/FileTypes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ TYPE("dSYM", dSYM, "dSYM", "")
4848
TYPE("dependencies", Dependencies, "d", "")
4949
TYPE("autolink", AutolinkFile, "autolink", "")
5050
TYPE("swiftmodule", SwiftModuleFile, "swiftmodule", "")
51+
TYPE("swiftmodule-summary", SwiftModuleSummaryFile, "swiftmodule.summary", "")
5152
TYPE("swiftdoc", SwiftModuleDocFile, "swiftdoc", "")
5253
TYPE("swiftinterface", SwiftModuleInterfaceFile, "swiftinterface", "")
5354
TYPE("private-swiftinterface", PrivateSwiftModuleInterfaceFile, "private.swiftinterface", "")

include/swift/Frontend/FrontendOptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class FrontendOptions {
7272
/// The path to which we should store indexing data, if any.
7373
std::string IndexStorePath;
7474

75+
/// The path to which we should emit combined module summary file
76+
std::string ModuleSummaryOutputPath;
7577
/// The path to look in when loading a module interface file, to see if a
7678
/// binary module has already been built for use by the compiler.
7779
std::string PrebuiltModuleCachePath;

include/swift/Option/FrontendOptions.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ def emit_module_doc_path
4040

4141
def emit_module_source_info : Flag<["-"], "emit-module-source-info">,
4242
HelpText<"Output module source info file">;
43+
44+
def emit_module_summary : Flag<["-"], "emit-module-summary">,
45+
HelpText<"Emit module summary">;
46+
47+
def module_summary_path
48+
: Separate<["-"], "module-summary-path">, MetaVarName<"<path>">,
49+
HelpText<"Combined module summary file <path>">;
4350

4451
def ignore_module_source_info : Flag<["-"], "ignore-module-source-info">,
4552
HelpText<"Avoid getting source location from .swiftsourceinfo files">;

include/swift/Option/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,12 @@ def emit_module_path_EQ : Joined<["-"], "emit-module-path=">,
443443
ArgumentIsPath, SupplementaryOutput]>,
444444
Alias<emit_module_path>;
445445

446+
def emit_module_summary_path : Separate<["-"], "emit-module-summary-path">,
447+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild,
448+
ArgumentIsPath, SupplementaryOutput]>,
449+
HelpText<"Emit a module summary to <path>">,
450+
MetaVarName<"<path>">;
451+
446452
def emit_module_interface :
447453
Flag<["-"], "emit-module-interface">,
448454
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild,

include/swift/SIL/ModuleSummary.h

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
//===----- ModuleSummary.h --------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_SIL_MODULE_SUMMARY_H
14+
#define SWIFT_SIL_MODULE_SUMMARY_H
15+
16+
#include "swift/AST/Decl.h"
17+
#include "swift/SIL/SILFunction.h"
18+
#include "llvm/Support/YAMLTraits.h"
19+
20+
namespace swift {
21+
22+
namespace modulesummary {
23+
24+
using GUID = uint64_t;
25+
26+
/// Compute globally unique identifier from the symbol.
27+
GUID getGUIDFromUniqueName(llvm::StringRef Name);
28+
29+
/// Function summary information to help callee analysis
30+
class FunctionSummary {
31+
public:
32+
/// Function call information
33+
class Call {
34+
public:
35+
/// Kinds of callee reference.
36+
enum KindTy {
37+
/// The call references a function statically
38+
Direct,
39+
/// The call references a function via a witness table.
40+
Witness,
41+
/// The call references a function via a vtable.
42+
VTable,
43+
kindCount,
44+
};
45+
46+
private:
47+
// For import/export
48+
friend llvm::yaml::MappingTraits<FunctionSummary::Call>;
49+
50+
/// The callee function GUID. This can be a static function or a virtual
51+
/// function GUID.
52+
GUID Callee;
53+
/// The symbol name of the callee function only for debug and test purposes.
54+
std::string Name;
55+
/// Kind of the callee reference.
56+
KindTy Kind;
57+
public:
58+
friend ::llvm::yaml::MappingTraits<Call>;
59+
Call() = default;
60+
Call(GUID callee, std::string name, KindTy kind)
61+
: Callee(callee), Name(name), Kind(kind) {}
62+
63+
KindTy getKind() const { return Kind; }
64+
GUID getCallee() const { return Callee; }
65+
std::string getName() const { return Name; };
66+
};
67+
68+
/// Function state flags
69+
struct FlagsTy {
70+
/// In per-module summary, always false.
71+
/// In combined summary, indicates that the function is live.
72+
bool Live;
73+
/// Indicates that the function must be considered a live root for liveness
74+
/// analysis.
75+
bool Preserved;
76+
};
77+
78+
using CallGraphEdgeListTy = std::vector<Call>;
79+
80+
private:
81+
// For import/export
82+
friend llvm::yaml::MappingTraits<FunctionSummary>;
83+
84+
/// The function identity.
85+
GUID Guid;
86+
/// The function state flags.
87+
FlagsTy Flags;
88+
/// List of Call from this function.
89+
CallGraphEdgeListTy CallGraphEdgeList;
90+
/// The symbol name of the function only for debug and test purposes.
91+
std::string Name;
92+
93+
public:
94+
FunctionSummary() = default;
95+
FunctionSummary(GUID guid)
96+
: Guid(guid), Flags({false, false}), CallGraphEdgeList(), Name("") {}
97+
98+
/// Add a call to the list.
99+
void addCall(Call call) { CallGraphEdgeList.push_back(call); }
100+
101+
/// Return the list of Call from this function
102+
ArrayRef<Call> calls() const { return CallGraphEdgeList; }
103+
104+
bool isLive() const { return Flags.Live; }
105+
void setLive(bool Live) { Flags.Live = Live; }
106+
107+
bool isPreserved() const { return Flags.Preserved; }
108+
void setPreserved(bool Preserved) { Flags.Preserved = Preserved; }
109+
110+
std::string getName() const { return Name; }
111+
void setName(std::string name) { this->Name = name; }
112+
113+
GUID getGUID() const { return Guid; }
114+
};
115+
116+
/// A slot in a set of virtual tables.
117+
struct VFuncSlot {
118+
/// Kinds of table.
119+
enum KindTy {
120+
Witness,
121+
VTable,
122+
kindCount,
123+
};
124+
125+
/// Kind of table.
126+
KindTy Kind;
127+
/// The virtual function GUID.
128+
GUID VFuncID;
129+
130+
VFuncSlot(KindTy Kind, GUID VFuncID) : Kind(Kind), VFuncID(VFuncID) {}
131+
};
132+
133+
struct VFuncImpl {
134+
GUID Guid;
135+
GUID TypeGuid;
136+
};
137+
138+
using FunctionSummaryMapTy = std::map<GUID, std::unique_ptr<FunctionSummary>>;
139+
using VFuncToImplsMapTy = std::map<GUID, std::vector<VFuncImpl>>;
140+
141+
/// Module summary that consists of function summaries and virtual function
142+
/// tables.
143+
class ModuleSummaryIndex {
144+
// For import/export
145+
friend llvm::yaml::MappingTraits<ModuleSummaryIndex>;
146+
147+
/// Map from function GUID to function summary.
148+
FunctionSummaryMapTy FunctionSummaryMap;
149+
/// Map from virtual function GUID to list of implementations for witness
150+
/// tables.
151+
VFuncToImplsMapTy WitnessTableMethodMap;
152+
/// Map from virtual function GUID to list of implementations for vtables.
153+
VFuncToImplsMapTy VTableMethodMap;
154+
/// The symbol name of the module.
155+
std::string Name;
156+
157+
VFuncToImplsMapTy &getVFuncMap(VFuncSlot::KindTy kind) {
158+
switch (kind) {
159+
case VFuncSlot::Witness:
160+
return WitnessTableMethodMap;
161+
case VFuncSlot::VTable:
162+
return VTableMethodMap;
163+
case VFuncSlot::kindCount: {
164+
llvm_unreachable("impossible");
165+
}
166+
}
167+
}
168+
const VFuncToImplsMapTy &getVFuncMap(VFuncSlot::KindTy kind) const {
169+
switch (kind) {
170+
case VFuncSlot::Witness:
171+
return WitnessTableMethodMap;
172+
case VFuncSlot::VTable:
173+
return VTableMethodMap;
174+
case VFuncSlot::kindCount: {
175+
llvm_unreachable("impossible");
176+
}
177+
}
178+
}
179+
public:
180+
friend ::llvm::yaml::MappingTraits<ModuleSummaryIndex>;
181+
ModuleSummaryIndex() = default;
182+
183+
std::string getName() const { return this->Name; }
184+
void setName(std::string name) { this->Name = name; }
185+
186+
/// Add a global value summary.
187+
void addFunctionSummary(std::unique_ptr<FunctionSummary> summary) {
188+
FunctionSummaryMap.insert(
189+
std::make_pair(summary->getGUID(), std::move(summary)));
190+
}
191+
192+
/// Return a FunctionSummary for GUID if it exists, otherwise return nullptr.
193+
FunctionSummary *getFunctionSummary(GUID guid) const {
194+
auto found = FunctionSummaryMap.find(guid);
195+
if (found == FunctionSummaryMap.end()) {
196+
return nullptr;
197+
}
198+
auto &entry = found->second;
199+
return entry.get();
200+
}
201+
202+
/// Record a implementation for the virtual function slot.
203+
void addImplementation(VFuncSlot slot, GUID implGUID, GUID typeGUID) {
204+
VFuncToImplsMapTy &table = getVFuncMap(slot.Kind);
205+
auto found = table.find(slot.VFuncID);
206+
VFuncImpl impl = {implGUID, typeGUID};
207+
if (found == table.end()) {
208+
table.insert(std::make_pair(slot.VFuncID, std::vector<VFuncImpl>{impl}));
209+
return;
210+
}
211+
found->second.push_back(impl);
212+
}
213+
214+
/// Return a list of implementations for the virtual function slot.
215+
ArrayRef<VFuncImpl> getImplementations(VFuncSlot slot) const {
216+
const VFuncToImplsMapTy &table = getVFuncMap(slot.Kind);
217+
auto found = table.find(slot.VFuncID);
218+
if (found == table.end()) {
219+
return ArrayRef<VFuncImpl>();
220+
}
221+
return ArrayRef<VFuncImpl>(found->second);
222+
}
223+
224+
const VFuncToImplsMapTy &getWitnessTableMethodMap() const {
225+
return WitnessTableMethodMap;
226+
}
227+
const VFuncToImplsMapTy &getVTableMethodMap() const {
228+
return VTableMethodMap;
229+
}
230+
231+
FunctionSummaryMapTy::const_iterator functions_begin() const {
232+
return FunctionSummaryMap.begin();
233+
}
234+
FunctionSummaryMapTy::const_iterator functions_end() const {
235+
return FunctionSummaryMap.end();
236+
}
237+
};
238+
239+
/// Compute a \c ModuleSummaryIndex from the given SILModule.
240+
std::unique_ptr<ModuleSummaryIndex> buildModuleSummaryIndex(SILModule &M);
241+
242+
/// Serializes a module summary to the given output file.
243+
///
244+
/// \returns false on success, true on error.
245+
bool writeModuleSummaryIndex(const ModuleSummaryIndex &index,
246+
DiagnosticEngine &diags, StringRef path);
247+
248+
/// Attempt to deserialize the module summary.
249+
///
250+
/// \returns false on success, true on error.
251+
bool loadModuleSummaryIndex(llvm::MemoryBufferRef inputBuffer,
252+
ModuleSummaryIndex &moduleSummary);
253+
} // namespace modulesummary
254+
} // namespace swift
255+
256+
#endif

include/swift/SIL/SILInstruction.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2953,7 +2953,10 @@ class KeyPathPatternComponent {
29532953
void visitReferencedFunctionsAndMethods(
29542954
std::function<void (SILFunction *)> functionCallBack,
29552955
std::function<void (SILDeclRef)> methodCallBack) const;
2956-
2956+
2957+
void clearReferencedFunctions_if(
2958+
llvm::function_ref<bool(SILFunction *)> predicate);
2959+
29572960
void incrementRefCounts() const;
29582961
void decrementRefCounts() const;
29592962

include/swift/SIL/SILProperty.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ class SILProperty : public llvm::ilist_node<SILProperty>,
6767
const Optional<KeyPathPatternComponent> &getComponent() const {
6868
return Component;
6969
}
70-
70+
71+
void clearReferencedFunctions_if(
72+
llvm::function_ref<bool(SILFunction *)> predicate) {
73+
if (Component) {
74+
Component->clearReferencedFunctions_if(predicate);
75+
}
76+
}
77+
7178
void print(SILPrintContext &Ctx) const;
7279
void dump() const;
7380

include/swift/SILOptimizer/PassManager/PassPipeline.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
PASSPIPELINE(Diagnostic, "Guaranteed Passes")
2626
PASSPIPELINE(OwnershipEliminator, "Utility pass to just run the ownership eliminator pass")
27+
PASSPIPELINE(CrossModuleEliminator, "Passes run at -module-summary-path")
2728
PASSPIPELINE(Performance, "Passes run at -O")
2829
PASSPIPELINE(Onone, "Passes run at -Onone")
2930
PASSPIPELINE(InstCount, "Utility pipeline to just run the inst count pass")

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ PASS(AccessEnforcementWMO, "access-enforcement-wmo",
6666
"Access Enforcement Whole Module Optimization")
6767
PASS(CrossModuleSerializationSetup, "cross-module-serialization-setup",
6868
"Setup serialization flags for cross-module optimization")
69+
PASS(CrossDeadFunctionElimination, "sil-cross-deadfuncelim",
70+
"Cross Dead Function Elimination")
6971
PASS(AccessSummaryDumper, "access-summary-dump",
7072
"Dump Address Parameter Access Summary")
7173
PASS(AccessedStorageAnalysisDumper, "accessed-storage-analysis-dump",

0 commit comments

Comments
 (0)