Skip to content

Commit 0045840

Browse files
authored
Merge pull request #42042 from slavapestov/rqm-reuse-machines
RequirementMachine: Re-use requirement machines constructed by minimization for queries
2 parents 7c226dd + e2a509c commit 0045840

29 files changed

+357
-82
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -535,13 +535,16 @@ GenericSignature buildGenericSignature(
535535

536536
/// Summary of error conditions detected by the Requirement Machine.
537537
enum class GenericSignatureErrorFlags {
538-
/// The original requirements referenced a non-existent type parameter.
539-
HasUnresolvedType = (1<<0),
540-
541-
/// The original requirements were in conflict with each other, meaning
538+
/// The original requirements referenced a non-existent type parameter,
539+
/// or the original requirements were in conflict with each other, meaning
542540
/// there are no possible concrete substitutions which statisfy the
543541
/// generic signature.
544-
HasConflict = (1<<1),
542+
HasInvalidRequirements = (1<<0),
543+
544+
/// The generic signature had non-redundant concrete conformance
545+
/// requirements, which means the rewrite system used for minimization
546+
/// must be discarded and a new one built for queries.
547+
HasConcreteConformances = (1<<1),
545548

546549
/// The Knuth-Bendix completion procedure failed to construct a confluent
547550
/// rewrite system.

lib/AST/GenericSignature.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,9 @@ void swift::validateGenericSignature(ASTContext &context,
10671067
GenericSignatureWithError());
10681068

10691069
// If there were any errors, the signature was invalid.
1070-
if (newSigWithError.getInt()) {
1070+
auto errorFlags = newSigWithError.getInt();
1071+
if (errorFlags.contains(GenericSignatureErrorFlags::HasInvalidRequirements) ||
1072+
errorFlags.contains(GenericSignatureErrorFlags::CompletionFailed)) {
10711073
context.Diags.diagnose(SourceLoc(), diag::generic_signature_not_valid,
10721074
sig->getAsString());
10731075
}

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8275,7 +8275,7 @@ AbstractGenericSignatureRequest::evaluate(
82758275
if (!rqmResult.getPointer() && !gsbResult.getPointer())
82768276
return rqmResult;
82778277

8278-
if (!rqmResult.getInt().contains(GenericSignatureErrorFlags::HasConflict) &&
8278+
if (!rqmResult.getInt().contains(GenericSignatureErrorFlags::HasInvalidRequirements) &&
82798279
!rqmResult.getInt().contains(GenericSignatureErrorFlags::CompletionFailed) &&
82808280
!rqmResult.getPointer()->isEqual(gsbResult.getPointer())) {
82818281
PrintOptions opts;
@@ -8427,7 +8427,7 @@ AbstractGenericSignatureRequestGSB::evaluate(
84278427

84288428
GenericSignatureErrors errorFlags;
84298429
if (builder.hadAnyError())
8430-
errorFlags |= GenericSignatureErrorFlags::HasUnresolvedType;
8430+
errorFlags |= GenericSignatureErrorFlags::HasInvalidRequirements;
84318431
auto result = std::move(builder).computeGenericSignature(
84328432
/*allowConcreteGenericParams=*/true);
84338433
return GenericSignatureWithError(result, errorFlags);
@@ -8489,7 +8489,7 @@ InferredGenericSignatureRequest::evaluate(
84898489
if (!rqmResult.getPointer() && !gsbResult.getPointer())
84908490
return rqmResult;
84918491

8492-
if (!rqmResult.getInt().contains(GenericSignatureErrorFlags::HasConflict) &&
8492+
if (!rqmResult.getInt().contains(GenericSignatureErrorFlags::HasInvalidRequirements) &&
84938493
!rqmResult.getInt().contains(GenericSignatureErrorFlags::CompletionFailed) &&
84948494
!rqmResult.getPointer()->isEqual(gsbResult.getPointer())) {
84958495
PrintOptions opts;
@@ -8635,7 +8635,7 @@ InferredGenericSignatureRequestGSB::evaluate(
86358635

86368636
GenericSignatureErrors errorFlags;
86378637
if (builder.hadAnyError())
8638-
errorFlags |= GenericSignatureErrorFlags::HasUnresolvedType;
8638+
errorFlags |= GenericSignatureErrorFlags::HasInvalidRequirements;
86398639
auto result = std::move(builder).computeGenericSignature(
86408640
allowConcreteGenericParams);
86418641
return GenericSignatureWithError(result, errorFlags);
@@ -8705,7 +8705,7 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
87058705
auto rqmResult = buildViaRQM();
87068706
auto gsbResult = buildViaGSB();
87078707

8708-
if (!rqmResult.getErrors().contains(GenericSignatureErrorFlags::HasConflict) &&
8708+
if (!rqmResult.getErrors().contains(GenericSignatureErrorFlags::HasInvalidRequirements) &&
87098709
!rqmResult.getErrors().contains(GenericSignatureErrorFlags::CompletionFailed) &&
87108710
!compare(rqmResult.getRequirements(),
87118711
gsbResult.getRequirements())) {

lib/AST/RequirementMachine/Debug.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ enum class DebugFlags : unsigned {
6969
/// Print debug output from propagating explicit requirement
7070
/// IDs from redundant rules.
7171
PropagateRequirementIDs = (1<<15),
72+
73+
/// Print a trace of requirement machines constructed and how long each took.
74+
Timers = (1<<16),
7275
};
7376

7477
using DebugOptions = OptionSet<DebugFlags>;

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ void RewriteSystem::minimizeRewriteSystem() {
471471

472472
assert(Complete);
473473
assert(!Minimized);
474+
assert(!Frozen);
474475
Minimized = 1;
475476

476477
propagateExplicitBits();
@@ -626,7 +627,7 @@ GenericSignatureErrors RewriteSystem::getErrors() const {
626627

627628
GenericSignatureErrors result;
628629

629-
for (const auto &rule : Rules) {
630+
for (const auto &rule : getLocalRules()) {
630631
if (rule.isPermanent())
631632
continue;
632633

@@ -636,10 +637,15 @@ GenericSignatureErrors RewriteSystem::getErrors() const {
636637
if (!rule.isRedundant() &&
637638
!rule.isProtocolTypeAliasRule() &&
638639
rule.containsUnresolvedSymbols())
639-
result |= GenericSignatureErrorFlags::HasUnresolvedType;
640+
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
640641

641642
if (rule.isConflicting())
642-
result |= GenericSignatureErrorFlags::HasConflict;
643+
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
644+
645+
if (!rule.isRedundant())
646+
if (auto property = rule.isPropertyRule())
647+
if (property->getKind() == Symbol::Kind::ConcreteConformance)
648+
result |= GenericSignatureErrorFlags::HasConcreteConformances;
643649
}
644650

645651
return result;

lib/AST/RequirementMachine/KnuthBendix.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ RewriteSystem::computeConfluentCompletion(unsigned maxRuleCount,
287287
unsigned maxRuleLength) {
288288
assert(Initialized);
289289
assert(!Minimized);
290+
assert(!Frozen);
290291

291292
// Complete might already be set, if we're re-running completion after
292293
// adding new rules in the property map's concrete type unification procedure.

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,16 @@ RequirementMachine::initWithProtocolSignatureRequirements(
9090
builder.initWithProtocolSignatureRequirements(protos);
9191

9292
// Add the initial set of rewrite rules to the rewrite system.
93-
System.initialize(/*recordLoops=*/true, protos,
93+
System.initialize(/*recordLoops=*/false, protos,
9494
std::move(builder.WrittenRequirements),
9595
std::move(builder.ImportedRules),
9696
std::move(builder.PermanentRules),
9797
std::move(builder.RequirementRules));
9898

9999
auto result = computeCompletion(RewriteSystem::DisallowInvalidRequirements);
100100

101+
freeze();
102+
101103
if (Dump) {
102104
llvm::dbgs() << "}\n";
103105
}
@@ -145,6 +147,8 @@ RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
145147

146148
auto result = computeCompletion(RewriteSystem::DisallowInvalidRequirements);
147149

150+
freeze();
151+
148152
if (Dump) {
149153
llvm::dbgs() << "}\n";
150154
}
@@ -332,6 +336,10 @@ RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy) {
332336
return std::make_pair(CompletionResult::Success, 0);
333337
}
334338

339+
void RequirementMachine::freeze() {
340+
System.freeze();
341+
}
342+
335343
std::string RequirementMachine::getRuleAsStringForDiagnostics(
336344
unsigned ruleID) const {
337345
const auto &rule = System.getRule(ruleID);
@@ -359,19 +367,18 @@ void RequirementMachine::dump(llvm::raw_ostream &out) const {
359367
out << "Requirement machine for ";
360368
if (Sig)
361369
out << Sig;
362-
else if (!Params.empty()) {
363-
out << "fresh signature <";
364-
for (auto paramTy : Params)
365-
out << " " << Type(paramTy);
366-
out << " >";
367-
} else {
370+
else if (!System.getProtocols().empty()) {
368371
auto protos = System.getProtocols();
369-
assert(!protos.empty());
370372
out << "protocols [";
371373
for (auto *proto : protos) {
372374
out << " " << proto->getName();
373375
}
374376
out << " ]";
377+
} else {
378+
out << "fresh signature <";
379+
for (auto paramTy : Params)
380+
out << " " << Type(paramTy);
381+
out << " >";
375382
}
376383
out << "\n";
377384

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class RequirementMachine final {
113113
std::pair<CompletionResult, unsigned>
114114
computeCompletion(RewriteSystem::ValidityPolicy policy);
115115

116+
void freeze();
117+
116118
MutableTerm getLongestValidPrefix(const MutableTerm &term) const;
117119

118120
void buildRequirementsFromRules(
@@ -159,8 +161,8 @@ class RequirementMachine final {
159161
llvm::DenseMap<const ProtocolDecl *, RequirementSignature>
160162
computeMinimalProtocolRequirements();
161163

162-
std::vector<Requirement>
163-
computeMinimalGenericSignatureRequirements(bool reconstituteSugar);
164+
GenericSignature
165+
computeMinimalGenericSignature(bool reconstituteSugar);
164166

165167
ArrayRef<Rule> getLocalRules() const;
166168

0 commit comments

Comments
 (0)