Skip to content

Commit c15d7ea

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 0e23eef commit c15d7ea

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
///
@@ -2399,6 +2409,26 @@ void IRGenSILFunction::emitSILFunction() {
23992409

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

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+
24022432
// It's really nice to be able to assume that we've already emitted
24032433
// all the values from dominating blocks --- it makes simple
24042434
// peepholing more powerful and allows us to avoid the need for
@@ -2560,6 +2590,42 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) {
25602590

25612591
visit(&I);
25622592

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
25632629
// Record the on-stack pack allocations emitted on behalf of this SIL
25642630
// instruction. They will be cleaned up when visiting the corresponding
25652631
// cleanup markers.

0 commit comments

Comments
 (0)