Skip to content

Commit 982ed09

Browse files
committed
[IRGen] NFC: Assert cleanups for metadata emits.
In debug builds, before SIL function emission, pass over the function to collect cleanups. After emitting an instruction for which an on-stack metadata/wtable pack was emitted, assert that there were cleanups for it in the function.
1 parent bcf2f8b commit 982ed09

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/Basic/ExternalUnion.h"
2727
#include "swift/Basic/Range.h"
2828
#include "swift/Basic/STLExtras.h"
29+
#include "swift/IRGen/GenericRequirement.h"
2930
#include "swift/IRGen/Linking.h"
3031
#include "swift/SIL/ApplySite.h"
3132
#include "swift/SIL/BasicBlockDatastructures.h"
@@ -442,6 +443,15 @@ class IRGenSILFunction :
442443
// A cached dominance analysis.
443444
std::unique_ptr<DominanceInfo> Dominance;
444445

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
445455
/// For each instruction which did allocate pack metadata on-stack, the stack
446456
/// locations at which they were allocated.
447457
///
@@ -2395,6 +2405,26 @@ void IRGenSILFunction::emitSILFunction() {
23952405

23962406
assert(params.empty() && "did not map all llvm params to SIL params?!");
23972407

2408+
#ifndef NDEBUG
2409+
for (auto &BB : *CurSILFn) {
2410+
for (auto &I : BB) {
2411+
if (auto *DPMI = dyn_cast<DeallocPackMetadataInst>(&I)) {
2412+
DynamicMetadataPackDeallocs[DPMI->getIntroducer()].push_back(DPMI);
2413+
continue;
2414+
}
2415+
if (auto *DSI = dyn_cast<DeallocStackInst>(&I)) {
2416+
auto *I = DSI->getOperand()->getDefiningInstruction();
2417+
if (!I)
2418+
continue;
2419+
auto *PAI = dyn_cast<PartialApplyInst>(I);
2420+
if (!PAI || !PAI->isOnStack())
2421+
continue;
2422+
DynamicMetadataPackDeallocs[PAI].push_back(DSI);
2423+
}
2424+
}
2425+
}
2426+
#endif
2427+
23982428
// It's really nice to be able to assume that we've already emitted
23992429
// all the values from dominating blocks --- it makes simple
24002430
// peepholing more powerful and allows us to avoid the need for
@@ -2556,6 +2586,42 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) {
25562586

25572587
visit(&I);
25582588

2589+
#ifndef NDEBUG
2590+
if (!OutstandingStackPackAllocs.empty()) {
2591+
auto iter = DynamicMetadataPackDeallocs.find(&I);
2592+
if (iter == DynamicMetadataPackDeallocs.end() ||
2593+
iter->getSecond().size() == 0) {
2594+
llvm::errs()
2595+
<< "Instruction missing on-stack pack metadata cleanups!\n";
2596+
I.print(llvm::errs());
2597+
llvm::errs() << "\n In function";
2598+
CurSILFn->print(llvm::errs());
2599+
llvm::errs() << "Allocated the following on-stack pack metadata:";
2600+
for (auto pair : OutstandingStackPackAllocs) {
2601+
StackAddress addr;
2602+
llvm::Value *shape;
2603+
uint8_t kind;
2604+
std::tie(addr, shape, kind) = pair;
2605+
switch ((GenericRequirement::Kind)kind) {
2606+
case GenericRequirement::Kind::MetadataPack:
2607+
llvm::errs() << "Metadata Pack: ";
2608+
break;
2609+
case GenericRequirement::Kind::WitnessTablePack:
2610+
llvm::errs() << "Witness Table Pack: ";
2611+
break;
2612+
default:
2613+
llvm_unreachable("bad requirement in stack pack alloc");
2614+
}
2615+
addr.getAddressPointer()->print(llvm::errs());
2616+
llvm::errs() << "\n";
2617+
}
2618+
CurFn->print(llvm::errs());
2619+
llvm::report_fatal_error(
2620+
"Instruction resulted in on-stack pack metadata emission but no "
2621+
"cleanup instructions were added");
2622+
}
2623+
}
2624+
#endif
25592625
// Record the on-stack pack allocations emitted on behalf of this SIL
25602626
// instruction. They will be cleaned up when visiting the corresponding
25612627
// cleanup markers.

0 commit comments

Comments
 (0)