Skip to content

Commit 835c701

Browse files
authored
Merge pull request swiftlang#28407 from eeckstein/cross-module-optimization
Cross module optimization
2 parents 213ccf8 + a5397b4 commit 835c701

23 files changed

+879
-71
lines changed

include/swift/AST/SILOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class SILOptions {
6262
/// Useful when you want to enable -O LLVM opts but not -O SIL opts.
6363
bool DisableSILPerfOptimizations = false;
6464

65+
/// Controls whether cross module optimization is enabled.
66+
bool CrossModuleOptimization = false;
67+
6568
/// Controls whether or not paranoid verification checks are run.
6669
bool VerifyAll = false;
6770

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,10 @@ def Oplayground : Flag<["-"], "Oplayground">, Group<O_Group>,
589589
Flags<[HelpHidden, FrontendOption, ModuleInterfaceOption]>,
590590
HelpText<"Compile with optimizations appropriate for a playground">;
591591

592+
def CrossModuleOptimization : Flag<["-"], "cross-module-optimization">,
593+
Flags<[HelpHidden, FrontendOption]>,
594+
HelpText<"Perform cross-module optimization">;
595+
592596
def RemoveRuntimeAsserts : Flag<["-"], "remove-runtime-asserts">,
593597
Flags<[FrontendOption]>,
594598
HelpText<"Remove runtime safety checks.">;

include/swift/SIL/SILInstruction.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,6 +2892,10 @@ class KeyPathPatternComponent {
28922892
return KeyPathPatternComponent(tupleIndex, ty);
28932893
}
28942894

2895+
void visitReferencedFunctionsAndMethods(
2896+
std::function<void (SILFunction *)> functionCallBack,
2897+
std::function<void (SILDeclRef)> methodCallBack) const;
2898+
28952899
void incrementRefCounts() const;
28962900
void decrementRefCounts() const;
28972901

@@ -2948,6 +2952,15 @@ class KeyPathPattern final
29482952

29492953
ArrayRef<KeyPathPatternComponent> getComponents() const;
29502954

2955+
void visitReferencedFunctionsAndMethods(
2956+
std::function<void (SILFunction *)> functionCallBack,
2957+
std::function<void (SILDeclRef)> methodCallBack) {
2958+
for (auto &component : getComponents()) {
2959+
component.visitReferencedFunctionsAndMethods(functionCallBack,
2960+
methodCallBack);
2961+
}
2962+
}
2963+
29512964
static KeyPathPattern *get(SILModule &M,
29522965
CanGenericSignature signature,
29532966
CanType rootType,

include/swift/SIL/SILModule.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ class SILModule {
194194
/// The list of SILDefaultWitnessTables in the module.
195195
DefaultWitnessTableListType defaultWitnessTables;
196196

197+
/// Declarations which are externally visible.
198+
///
199+
/// These are method declarations which are referenced from inlinable
200+
/// functions due to cross-module-optimzation. Those declarations don't have
201+
/// any attributes or linkage which mark them as externally visible by
202+
/// default.
203+
/// Currently this table is not serialized.
204+
llvm::SetVector<ValueDecl *> externallyVisible;
205+
197206
/// Lookup table for SIL Global Variables.
198207
llvm::StringMap<SILGlobalVariable *> GlobalVariableMap;
199208

@@ -446,6 +455,13 @@ class SILModule {
446455
return {defaultWitnessTables.begin(), defaultWitnessTables.end()};
447456
}
448457

458+
void addExternallyVisibleDecl(ValueDecl *decl) {
459+
externallyVisible.insert(decl);
460+
}
461+
bool isExternallyVisibleDecl(ValueDecl *decl) {
462+
return externallyVisible.count(decl) != 0;
463+
}
464+
449465
using sil_global_iterator = GlobalListType::iterator;
450466
using sil_global_const_iterator = GlobalListType::const_iterator;
451467
GlobalListType &getSILGlobalList() { return silGlobals; }

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ PASS(AccessEnforcementSelection, "access-enforcement-selection",
6464
"Access Enforcement Selection")
6565
PASS(AccessEnforcementWMO, "access-enforcement-wmo",
6666
"Access Enforcement Whole Module Optimization")
67+
PASS(CrossModuleSerializationSetup, "cross-module-serialization-setup",
68+
"Setup serialization flags for cross-module optimization")
6769
PASS(AccessSummaryDumper, "access-summary-dump",
6870
"Dump Address Parameter Access Summary")
6971
PASS(AccessedStorageDumper, "accessed-storage-dump",

include/swift/SILOptimizer/Utils/InstOptUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ struct LLVM_LIBRARY_VISIBILITY FindLocalApplySitesResult {
388388
Optional<FindLocalApplySitesResult>
389389
findLocalApplySites(FunctionRefBaseInst *fri);
390390

391+
/// Gets the base implementation of a method.
392+
AbstractFunctionDecl *getBaseMethod(AbstractFunctionDecl *FD);
393+
391394
} // end namespace swift
392395

393396
#endif

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2995,7 +2995,7 @@ SourceLoc ValueDecl::getAttributeInsertionLoc(bool forModifier) const {
29952995
/// Returns true if \p VD needs to be treated as publicly-accessible
29962996
/// at the SIL, LLVM, and machine levels due to being @usableFromInline.
29972997
bool ValueDecl::isUsableFromInline() const {
2998-
assert(getFormalAccess() == AccessLevel::Internal);
2998+
assert(getFormalAccess() <= AccessLevel::Internal);
29992999

30003000
if (getAttrs().hasAttribute<UsableFromInlineAttr>() ||
30013001
getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>() ||
@@ -3092,7 +3092,7 @@ static AccessLevel getAdjustedFormalAccess(const ValueDecl *VD,
30923092
return getMaximallyOpenAccessFor(VD);
30933093

30943094
if (treatUsableFromInlineAsPublic &&
3095-
access == AccessLevel::Internal &&
3095+
(access == AccessLevel::Internal || access == AccessLevel::Private) &&
30963096
VD->isUsableFromInline()) {
30973097
return AccessLevel::Public;
30983098
}

lib/Driver/ToolChains.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ ToolChain::constructInvocation(const CompileJobAction &job,
400400
Arguments.push_back("-module-name");
401401
Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName));
402402

403+
if (context.Args.hasArg(options::OPT_CrossModuleOptimization)) {
404+
Arguments.push_back("-cross-module-optimization");
405+
}
406+
403407
addOutputsOfType(Arguments, context.Output, context.Args,
404408
file_types::TY_OptRecord, "-save-optimization-record-path");
405409

lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,7 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
871871
Opts.EnableARCOptimizations &= !Args.hasArg(OPT_disable_arc_opts);
872872
Opts.EnableOSSAOptimizations &= !Args.hasArg(OPT_disable_ossa_opts);
873873
Opts.DisableSILPerfOptimizations |= Args.hasArg(OPT_disable_sil_perf_optzns);
874+
Opts.CrossModuleOptimization |= Args.hasArg(OPT_CrossModuleOptimization);
874875
Opts.VerifyAll |= Args.hasArg(OPT_sil_verify_all);
875876
Opts.DebugSerialization |= Args.hasArg(OPT_sil_debug_serialization);
876877
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);

lib/FrontendTool/FrontendTool.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,9 @@ static bool validateTBDIfNeeded(CompilerInvocation &Invocation,
13941394
if (!astGuaranteedToCorrespondToSIL ||
13951395
!inputFileKindCanHaveTBDValidated(Invocation.getInputKind()))
13961396
return false;
1397+
1398+
if (Invocation.getSILOptions().CrossModuleOptimization)
1399+
return false;
13971400

13981401
const auto &frontendOpts = Invocation.getFrontendOptions();
13991402
auto mode = frontendOpts.ValidateTBDAgainstIR;

0 commit comments

Comments
 (0)