summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-08-02 02:16:17 +0000
committerChris Lattner <sabre@nondot.org>2005-08-02 02:16:17 +0000
commitf9aaae06cd2109082cda2b09ef3f23e0e1cff47b (patch)
tree2464ee9f4149dbeba1695647ba8e4c24dd23ae9b /tools
parentfa8c292ebd893b3effef4ead9c88d261c628c340 (diff)
downloadllvm-f9aaae06cd2109082cda2b09ef3f23e0e1cff47b.tar.gz
llvm-f9aaae06cd2109082cda2b09ef3f23e0e1cff47b.tar.bz2
llvm-f9aaae06cd2109082cda2b09ef3f23e0e1cff47b.tar.xz
When the user hits ctrl-c, bugpoint should attempt to stop reduction as
quickly as possible and output what it has so far. If they hit it twice, bugpoint is killed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22579 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/bugpoint/BugDriver.h4
-rw-r--r--tools/bugpoint/CrashDebugger.cpp41
-rw-r--r--tools/bugpoint/ListReducer.h13
-rw-r--r--tools/bugpoint/Miscompilation.cpp21
-rw-r--r--tools/bugpoint/bugpoint.cpp10
5 files changed, 59 insertions, 30 deletions
diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h
index 51798d29a5..192ed52717 100644
--- a/tools/bugpoint/BugDriver.h
+++ b/tools/bugpoint/BugDriver.h
@@ -35,6 +35,10 @@ class GCC;
extern bool DisableSimplifyCFG;
+/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
+///
+extern bool BugpointIsInterrupted;
+
class BugDriver {
const std::string ToolName; // Name of bugpoint
std::string ReferenceOutputFile; // Name of `good' output file
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index b63ce219e8..0d04b2563f 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -261,8 +261,6 @@ bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
/// on a program, try to destructively reduce the program while still keeping
/// the predicate true.
static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
- bool AnyReduction = false;
-
// See if we can get away with nuking all of the global variable initializers
// in the program...
if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
@@ -282,7 +280,6 @@ static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
std::cout << "\nChecking to see if we can delete global inits: ";
if (TestFn(BD, M)) { // Still crashes?
BD.setNewProgram(M);
- AnyReduction = true;
std::cout << "\n*** Able to remove all global initializers!\n";
} else { // No longer crashes?
std::cout << " - Removing all global inits hides problem!\n";
@@ -298,17 +295,15 @@ static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
if (!I->isExternal())
Functions.push_back(I);
- if (Functions.size() > 1) {
+ if (Functions.size() > 1 && !BugpointIsInterrupted) {
std::cout << "\n*** Attempting to reduce the number of functions "
"in the testcase\n";
unsigned OldSize = Functions.size();
ReduceCrashingFunctions(BD, TestFn).reduceList(Functions);
- if (Functions.size() < OldSize) {
+ if (Functions.size() < OldSize)
BD.EmitProgressBytecode("reduced-function");
- AnyReduction = true;
- }
}
// Attempt to delete entire basic blocks at a time to speed up
@@ -316,7 +311,7 @@ static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
// to a return instruction then running simplifycfg, which can potentially
// shrinks the code dramatically quickly
//
- if (!DisableSimplifyCFG) {
+ if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
std::vector<const BasicBlock*> Blocks;
for (Module::const_iterator I = BD.getProgram()->begin(),
E = BD.getProgram()->end(); I != E; ++I)
@@ -329,6 +324,7 @@ static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
// larger chunks of instructions at a time!
unsigned Simplification = 2;
do {
+ if (BugpointIsInterrupted) break;
--Simplification;
std::cout << "\n*** Attempting to reduce testcase by deleting instruc"
<< "tions: Simplification Level #" << Simplification << '\n';
@@ -357,6 +353,8 @@ static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
if (InstructionsToSkipBeforeDeleting) {
--InstructionsToSkipBeforeDeleting;
} else {
+ if (BugpointIsInterrupted) goto ExitLoops;
+
std::cout << "Checking instruction '" << I->getName() << "': ";
Module *M = BD.deleteInstructionFromProgram(I, Simplification);
@@ -365,7 +363,6 @@ static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
// Yup, it does, we delete the old module, and continue trying
// to reduce the testcase...
BD.setNewProgram(M);
- AnyReduction = true;
InstructionsToSkipBeforeDeleting = CurInstructionNum;
goto TryAgain; // I wish I had a multi-level break here!
}
@@ -381,22 +378,23 @@ static bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) {
}
} while (Simplification);
+ExitLoops:
// Try to clean up the testcase by running funcresolve and globaldce...
- std::cout << "\n*** Attempting to perform final cleanups: ";
- Module *M = CloneModule(BD.getProgram());
- M = BD.performFinalCleanups(M, true);
+ if (!BugpointIsInterrupted) {
+ std::cout << "\n*** Attempting to perform final cleanups: ";
+ Module *M = CloneModule(BD.getProgram());
+ M = BD.performFinalCleanups(M, true);
- // Find out if the pass still crashes on the cleaned up program...
- if (TestFn(BD, M)) {
- BD.setNewProgram(M); // Yup, it does, keep the reduced version...
- AnyReduction = true;
- } else {
- delete M;
+ // Find out if the pass still crashes on the cleaned up program...
+ if (TestFn(BD, M)) {
+ BD.setNewProgram(M); // Yup, it does, keep the reduced version...
+ } else {
+ delete M;
+ }
}
- if (AnyReduction)
- BD.EmitProgressBytecode("reduced-simplified");
+ BD.EmitProgressBytecode("reduced-simplified");
return false;
}
@@ -414,7 +412,8 @@ bool BugDriver::debugOptimizerCrash() {
// Reduce the list of passes which causes the optimizer to crash...
unsigned OldSize = PassesToRun.size();
- ReducePassList(*this).reduceList(PassesToRun);
+ if (!BugpointIsInterrupted)
+ ReducePassList(*this).reduceList(PassesToRun);
std::cout << "\n*** Found crashing pass"
<< (PassesToRun.size() == 1 ? ": " : "es: ")
diff --git a/tools/bugpoint/ListReducer.h b/tools/bugpoint/ListReducer.h
index daeadba885..ff2a11d5e9 100644
--- a/tools/bugpoint/ListReducer.h
+++ b/tools/bugpoint/ListReducer.h
@@ -19,6 +19,8 @@
#include <iostream>
namespace llvm {
+
+ extern bool BugpointIsInterrupted;
template<typename ElTy>
struct ListReducer {
@@ -62,6 +64,12 @@ struct ListReducer {
unsigned MidTop = TheList.size();
while (MidTop > 1) {
+ // Halt if the user presses ctrl-c.
+ if (BugpointIsInterrupted) {
+ std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n";
+ return true;
+ }
+
unsigned Mid = MidTop / 2;
std::vector<ElTy> Prefix(TheList.begin(), TheList.begin()+Mid);
std::vector<ElTy> Suffix(TheList.begin()+Mid, TheList.end());
@@ -97,6 +105,11 @@ struct ListReducer {
Changed = false;
std::vector<ElTy> TrimmedList;
for (unsigned i = 1; i < TheList.size()-1; ++i) { // Check interior elts
+ if (BugpointIsInterrupted) {
+ std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n";
+ return true;
+ }
+
std::vector<ElTy> TestList(TheList);
TestList.erase(TestList.begin()+i);
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index dc43126670..834e687995 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -407,6 +407,8 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs) {
static bool ExtractBlocks(BugDriver &BD,
bool (*TestFn)(BugDriver &, Module *, Module *),
std::vector<Function*> &MiscompiledFunctions) {
+ if (BugpointIsInterrupted) return false;
+
std::vector<BasicBlock*> Blocks;
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
for (Function::iterator I = MiscompiledFunctions[i]->begin(),
@@ -493,7 +495,8 @@ DebugAMiscompilation(BugDriver &BD,
MiscompiledFunctions.push_back(I);
// Do the reduction...
- ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);
+ if (!BugpointIsInterrupted)
+ ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);
std::cout << "\n*** The following function"
<< (MiscompiledFunctions.size() == 1 ? " is" : "s are")
@@ -513,7 +516,8 @@ DebugAMiscompilation(BugDriver &BD,
DisambiguateGlobalSymbols(BD.getProgram());
// Do the reduction...
- ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);
+ if (!BugpointIsInterrupted)
+ ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);
std::cout << "\n*** The following function"
<< (MiscompiledFunctions.size() == 1 ? " is" : "s are")
@@ -570,11 +574,12 @@ static bool TestOptimizer(BugDriver &BD, Module *Test, Module *Safe) {
///
bool BugDriver::debugMiscompilation() {
// Make sure something was miscompiled...
- if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) {
- std::cerr << "*** Optimized program matches reference output! No problem "
- << "detected...\nbugpoint can't help you with your problem!\n";
- return false;
- }
+ if (!BugpointIsInterrupted)
+ if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) {
+ std::cerr << "*** Optimized program matches reference output! No problem"
+ << " detected...\nbugpoint can't help you with your problem!\n";
+ return false;
+ }
std::cout << "\n*** Found miscompiling pass"
<< (getPassesToRun().size() == 1 ? "" : "es") << ": "
@@ -663,7 +668,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
if (F->isExternal() && !F->use_empty() && &*F != resolverFunc &&
F->getIntrinsicID() == 0 /* ignore intrinsics */) {
- Function *TestFn = Test->getFunction(F->getName(), F->getFunctionType());
+ Function *TestFn = Test->getNamedFunction(F->getName());
// Don't forward functions which are external in the test module too.
if (TestFn && !TestFn->isExternal()) {
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
index 3cbb4c0ff6..a4442c7ef9 100644
--- a/tools/bugpoint/bugpoint.cpp
+++ b/tools/bugpoint/bugpoint.cpp
@@ -32,13 +32,21 @@ InputFilenames(cl::Positional, cl::OneOrMore,
static cl::list<const PassInfo*, bool, PassNameParser>
PassList(cl::desc("Passes available:"), cl::ZeroOrMore);
+/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
+bool llvm::BugpointIsInterrupted = false;
+
+static void BugpointInterruptFunction() {
+ BugpointIsInterrupted = true;
+}
+
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv,
" LLVM automatic testcase reducer. See\nhttp://"
"llvm.cs.uiuc.edu/docs/CommandGuide/bugpoint.html"
" for more information.\n");
sys::PrintStackTraceOnErrorSignal();
-
+ sys::SetInterruptFunction(BugpointInterruptFunction);
+
BugDriver D(argv[0]);
if (D.addSources(InputFilenames)) return 1;
D.addPasses(PassList.begin(), PassList.end());