Skip to content

Commit e8cba2c

Browse files
authored
Merge pull request #61199 from slavapestov/rqm-redo-concrete-contraction
RequirementMachine: Redo concrete contraction after splitting concrete equivalence classes
2 parents 238270f + 658ba01 commit e8cba2c

File tree

4 files changed

+83
-38
lines changed

4 files changed

+83
-38
lines changed

lib/AST/RequirementMachine/Debug.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ enum class DebugFlags : unsigned {
7878

7979
/// Print conflicting rules.
8080
ConflictingRules = (1<<18),
81+
82+
/// Print debug output from concrete equivalence class splitting during
83+
/// minimization.
84+
SplitConcreteEquivalenceClass = (1<<19),
8185
};
8286

8387
using DebugOptions = OptionSet<DebugFlags>;

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ static void splitConcreteEquivalenceClasses(
155155
TypeArrayView<GenericTypeParamType> genericParams,
156156
SmallVectorImpl<StructuralRequirement> &splitRequirements,
157157
unsigned &attempt) {
158+
bool debug = machine->getDebugOptions().contains(
159+
DebugFlags::SplitConcreteEquivalenceClass);
160+
158161
unsigned maxAttempts =
159162
ctx.LangOpts.RequirementMachineMaxSplitConcreteEquivClassAttempts;
160163

@@ -172,6 +175,10 @@ static void splitConcreteEquivalenceClasses(
172175

173176
splitRequirements.clear();
174177

178+
if (debug) {
179+
llvm::dbgs() << "\n# Splitting concrete equivalence classes:\n";
180+
}
181+
175182
for (auto req : requirements) {
176183
if (shouldSplitConcreteEquivalenceClass(req, proto, machine)) {
177184
auto concreteType = machine->getConcreteType(
@@ -183,10 +190,24 @@ static void splitConcreteEquivalenceClasses(
183190
req.getSecondType(), concreteType);
184191
splitRequirements.push_back({firstReq, SourceLoc(), /*inferred=*/false});
185192
splitRequirements.push_back({secondReq, SourceLoc(), /*inferred=*/false});
193+
194+
if (debug) {
195+
llvm::dbgs() << "- First split: ";
196+
firstReq.dump(llvm::dbgs());
197+
llvm::dbgs() << "\n- Second split: ";
198+
secondReq.dump(llvm::dbgs());
199+
llvm::dbgs() << "\n";
200+
}
186201
continue;
187202
}
188203

189204
splitRequirements.push_back({req, SourceLoc(), /*inferred=*/false});
205+
206+
if (debug) {
207+
llvm::dbgs() << "- Not split: ";
208+
req.dump(llvm::dbgs());
209+
llvm::dbgs() << "\n";
210+
}
190211
}
191212
}
192213

@@ -299,20 +320,6 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
299320
requirements.push_back(req);
300321
for (auto req : proto->getTypeAliasRequirements())
301322
requirements.push_back({req, SourceLoc(), /*inferred=*/false});
302-
303-
// Preprocess requirements to eliminate conformances on type parameters
304-
// which are made concrete.
305-
if (ctx.LangOpts.EnableRequirementMachineConcreteContraction) {
306-
SmallVector<StructuralRequirement, 4> contractedRequirements;
307-
308-
bool debug = rewriteCtx.getDebugOptions()
309-
.contains(DebugFlags::ConcreteContraction);
310-
311-
if (performConcreteContraction(requirements, contractedRequirements,
312-
errors, debug)) {
313-
std::swap(contractedRequirements, requirements);
314-
}
315-
}
316323
}
317324

318325
if (rewriteCtx.getDebugOptions().contains(DebugFlags::Timers)) {
@@ -335,6 +342,24 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
335342

336343
unsigned attempt = 0;
337344
for (;;) {
345+
for (const auto *proto : component) {
346+
auto &requirements = protos[proto];
347+
348+
// Preprocess requirements to eliminate conformances on type parameters
349+
// which are made concrete.
350+
if (ctx.LangOpts.EnableRequirementMachineConcreteContraction) {
351+
SmallVector<StructuralRequirement, 4> contractedRequirements;
352+
353+
bool debug = rewriteCtx.getDebugOptions()
354+
.contains(DebugFlags::ConcreteContraction);
355+
356+
if (performConcreteContraction(requirements, contractedRequirements,
357+
errors, debug)) {
358+
std::swap(contractedRequirements, requirements);
359+
}
360+
}
361+
}
362+
338363
// Heap-allocate the requirement machine to save stack space.
339364
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(
340365
rewriteCtx));
@@ -639,20 +664,20 @@ AbstractGenericSignatureRequest::evaluate(
639664
llvm::dbgs() << "\n";
640665
}
641666

642-
// Preprocess requirements to eliminate conformances on generic parameters
643-
// which are made concrete.
644-
if (ctx.LangOpts.EnableRequirementMachineConcreteContraction) {
645-
SmallVector<StructuralRequirement, 4> contractedRequirements;
646-
bool debug = rewriteCtx.getDebugOptions()
647-
.contains(DebugFlags::ConcreteContraction);
648-
if (performConcreteContraction(requirements, contractedRequirements,
649-
errors, debug)) {
650-
std::swap(contractedRequirements, requirements);
651-
}
652-
}
653-
654667
unsigned attempt = 0;
655668
for (;;) {
669+
// Preprocess requirements to eliminate conformances on generic parameters
670+
// which are made concrete.
671+
if (ctx.LangOpts.EnableRequirementMachineConcreteContraction) {
672+
SmallVector<StructuralRequirement, 4> contractedRequirements;
673+
bool debug = rewriteCtx.getDebugOptions()
674+
.contains(DebugFlags::ConcreteContraction);
675+
if (performConcreteContraction(requirements, contractedRequirements,
676+
errors, debug)) {
677+
std::swap(contractedRequirements, requirements);
678+
}
679+
}
680+
656681
// Heap-allocate the requirement machine to save stack space.
657682
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(
658683
rewriteCtx));
@@ -834,20 +859,20 @@ InferredGenericSignatureRequest::evaluate(
834859
llvm::dbgs() << "\n";
835860
}
836861

837-
// Preprocess requirements to eliminate conformances on generic parameters
838-
// which are made concrete.
839-
if (ctx.LangOpts.EnableRequirementMachineConcreteContraction) {
840-
SmallVector<StructuralRequirement, 4> contractedRequirements;
841-
bool debug = rewriteCtx.getDebugOptions()
842-
.contains(DebugFlags::ConcreteContraction);
843-
if (performConcreteContraction(requirements, contractedRequirements,
844-
errors, debug)) {
845-
std::swap(contractedRequirements, requirements);
846-
}
847-
}
848-
849862
unsigned attempt = 0;
850863
for (;;) {
864+
// Preprocess requirements to eliminate conformances on generic parameters
865+
// which are made concrete.
866+
if (ctx.LangOpts.EnableRequirementMachineConcreteContraction) {
867+
SmallVector<StructuralRequirement, 4> contractedRequirements;
868+
bool debug = rewriteCtx.getDebugOptions()
869+
.contains(DebugFlags::ConcreteContraction);
870+
if (performConcreteContraction(requirements, contractedRequirements,
871+
errors, debug)) {
872+
std::swap(contractedRequirements, requirements);
873+
}
874+
}
875+
851876
// Heap-allocate the requirement machine to save stack space.
852877
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(
853878
rewriteCtx));

lib/AST/RequirementMachine/RewriteContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static DebugOptions parseDebugFlags(StringRef debugFlags) {
179179
.Case("propagate-requirement-ids", DebugFlags::PropagateRequirementIDs)
180180
.Case("timers", DebugFlags::Timers)
181181
.Case("conflicting-rules", DebugFlags::ConflictingRules)
182+
.Case("split-concrete-equiv-class", DebugFlags::SplitConcreteEquivalenceClass)
182183
.Default(None);
183184
if (!flag) {
184185
llvm::errs() << "Unknown debug flag in -debug-requirement-machine "

test/Generics/issue-61192.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -typecheck -verify %s -debug-generic-signatures -warn-redundant-requirements 2>&1 | %FileCheck %s
2+
3+
struct C {}
4+
5+
protocol P {
6+
associatedtype A
7+
}
8+
9+
struct G<A>: P {}
10+
11+
struct Body<T: P> where T.A == C {
12+
// CHECK-LABEL: .init(_:)@
13+
// CHECK-NEXT: <T, U where T == G<C>, U : P, U.[P]A == C>
14+
init<U: P>(_: U) where T == G<T.A>, U.A == T.A {}
15+
}

0 commit comments

Comments
 (0)