|
18 | 18 | // |
19 | 19 | //===----------------------------------------------------------------------===// |
20 | 20 |
|
| 21 | +#include "RequirementMachine.h" |
21 | 22 | #include "swift/AST/ASTContext.h" |
22 | 23 | #include "swift/AST/Decl.h" |
23 | 24 | #include "swift/AST/GenericSignature.h" |
|
27 | 28 | #include "swift/Basic/Statistic.h" |
28 | 29 | #include <vector> |
29 | 30 |
|
30 | | -#include "../GenericSignatureBuilder.h" // FIXME: This is temporary |
31 | | -#include "RequirementMachine.h" |
32 | | - |
33 | 31 | using namespace swift; |
34 | 32 | using namespace rewriting; |
35 | 33 |
|
36 | | -#define DEBUG_TYPE "Serialization" |
37 | | - |
38 | | -STATISTIC(NumLazyRequirementSignaturesLoaded, |
39 | | - "# of lazily-deserialized requirement signatures loaded"); |
40 | | - |
41 | | -#undef DEBUG_TYPE |
42 | | - |
43 | 34 | namespace { |
44 | 35 |
|
45 | 36 | /// Represents a set of types related by same-type requirements, and an |
@@ -222,104 +213,54 @@ RequirementMachine::computeMinimalRequirements() { |
222 | 213 | } |
223 | 214 |
|
224 | 215 | ArrayRef<Requirement> |
225 | | -RequirementSignatureRequest::evaluate(Evaluator &evaluator, |
226 | | - ProtocolDecl *proto) const { |
| 216 | +RequirementSignatureRequestRQM::evaluate(Evaluator &evaluator, |
| 217 | + ProtocolDecl *proto) const { |
227 | 218 | ASTContext &ctx = proto->getASTContext(); |
228 | 219 |
|
229 | 220 | // First check if we have a deserializable requirement signature. |
230 | | - if (proto->hasLazyRequirementSignature()) { |
231 | | - ++NumLazyRequirementSignaturesLoaded; |
232 | | - // FIXME: (transitional) increment the redundant "always-on" counter. |
233 | | - if (ctx.Stats) |
234 | | - ++ctx.Stats->getFrontendCounters().NumLazyRequirementSignaturesLoaded; |
235 | | - |
236 | | - auto contextData = static_cast<LazyProtocolData *>( |
237 | | - ctx.getOrCreateLazyContextData(proto, nullptr)); |
238 | | - |
239 | | - SmallVector<Requirement, 8> requirements; |
240 | | - contextData->loader->loadRequirementSignature( |
241 | | - proto, contextData->requirementSignatureData, requirements); |
242 | | - if (requirements.empty()) |
243 | | - return None; |
244 | | - return ctx.AllocateCopy(requirements); |
245 | | - } |
| 221 | + assert(!proto->hasLazyRequirementSignature() && |
| 222 | + "Should be handled in RequirementSignatureRequest"); |
246 | 223 |
|
247 | | - auto buildViaGSB = [&]() { |
248 | | - GenericSignatureBuilder builder(proto->getASTContext()); |
249 | | - |
250 | | - // Add all of the generic parameters. |
251 | | - for (auto gp : *proto->getGenericParams()) |
252 | | - builder.addGenericParameter(gp); |
253 | | - |
254 | | - // Add the conformance of 'self' to the protocol. |
255 | | - auto selfType = |
256 | | - proto->getSelfInterfaceType()->castTo<GenericTypeParamType>(); |
257 | | - auto requirement = |
258 | | - Requirement(RequirementKind::Conformance, selfType, |
259 | | - proto->getDeclaredInterfaceType()); |
260 | | - |
261 | | - builder.addRequirement( |
262 | | - requirement, |
263 | | - GenericSignatureBuilder::RequirementSource::forRequirementSignature( |
264 | | - builder, selfType, proto), |
265 | | - nullptr); |
266 | | - |
267 | | - auto reqSignature = std::move(builder).computeGenericSignature( |
268 | | - /*allowConcreteGenericParams=*/false, |
269 | | - /*requirementSignatureSelfProto=*/proto); |
270 | | - return reqSignature.getRequirements(); |
271 | | - }; |
| 224 | + // We build requirement signatures for all protocols in a strongly connected |
| 225 | + // component at the same time. |
| 226 | + auto *machine = ctx.getOrCreateRequirementMachine(proto); |
| 227 | + auto requirements = machine->computeMinimalRequirements(); |
272 | 228 |
|
273 | | - auto buildViaRQM = [&]() { |
274 | | - // We build requirement signatures for all protocols in a strongly connected |
275 | | - // component at the same time. |
276 | | - auto *machine = ctx.getOrCreateRequirementMachine(proto); |
277 | | - auto requirements = machine->computeMinimalRequirements(); |
278 | | - |
279 | | - bool debug = machine->getDebugOptions().contains(DebugFlags::Minimization); |
280 | | - |
281 | | - // The requirement signature for the actual protocol that the result |
282 | | - // was kicked off with. |
283 | | - ArrayRef<Requirement> result; |
284 | | - |
285 | | - for (const auto &pair : requirements) { |
286 | | - auto *otherProto = pair.first; |
287 | | - const auto &reqs = pair.second; |
288 | | - |
289 | | - // setRequirementSignature() doesn't take ownership of the memory, so |
290 | | - // we have to make a copy of the std::vector temporary. |
291 | | - ArrayRef<Requirement> reqsCopy = ctx.AllocateCopy(reqs); |
292 | | - |
293 | | - // Don't call setRequirementSignature() on the original proto; the |
294 | | - // request evaluator will do it for us. |
295 | | - if (otherProto == proto) |
296 | | - result = reqsCopy; |
297 | | - else |
298 | | - const_cast<ProtocolDecl *>(otherProto)->setRequirementSignature(reqsCopy); |
299 | | - |
300 | | - // Dump the result if requested. |
301 | | - if (debug) { |
302 | | - llvm::dbgs() << "Protocol " << otherProto->getName() << ": "; |
303 | | - |
304 | | - auto sig = GenericSignature::get( |
305 | | - otherProto->getGenericSignature().getGenericParams(), |
306 | | - reqsCopy); |
307 | | - llvm::dbgs() << sig << "\n"; |
308 | | - } |
309 | | - } |
| 229 | + bool debug = machine->getDebugOptions().contains(DebugFlags::Minimization); |
310 | 230 |
|
311 | | - // Return the result for the specific protocol this request was kicked off on. |
312 | | - return result; |
313 | | - }; |
| 231 | + // The requirement signature for the actual protocol that the result |
| 232 | + // was kicked off with. |
| 233 | + ArrayRef<Requirement> result; |
| 234 | + |
| 235 | + for (const auto &pair : requirements) { |
| 236 | + auto *otherProto = pair.first; |
| 237 | + const auto &reqs = pair.second; |
| 238 | + |
| 239 | + // setRequirementSignature() doesn't take ownership of the memory, so |
| 240 | + // we have to make a copy of the std::vector temporary. |
| 241 | + ArrayRef<Requirement> reqsCopy = ctx.AllocateCopy(reqs); |
314 | 242 |
|
315 | | - switch (ctx.LangOpts.RequirementMachineProtocolSignatures) { |
316 | | - case RequirementMachineMode::Disabled: |
317 | | - return buildViaGSB(); |
| 243 | + // Dump the result if requested. |
| 244 | + if (debug) { |
| 245 | + llvm::dbgs() << "Protocol " << otherProto->getName() << ": "; |
318 | 246 |
|
319 | | - case RequirementMachineMode::Enabled: |
320 | | - return buildViaRQM(); |
| 247 | + auto sig = GenericSignature::get( |
| 248 | + otherProto->getGenericSignature().getGenericParams(), |
| 249 | + reqsCopy); |
| 250 | + llvm::dbgs() << sig << "\n"; |
| 251 | + } |
321 | 252 |
|
322 | | - case RequirementMachineMode::Verify: |
323 | | - abort(); |
| 253 | + // Don't call setRequirementSignature() on the original proto; the |
| 254 | + // request evaluator will do it for us. |
| 255 | + if (otherProto == proto) |
| 256 | + result = reqsCopy; |
| 257 | + else { |
| 258 | + ctx.evaluator.cacheOutput( |
| 259 | + RequirementSignatureRequestRQM{const_cast<ProtocolDecl *>(otherProto)}, |
| 260 | + std::move(reqsCopy)); |
| 261 | + } |
324 | 262 | } |
| 263 | + |
| 264 | + // Return the result for the specific protocol this request was kicked off on. |
| 265 | + return result; |
325 | 266 | } |
0 commit comments