Skip to content

Commit ab68d94

Browse files
committed
Verifier should traverse BBs in RPOT order.
This ensures that any open_existential instructions opening archetypes are seen before the uses of these archetypes.
1 parent 794d72e commit ab68d94

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

lib/SIL/SILVerifier.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/Basic/Range.h"
3131
#include "llvm/Support/Debug.h"
3232
#include "llvm/ADT/DenseSet.h"
33+
#include "llvm/ADT/PostOrderIterator.h"
3334
#include "llvm/ADT/StringSet.h"
3435
#include "llvm/Support/CommandLine.h"
3536
using namespace swift;
@@ -3212,6 +3213,27 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
32123213
SILVisitor::visitSILBasicBlock(BB);
32133214
}
32143215

3216+
void visitSILBasicBlocks(SILFunction *F) {
3217+
// Visit all basic blocks in the RPOT order.
3218+
// This ensures that any open_existential instructions, which
3219+
// open archetypes, are seen before the uses of these archetypes.
3220+
llvm::ReversePostOrderTraversal<SILFunction *> RPOT(F);
3221+
llvm::DenseSet<SILBasicBlock *> VisitedBBs;
3222+
for (auto Iter = RPOT.begin(), E = RPOT.end(); Iter != E; ++Iter) {
3223+
auto *BB = *Iter;
3224+
VisitedBBs.insert(BB);
3225+
visitSILBasicBlock(BB);
3226+
}
3227+
3228+
// Visit all basic blocks that were not visited during the RPOT traversal,
3229+
// e.g. unrechable basic blocks.
3230+
for (auto &BB : *F) {
3231+
if (VisitedBBs.count(&BB))
3232+
continue;
3233+
visitSILBasicBlock(&BB);
3234+
}
3235+
}
3236+
32153237
void visitSILFunction(SILFunction *F) {
32163238
PrettyStackTraceSILFunction stackTrace("verifying", F);
32173239

@@ -3262,7 +3284,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
32623284
verifyEpilogBlocks(F);
32633285
verifyStackHeight(F);
32643286
verifyBranches(F);
3265-
SILVisitor::visitSILFunction(F);
3287+
3288+
visitSILBasicBlocks(F);
3289+
3290+
// Verify archetypes after all basic blocks are visited,
3291+
// because we build the map of archteypes as we visit the
3292+
// instructions.
3293+
verifyOpenedArchetypes(F);
32663294
}
32673295

32683296
void verify() {

0 commit comments

Comments
 (0)