summaryrefslogtreecommitdiff
path: root/tools/bugpoint/CrashDebugger.cpp
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2016-09-06 04:45:37 +0000
committerJustin Bogner <mail@justinbogner.com>2016-09-06 04:45:37 +0000
commit79a93a638f39672b9afdc490392cb54961bec33d (patch)
treeee81eafb2b4ace444143b4038d293cac69c6d8fb /tools/bugpoint/CrashDebugger.cpp
parent3023eeb5005e73763a81ea2188b456ab141afbe1 (diff)
Revert "bugpoint: Stop threading errors through APIs that never fail"
This isn't the right thing to do - it turns out a number of the APIs that "never fail" just exit(1) if something bad happens. We can and should thread Error through this instead. That diff will make more sense with this reverted. Sorry for the noise. This reverts r280690 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280691 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/bugpoint/CrashDebugger.cpp')
-rw-r--r--tools/bugpoint/CrashDebugger.cpp72
1 files changed, 44 insertions, 28 deletions
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index 7a565c0140b..649cac7c681 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -71,13 +71,14 @@ public:
// passes. If we return true, we update the current module of bugpoint.
//
TestResult doTest(std::vector<std::string> &Removed,
- std::vector<std::string> &Kept) override;
+ std::vector<std::string> &Kept,
+ std::string &Error) override;
};
}
ReducePassList::TestResult
ReducePassList::doTest(std::vector<std::string> &Prefix,
- std::vector<std::string> &Suffix) {
+ std::vector<std::string> &Suffix, std::string &Error) {
std::string PrefixOutput;
Module *OrigProgram = nullptr;
if (!Prefix.empty()) {
@@ -128,7 +129,8 @@ public:
: BD(bd), TestFn(testFn) {}
TestResult doTest(std::vector<GlobalVariable *> &Prefix,
- std::vector<GlobalVariable *> &Kept) override {
+ std::vector<GlobalVariable *> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestGlobalVariables(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestGlobalVariables(Prefix))
@@ -197,7 +199,8 @@ public:
: BD(bd), TestFn(testFn) {}
TestResult doTest(std::vector<Function *> &Prefix,
- std::vector<Function *> &Kept) override {
+ std::vector<Function *> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestFuncs(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestFuncs(Prefix))
@@ -370,7 +373,8 @@ public:
: BD(BD), TestFn(testFn) {}
TestResult doTest(std::vector<const BasicBlock *> &Prefix,
- std::vector<const BasicBlock *> &Kept) override {
+ std::vector<const BasicBlock *> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestBlocks(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestBlocks(Prefix))
@@ -491,7 +495,8 @@ public:
: BD(bd), TestFn(testFn), Direction(Direction) {}
TestResult doTest(std::vector<const BasicBlock *> &Prefix,
- std::vector<const BasicBlock *> &Kept) override {
+ std::vector<const BasicBlock *> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestBlocks(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestBlocks(Prefix))
@@ -598,7 +603,8 @@ public:
: BD(bd), TestFn(testFn), TTI(bd.getProgram()->getDataLayout()) {}
TestResult doTest(std::vector<const BasicBlock *> &Prefix,
- std::vector<const BasicBlock *> &Kept) override {
+ std::vector<const BasicBlock *> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestBlocks(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestBlocks(Prefix))
@@ -692,7 +698,8 @@ public:
: BD(bd), TestFn(testFn) {}
TestResult doTest(std::vector<const Instruction *> &Prefix,
- std::vector<const Instruction *> &Kept) override {
+ std::vector<const Instruction *> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestInsts(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestInsts(Prefix))
@@ -768,7 +775,8 @@ public:
: BD(bd), TestFn(testFn) {}
TestResult doTest(std::vector<std::string> &Prefix,
- std::vector<std::string> &Kept) override {
+ std::vector<std::string> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestNamedMDs(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestNamedMDs(Prefix))
@@ -837,7 +845,8 @@ public:
: BD(bd), TestFn(testFn) {}
TestResult doTest(std::vector<const MDNode *> &Prefix,
- std::vector<const MDNode *> &Kept) override {
+ std::vector<const MDNode *> &Kept,
+ std::string &Error) override {
if (!Kept.empty() && TestNamedMDOps(Kept))
return KeepSuffix;
if (!Prefix.empty() && TestNamedMDOps(Prefix))
@@ -900,7 +909,8 @@ bool ReduceCrashingNamedMDOps::TestNamedMDOps(
static void ReduceGlobalInitializers(BugDriver &BD,
bool (*TestFn)(const BugDriver &,
- Module *)) {
+ Module *),
+ std::string &Error) {
if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
// Now try to reduce the number of global variable initializers in the
// module to something small.
@@ -942,7 +952,8 @@ static void ReduceGlobalInitializers(BugDriver &BD,
<< "variables in the testcase\n";
unsigned OldSize = GVs.size();
- ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs);
+ ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs, Error);
+ assert(!Error.empty());
if (GVs.size() < OldSize)
BD.EmitProgressBitcode(BD.getProgram(), "reduced-global-variables");
@@ -953,7 +964,8 @@ static void ReduceGlobalInitializers(BugDriver &BD,
}
static void ReduceInsts(BugDriver &BD,
- bool (*TestFn)(const BugDriver &, Module *)) {
+ bool (*TestFn)(const BugDriver &, Module *),
+ std::string &Error) {
// Attempt to delete instructions using bisection. This should help out nasty
// cases with large basic blocks where the problem is at one end.
if (!BugpointIsInterrupted) {
@@ -964,7 +976,7 @@ static void ReduceInsts(BugDriver &BD,
if (!isa<TerminatorInst>(&I))
Insts.push_back(&I);
- ReduceCrashingInstructions(BD, TestFn).reduceList(Insts);
+ ReduceCrashingInstructions(BD, TestFn).reduceList(Insts, Error);
}
unsigned Simplification = 2;
@@ -1034,11 +1046,12 @@ static void ReduceInsts(BugDriver &BD,
/// on a program, try to destructively reduce the program while still keeping
/// the predicate true.
static bool DebugACrash(BugDriver &BD,
- bool (*TestFn)(const BugDriver &, Module *)) {
+ bool (*TestFn)(const BugDriver &, Module *),
+ std::string &Error) {
// See if we can get away with nuking some of the global variable initializers
// in the program...
if (!NoGlobalRM)
- ReduceGlobalInitializers(BD, TestFn);
+ ReduceGlobalInitializers(BD, TestFn, Error);
// Now try to reduce the number of functions in the module to something small.
std::vector<Function *> Functions;
@@ -1051,7 +1064,7 @@ static bool DebugACrash(BugDriver &BD,
"in the testcase\n";
unsigned OldSize = Functions.size();
- ReduceCrashingFunctions(BD, TestFn).reduceList(Functions);
+ ReduceCrashingFunctions(BD, TestFn).reduceList(Functions, Error);
if (Functions.size() < OldSize)
BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
@@ -1065,8 +1078,8 @@ static bool DebugACrash(BugDriver &BD,
for (BasicBlock &BB : F)
Blocks.push_back(&BB);
unsigned OldSize = Blocks.size();
- ReduceCrashingConditionals(BD, TestFn, true).reduceList(Blocks);
- ReduceCrashingConditionals(BD, TestFn, false).reduceList(Blocks);
+ ReduceCrashingConditionals(BD, TestFn, true).reduceList(Blocks, Error);
+ ReduceCrashingConditionals(BD, TestFn, false).reduceList(Blocks, Error);
if (Blocks.size() < OldSize)
BD.EmitProgressBitcode(BD.getProgram(), "reduced-conditionals");
}
@@ -1082,7 +1095,7 @@ static bool DebugACrash(BugDriver &BD,
for (BasicBlock &BB : F)
Blocks.push_back(&BB);
unsigned OldSize = Blocks.size();
- ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks);
+ ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks, Error);
if (Blocks.size() < OldSize)
BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks");
}
@@ -1093,7 +1106,7 @@ static bool DebugACrash(BugDriver &BD,
for (BasicBlock &BB : F)
Blocks.push_back(&BB);
unsigned OldSize = Blocks.size();
- ReduceSimplifyCFG(BD, TestFn).reduceList(Blocks);
+ ReduceSimplifyCFG(BD, TestFn).reduceList(Blocks, Error);
if (Blocks.size() < OldSize)
BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplifycfg");
}
@@ -1101,7 +1114,7 @@ static bool DebugACrash(BugDriver &BD,
// Attempt to delete instructions using bisection. This should help out nasty
// cases with large basic blocks where the problem is at one end.
if (!BugpointIsInterrupted)
- ReduceInsts(BD, TestFn);
+ ReduceInsts(BD, TestFn, Error);
if (!NoNamedMDRM) {
if (!BugpointIsInterrupted) {
@@ -1111,7 +1124,7 @@ static bool DebugACrash(BugDriver &BD,
std::vector<std::string> NamedMDNames;
for (auto &NamedMD : BD.getProgram()->named_metadata())
NamedMDNames.push_back(NamedMD.getName().str());
- ReduceCrashingNamedMD(BD, TestFn).reduceList(NamedMDNames);
+ ReduceCrashingNamedMD(BD, TestFn).reduceList(NamedMDNames, Error);
}
if (!BugpointIsInterrupted) {
@@ -1121,7 +1134,7 @@ static bool DebugACrash(BugDriver &BD,
for (auto &NamedMD : BD.getProgram()->named_metadata())
for (auto op : NamedMD.operands())
NamedMDOps.push_back(op);
- ReduceCrashingNamedMDOps(BD, TestFn).reduceList(NamedMDOps);
+ ReduceCrashingNamedMDOps(BD, TestFn).reduceList(NamedMDOps, Error);
}
BD.EmitProgressBitcode(BD.getProgram(), "reduced-named-md");
}
@@ -1156,9 +1169,11 @@ static bool TestForOptimizerCrash(const BugDriver &BD, Module *M) {
bool BugDriver::debugOptimizerCrash(const std::string &ID) {
outs() << "\n*** Debugging optimizer crash!\n";
+ std::string Error;
// Reduce the list of passes which causes the optimizer to crash...
if (!BugpointIsInterrupted && !DontReducePassList)
- ReducePassList(*this).reduceList(PassesToRun);
+ ReducePassList(*this).reduceList(PassesToRun, Error);
+ assert(Error.empty());
outs() << "\n*** Found crashing pass"
<< (PassesToRun.size() == 1 ? ": " : "es: ")
@@ -1166,7 +1181,8 @@ bool BugDriver::debugOptimizerCrash(const std::string &ID) {
EmitProgressBitcode(Program, ID);
- bool Success = DebugACrash(*this, TestForOptimizerCrash);
+ bool Success = DebugACrash(*this, TestForOptimizerCrash, Error);
+ assert(Error.empty());
return Success;
}
@@ -1187,8 +1203,8 @@ static bool TestForCodeGenCrash(const BugDriver &BD, Module *M) {
/// debugCodeGeneratorCrash - This method is called when the code generator
/// crashes on an input. It attempts to reduce the input as much as possible
/// while still causing the code generator to crash.
-bool BugDriver::debugCodeGeneratorCrash() {
+bool BugDriver::debugCodeGeneratorCrash(std::string &Error) {
errs() << "*** Debugging code generator crash!\n";
- return DebugACrash(*this, TestForCodeGenCrash);
+ return DebugACrash(*this, TestForCodeGenCrash, Error);
}