RequirementMachine: Preliminary refactoring in preparation for computing top-level generic signatures

This commit is contained in:
Slava Pestov
2021-11-10 23:01:39 -05:00
parent 796123eebd
commit 952dafad72
7 changed files with 111 additions and 33 deletions

View File

@@ -88,17 +88,16 @@ void ConnectedComponent::buildRequirements(Type subjectType,
} // end namespace
/// Convert a list of non-permanent, non-redundant rewrite rules into a minimal
/// protocol requirement signature for \p proto. The requirements are sorted in
/// canonical order, and same-type requirements are canonicalized.
/// Convert a list of non-permanent, non-redundant rewrite rules into a list of
/// requirements sorted in canonical order. The \p genericParams are used to
/// produce sugared types.
std::vector<Requirement>
RequirementMachine::buildRequirementSignature(ArrayRef<unsigned> rules,
const ProtocolDecl *proto) const {
RequirementMachine::buildRequirementsFromRules(
ArrayRef<unsigned> rules,
TypeArrayView<GenericTypeParamType> genericParams) const {
std::vector<Requirement> reqs;
llvm::SmallDenseMap<TypeBase *, ConnectedComponent> sameTypeReqs;
auto genericParams = proto->getGenericSignature().getGenericParams();
// Convert a rewrite rule into a requirement.
auto createRequirementFromRule = [&](const Rule &rule) {
if (auto prop = rule.isPropertyRule()) {
@@ -196,8 +195,12 @@ RequirementMachine::buildRequirementSignature(ArrayRef<unsigned> rules,
/// Builds the requirement signatures for each protocol in this strongly
/// connected component.
llvm::DenseMap<const ProtocolDecl *, std::vector<Requirement>>
RequirementMachine::computeMinimalRequirements() {
assert(Protos.size() > 0);
RequirementMachine::computeMinimalProtocolRequirements() {
assert(Protos.size() > 0 &&
"Not a protocol connected component rewrite system");
assert(Params.empty() &&
"Not a protocol connected component rewrite system");
System.minimizeRewriteSystem();
if (Dump) {
@@ -205,14 +208,16 @@ RequirementMachine::computeMinimalRequirements() {
dump(llvm::dbgs());
}
auto rules = System.getMinimizedRules(Protos);
auto rules = System.getMinimizedProtocolRules(Protos);
// Note that we build 'result' by iterating over 'Protos' rather than
// 'rules'; this is intentional, so that even if a protocol has no
// rules, we still end up creating an entry for it in 'result'.
llvm::DenseMap<const ProtocolDecl *, std::vector<Requirement>> result;
for (const auto *proto : Protos)
result[proto] = buildRequirementSignature(rules[proto], proto);
for (const auto *proto : Protos) {
auto genericParams = proto->getGenericSignature().getGenericParams();
result[proto] = buildRequirementsFromRules(rules[proto], genericParams);
}
return result;
}
@@ -229,7 +234,7 @@ RequirementSignatureRequestRQM::evaluate(Evaluator &evaluator,
// We build requirement signatures for all protocols in a strongly connected
// component at the same time.
auto *machine = ctx.getOrCreateRequirementMachine(proto);
auto requirements = machine->computeMinimalRequirements();
auto requirements = machine->computeMinimalProtocolRequirements();
bool debug = machine->getDebugOptions().contains(DebugFlags::Minimization);
@@ -269,3 +274,22 @@ RequirementSignatureRequestRQM::evaluate(Evaluator &evaluator,
// Return the result for the specific protocol this request was kicked off on.
return result;
}
/// Builds the top-level generic signature requirements for this rewrite system.
std::vector<Requirement>
RequirementMachine::computeMinimalGenericSignatureRequirements() {
assert(Protos.empty() &&
"Not a top-level generic signature rewrite system");
assert(!Params.empty() &&
"Not a from-source top-level generic signature rewrite system");
System.minimizeRewriteSystem();
if (Dump) {
llvm::dbgs() << "Minimized rewrite system:\n";
dump(llvm::dbgs());
}
auto rules = System.getMinimizedGenericSignatureRules();
return buildRequirementsFromRules(rules, getGenericParams());
}