X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fbugpoint%2FListReducer.h;h=8083e2d65fb191ec0fc540b024e9b994f33dd959;hb=d6f0c34273dd3536102f2d643403252468dfc4a3;hp=cd629da3457df1476e1094b88bb6b25c2b3e3e22;hpb=21c62da287237d39d0d95004881ea4baae3be6da;p=oota-llvm.git diff --git a/tools/bugpoint/ListReducer.h b/tools/bugpoint/ListReducer.h index cd629da3457..8083e2d65fb 100644 --- a/tools/bugpoint/ListReducer.h +++ b/tools/bugpoint/ListReducer.h @@ -15,10 +15,11 @@ #ifndef BUGPOINT_LIST_REDUCER_H #define BUGPOINT_LIST_REDUCER_H -#include -#include -#include +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include +#include +#include namespace llvm { @@ -29,7 +30,8 @@ struct ListReducer { enum TestResult { NoFailure, // No failure of the predicate was detected KeepSuffix, // The suffix alone satisfies the predicate - KeepPrefix // The prefix alone satisfies the predicate + KeepPrefix, // The prefix alone satisfies the predicate + InternalError // Encountered an error trying to run the predicate }; virtual ~ListReducer() {} @@ -40,16 +42,17 @@ struct ListReducer { // the prefix anyway, it can. // virtual TestResult doTest(std::vector &Prefix, - std::vector &Kept) = 0; + std::vector &Kept, + std::string &Error) = 0; // reduceList - This function attempts to reduce the length of the specified // list while still maintaining the "test" property. This is the core of the // "work" that bugpoint does. // - bool reduceList(std::vector &TheList) { + bool reduceList(std::vector &TheList, std::string &Error) { std::vector empty; std::srand(0x6e5ea738); // Seed the random number generator - switch (doTest(TheList, empty)) { + switch (doTest(TheList, empty, Error)) { case KeepPrefix: if (TheList.size() == 1) // we are done, it's the base case and it fails return true; @@ -58,11 +61,15 @@ struct ListReducer { case KeepSuffix: // cannot be reached! - std::cerr << "bugpoint ListReducer internal error: selected empty set.\n"; - abort(); + llvm_unreachable("bugpoint ListReducer internal error: " + "selected empty set."); case NoFailure: return false; // there is no failure with the full set of passes/funcs! + + case InternalError: + assert(!Error.empty()); + return true; } // Maximal number of allowed splitting iterations, @@ -77,40 +84,39 @@ Backjump: while (MidTop > 1) { // Binary split reduction loop // Halt if the user presses ctrl-c. if (BugpointIsInterrupted) { - std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n"; + errs() << "\n\n*** Reduction Interrupted, cleaning up...\n\n"; return true; } - + // If the loop doesn't make satisfying progress, try shuffling. // The purpose of shuffling is to avoid the heavy tails of the // distribution (improving the speed of convergence). if (ShufflingEnabled && - NumOfIterationsWithoutProgress > MaxIterations) { - - std::vector ShuffledList(TheList); - std::random_shuffle(ShuffledList.begin(), ShuffledList.end()); - std::cerr << "\n\n*** Testing shuffled set...\n\n"; - // Check that random shuffle doesn't loose the bug - if (doTest(ShuffledList, empty) == KeepPrefix) { + NumOfIterationsWithoutProgress > MaxIterations) { + std::vector ShuffledList(TheList); + std::random_shuffle(ShuffledList.begin(), ShuffledList.end()); + errs() << "\n\n*** Testing shuffled set...\n\n"; + // Check that random shuffle doesn't loose the bug + if (doTest(ShuffledList, empty, Error) == KeepPrefix) { // If the bug is still here, use the shuffled list. TheList.swap(ShuffledList); MidTop = TheList.size(); // Must increase the shuffling treshold to avoid the small // probability of inifinite looping without making progress. MaxIterations += 2; - std::cerr << "\n\n*** Shuffling does not hide the bug...\n\n"; - } else { + errs() << "\n\n*** Shuffling does not hide the bug...\n\n"; + } else { ShufflingEnabled = false; // Disable shuffling further on - std::cerr << "\n\n*** Shuffling hides the bug...\n\n"; - } - NumOfIterationsWithoutProgress = 0; + errs() << "\n\n*** Shuffling hides the bug...\n\n"; + } + NumOfIterationsWithoutProgress = 0; } unsigned Mid = MidTop / 2; std::vector Prefix(TheList.begin(), TheList.begin()+Mid); std::vector Suffix(TheList.begin()+Mid, TheList.end()); - switch (doTest(Prefix, Suffix)) { + switch (doTest(Prefix, Suffix, Error)) { case KeepSuffix: // The property still holds. We can just drop the prefix elements, and // shorten the list to the "kept" elements. @@ -134,7 +140,10 @@ Backjump: MidTop = Mid; NumOfIterationsWithoutProgress++; break; + case InternalError: + return true; // Error was set by doTest. } + assert(Error.empty() && "doTest did not return InternalError for error"); } // Probability of backjumping from the trimming loop back to the binary @@ -161,19 +170,21 @@ Backjump: for (unsigned i = 1; i < TheList.size()-1; ++i) { // Check interior elts if (BugpointIsInterrupted) { - std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n"; + errs() << "\n\n*** Reduction Interrupted, cleaning up...\n\n"; return true; } std::vector TestList(TheList); TestList.erase(TestList.begin()+i); - if (doTest(EmptyList, TestList) == KeepSuffix) { + if (doTest(EmptyList, TestList, Error) == KeepSuffix) { // We can trim down the list! TheList.swap(TestList); --i; // Don't skip an element of the list Changed = true; } + if (!Error.empty()) + return true; } // This can take a long time if left uncontrolled. For now, don't // iterate.