Skip to content

Commit 85dfbcd

Browse files
committed
RequirementMachine: Move some code from RequirementMachine.cpp to RequirementMachineRequests.cpp
1 parent 7244102 commit 85dfbcd

File tree

2 files changed

+115
-108
lines changed

2 files changed

+115
-108
lines changed

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 0 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -534,108 +534,3 @@ void RequirementMachine::computeCompletion(RewriteSystem::ValidityPolicy policy)
534534
bool RequirementMachine::isComplete() const {
535535
return Complete;
536536
}
537-
538-
/// Convert a list of non-permanent, non-redundant rewrite rules into a minimal
539-
/// protocol requirement signature for \p proto. The requirements are sorted in
540-
/// canonical order, and same-type requirements are canonicalized.
541-
std::vector<Requirement>
542-
RequirementMachine::buildRequirementSignature(ArrayRef<unsigned> rules,
543-
const ProtocolDecl *proto) const {
544-
std::vector<Requirement> reqs;
545-
llvm::SmallDenseMap<TypeBase *, llvm::SmallVector<Type, 2>> sameTypeReqs;
546-
547-
auto genericParams = proto->getGenericSignature().getGenericParams();
548-
549-
// Convert a rewrite rule into a requirement.
550-
auto createRequirementFromRule = [&](const Rule &rule) {
551-
if (auto prop = rule.isPropertyRule()) {
552-
auto subjectType = Context.getTypeForTerm(rule.getRHS(), genericParams,
553-
System.getProtocols());
554-
555-
switch (prop->getKind()) {
556-
case Symbol::Kind::Protocol:
557-
reqs.emplace_back(RequirementKind::Conformance,
558-
subjectType,
559-
prop->getProtocol()->getDeclaredInterfaceType());
560-
return;
561-
562-
case Symbol::Kind::Layout:
563-
case Symbol::Kind::ConcreteType:
564-
case Symbol::Kind::Superclass:
565-
// FIXME
566-
return;
567-
568-
case Symbol::Kind::Name:
569-
case Symbol::Kind::AssociatedType:
570-
case Symbol::Kind::GenericParam:
571-
break;
572-
}
573-
574-
llvm_unreachable("Invalid symbol kind");
575-
} else if (rule.getLHS().back().getKind() != Symbol::Kind::Protocol) {
576-
auto constraintType = Context.getTypeForTerm(rule.getLHS(), genericParams,
577-
System.getProtocols());
578-
auto subjectType = Context.getTypeForTerm(rule.getRHS(), genericParams,
579-
System.getProtocols());
580-
581-
sameTypeReqs[subjectType.getPointer()].push_back(constraintType);
582-
}
583-
};
584-
585-
// Build the list of requirements, storing same-type requirements off
586-
// to the side.
587-
for (unsigned ruleID : rules) {
588-
const auto &rule = System.getRule(ruleID);
589-
createRequirementFromRule(rule);
590-
}
591-
592-
// A set of rewrite rules of the form:
593-
//
594-
// B => A
595-
// C => A
596-
// D => A
597-
//
598-
// Become a series of same-type requirements
599-
//
600-
// A == B, B == C, C == D
601-
//
602-
for (auto &pair : sameTypeReqs) {
603-
std::sort(pair.second.begin(), pair.second.end(),
604-
[](Type first, Type second) -> bool {
605-
return compareDependentTypes(first, second) < 0;
606-
});
607-
608-
Type subjectType(pair.first);
609-
for (auto constraintType : pair.second) {
610-
reqs.emplace_back(RequirementKind::SameType, subjectType, constraintType);
611-
subjectType = constraintType;
612-
}
613-
}
614-
615-
// Sort the requirements in canonical order.
616-
std::sort(reqs.begin(), reqs.end(),
617-
[](const Requirement &lhs, const Requirement &rhs) -> bool {
618-
return lhs.compare(rhs) < 0;
619-
});
620-
621-
return reqs;
622-
}
623-
624-
/// Builds the requirement signatures for each protocol in this strongly
625-
/// connected component.
626-
llvm::DenseMap<const ProtocolDecl *, std::vector<Requirement>>
627-
RequirementMachine::computeMinimalRequirements() {
628-
assert(Protos.size() > 0);
629-
System.minimizeRewriteSystem();
630-
631-
auto rules = System.getMinimizedRules(Protos);
632-
633-
// Note that we build 'result' by iterating over 'Protos' rather than
634-
// 'rules'; this is intentional, so that even if a protocol has no
635-
// rules, we still end up creating an entry for it in 'result'.
636-
llvm::DenseMap<const ProtocolDecl *, std::vector<Requirement>> result;
637-
for (const auto *proto : Protos)
638-
result[proto] = buildRequirementSignature(rules[proto], proto);
639-
640-
return result;
641-
}

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,25 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// This file implements the main entry points into the requirement machine
14-
// via the request evaluator.
13+
// This file implements the main entry points for computing minimized generic
14+
// signatures using the requirement machine via the request evaluator.
15+
//
16+
// The actual logic for finding a minimal set of rewrite rules is implemented in
17+
// HomotopyReduction.cpp and GeneratingConformances.cpp.
1518
//
1619
//===----------------------------------------------------------------------===//
1720

18-
#include "RequirementMachine.h"
1921
#include "swift/AST/ASTContext.h"
2022
#include "swift/AST/Decl.h"
23+
#include "swift/AST/GenericSignature.h"
2124
#include "swift/AST/GenericSignatureBuilder.h"
2225
#include "swift/AST/LazyResolver.h"
26+
#include "swift/AST/Requirement.h"
2327
#include "swift/AST/TypeCheckRequests.h"
2428
#include "swift/Basic/Statistic.h"
29+
#include <vector>
30+
31+
#include "RequirementMachine.h"
2532

2633
using namespace swift;
2734
using namespace rewriting;
@@ -33,6 +40,111 @@ STATISTIC(NumLazyRequirementSignaturesLoaded,
3340

3441
#undef DEBUG_TYPE
3542

43+
/// Convert a list of non-permanent, non-redundant rewrite rules into a minimal
44+
/// protocol requirement signature for \p proto. The requirements are sorted in
45+
/// canonical order, and same-type requirements are canonicalized.
46+
std::vector<Requirement>
47+
RequirementMachine::buildRequirementSignature(ArrayRef<unsigned> rules,
48+
const ProtocolDecl *proto) const {
49+
std::vector<Requirement> reqs;
50+
llvm::SmallDenseMap<TypeBase *, llvm::SmallVector<Type, 2>> sameTypeReqs;
51+
52+
auto genericParams = proto->getGenericSignature().getGenericParams();
53+
54+
// Convert a rewrite rule into a requirement.
55+
auto createRequirementFromRule = [&](const Rule &rule) {
56+
if (auto prop = rule.isPropertyRule()) {
57+
auto subjectType = Context.getTypeForTerm(rule.getRHS(), genericParams,
58+
System.getProtocols());
59+
60+
switch (prop->getKind()) {
61+
case Symbol::Kind::Protocol:
62+
reqs.emplace_back(RequirementKind::Conformance,
63+
subjectType,
64+
prop->getProtocol()->getDeclaredInterfaceType());
65+
return;
66+
67+
case Symbol::Kind::Layout:
68+
case Symbol::Kind::ConcreteType:
69+
case Symbol::Kind::Superclass:
70+
// FIXME
71+
return;
72+
73+
case Symbol::Kind::Name:
74+
case Symbol::Kind::AssociatedType:
75+
case Symbol::Kind::GenericParam:
76+
break;
77+
}
78+
79+
llvm_unreachable("Invalid symbol kind");
80+
} else if (rule.getLHS().back().getKind() != Symbol::Kind::Protocol) {
81+
auto constraintType = Context.getTypeForTerm(rule.getLHS(), genericParams,
82+
System.getProtocols());
83+
auto subjectType = Context.getTypeForTerm(rule.getRHS(), genericParams,
84+
System.getProtocols());
85+
86+
sameTypeReqs[subjectType.getPointer()].push_back(constraintType);
87+
}
88+
};
89+
90+
// Build the list of requirements, storing same-type requirements off
91+
// to the side.
92+
for (unsigned ruleID : rules) {
93+
const auto &rule = System.getRule(ruleID);
94+
createRequirementFromRule(rule);
95+
}
96+
97+
// A set of rewrite rules of the form:
98+
//
99+
// B => A
100+
// C => A
101+
// D => A
102+
//
103+
// Become a series of same-type requirements
104+
//
105+
// A == B, B == C, C == D
106+
//
107+
for (auto &pair : sameTypeReqs) {
108+
std::sort(pair.second.begin(), pair.second.end(),
109+
[](Type first, Type second) -> bool {
110+
return compareDependentTypes(first, second) < 0;
111+
});
112+
113+
Type subjectType(pair.first);
114+
for (auto constraintType : pair.second) {
115+
reqs.emplace_back(RequirementKind::SameType, subjectType, constraintType);
116+
subjectType = constraintType;
117+
}
118+
}
119+
120+
// Sort the requirements in canonical order.
121+
std::sort(reqs.begin(), reqs.end(),
122+
[](const Requirement &lhs, const Requirement &rhs) -> bool {
123+
return lhs.compare(rhs) < 0;
124+
});
125+
126+
return reqs;
127+
}
128+
129+
/// Builds the requirement signatures for each protocol in this strongly
130+
/// connected component.
131+
llvm::DenseMap<const ProtocolDecl *, std::vector<Requirement>>
132+
RequirementMachine::computeMinimalRequirements() {
133+
assert(Protos.size() > 0);
134+
System.minimizeRewriteSystem();
135+
136+
auto rules = System.getMinimizedRules(Protos);
137+
138+
// Note that we build 'result' by iterating over 'Protos' rather than
139+
// 'rules'; this is intentional, so that even if a protocol has no
140+
// rules, we still end up creating an entry for it in 'result'.
141+
llvm::DenseMap<const ProtocolDecl *, std::vector<Requirement>> result;
142+
for (const auto *proto : Protos)
143+
result[proto] = buildRequirementSignature(rules[proto], proto);
144+
145+
return result;
146+
}
147+
36148
ArrayRef<Requirement>
37149
RequirementSignatureRequest::evaluate(Evaluator &evaluator,
38150
ProtocolDecl *proto) const {

0 commit comments

Comments
 (0)