diff options
author | Chris Lattner <sabre@nondot.org> | 2003-01-23 02:48:33 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-01-23 02:48:33 +0000 |
commit | 6520785dcd22012535934098942d57c07c7631c2 (patch) | |
tree | 9779528e1f51c9a49cdff12110c7440af45947b6 /tools/bugpoint/CrashDebugger.cpp | |
parent | e5fa63a578187ba91bf2b93ad5a58baa3d3307b2 (diff) | |
download | llvm-6520785dcd22012535934098942d57c07c7631c2.tar.gz llvm-6520785dcd22012535934098942d57c07c7631c2.tar.bz2 llvm-6520785dcd22012535934098942d57c07c7631c2.tar.xz |
Make bugpoint *much* more powerful, giving it the capability to delete instructions
out of a large function to reduce it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5408 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/bugpoint/CrashDebugger.cpp')
-rw-r--r-- | tools/bugpoint/CrashDebugger.cpp | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp index c69ca45362..daf3915a5e 100644 --- a/tools/bugpoint/CrashDebugger.cpp +++ b/tools/bugpoint/CrashDebugger.cpp @@ -114,18 +114,63 @@ bool BugDriver::debugPassCrash(const PassInfo *Pass) { delete Program; Program = M; } - } - if (CountFunctions(Program) > 1) { - std::cout << "\n*** Couldn't reduce testcase to one function.\n" - << " Attempting to remove individual functions.\n"; - std::cout << "XXX Individual function removal unimplemented!\n"; + if (CountFunctions(Program) > 1) { + std::cout << "\n*** Couldn't reduce testcase to one function.\n" + << " Attempting to remove individual functions.\n"; + std::cout << "XXX Individual function removal unimplemented!\n"; + } } - // Now that we have deleted the functions that are unneccesary for the - // program, try to remove instructions and basic blocks that are not neccesary - // to cause the crash. - // + // FIXME: This should attempt to delete entire basic blocks at a time to speed + // up convergence... + + unsigned Simplification = 4; + do { + --Simplification; + std::cout << "\n*** Attempting to reduce testcase by deleting instruc" + << "tions: Simplification Level #" << Simplification << "\n"; + + // Now that we have deleted the functions that are unneccesary for the + // program, try to remove instructions that are not neccesary to cause the + // crash. To do this, we loop through all of the instructions in the + // remaining functions, deleting them (replacing any values produced with + // nulls), and then running ADCE and SimplifyCFG. If the transformed input + // still triggers failure, keep deleting until we cannot trigger failure + // anymore. + // + TryAgain: + + // Loop over all of the (non-terminator) instructions remaining in the + // function, attempting to delete them. + for (Module::iterator FI = Program->begin(), E = Program->end(); + FI != E; ++FI) + if (!FI->isExternal()) { + for (Function::iterator BI = FI->begin(), E = FI->end(); BI != E; ++BI) + for (BasicBlock::iterator I = BI->begin(), E = --BI->end(); + I != E; ++I) { + Module *M = deleteInstructionFromProgram(I, Simplification); + + // Make the function the current program... + std::swap(Program, M); + + // Find out if the pass still crashes on this pass... + std::cout << "Checking instruction '" << I->getName() << "': "; + if (runPass(Pass)) { + // Yup, it does, we delete the old module, and continue trying to + // reduce the testcase... + EmitProgressBytecode(Pass, "reduced-" + I->getName()); + delete M; + goto TryAgain; // I wish I had a multi-level break here! + } + + // This pass didn't crash without this instruction, try the next + // one. + delete Program; + Program = M; + } + } + } while (Simplification); return false; } |