|
26 | 26 | #include "swift/Basic/ExternalUnion.h"
|
27 | 27 | #include "swift/Basic/Range.h"
|
28 | 28 | #include "swift/Basic/STLExtras.h"
|
| 29 | +#include "swift/IRGen/GenericRequirement.h" |
29 | 30 | #include "swift/IRGen/Linking.h"
|
30 | 31 | #include "swift/SIL/ApplySite.h"
|
31 | 32 | #include "swift/SIL/BasicBlockDatastructures.h"
|
@@ -442,6 +443,15 @@ class IRGenSILFunction :
|
442 | 443 | // A cached dominance analysis.
|
443 | 444 | std::unique_ptr<DominanceInfo> Dominance;
|
444 | 445 |
|
| 446 | +#ifndef NDEBUG |
| 447 | + /// For each instruction which might allocate pack metadata on stack, the |
| 448 | + /// corresponding cleanup instructions. |
| 449 | + /// |
| 450 | + /// Used to verify that every instruction on behalf of which on-stack pack |
| 451 | + /// metadata is emitted has some corresponding cleanup instructions. |
| 452 | + llvm::DenseMap<SILInstruction *, llvm::SmallVector<SILInstruction *, 2>> |
| 453 | + DynamicMetadataPackDeallocs; |
| 454 | +#endif |
445 | 455 | /// For each instruction which did allocate pack metadata on-stack, the stack
|
446 | 456 | /// locations at which they were allocated.
|
447 | 457 | ///
|
@@ -2399,6 +2409,26 @@ void IRGenSILFunction::emitSILFunction() {
|
2399 | 2409 |
|
2400 | 2410 | assert(params.empty() && "did not map all llvm params to SIL params?!");
|
2401 | 2411 |
|
| 2412 | +#ifndef NDEBUG |
| 2413 | + for (auto &BB : *CurSILFn) { |
| 2414 | + for (auto &I : BB) { |
| 2415 | + if (auto *DPMI = dyn_cast<DeallocPackMetadataInst>(&I)) { |
| 2416 | + DynamicMetadataPackDeallocs[DPMI->getIntroducer()].push_back(DPMI); |
| 2417 | + continue; |
| 2418 | + } |
| 2419 | + if (auto *DSI = dyn_cast<DeallocStackInst>(&I)) { |
| 2420 | + auto *I = DSI->getOperand()->getDefiningInstruction(); |
| 2421 | + if (!I) |
| 2422 | + continue; |
| 2423 | + auto *PAI = dyn_cast<PartialApplyInst>(I); |
| 2424 | + if (!PAI || !PAI->isOnStack()) |
| 2425 | + continue; |
| 2426 | + DynamicMetadataPackDeallocs[PAI].push_back(DSI); |
| 2427 | + } |
| 2428 | + } |
| 2429 | + } |
| 2430 | +#endif |
| 2431 | + |
2402 | 2432 | // It's really nice to be able to assume that we've already emitted
|
2403 | 2433 | // all the values from dominating blocks --- it makes simple
|
2404 | 2434 | // peepholing more powerful and allows us to avoid the need for
|
@@ -2560,6 +2590,42 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) {
|
2560 | 2590 |
|
2561 | 2591 | visit(&I);
|
2562 | 2592 |
|
| 2593 | +#ifndef NDEBUG |
| 2594 | + if (!OutstandingStackPackAllocs.empty()) { |
| 2595 | + auto iter = DynamicMetadataPackDeallocs.find(&I); |
| 2596 | + if (iter == DynamicMetadataPackDeallocs.end() || |
| 2597 | + iter->getSecond().size() == 0) { |
| 2598 | + llvm::errs() |
| 2599 | + << "Instruction missing on-stack pack metadata cleanups!\n"; |
| 2600 | + I.print(llvm::errs()); |
| 2601 | + llvm::errs() << "\n In function"; |
| 2602 | + CurSILFn->print(llvm::errs()); |
| 2603 | + llvm::errs() << "Allocated the following on-stack pack metadata:"; |
| 2604 | + for (auto pair : OutstandingStackPackAllocs) { |
| 2605 | + StackAddress addr; |
| 2606 | + llvm::Value *shape; |
| 2607 | + uint8_t kind; |
| 2608 | + std::tie(addr, shape, kind) = pair; |
| 2609 | + switch ((GenericRequirement::Kind)kind) { |
| 2610 | + case GenericRequirement::Kind::MetadataPack: |
| 2611 | + llvm::errs() << "Metadata Pack: "; |
| 2612 | + break; |
| 2613 | + case GenericRequirement::Kind::WitnessTablePack: |
| 2614 | + llvm::errs() << "Witness Table Pack: "; |
| 2615 | + break; |
| 2616 | + default: |
| 2617 | + llvm_unreachable("bad requirement in stack pack alloc"); |
| 2618 | + } |
| 2619 | + addr.getAddressPointer()->print(llvm::errs()); |
| 2620 | + llvm::errs() << "\n"; |
| 2621 | + } |
| 2622 | + CurFn->print(llvm::errs()); |
| 2623 | + llvm::report_fatal_error( |
| 2624 | + "Instruction resulted in on-stack pack metadata emission but no " |
| 2625 | + "cleanup instructions were added"); |
| 2626 | + } |
| 2627 | + } |
| 2628 | +#endif |
2563 | 2629 | // Record the on-stack pack allocations emitted on behalf of this SIL
|
2564 | 2630 | // instruction. They will be cleaned up when visiting the corresponding
|
2565 | 2631 | // cleanup markers.
|
|
0 commit comments