Skip to content

Commit 2e8c037

Browse files
Merge pull request #5495 from swiftwasm/main
[pull] swiftwasm from main
2 parents 358b507 + c285987 commit 2e8c037

32 files changed

+807
-339
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,11 @@ ERROR(sil_movechecking_notconsumable_but_assignable_was_consumed, none,
776776
ERROR(sil_movechecking_cannot_destructure_has_deinit, none,
777777
"cannot partially consume '%0' when it has a deinitializer",
778778
(StringRef))
779+
ERROR(sil_movechecking_discard_missing_consume_self, none,
780+
"must consume 'self' before exiting method that discards self", ())
779781

782+
NOTE(sil_movechecking_discard_self_here, none,
783+
"discarded self here", ())
780784
NOTE(sil_movechecking_partial_consume_here, none,
781785
"partially consumed here", ())
782786
NOTE(sil_movechecking_consuming_use_here, none,

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,6 @@ namespace swift {
333333
/// Flags for developers
334334
///
335335

336-
/// Enable named lazy member loading.
337-
bool NamedLazyMemberLoading = true;
338-
339336
/// Whether to record request references for incremental builds.
340337
bool RecordRequestReferences = true;
341338

include/swift/SIL/SILBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,9 @@ class SILBuilder {
489489
#endif
490490
llvm::SmallString<4> Name;
491491
Loc.markAsPrologue();
492+
#if defined(NDEBUG)
493+
(void) skipVarDeclAssert;
494+
#endif
492495
assert((skipVarDeclAssert ||
493496
!dyn_cast_or_null<VarDecl>(Loc.getAsASTNode<Decl>()) || Var) &&
494497
"location is a VarDecl, but SILDebugVariable is empty");

include/swift/SIL/SILCloner.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -955,11 +955,9 @@ SILCloner<ImplClass>::visitAllocBoxInst(AllocBoxInst *Inst) {
955955
Inst,
956956
getBuilder().createAllocBox(
957957
Loc, this->getOpType(Inst->getType()).template castTo<SILBoxType>(),
958-
VarInfo, false, false, false
959-
#ifndef NDEBUG
960-
,
961-
true
962-
#endif
958+
VarInfo, /*hasDynamicLifetime*/ false,
959+
/*reflection*/ false,
960+
/*usesMoveableValueDebugInfo*/ false, /*skipVarDeclAssert*/ true
963961
));
964962
}
965963

lib/AST/Module.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range decls,
249249
// Cache the value under both its compound name and its full name.
250250
TopLevelValues.add(VD);
251251

252-
if (VD->getAttrs().hasAttribute<CustomAttr>()) {
252+
if (!onlyOperators && VD->getAttrs().hasAttribute<CustomAttr>()) {
253253
MayHaveAuxiliaryDecls.push_back(VD);
254254
}
255255
}
@@ -279,8 +279,10 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range decls,
279279
else if (auto *PG = dyn_cast<PrecedenceGroupDecl>(D))
280280
PrecedenceGroups[PG->getName()].push_back(PG);
281281

282-
else if (auto *MED = dyn_cast<MacroExpansionDecl>(D))
283-
MayHaveAuxiliaryDecls.push_back(MED);
282+
else if (auto *MED = dyn_cast<MacroExpansionDecl>(D)) {
283+
if (!onlyOperators)
284+
MayHaveAuxiliaryDecls.push_back(MED);
285+
}
284286
}
285287
}
286288

@@ -403,13 +405,6 @@ void SourceLookupCache::populateAuxiliaryDeclCache() {
403405
for (auto macroNames : introducedNames) {
404406
auto macroRef = macroNames.getFirst();
405407
for (auto name : macroNames.getSecond()) {
406-
407-
// If this macro isn't in a module-scope context, and the introduced
408-
// name isn't an operator, we shouldn't be able to see it.
409-
if (!decl->getDeclContext()->isModuleScopeContext() &&
410-
!name.getBaseName().isOperator())
411-
continue;
412-
413408
auto *placeholder = MissingDecl::forUnexpandedMacro(macroRef, decl);
414409
name.addToLookupTable(TopLevelAuxiliaryDecls, placeholder);
415410
}
@@ -492,12 +487,6 @@ void SourceLookupCache::lookupValue(DeclName Name, NLKind LookupKind,
492487
for (auto *unexpandedDecl : unexpandedDecls) {
493488
unexpandedDecl->forEachMacroExpandedDecl(
494489
[&](ValueDecl *decl) {
495-
// If the declaration is not a module-scope declaration, and
496-
// isn't an operator, ignore it.
497-
if (!decl->getDeclContext()->isModuleScopeContext() &&
498-
!decl->getName().getBaseName().isOperator())
499-
return;
500-
501490
if (decl->getName().matchesRef(Name)) {
502491
if (macroExpandedDecls.insert(decl).second)
503492
Result.push_back(decl);

lib/AST/NameLookup.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,9 @@ class swift::MemberLookupTable : public ASTAllocated<swift::MemberLookupTable> {
12181218
/// Lookup table mapping names to the set of declarations with that name.
12191219
LookupTable Lookup;
12201220

1221+
/// List of containers that have lazily-loaded members
1222+
llvm::SmallVector<ExtensionDecl *, 2> ExtensionsWithLazyMembers;
1223+
12211224
/// The set of names of lazily-loaded members that the lookup table has a
12221225
/// complete accounting of with respect to all known extensions of its
12231226
/// parent nominal type.
@@ -1246,6 +1249,14 @@ class swift::MemberLookupTable : public ASTAllocated<swift::MemberLookupTable> {
12461249
/// Add the given members to the lookup table.
12471250
void addMembers(DeclRange members);
12481251

1252+
void addExtensionWithLazyMembers(ExtensionDecl *ext) {
1253+
ExtensionsWithLazyMembers.push_back(ext);
1254+
}
1255+
1256+
ArrayRef<ExtensionDecl *> getExtensionsWithLazyMembers() const {
1257+
return ExtensionsWithLazyMembers;
1258+
}
1259+
12491260
/// Returns \c true if the lookup table has a complete accounting of the
12501261
/// given name.
12511262
bool isLazilyComplete(DeclBaseName name) const {
@@ -1435,10 +1446,11 @@ void NominalTypeDecl::addedExtension(ExtensionDecl *ext) {
14351446
auto *table = LookupTable.getPointer();
14361447
assert(table);
14371448

1438-
if (ext->hasLazyMembers()) {
1449+
if (ext->wasDeserialized() || ext->hasClangNode()) {
14391450
table->addMembers(ext->getCurrentMembersWithoutLoading());
14401451
table->clearLazilyCompleteCache();
14411452
table->clearLazilyCompleteForMacroExpansionCache();
1453+
table->addExtensionWithLazyMembers(ext);
14421454
} else {
14431455
table->addMembers(ext->getMembers());
14441456
}
@@ -1534,6 +1546,9 @@ populateLookupTableEntryFromLazyIDCLoader(ASTContext &ctx,
15341546
MemberLookupTable &LookupTable,
15351547
DeclBaseName name,
15361548
IterableDeclContext *IDC) {
1549+
if (!IDC->hasLazyMembers())
1550+
return;
1551+
15371552
auto ci = ctx.getOrCreateLazyIterableContextData(IDC,
15381553
/*lazyLoader=*/nullptr);
15391554
auto res = ci->loader->loadNamedMembers(IDC, name, ci->memberData);
@@ -1553,7 +1568,7 @@ populateLookupTableEntryFromExtensions(ASTContext &ctx,
15531568
assert(!table.isLazilyComplete(name) &&
15541569
"Should not be searching extensions for complete name!");
15551570

1556-
for (auto e : nominal->getExtensions()) {
1571+
for (auto e : table.getExtensionsWithLazyMembers()) {
15571572
// If there's no lazy members to look at, all the members of this extension
15581573
// are present in the lookup table.
15591574
if (!e->hasLazyMembers()) {
@@ -1789,6 +1804,7 @@ void NominalTypeDecl::prepareLookupTable() {
17891804
// LazyMemberLoader::loadNamedMembers().
17901805
if (e->wasDeserialized() || e->hasClangNode()) {
17911806
table->addMembers(e->getCurrentMembersWithoutLoading());
1807+
table->addExtensionWithLazyMembers(e);
17921808
continue;
17931809
}
17941810

@@ -1848,21 +1864,14 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
18481864
const auto flags = desc.Options;
18491865
auto *decl = desc.DC;
18501866

1851-
// We only use NamedLazyMemberLoading when a user opts-in and we have
1852-
// not yet loaded all the members into the IDC list in the first place.
18531867
ASTContext &ctx = decl->getASTContext();
1854-
const bool useNamedLazyMemberLoading = (ctx.LangOpts.NamedLazyMemberLoading &&
1855-
decl->hasLazyMembers());
18561868
const bool includeAttrImplements =
18571869
flags.contains(NominalTypeDecl::LookupDirectFlags::IncludeAttrImplements);
18581870
const bool excludeMacroExpansions =
18591871
flags.contains(NominalTypeDecl::LookupDirectFlags::ExcludeMacroExpansions);
18601872

18611873
LLVM_DEBUG(llvm::dbgs() << decl->getNameStr() << ".lookupDirect("
18621874
<< name << ")"
1863-
<< ", hasLazyMembers()=" << decl->hasLazyMembers()
1864-
<< ", useNamedLazyMemberLoading="
1865-
<< useNamedLazyMemberLoading
18661875
<< ", excludeMacroExpansions="
18671876
<< excludeMacroExpansions
18681877
<< "\n");
@@ -1875,15 +1884,7 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
18751884
decl->prepareExtensions();
18761885

18771886
auto &Table = *decl->getLookupTable();
1878-
if (!useNamedLazyMemberLoading) {
1879-
// Make sure we have the complete list of members (in this nominal and in
1880-
// all extensions).
1881-
(void)decl->getMembers();
1882-
1883-
for (auto E : decl->getExtensions())
1884-
(void)E->getMembers();
1885-
1886-
} else if (!Table.isLazilyComplete(name.getBaseName())) {
1887+
if (!Table.isLazilyComplete(name.getBaseName())) {
18871888
DeclBaseName baseName(name.getBaseName());
18881889

18891890
if (isa_and_nonnull<clang::NamespaceDecl>(decl->getClangDecl())) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
682682
/*default*/ false);
683683
Opts.UseClangFunctionTypes |= Args.hasArg(OPT_use_clang_function_types);
684684

685-
Opts.NamedLazyMemberLoading &= !Args.hasArg(OPT_disable_named_lazy_member_loading);
686-
687685
if (Args.hasArg(OPT_emit_fine_grained_dependency_sourcefile_dot_files))
688686
Opts.EmitFineGrainedDependencySourcefileDotFiles = true;
689687

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5162,7 +5162,7 @@ void Parser::recordLocalType(TypeDecl *TD) {
51625162
return;
51635163

51645164
if (!InInactiveClauseEnvironment)
5165-
SF.LocalTypeDecls.insert(TD);
5165+
SF.getOutermostParentSourceFile()->LocalTypeDecls.insert(TD);
51665166
}
51675167

51685168
/// Set the original declaration in `@differentiable` attributes.

lib/SILGen/SILGenDecl.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -519,12 +519,10 @@ class LocalVariableInitialization : public SingleBufferInitialization {
519519
Optional<SILDebugVariable> DbgVar;
520520
if (generateDebugInfo)
521521
DbgVar = SILDebugVariable(decl->isLet(), ArgNo);
522-
Box = SGF.B.createAllocBox(decl, boxType, DbgVar, false, false, false
523-
#ifndef NDEBUG
524-
,
525-
!generateDebugInfo
526-
#endif
527-
);
522+
Box = SGF.B.createAllocBox(
523+
decl, boxType, DbgVar, /*hasDynamicLifetime*/ false,
524+
/*reflection*/ false, /*usesMoveableValueDebugInfo*/ false,
525+
!generateDebugInfo);
528526

529527
// Mark the memory as uninitialized, so DI will track it for us.
530528
if (kind)

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ struct UseState {
691691
/// [assign] that are reinits that we will convert to inits and true reinits.
692692
llvm::SmallMapVector<SILInstruction *, TypeTreeLeafTypeRange, 4> reinitInsts;
693693

694+
/// The set of drop_deinits of this mark_must_check
695+
SmallSetVector<SILInstruction *, 2> dropDeinitInsts;
696+
694697
/// A "inout terminator use" is an implicit liveness use of the entire value
695698
/// placed on a terminator. We use this both so we add liveness for the
696699
/// terminator user and so that we can use the set to quickly identify later
@@ -712,6 +715,31 @@ struct UseState {
712715
return inoutTermUsers.count(inst);
713716
}
714717

718+
/// Returns true if the given instruction is within the same block as a reinit
719+
/// and precedes a reinit instruction in that block.
720+
bool precedesReinitInSameBlock(SILInstruction *inst) const {
721+
SILBasicBlock *block = inst->getParent();
722+
SmallSetVector<SILInstruction *, 8> sameBlockReinits;
723+
724+
// First, search for all reinits that are within the same block.
725+
for (auto &reinit : reinitInsts) {
726+
if (reinit.first->getParent() != block)
727+
continue;
728+
sameBlockReinits.insert(reinit.first);
729+
}
730+
731+
if (sameBlockReinits.empty())
732+
return false;
733+
734+
// Walk down from the given instruction to see if we encounter a reinit.
735+
for (auto ii = std::next(inst->getIterator()); ii != block->end(); ++ii) {
736+
if (sameBlockReinits.contains(&*ii))
737+
return true;
738+
}
739+
740+
return false;
741+
}
742+
715743
void clear() {
716744
address = nullptr;
717745
destroys.clear();
@@ -721,6 +749,7 @@ struct UseState {
721749
takeInsts.clear();
722750
initInsts.clear();
723751
reinitInsts.clear();
752+
dropDeinitInsts.clear();
724753
inoutTermUsers.clear();
725754
debugValue = nullptr;
726755
}
@@ -755,6 +784,10 @@ struct UseState {
755784
for (auto pair : reinitInsts) {
756785
llvm::dbgs() << *pair.first;
757786
}
787+
llvm::dbgs() << "DropDeinits:\n";
788+
for (auto *inst : dropDeinitInsts) {
789+
llvm::dbgs() << *inst;
790+
}
758791
llvm::dbgs() << "InOut Term Users:\n";
759792
for (auto *inst : inoutTermUsers) {
760793
llvm::dbgs() << *inst;
@@ -1737,6 +1770,12 @@ bool GatherUsesVisitor::visitUse(Operand *op) {
17371770
LLVM_DEBUG(llvm::dbgs() << "Running copy propagation!\n");
17381771
moveChecker.changed |= moveChecker.canonicalizer.canonicalize();
17391772

1773+
// Export the drop_deinit's discovered by the ObjectChecker into the
1774+
// AddressChecker to preserve it for later use. We need to do this since
1775+
// the ObjectChecker's state gets cleared after running on this LoadInst.
1776+
for (auto *dropDeinit : moveChecker.canonicalizer.getDropDeinitUses())
1777+
moveChecker.addressUseState.dropDeinitInsts.insert(dropDeinit);
1778+
17401779
// If we are asked to perform no_consume_or_assign checking or
17411780
// assignable_but_not_consumable checking, if we found any consumes of our
17421781
// load, then we need to emit an error.
@@ -2458,10 +2497,41 @@ void MoveOnlyAddressCheckerPImpl::rewriteUses(
24582497
FieldSensitiveMultiDefPrunedLiveRange &liveness,
24592498
const FieldSensitivePrunedLivenessBoundary &boundary) {
24602499
LLVM_DEBUG(llvm::dbgs() << "MoveOnlyAddressChecker Rewrite Uses!\n");
2461-
// First remove all destroy_addr that have not been claimed.
2500+
2501+
/// Whether the marked value appeared in a discard statement.
2502+
const bool isDiscardingContext = !addressUseState.dropDeinitInsts.empty();
2503+
2504+
// Process destroys
24622505
for (auto destroyPair : addressUseState.destroys) {
2463-
if (!consumes.claimConsume(destroyPair.first, destroyPair.second)) {
2506+
/// Is this destroy instruction a final consuming use?
2507+
bool isFinalConsume =
2508+
consumes.claimConsume(destroyPair.first, destroyPair.second);
2509+
2510+
// Remove destroys that are not the final consuming use.
2511+
if (!isFinalConsume) {
24642512
destroyPair.first->eraseFromParent();
2513+
continue;
2514+
}
2515+
2516+
// Otherwise, if we're in a discarding context, flag this final destroy_addr
2517+
// as a point where we're missing an explicit `consume self`. The reasoning
2518+
// here is that if a destroy of self is the final consuming use,
2519+
// then these are the points where we implicitly destroy self to clean-up
2520+
// that self var before exiting the scope. An explicit 'consume self'
2521+
// that is thrown away is a consume of this mark_must_check'd var and not a
2522+
// destroy of it, according to the use classifier.
2523+
if (isDiscardingContext) {
2524+
2525+
// Since the boundary computations treat a newly-added destroy prior to
2526+
// a reinit within that same block as a "final consuming use", exclude
2527+
// such destroys-before-reinit. We are only interested in the final
2528+
// destroy of a var, not intermediate destroys of the var.
2529+
if (addressUseState.precedesReinitInSameBlock(destroyPair.first))
2530+
continue;
2531+
2532+
auto *dropDeinit = addressUseState.dropDeinitInsts.front();
2533+
diagnosticEmitter.emitMissingConsumeInDiscardingContext(destroyPair.first,
2534+
dropDeinit);
24652535
}
24662536
}
24672537

0 commit comments

Comments
 (0)