Skip to content

Commit 7244102

Browse files
committed
RequirementMachine: Wire up protocol requirement signature minimization
1 parent 0e21d85 commit 7244102

File tree

1 file changed

+80
-23
lines changed

1 file changed

+80
-23
lines changed

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18+
#include "RequirementMachine.h"
1819
#include "swift/AST/ASTContext.h"
1920
#include "swift/AST/Decl.h"
2021
#include "swift/AST/GenericSignatureBuilder.h"
@@ -23,6 +24,7 @@
2324
#include "swift/Basic/Statistic.h"
2425

2526
using namespace swift;
27+
using namespace rewriting;
2628

2729
#define DEBUG_TYPE "Serialization"
2830

@@ -54,27 +56,82 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
5456
return ctx.AllocateCopy(requirements);
5557
}
5658

57-
GenericSignatureBuilder builder(proto->getASTContext());
58-
59-
// Add all of the generic parameters.
60-
for (auto gp : *proto->getGenericParams())
61-
builder.addGenericParameter(gp);
62-
63-
// Add the conformance of 'self' to the protocol.
64-
auto selfType =
65-
proto->getSelfInterfaceType()->castTo<GenericTypeParamType>();
66-
auto requirement =
67-
Requirement(RequirementKind::Conformance, selfType,
68-
proto->getDeclaredInterfaceType());
69-
70-
builder.addRequirement(
71-
requirement,
72-
GenericSignatureBuilder::RequirementSource::forRequirementSignature(
73-
builder, selfType, proto),
74-
nullptr);
75-
76-
auto reqSignature = std::move(builder).computeGenericSignature(
77-
/*allowConcreteGenericParams=*/false,
78-
/*requirementSignatureSelfProto=*/proto);
79-
return reqSignature.getRequirements();
59+
auto buildViaGSB = [&]() {
60+
GenericSignatureBuilder builder(proto->getASTContext());
61+
62+
// Add all of the generic parameters.
63+
for (auto gp : *proto->getGenericParams())
64+
builder.addGenericParameter(gp);
65+
66+
// Add the conformance of 'self' to the protocol.
67+
auto selfType =
68+
proto->getSelfInterfaceType()->castTo<GenericTypeParamType>();
69+
auto requirement =
70+
Requirement(RequirementKind::Conformance, selfType,
71+
proto->getDeclaredInterfaceType());
72+
73+
builder.addRequirement(
74+
requirement,
75+
GenericSignatureBuilder::RequirementSource::forRequirementSignature(
76+
builder, selfType, proto),
77+
nullptr);
78+
79+
auto reqSignature = std::move(builder).computeGenericSignature(
80+
/*allowConcreteGenericParams=*/false,
81+
/*requirementSignatureSelfProto=*/proto);
82+
return reqSignature.getRequirements();
83+
};
84+
85+
auto buildViaRQM = [&]() {
86+
// We build requirement signatures for all protocols in a strongly connected
87+
// component at the same time.
88+
auto *machine = ctx.getOrCreateRequirementMachine(proto);
89+
auto requirements = machine->computeMinimalRequirements();
90+
91+
bool debug = machine->getDebugOptions().contains(DebugFlags::Minimization);
92+
93+
// The requirement signature for the actual protocol that the result
94+
// was kicked off with.
95+
ArrayRef<Requirement> result;
96+
97+
for (const auto &pair : requirements) {
98+
auto *otherProto = pair.first;
99+
const auto &reqs = pair.second;
100+
101+
// setRequirementSignature() doesn't take ownership of the memory, so
102+
// we have to make a copy of the std::vector temporary.
103+
ArrayRef<Requirement> reqsCopy = ctx.AllocateCopy(reqs);
104+
105+
// Don't call setRequirementSignature() on the original proto; the
106+
// request evaluator will do it for us.
107+
if (otherProto == proto)
108+
result = reqsCopy;
109+
else
110+
const_cast<ProtocolDecl *>(otherProto)->setRequirementSignature(reqsCopy);
111+
112+
// Dump the result if requested.
113+
if (debug) {
114+
llvm::dbgs() << "Protocol " << otherProto->getName() << ": ";
115+
116+
auto sig = GenericSignature::get(
117+
otherProto->getGenericSignature().getGenericParams(),
118+
reqsCopy);
119+
llvm::dbgs() << sig << "\n";
120+
}
121+
}
122+
123+
// Return the result for the specific protocol this request was kicked off on.
124+
return result;
125+
};
126+
127+
switch (ctx.LangOpts.RequirementMachineProtocolSignatures) {
128+
case RequirementMachineMode::Disabled:
129+
return buildViaGSB();
130+
131+
case RequirementMachineMode::Enabled:
132+
return buildViaRQM();
133+
134+
case RequirementMachineMode::Verify:
135+
abort();
136+
}
80137
}

0 commit comments

Comments
 (0)