Skip to content

Commit ad1a9c0

Browse files
authored
Merge pull request #38967 from slavapestov/clean-up-merged-assoc-types
RequirementMachine: Clean up merged associated type processing
2 parents d5b30a6 + c092599 commit ad1a9c0

27 files changed

+228
-102
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,15 @@ namespace swift {
459459
RequirementMachineMode EnableRequirementMachine =
460460
RequirementMachineMode::Disabled;
461461

462-
/// Enables debugging output from the requirement machine.
463-
bool DebugRequirementMachine = false;
462+
/// Enables dumping rewrite systems from the requirement machine.
463+
bool DumpRequirementMachine = false;
464464

465465
/// Enables statistics output from the requirement machine.
466466
bool AnalyzeRequirementMachine = false;
467467

468+
/// Enables fine-grained debug output from the requirement machine.
469+
std::string DebugRequirementMachine;
470+
468471
/// Maximum iteration count for requirement machine confluent completion
469472
/// algorithm.
470473
unsigned RequirementMachineStepLimit = 2000;

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,11 @@ def debug_constraints_on_line_EQ : Joined<["-"], "debug-constraints-on-line=">,
273273
def disable_named_lazy_member_loading : Flag<["-"], "disable-named-lazy-member-loading">,
274274
HelpText<"Disable per-name lazy member loading">;
275275

276-
def debug_requirement_machine : Flag<["-"], "debug-requirement-machine">,
277-
HelpText<"Enables debugging output from the generics implementation">;
276+
def dump_requirement_machine : Flag<["-"], "dump-requirement-machine">,
277+
HelpText<"Enables dumping rewrite systems from the generics implementation">;
278+
279+
def debug_requirement_machine : Joined<["-"], "debug-requirement-machine=">,
280+
HelpText<"Fine-grained debug output from the generics implementation">;
278281

279282
def analyze_requirement_machine : Flag<["-"], "analyze-requirement-machine">,
280283
Flags<[FrontendOption, HelpHidden, DoesNotAffectIncrementalBuild]>,

lib/AST/RequirementMachine/Debug.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===--- Debug.h - Requirement machine debugging flags ----------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 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_RQM_DEBUG_H
14+
#define SWIFT_RQM_DEBUG_H
15+
16+
namespace swift {
17+
18+
namespace rewriting {
19+
20+
enum class DebugFlags : unsigned {
21+
/// Print debug output when simplifying terms.
22+
Simplify = (1<<0),
23+
24+
/// Print debug output when adding rules.
25+
Add = (1<<1),
26+
27+
/// Print debug output when merging associated types.
28+
Merge = (1<<2),
29+
30+
/// Print debug output from the Knuth-Bendix algorithm.
31+
Completion = (1<<3),
32+
33+
/// Print debug output when unifying concrete types in the property map.
34+
ConcreteUnification = (1<<4),
35+
36+
/// Print debug output when concretizing nested types in the property map.
37+
ConcretizeNestedTypes = (1<<5)
38+
};
39+
40+
using DebugOptions = OptionSet<DebugFlags>;
41+
42+
}
43+
44+
}
45+
46+
#endif

lib/AST/RequirementMachine/PropertyMap.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ void PropertyMap::addProperty(
736736
assert(property.isProperty());
737737
auto *props = getOrCreateProperties(key);
738738
props->addProperty(property, Context,
739-
inducedRules, DebugConcreteUnification);
739+
inducedRules, Debug.contains(DebugFlags::ConcreteUnification));
740740
}
741741

742742
/// For each fully-concrete type, find the shortest term having that concrete type.
@@ -772,7 +772,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
772772
if (props->getConformsTo().empty())
773773
continue;
774774

775-
if (DebugConcretizeNestedTypes) {
775+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
776776
if (props->isConcreteType() ||
777777
props->hasSuperclassBound()) {
778778
llvm::dbgs() << "^ Concretizing nested types of ";
@@ -782,7 +782,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
782782
}
783783

784784
if (props->isConcreteType()) {
785-
if (DebugConcretizeNestedTypes) {
785+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
786786
llvm::dbgs() << "- via concrete type requirement\n";
787787
}
788788

@@ -797,7 +797,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
797797
}
798798

799799
if (props->hasSuperclassBound()) {
800-
if (DebugConcretizeNestedTypes) {
800+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
801801
llvm::dbgs() << "- via superclass requirement\n";
802802
}
803803

@@ -863,7 +863,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
863863
const_cast<ProtocolDecl *>(proto));
864864
if (conformance.isInvalid()) {
865865
// FIXME: Diagnose conflict
866-
if (DebugConcretizeNestedTypes) {
866+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
867867
llvm::dbgs() << "^^ " << concreteType << " does not conform to "
868868
<< proto->getName() << "\n";
869869
}
@@ -886,15 +886,15 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
886886
continue;
887887

888888
for (auto *assocType : assocTypes) {
889-
if (DebugConcretizeNestedTypes) {
889+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
890890
llvm::dbgs() << "^^ " << "Looking up type witness for "
891891
<< proto->getName() << ":" << assocType->getName()
892892
<< " on " << concreteType << "\n";
893893
}
894894

895895
auto t = concrete->getTypeWitness(assocType);
896896
if (!t) {
897-
if (DebugConcretizeNestedTypes) {
897+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
898898
llvm::dbgs() << "^^ " << "Type witness for " << assocType->getName()
899899
<< " of " << concreteType << " could not be inferred\n";
900900
}
@@ -904,7 +904,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
904904

905905
auto typeWitness = t->getCanonicalType();
906906

907-
if (DebugConcretizeNestedTypes) {
907+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
908908
llvm::dbgs() << "^^ " << "Type witness for " << assocType->getName()
909909
<< " of " << concreteType << " is " << typeWitness << "\n";
910910
}
@@ -920,7 +920,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
920920
// FIXME: ConcreteTypeInDomainMap should support substitutions so
921921
// that we can remove this.
922922

923-
if (DebugConcretizeNestedTypes) {
923+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
924924
llvm::dbgs() << "^^ Type witness is the same as the concrete type\n";
925925
}
926926

@@ -933,7 +933,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
933933
}
934934

935935
inducedRules.emplace_back(subjectType, constraintType);
936-
if (DebugConcretizeNestedTypes) {
936+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
937937
llvm::dbgs() << "^^ Induced rule " << constraintType
938938
<< " => " << subjectType << "\n";
939939
}
@@ -977,7 +977,7 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
977977
if (found != ConcreteTypeInDomainMap.end()) {
978978
MutableTerm result(found->second);
979979
if (result != subjectType) {
980-
if (DebugConcretizeNestedTypes) {
980+
if (Debug.contains(DebugFlags::ConcretizeNestedTypes)) {
981981
llvm::dbgs() << "^^ Type witness can re-use property bag of "
982982
<< found->second << "\n";
983983
}

lib/AST/RequirementMachine/PropertyMap.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <algorithm>
2626
#include <vector>
2727

28+
#include "Debug.h"
2829
#include "ProtocolGraph.h"
2930
#include "RewriteContext.h"
3031
#include "RewriteSystem.h"
@@ -145,8 +146,7 @@ class PropertyMap {
145146
llvm::DenseMap<ConcreteTypeInDomain, Term> ConcreteTypeInDomainMap;
146147

147148
const ProtocolGraph &Protos;
148-
unsigned DebugConcreteUnification : 1;
149-
unsigned DebugConcretizeNestedTypes : 1;
149+
DebugOptions Debug;
150150

151151
PropertyBag *getOrCreateProperties(Term key);
152152

@@ -159,8 +159,7 @@ class PropertyMap {
159159
explicit PropertyMap(RewriteContext &ctx,
160160
const ProtocolGraph &protos)
161161
: Context(ctx), Protos(protos) {
162-
DebugConcreteUnification = false;
163-
DebugConcretizeNestedTypes = false;
162+
Debug = ctx.getDebugOptions();
164163
}
165164

166165
~PropertyMap();

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace {
3030
/// transitively-referenced protocols.
3131
struct RewriteSystemBuilder {
3232
RewriteContext &Context;
33-
bool Debug;
33+
bool Dump;
3434

3535
ProtocolGraph Protocols;
3636
std::vector<std::pair<MutableTerm, MutableTerm>> Rules;
@@ -39,8 +39,8 @@ struct RewriteSystemBuilder {
3939
const ProtocolDecl *proto,
4040
SmallVectorImpl<Term> &result);
4141

42-
RewriteSystemBuilder(RewriteContext &ctx, bool debug)
43-
: Context(ctx), Debug(debug) {}
42+
RewriteSystemBuilder(RewriteContext &ctx, bool dump)
43+
: Context(ctx), Dump(dump) {}
4444
void addGenericSignature(CanGenericSignature sig);
4545
void addAssociatedType(const AssociatedTypeDecl *type,
4646
const ProtocolDecl *proto);
@@ -86,7 +86,7 @@ void RewriteSystemBuilder::addGenericSignature(CanGenericSignature sig) {
8686

8787
// Add rewrite rules for each protocol.
8888
for (auto *proto : Protocols.getProtocols()) {
89-
if (Debug) {
89+
if (Dump) {
9090
llvm::dbgs() << "protocol " << proto->getName() << " {\n";
9191
}
9292

@@ -101,7 +101,7 @@ void RewriteSystemBuilder::addGenericSignature(CanGenericSignature sig) {
101101
for (auto req : info.Requirements)
102102
addRequirement(req.getCanonical(), proto);
103103

104-
if (Debug) {
104+
if (Dump) {
105105
llvm::dbgs() << "}\n";
106106
}
107107
}
@@ -140,7 +140,7 @@ void RewriteSystemBuilder::addAssociatedType(const AssociatedTypeDecl *type,
140140
/// protocol symbol.
141141
void RewriteSystemBuilder::addRequirement(const Requirement &req,
142142
const ProtocolDecl *proto) {
143-
if (Debug) {
143+
if (Dump) {
144144
llvm::dbgs() << "+ ";
145145
req.dump(llvm::dbgs());
146146
llvm::dbgs() << "\n";
@@ -310,7 +310,7 @@ void RequirementMachine::dump(llvm::raw_ostream &out) const {
310310
RequirementMachine::RequirementMachine(RewriteContext &ctx)
311311
: Context(ctx), System(ctx), Map(ctx, System.getProtocols()) {
312312
auto &langOpts = ctx.getASTContext().LangOpts;
313-
Debug = langOpts.DebugRequirementMachine;
313+
Dump = langOpts.DumpRequirementMachine;
314314
RequirementMachineStepLimit = langOpts.RequirementMachineStepLimit;
315315
RequirementMachineDepthLimit = langOpts.RequirementMachineDepthLimit;
316316
Stats = ctx.getASTContext().Stats;
@@ -331,14 +331,14 @@ void RequirementMachine::addGenericSignature(CanGenericSignature sig) {
331331

332332
FrontendStatsTracer tracer(Stats, "build-rewrite-system");
333333

334-
if (Debug) {
334+
if (Dump) {
335335
llvm::dbgs() << "Adding generic signature " << sig << " {\n";
336336
}
337337

338338

339339
// Collect the top-level requirements, and all transtively-referenced
340340
// protocol requirement signatures.
341-
RewriteSystemBuilder builder(Context, Debug);
341+
RewriteSystemBuilder builder(Context, Dump);
342342
builder.addGenericSignature(sig);
343343

344344
// Add the initial set of rewrite rules to the rewrite system, also
@@ -348,7 +348,7 @@ void RequirementMachine::addGenericSignature(CanGenericSignature sig) {
348348

349349
computeCompletion();
350350

351-
if (Debug) {
351+
if (Dump) {
352352
llvm::dbgs() << "}\n";
353353
}
354354
}
@@ -413,7 +413,7 @@ void RequirementMachine::computeCompletion() {
413413
break;
414414
}
415415

416-
if (Debug) {
416+
if (Dump) {
417417
dump(llvm::dbgs());
418418
}
419419

lib/AST/RequirementMachine/RequirementMachine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class RequirementMachine final {
5252
RewriteSystem System;
5353
PropertyMap Map;
5454

55-
bool Debug = false;
55+
bool Dump = false;
5656
bool Complete = false;
5757
unsigned RequirementMachineStepLimit;
5858
unsigned RequirementMachineDepthLimit;

lib/AST/RequirementMachine/RewriteContext.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,33 @@
1919
using namespace swift;
2020
using namespace rewriting;
2121

22+
/// Build a DebugOptions by parsing a comma-separated list of debug flags.
23+
static DebugOptions parseDebugFlags(StringRef debugFlags) {
24+
DebugOptions result;
25+
26+
SmallVector<StringRef, 2> debug;
27+
debugFlags.split(debug, ',');
28+
for (auto flagStr : debug) {
29+
auto flag = llvm::StringSwitch<Optional<DebugFlags>>(flagStr)
30+
.Case("simplify", DebugFlags::Simplify)
31+
.Case("add", DebugFlags::Add)
32+
.Case("merge", DebugFlags::Merge)
33+
.Case("completion", DebugFlags::Completion)
34+
.Case("concrete-unification", DebugFlags::ConcreteUnification)
35+
.Case("concretize-nested-types", DebugFlags::ConcretizeNestedTypes)
36+
.Default(None);
37+
if (!flag) {
38+
llvm::errs() << "Unknown debug flag in -debug-requirement-machine "
39+
<< flagStr << "\n";
40+
abort();
41+
}
42+
43+
result |= *flag;
44+
}
45+
46+
return result;
47+
}
48+
2249
RewriteContext::RewriteContext(ASTContext &ctx)
2350
: Context(ctx),
2451
Stats(ctx.Stats),
@@ -28,6 +55,9 @@ RewriteContext::RewriteContext(ASTContext &ctx)
2855
RuleTrieRootHistogram(16),
2956
PropertyTrieHistogram(16, /*Start=*/1),
3057
PropertyTrieRootHistogram(16) {
58+
auto debugFlags = StringRef(ctx.LangOpts.DebugRequirementMachine);
59+
if (!debugFlags.empty())
60+
Debug = parseDebugFlags(debugFlags);
3161
}
3262

3363
Term RewriteContext::getTermForType(CanType paramType,

lib/AST/RequirementMachine/RewriteContext.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/DenseMap.h"
2020
#include "llvm/ADT/FoldingSet.h"
2121
#include "llvm/Support/Allocator.h"
22+
#include "Debug.h"
2223
#include "Histogram.h"
2324
#include "Symbol.h"
2425
#include "Term.h"
@@ -48,13 +49,18 @@ class RewriteContext final {
4849
/// Cache for associated type declarations.
4950
llvm::DenseMap<Symbol, AssociatedTypeDecl *> AssocTypes;
5051

52+
/// Cache for merged associated type symbols.
53+
llvm::DenseMap<std::pair<Symbol, Symbol>, Symbol> MergedAssocTypes;
54+
55+
ASTContext &Context;
56+
57+
DebugOptions Debug;
58+
5159
RewriteContext(const RewriteContext &) = delete;
5260
RewriteContext(RewriteContext &&) = delete;
5361
RewriteContext &operator=(const RewriteContext &) = delete;
5462
RewriteContext &operator=(RewriteContext &&) = delete;
5563

56-
ASTContext &Context;
57-
5864
public:
5965
/// Statistics.
6066
UnifiedStatsReporter *Stats;
@@ -69,6 +75,8 @@ class RewriteContext final {
6975

7076
explicit RewriteContext(ASTContext &ctx);
7177

78+
DebugOptions getDebugOptions() const { return Debug; }
79+
7280
Term getTermForType(CanType paramType, const ProtocolDecl *proto);
7381

7482
MutableTerm getMutableTermForType(CanType paramType,
@@ -91,6 +99,9 @@ class RewriteContext final {
9199
AssociatedTypeDecl *getAssociatedTypeForSymbol(Symbol symbol,
92100
const ProtocolGraph &protos);
93101

102+
Symbol mergeAssociatedTypes(Symbol lhs, Symbol rhs,
103+
const ProtocolGraph &protos);
104+
94105
~RewriteContext();
95106
};
96107

0 commit comments

Comments
 (0)