blob: 9b13bf9494f1a52b350d2e7a740e100de2f9ed25 [file] [log] [blame]
//===--- PassManagerVerifierAnalysis.cpp ----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sil-passmanager-verifier-analysis"
#include "swift/SILOptimizer/Analysis/PassManagerVerifierAnalysis.h"
#include "swift/SIL/SILModule.h"
#include "llvm/Support/CommandLine.h"
static llvm::cl::opt<bool>
EnableVerifier("enable-sil-passmanager-verifier-analysis",
llvm::cl::desc("Enable verification of the passmanagers "
"function notification infrastructure"),
llvm::cl::init(false));
using namespace swift;
PassManagerVerifierAnalysis::PassManagerVerifierAnalysis(SILModule *mod)
: SILAnalysis(SILAnalysisKind::PassManagerVerifier), mod(*mod) {
#ifndef NDEBUG
if (!EnableVerifier)
return;
for (auto &fn : *mod) {
LLVM_DEBUG(llvm::dbgs() << "PMVerifierAnalysis. Add: " << fn.getName()
<< '\n');
liveFunctions.insert(&fn);
}
#endif
}
/// Validate that the analysis is able to look up all functions and that those
/// functions are live.
void PassManagerVerifierAnalysis::invalidate() {}
/// Validate that the analysis is able to look up the given function.
void PassManagerVerifierAnalysis::invalidate(SILFunction *f,
InvalidationKind k) {}
/// If a function has not yet been seen start tracking it.
void PassManagerVerifierAnalysis::notifyAddedOrModifiedFunction(
SILFunction *f) {
#ifndef NDEBUG
if (!EnableVerifier)
return;
LLVM_DEBUG(llvm::dbgs() << "PMVerifierAnalysis. Add|Mod: " << f->getName()
<< '\n');
liveFunctions.insert(f);
#endif
}
/// Stop tracking a function.
void PassManagerVerifierAnalysis::notifyWillDeleteFunction(SILFunction *f) {
#ifndef NDEBUG
if (!EnableVerifier)
return;
LLVM_DEBUG(llvm::dbgs() << "PMVerifierAnalysis. Delete: " << f->getName()
<< '\n');
assert(liveFunctions.count(f) &&
"Tried to delete function that analysis was not aware of?!");
liveFunctions.erase(f);
#endif
}
/// Make sure that when we invalidate a function table, make sure we can find
/// all functions for all witness tables.
void PassManagerVerifierAnalysis::invalidateFunctionTables() {}
/// Run the entire verification.
void PassManagerVerifierAnalysis::verify() const {
#ifndef NDEBUG
if (!EnableVerifier)
return;
// We check that all functions in the module are in liveFunctions /and/ then
// make sure that liveFunctions has the same number of elements. If we have
// too many elements, this means we missed a delete event.
unsigned funcCount = 0;
for (auto &fn : mod) {
++funcCount;
assert(liveFunctions.count(&fn) &&
"Found function in module that verifier is not aware of?!");
}
assert(liveFunctions.size() == funcCount &&
"Analysis has state for deleted functions?!");
#endif
}
//===----------------------------------------------------------------------===//
// Main Entry Point
//===----------------------------------------------------------------------===//
SILAnalysis *swift::createPassManagerVerifierAnalysis(SILModule *m) {
return new PassManagerVerifierAnalysis(m);
}