summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2016-05-09 19:57:29 +0000
committerAdrian Prantl <aprantl@apple.com>2016-05-09 19:57:29 +0000
commite36561855cea5f8946f5462afee12681841cedc7 (patch)
tree1a06cd5e5a27ba6f5776e354839c33ccd6556902 /llvm/lib
parentfe7a38245303a221798837bfd1ecdbb5c6af9e49 (diff)
downloadbcm5719-llvm-e36561855cea5f8946f5462afee12681841cedc7.tar.gz
bcm5719-llvm-e36561855cea5f8946f5462afee12681841cedc7.zip
Separate the Verifier into an analysis and a transformation pass and
allow the transformation to strip invalid debug info. This patch separates the Verifier into an analysis and a transformation pass, with the transformation pass optionally stripping malformed debug info. The problem I'm trying to solve with this sequence of patches is that historically we've done a really bad job at verifying debug info. We want to be able to make the verifier stricter without having to worry about breaking bitcode compatibility with existing producers. For example, we don't necessarily want IR produced by an older version of clang to be rejected by an LTO link just because of malformed debug info, and rather provide an option to strip it. Note that merely outdated (but well-formed) debug info would continue to be auto-upgraded in this scenario. http://reviews.llvm.org/D19988 rdar://problem/25818489 This reapplies r268937 without modifications. llvm-svn: 268966
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/DiagnosticInfo.cpp5
-rw-r--r--llvm/lib/IR/Verifier.cpp34
-rw-r--r--llvm/lib/Passes/PassRegistry.def2
3 files changed, 36 insertions, 5 deletions
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index 10d9d55ed71..91463ec5f1e 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -122,6 +122,11 @@ void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
<< ") in " << getModule();
}
+void DiagnosticInfoIgnoringInvalidDebugMetadata::print(
+ DiagnosticPrinter &DP) const {
+ DP << "ignoring invalid debug info in " << getModule().getModuleIdentifier();
+}
+
void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
if (!FileName.empty()) {
DP << getFileName();
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e09f763f10b..9abe8d850f5 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -59,6 +59,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h"
@@ -4482,15 +4483,38 @@ FunctionPass *llvm::createVerifierPass(bool FatalErrors) {
return new VerifierLegacyPass(FatalErrors);
}
-PreservedAnalyses VerifierPass::run(Module &M) {
- if (verifyModule(M, &dbgs()) && FatalErrors)
- report_fatal_error("Broken module found, compilation aborted!");
+char VerifierAnalysis::PassID;
+VerifierAnalysis::Result VerifierAnalysis::run(Module &M) {
+ Result Res;
+ Res.IRBroken = llvm::verifyModule(M, &dbgs(), &Res.DebugInfoBroken);
+ return Res;
+}
+
+VerifierAnalysis::Result VerifierAnalysis::run(Function &F) {
+ return { llvm::verifyFunction(F, &dbgs()), false };
+}
+PreservedAnalyses VerifierPass::run(Module &M, ModuleAnalysisManager &AM) {
+ auto Res = AM.getResult<VerifierAnalysis>(M);
+ if (FatalErrors) {
+ if (Res.IRBroken)
+ report_fatal_error("Broken module found, compilation aborted!");
+ assert(!Res.DebugInfoBroken && "Module contains invalid debug info");
+ }
+
+ // Strip broken debug info.
+ if (Res.DebugInfoBroken) {
+ DiagnosticInfoIgnoringInvalidDebugMetadata DiagInvalid(M);
+ M.getContext().diagnose(DiagInvalid);
+ if (!StripDebugInfo(M))
+ report_fatal_error("Failed to strip malformed debug info");
+ }
return PreservedAnalyses::all();
}
-PreservedAnalyses VerifierPass::run(Function &F) {
- if (verifyFunction(F, &dbgs()) && FatalErrors)
+PreservedAnalyses VerifierPass::run(Function &F, FunctionAnalysisManager &AM) {
+ auto res = AM.getResult<VerifierAnalysis>(F);
+ if (res.IRBroken && FatalErrors)
report_fatal_error("Broken function found, compilation aborted!");
return PreservedAnalyses::all();
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 9a31be3c816..d79a39cf952 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -23,6 +23,7 @@ MODULE_ANALYSIS("callgraph", CallGraphAnalysis())
MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis())
MODULE_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
+MODULE_ANALYSIS("verify", VerifierAnalysis())
#ifndef MODULE_ALIAS_ANALYSIS
#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
@@ -87,6 +88,7 @@ FUNCTION_ANALYSIS("scalar-evolution", ScalarEvolutionAnalysis())
FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis())
FUNCTION_ANALYSIS("targetir",
TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())
+FUNCTION_ANALYSIS("verify", VerifierAnalysis())
#ifndef FUNCTION_ALIAS_ANALYSIS
#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
OpenPOWER on IntegriCloud