Skip to content

Commit 10e4ffd

Browse files
committed
RequirementMachine: Track known protocols in the rewrite system
Conditional requirement inference needs to be able to add rewrite rules from the requirement signatures of hitherto-unseen protocols, so to help with that, extract out the RuleBuilder's ProtocolMap and move it into the RewriteSystem.
1 parent 9612283 commit 10e4ffd

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

lib/AST/RequirementMachine/RequirementLowering.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ getRuleForRequirement(const Requirement &req,
6565
/// appearing on the right hand side of conformance requirements.
6666
struct RuleBuilder {
6767
RewriteContext &Context;
68-
bool Dump;
6968

7069
/// The keys are the unique protocols we've added so far. The value indicates
7170
/// whether the protocol's SCC is an initial component for the rewrite system.
@@ -81,7 +80,9 @@ struct RuleBuilder {
8180
///
8281
/// This is what breaks the cycle in requirement signature computation for a
8382
/// group of interdependent protocols.
84-
llvm::DenseMap<const ProtocolDecl *, bool> ProtocolMap;
83+
llvm::DenseMap<const ProtocolDecl *, bool> &ProtocolMap;
84+
85+
/// The keys of the above map in insertion order.
8586
std::vector<const ProtocolDecl *> Protocols;
8687

8788
/// New rules to add which will be marked 'permanent'. These are rules for
@@ -95,7 +96,15 @@ struct RuleBuilder {
9596
/// eliminated by homotopy reduction.
9697
std::vector<std::pair<MutableTerm, MutableTerm>> RequirementRules;
9798

98-
RuleBuilder(RewriteContext &ctx, bool dump) : Context(ctx), Dump(dump) {}
99+
/// Enables debugging output. Controlled by the -dump-requirement-machine
100+
/// frontend flag.
101+
bool Dump;
102+
103+
RuleBuilder(RewriteContext &ctx,
104+
llvm::DenseMap<const ProtocolDecl *, bool> &protocolMap)
105+
: Context(ctx), ProtocolMap(protocolMap),
106+
Dump(ctx.getASTContext().LangOpts.DumpRequirementMachine) {}
107+
99108
void addRequirements(ArrayRef<Requirement> requirements);
100109
void addRequirements(ArrayRef<StructuralRequirement> requirements);
101110
void addProtocols(ArrayRef<const ProtocolDecl *> proto);

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
7676

7777
// Collect the top-level requirements, and all transtively-referenced
7878
// protocol requirement signatures.
79-
RuleBuilder builder(Context, Dump);
79+
RuleBuilder builder(Context, System.getProtocolMap());
8080
builder.addRequirements(sig.getRequirements());
8181

8282
// Add the initial set of rewrite rules to the rewrite system.
@@ -115,7 +115,7 @@ RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos) {
115115
llvm::dbgs() << " {\n";
116116
}
117117

118-
RuleBuilder builder(Context, Dump);
118+
RuleBuilder builder(Context, System.getProtocolMap());
119119
builder.addProtocols(protos);
120120

121121
// Add the initial set of rewrite rules to the rewrite system.
@@ -157,7 +157,7 @@ void RequirementMachine::initWithAbstractRequirements(
157157

158158
// Collect the top-level requirements, and all transtively-referenced
159159
// protocol requirement signatures.
160-
RuleBuilder builder(Context, Dump);
160+
RuleBuilder builder(Context, System.getProtocolMap());
161161
builder.addRequirements(requirements);
162162

163163
// Add the initial set of rewrite rules to the rewrite system.
@@ -200,7 +200,7 @@ RequirementMachine::initWithWrittenRequirements(
200200

201201
// Collect the top-level requirements, and all transtively-referenced
202202
// protocol requirement signatures.
203-
RuleBuilder builder(Context, Dump);
203+
RuleBuilder builder(Context, System.getProtocolMap());
204204
builder.addRequirements(requirements);
205205

206206
// Add the initial set of rewrite rules to the rewrite system.

lib/AST/RequirementMachine/RewriteSystem.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,17 @@ class RewriteSystem final {
203203
/// type is an index into the Rules array defined above.
204204
Trie<unsigned, MatchKind::Shortest> Trie;
205205

206+
/// The set of protocols known to this rewrite system. The boolean associated
207+
/// with each key is true if the protocol is part of the 'Protos' set above,
208+
/// otherwies it is false.
209+
///
210+
/// See RuleBuilder::ProtocolMap for a more complete explanation. For the most
211+
/// part, this is only used while building the rewrite system, but conditional
212+
/// requirement inference forces us to be able to add new protocols to the
213+
/// rewrite system after the fact, so this little bit of RuleBuilder state
214+
/// outlives the initialization phase.
215+
llvm::DenseMap<const ProtocolDecl *, bool> ProtocolMap;
216+
206217
DebugOptions Debug;
207218

208219
/// Whether we've initialized the rewrite system with a call to initialize().
@@ -233,6 +244,10 @@ class RewriteSystem final {
233244
/// Return the rewrite context used for allocating memory.
234245
RewriteContext &getRewriteContext() const { return Context; }
235246

247+
llvm::DenseMap<const ProtocolDecl *, bool> &getProtocolMap() {
248+
return ProtocolMap;
249+
}
250+
236251
DebugOptions getDebugOptions() const { return Debug; }
237252

238253
void initialize(bool recordLoops, ArrayRef<const ProtocolDecl *> protos,
@@ -243,6 +258,10 @@ class RewriteSystem final {
243258
return Protos;
244259
}
245260

261+
bool isKnownProtocol(const ProtocolDecl *proto) const {
262+
return ProtocolMap.find(proto) != ProtocolMap.end();
263+
}
264+
246265
unsigned getRuleID(const Rule &rule) const {
247266
assert((unsigned)(&rule - &*Rules.begin()) < Rules.size());
248267
return (unsigned)(&rule - &*Rules.begin());

0 commit comments

Comments
 (0)