Skip to content

Commit f90e030

Browse files
authored
Merge pull request swiftlang#31690 from hamishknight/guilt-by-association
2 parents 8c0e493 + 574dd2b commit f90e030

File tree

14 files changed

+45
-110
lines changed

14 files changed

+45
-110
lines changed

include/swift/AST/SILGenRequests.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@ struct SILGenDescriptor {
8181
/// If the module or file contains SIL that needs parsing, returns the file
8282
/// to be parsed, or \c nullptr if parsing isn't required.
8383
SourceFile *getSourceFileToParse() const;
84-
85-
/// Whether the SIL is being emitted for a whole module.
86-
bool isWholeModule() const;
8784
};
8885

8986
void simple_display(llvm::raw_ostream &out, const SILGenDescriptor &d);

include/swift/SIL/SILModule.h

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ enum class SILStage {
107107
/// when a Swift compilation context is lowered to SIL.
108108
class SILModule {
109109
friend class SILFunctionBuilder;
110-
friend class SILGenSourceFileRequest;
111-
friend class SILGenWholeModuleRequest;
112110

113111
public:
114112
using FunctionListType = llvm::ilist<SILFunction>;
@@ -262,10 +260,6 @@ class SILModule {
262260
/// The indexed profile data to be used for PGO, or nullptr.
263261
std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader;
264262

265-
/// True if this SILModule really contains the whole module, i.e.
266-
/// optimizations can assume that they see the whole module.
267-
bool wholeModule;
268-
269263
/// The options passed into this SILModule.
270264
const SILOptions &Options;
271265

@@ -280,11 +274,8 @@ class SILModule {
280274
/// invalidation message is sent.
281275
llvm::SetVector<DeleteNotificationHandler*> NotificationHandlers;
282276

283-
// Intentionally marked private so that we need to use 'constructSIL()'
284-
// to construct a SILModule.
285-
SILModule(ModuleDecl *M, Lowering::TypeConverter &TC,
286-
const SILOptions &Options, const DeclContext *associatedDC,
287-
bool wholeModule);
277+
SILModule(llvm::PointerUnion<FileUnit *, ModuleDecl *> context,
278+
Lowering::TypeConverter &TC, const SILOptions &Options);
288279

289280
SILModule(const SILModule&) = delete;
290281
void operator=(const SILModule&) = delete;
@@ -355,47 +346,38 @@ class SILModule {
355346
/// Erase a global SIL variable from the module.
356347
void eraseGlobalVariable(SILGlobalVariable *G);
357348

358-
/// Construct a SIL module from an AST module.
359-
///
360-
/// The module will be constructed in the Raw stage. The provided AST module
361-
/// should contain source files.
349+
/// Create and return an empty SIL module suitable for generating or parsing
350+
/// SIL into.
362351
///
363-
/// If a source file is provided, SIL will only be emitted for decls in that
364-
/// source file.
365-
static std::unique_ptr<SILModule>
366-
constructSIL(ModuleDecl *M, Lowering::TypeConverter &TC,
367-
const SILOptions &Options, FileUnit *sf = nullptr);
368-
369-
/// Create and return an empty SIL module that we can
370-
/// later parse SIL bodies directly into, without converting from an AST.
352+
/// \param context The associated decl context. This should be a FileUnit in
353+
/// single-file mode, and a ModuleDecl in whole-module mode.
371354
static std::unique_ptr<SILModule>
372-
createEmptyModule(ModuleDecl *M, Lowering::TypeConverter &TC,
373-
const SILOptions &Options,
374-
bool WholeModule = false);
355+
createEmptyModule(llvm::PointerUnion<FileUnit *, ModuleDecl *> context,
356+
Lowering::TypeConverter &TC, const SILOptions &Options);
375357

376358
/// Get the Swift module associated with this SIL module.
377359
ModuleDecl *getSwiftModule() const { return TheSwiftModule; }
378360
/// Get the AST context used for type uniquing etc. by this SIL module.
379361
ASTContext &getASTContext() const;
380362
SourceManager &getSourceManager() const { return getASTContext().SourceMgr; }
381363

382-
/// Get the Swift DeclContext associated with this SIL module.
364+
/// Get the Swift DeclContext associated with this SIL module. This is never
365+
/// null.
383366
///
384367
/// All AST declarations within this context are assumed to have been fully
385368
/// processed as part of generating this module. This allows certain passes
386369
/// to make additional assumptions about these declarations.
387370
///
388371
/// If this is the same as TheSwiftModule, the entire module is being
389-
/// compiled as a single unit. If this is null, no context-based assumptions
390-
/// can be made.
372+
/// compiled as a single unit.
391373
const DeclContext *getAssociatedContext() const {
392374
return AssociatedDeclContext;
393375
}
394376

395377
/// Returns true if this SILModule really contains the whole module, i.e.
396378
/// optimizations can assume that they see the whole module.
397379
bool isWholeModule() const {
398-
return wholeModule;
380+
return isa<ModuleDecl>(AssociatedDeclContext);
399381
}
400382

401383
bool isStdlibModule() const;

lib/IRGen/IRGenModule.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,14 +1203,9 @@ static bool isFirstObjectFileInModule(IRGenModule &IGM) {
12031203
if (IGM.getSILModule().isWholeModule())
12041204
return IGM.IRGen.getPrimaryIGM() == &IGM;
12051205

1206-
const DeclContext *DC = IGM.getSILModule().getAssociatedContext();
1207-
if (!DC)
1208-
return false;
1209-
1210-
assert(!isa<ModuleDecl>(DC) && "that would be a whole module build");
1211-
assert(isa<FileUnit>(DC) && "compiling something smaller than a file?");
1212-
ModuleDecl *containingModule = cast<FileUnit>(DC)->getParentModule();
1213-
return containingModule->getFiles().front() == DC;
1206+
auto *file = cast<FileUnit>(IGM.getSILModule().getAssociatedContext());
1207+
auto *containingModule = file->getParentModule();
1208+
return containingModule->getFiles().front() == file;
12141209
}
12151210

12161211
void IRGenModule::emitAutolinkInfo() {

lib/SIL/IR/SIL.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,6 @@ bool SILModule::isTypeMetadataAccessible(CanType type) {
127127
// Private declarations are inaccessible from different files unless
128128
// this is WMO and we're in the same module.
129129
case FormalLinkage::Private: {
130-
// The only time we don't have an associated DC is in the
131-
// integrated REPL, where we also don't have a concept of other
132-
// source files within the current module.
133-
if (!AssociatedDeclContext)
134-
return (decl->getModuleContext() != getSwiftModule());
135-
136130
// The associated DC should be either a SourceFile or, in WMO mode,
137131
// a ModuleDecl. In the WMO modes, IRGen will ensure that private
138132
// declarations are usable throughout the module. Therefore, in

lib/SIL/IR/SILModule.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,18 @@ class SILModule::SerializationCallback final
9292
}
9393
};
9494

95-
SILModule::SILModule(ModuleDecl *SwiftModule, TypeConverter &TC,
96-
const SILOptions &Options, const DeclContext *associatedDC,
97-
bool wholeModule)
98-
: TheSwiftModule(SwiftModule),
99-
AssociatedDeclContext(associatedDC),
100-
Stage(SILStage::Raw), wholeModule(wholeModule), Options(Options),
101-
serialized(false), SerializeSILAction(), Types(TC) {
95+
SILModule::SILModule(llvm::PointerUnion<FileUnit *, ModuleDecl *> context,
96+
Lowering::TypeConverter &TC, const SILOptions &Options)
97+
: Stage(SILStage::Raw), Options(Options), serialized(false),
98+
SerializeSILAction(), Types(TC) {
99+
assert(!context.isNull());
100+
if (auto *file = context.dyn_cast<FileUnit *>()) {
101+
AssociatedDeclContext = file;
102+
} else {
103+
AssociatedDeclContext = context.get<ModuleDecl *>();
104+
}
105+
TheSwiftModule = AssociatedDeclContext->getParentModule();
106+
102107
// We always add the base SILModule serialization callback.
103108
std::unique_ptr<DeserializationNotificationHandler> callback(
104109
new SILModule::SerializationCallback());
@@ -122,11 +127,10 @@ SILModule::~SILModule() {
122127
}
123128
}
124129

125-
std::unique_ptr<SILModule>
126-
SILModule::createEmptyModule(ModuleDecl *M, TypeConverter &TC, const SILOptions &Options,
127-
bool WholeModule) {
128-
return std::unique_ptr<SILModule>(
129-
new SILModule(M, TC, Options, M, WholeModule));
130+
std::unique_ptr<SILModule> SILModule::createEmptyModule(
131+
llvm::PointerUnion<FileUnit *, ModuleDecl *> context,
132+
Lowering::TypeConverter &TC, const SILOptions &Options) {
133+
return std::unique_ptr<SILModule>(new SILModule(context, TC, Options));
130134
}
131135

132136
ASTContext &SILModule::getASTContext() const {

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,8 @@ ParseSILModuleRequest::evaluate(Evaluator &evaluator,
115115
auto bufferID = SF->getBufferID();
116116
assert(bufferID);
117117

118-
auto *mod = SF->getParentModule();
119-
auto silMod = SILModule::createEmptyModule(mod, desc.conv, desc.opts,
120-
desc.isWholeModule());
118+
auto silMod = SILModule::createEmptyModule(desc.context, desc.conv,
119+
desc.opts);
121120
SILParserState parserState(silMod.get());
122121
Parser parser(*bufferID, *SF, parserState.Impl.get());
123122
PrettyStackTraceParser StackTrace(parser);
@@ -126,8 +125,7 @@ ParseSILModuleRequest::evaluate(Evaluator &evaluator,
126125
if (hadError) {
127126
// The rest of the SIL pipeline expects well-formed SIL, so if we encounter
128127
// a parsing error, just return an empty SIL module.
129-
return SILModule::createEmptyModule(mod, desc.conv, desc.opts,
130-
desc.isWholeModule());
128+
return SILModule::createEmptyModule(desc.context, desc.conv, desc.opts);
131129
}
132130
return silMod;
133131
}

lib/SILGen/SILGen.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,8 +1867,7 @@ SILGenSourceFileRequest::evaluate(Evaluator &evaluator,
18671867

18681868
auto *unit = desc.context.get<FileUnit *>();
18691869
auto *mod = unit->getParentModule();
1870-
auto M = std::unique_ptr<SILModule>(
1871-
new SILModule(mod, desc.conv, desc.opts, unit, /*wholeModule*/ false));
1870+
auto M = SILModule::createEmptyModule(desc.context, desc.conv, desc.opts);
18721871
SILGenModuleRAII scope(*M, mod);
18731872

18741873
if (auto *file = dyn_cast<SourceFile>(unit)) {
@@ -1890,8 +1889,7 @@ SILGenWholeModuleRequest::evaluate(Evaluator &evaluator,
18901889
}
18911890

18921891
auto *mod = desc.context.get<ModuleDecl *>();
1893-
auto M = std::unique_ptr<SILModule>(
1894-
new SILModule(mod, desc.conv, desc.opts, mod, /*wholeModule*/ true));
1892+
auto M = SILModule::createEmptyModule(desc.context, desc.conv, desc.opts);
18951893
SILGenModuleRAII scope(*M, mod);
18961894

18971895
for (auto file : mod->getFiles()) {

lib/SILGen/SILGenExpr.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4099,8 +4099,6 @@ static bool isVerbatimNullableTypeInC(SILModule &M, Type ty) {
40994099

41004100
// Other types like UnsafePointer can also be nullable.
41014101
const DeclContext *DC = M.getAssociatedContext();
4102-
if (!DC)
4103-
DC = M.getSwiftModule();
41044102
ty = OptionalType::get(ty);
41054103
return ty->isTriviallyRepresentableIn(ForeignLanguage::C, DC);
41064104
}

lib/SILGen/SILGenRequests.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ ArrayRef<FileUnit *> SILGenDescriptor::getFiles() const {
6565
return llvm::makeArrayRef(*context.getAddrOfPtr1());
6666
}
6767

68-
bool SILGenDescriptor::isWholeModule() const {
69-
return context.is<ModuleDecl *>();
70-
}
71-
7268
SourceFile *SILGenDescriptor::getSourceFileToParse() const {
7369
#ifndef NDEBUG
7470
auto sfCount = llvm::count_if(getFiles(), [](FileUnit *file) {

lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,6 @@ static bool isDefaultCaseKnown(ClassHierarchyAnalysis *CHA,
285285
auto *Method = CMI->getMember().getAbstractFunctionDecl();
286286
assert(Method && "not a function");
287287

288-
const DeclContext *DC = AI.getModule().getAssociatedContext();
289-
290288
if (CD->isFinal())
291289
return true;
292290

@@ -295,13 +293,8 @@ static bool isDefaultCaseKnown(ClassHierarchyAnalysis *CHA,
295293
if (CD->checkAncestry(AncestryFlags::ObjC))
296294
return false;
297295

298-
// Without an associated context we cannot perform any
299-
// access-based optimizations.
300-
if (!DC)
301-
return false;
302-
303296
// Only handle classes defined within the SILModule's associated context.
304-
if (!CD->isChildContextOf(DC))
297+
if (!CD->isChildContextOf(AI.getModule().getAssociatedContext()))
305298
return false;
306299

307300
if (!CD->hasAccess())

0 commit comments

Comments
 (0)