CrashDebugger.cpp revision 7c0a93785e283110ff05e4a95062990fd32a8389
1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// The LLVM Compiler Infrastructure 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 57c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// This file was developed by the LLVM research group and is distributed under 67c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===// 9afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 10afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This file defines the bugpoint internals that narrow down compilation crashes 11afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 12afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===----------------------------------------------------------------------===// 13afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 14afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "BugDriver.h" 15aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner#include "ListReducer.h" 16286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner#include "llvm/Constant.h" 1747b14a4a6a455c7be169cfd312fcbe796f0ad426Misha Brukman#include "llvm/Instructions.h" 18e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Module.h" 19e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Pass.h" 20e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/PassManager.h" 21286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner#include "llvm/SymbolTable.h" 22e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Type.h" 23286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner#include "llvm/Analysis/Verifier.h" 24e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Bytecode/Writer.h" 25e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Support/CFG.h" 268b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner#include "llvm/Support/ToolRunner.h" 27286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner#include "llvm/Transforms/Scalar.h" 28aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner#include "llvm/Transforms/Utils/Cloning.h" 29551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/FileUtilities.h" 307c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth#include "llvm/Support/CommandLine.h" 31afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <fstream> 32aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner#include <set> 33fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattnerusing namespace llvm; 34afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 357c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharthnamespace { 367c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth cl::opt<bool> 377c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth KeepMain("keep-main", 387c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth cl::desc("Force function reduction to keep main"), 397c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth cl::init(false)); 407c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth} 417c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth 42d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm { 4306905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner class ReducePassList : public ListReducer<const PassInfo*> { 44fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner BugDriver &BD; 45fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner public: 4606905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner ReducePassList(BugDriver &bd) : BD(bd) {} 473da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 48fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner // doTest - Return true iff running the "removed" passes succeeds, and 49fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner // running the "Kept" passes fail when run on the output of the "removed" 50fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner // passes. If we return true, we update the current module of bugpoint. 51fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner // 52fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner virtual TestResult doTest(std::vector<const PassInfo*> &Removed, 53fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner std::vector<const PassInfo*> &Kept); 54fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner }; 55fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner} 56aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 5706905db7d2a2b83c1b3236d5552629ada2d8d56dChris LattnerReducePassList::TestResult 5806905db7d2a2b83c1b3236d5552629ada2d8d56dChris LattnerReducePassList::doTest(std::vector<const PassInfo*> &Prefix, 5906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner std::vector<const PassInfo*> &Suffix) { 605f76760c880e6d61c229d2058c5699b033caeae1Reid Spencer sys::Path PrefixOutput; 61b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner Module *OrigProgram = 0; 62aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner if (!Prefix.empty()) { 63aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner std::cout << "Checking to see if these passes crash: " 64aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner << getPassesString(Prefix) << ": "; 655f76760c880e6d61c229d2058c5699b033caeae1Reid Spencer std::string PfxOutput; 665f76760c880e6d61c229d2058c5699b033caeae1Reid Spencer if (BD.runPasses(Prefix, PfxOutput)) 67aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner return KeepPrefix; 68b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner 69dd04df0ec33a903ee7fc747701bafde622f77d8bReid Spencer PrefixOutput.set(PfxOutput); 70b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner OrigProgram = BD.Program; 71b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner 725f76760c880e6d61c229d2058c5699b033caeae1Reid Spencer BD.Program = ParseInputFile(PrefixOutput.toString()); 73b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner if (BD.Program == 0) { 74b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner std::cerr << BD.getToolName() << ": Error reading bytecode file '" 75b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner << PrefixOutput << "'!\n"; 76b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner exit(1); 77b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner } 78a229c5cce75209047db32c6039aa0b0fd481f049Reid Spencer PrefixOutput.eraseFromDisk(); 79aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner } 80aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 81aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner std::cout << "Checking to see if these passes crash: " 82aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner << getPassesString(Suffix) << ": "; 833da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 84aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner if (BD.runPasses(Suffix)) { 85aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner delete OrigProgram; // The suffix crashes alone... 86aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner return KeepSuffix; 87aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner } 88aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 89aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // Nothing failed, restore state... 90b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner if (OrigProgram) { 91b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner delete BD.Program; 92b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner BD.Program = OrigProgram; 93b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner } 94aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner return NoFailure; 95aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner} 96aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 97fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattnernamespace llvm { 98efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner class ReduceCrashingFunctions : public ListReducer<Function*> { 99fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner BugDriver &BD; 1008b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner bool (*TestFn)(BugDriver &, Module *); 101fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner public: 1028b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner ReduceCrashingFunctions(BugDriver &bd, 1038b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner bool (*testFn)(BugDriver &, Module *)) 1048b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner : BD(bd), TestFn(testFn) {} 1053da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 106efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner virtual TestResult doTest(std::vector<Function*> &Prefix, 107efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::vector<Function*> &Kept) { 108fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner if (!Kept.empty() && TestFuncs(Kept)) 109fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner return KeepSuffix; 110fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner if (!Prefix.empty() && TestFuncs(Prefix)) 111fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner return KeepPrefix; 112fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner return NoFailure; 113fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner } 1143da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 115efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner bool TestFuncs(std::vector<Function*> &Prefix); 116fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner }; 117fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner} 118aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 119efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnerbool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) { 1207c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth 1217c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth //if main isn't present, claim there is no problem 1227c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth if (KeepMain && find(Funcs.begin(), Funcs.end(), BD.getProgram()->getMainFunction()) == Funcs.end()) 1237c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth return false; 1247c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth 125cf00c4ab3ba308d45d98c5ccab87362cf802facbMisha Brukman // Clone the program to try hacking it apart... 12606905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner Module *M = CloneModule(BD.getProgram()); 1273da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 128aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // Convert list to set for fast lookup... 129aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner std::set<Function*> Functions; 130aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { 1313da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman Function *CMF = M->getFunction(Funcs[i]->getName(), 132aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner Funcs[i]->getFunctionType()); 133aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner assert(CMF && "Function not in module?!"); 134f607b79bc78fcbfd8cda01d2d5dbda6cd8253a40Chris Lattner Functions.insert(CMF); 135aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner } 136aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 137efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::cout << "Checking for crash with only these functions: "; 138efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner PrintFunctionList(Funcs); 139aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner std::cout << ": "; 140aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 141aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // Loop over and delete any functions which we aren't supposed to be playing 142aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // with... 143aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 144f607b79bc78fcbfd8cda01d2d5dbda6cd8253a40Chris Lattner if (!I->isExternal() && !Functions.count(I)) 145aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner DeleteFunctionBody(I); 146aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 147aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // Try running the hacked up program... 1488b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner if (TestFn(BD, M)) { 14906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner BD.setNewProgram(M); // It crashed, keep the trimmed version... 150aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 151aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // Make sure to use function pointers that point into the now-current 152aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // module. 153aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner Funcs.assign(Functions.begin(), Functions.end()); 154aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner return true; 155aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner } 15606905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner delete M; 157aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner return false; 158aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner} 159aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 160640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 161f913f40be8501738fa4bdcae2015dd196dcbfc50Chris Lattnernamespace { 162fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner /// ReduceCrashingBlocks reducer - This works by setting the terminators of 163fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner /// all terminators except the specified basic blocks to a 'ret' instruction, 164fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner /// then running the simplify-cfg pass. This has the effect of chopping up 165fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner /// the CFG really fast which can reduce large functions quickly. 166fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner /// 1678b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner class ReduceCrashingBlocks : public ListReducer<const BasicBlock*> { 168fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner BugDriver &BD; 1698b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner bool (*TestFn)(BugDriver &, Module *); 170fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner public: 1718b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner ReduceCrashingBlocks(BugDriver &bd, bool (*testFn)(BugDriver &, Module *)) 1728b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner : BD(bd), TestFn(testFn) {} 1733da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 1748b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner virtual TestResult doTest(std::vector<const BasicBlock*> &Prefix, 1758b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner std::vector<const BasicBlock*> &Kept) { 176fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner if (!Kept.empty() && TestBlocks(Kept)) 177fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner return KeepSuffix; 178fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner if (!Prefix.empty() && TestBlocks(Prefix)) 179fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner return KeepPrefix; 180fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner return NoFailure; 181fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner } 1823da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 1838b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner bool TestBlocks(std::vector<const BasicBlock*> &Prefix); 184fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner }; 185fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner} 186286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 1878b189277bde5f617405dded0bbd6583e6665f4dfChris Lattnerbool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) { 188cf00c4ab3ba308d45d98c5ccab87362cf802facbMisha Brukman // Clone the program to try hacking it apart... 18906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner Module *M = CloneModule(BD.getProgram()); 1903da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 191286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Convert list to set for fast lookup... 192286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner std::set<BasicBlock*> Blocks; 193286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner for (unsigned i = 0, e = BBs.size(); i != e; ++i) { 194286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Convert the basic block from the original module to the new module... 1958b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner const Function *F = BBs[i]->getParent(); 196286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner Function *CMF = M->getFunction(F->getName(), F->getFunctionType()); 197286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner assert(CMF && "Function not in module?!"); 198286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 199286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Get the mapped basic block... 200286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner Function::iterator CBI = CMF->begin(); 2018b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner std::advance(CBI, std::distance(F->begin(), 2028b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner Function::const_iterator(BBs[i]))); 203286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner Blocks.insert(CBI); 204286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner } 205286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 206286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner std::cout << "Checking for crash with only these blocks:"; 20773b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner unsigned NumPrint = Blocks.size(); 20873b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner if (NumPrint > 10) NumPrint = 10; 20973b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner for (unsigned i = 0, e = NumPrint; i != e; ++i) 210286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner std::cout << " " << BBs[i]->getName(); 21173b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner if (NumPrint < Blocks.size()) 21273b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner std::cout << "... <" << Blocks.size() << " total>"; 213286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner std::cout << ": "; 214286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 215286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Loop over and delete any hack up any blocks that are not listed... 216286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 217286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB) 2188bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner if (!Blocks.count(BB) && BB->getTerminator()->getNumSuccessors()) { 219286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Loop over all of the successors of this block, deleting any PHI nodes 220286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // that might include it. 221286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) 222286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner (*SI)->removePredecessor(BB); 223286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 2248bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner if (BB->getTerminator()->getType() != Type::VoidTy) 2258bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner BB->getTerminator()->replaceAllUsesWith( 2268bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner Constant::getNullValue(BB->getTerminator()->getType())); 2278bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner 228286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Delete the old terminator instruction... 229286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner BB->getInstList().pop_back(); 2303da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 231286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Add a new return instruction of the appropriate type... 232286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner const Type *RetTy = BB->getParent()->getReturnType(); 2338bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner new ReturnInst(RetTy == Type::VoidTy ? 0 : 2348bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner Constant::getNullValue(RetTy), BB); 235286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner } 236286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 237286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // The CFG Simplifier pass may delete one of the basic blocks we are 238286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // interested in. If it does we need to take the block out of the list. Make 239286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // a "persistent mapping" by turning basic blocks into <function, name> pairs. 240286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // This won't work well if blocks are unnamed, but that is just the risk we 241286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // have to take. 242286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner std::vector<std::pair<Function*, std::string> > BlockInfo; 243286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 244286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner for (std::set<BasicBlock*>::iterator I = Blocks.begin(), E = Blocks.end(); 245286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner I != E; ++I) 246286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner BlockInfo.push_back(std::make_pair((*I)->getParent(), (*I)->getName())); 247286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 248286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Now run the CFG simplify pass on the function... 249286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner PassManager Passes; 250286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner Passes.add(createCFGSimplificationPass()); 251286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner Passes.add(createVerifierPass()); 252286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner Passes.run(*M); 253286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 254286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Try running on the hacked up program... 2558b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner if (TestFn(BD, M)) { 25606905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner BD.setNewProgram(M); // It crashed, keep the trimmed version... 257286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 258286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Make sure to use basic block pointers that point into the now-current 259286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // module, and that they don't include any deleted blocks. 260286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner BBs.clear(); 261286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) { 262286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner SymbolTable &ST = BlockInfo[i].first->getSymbolTable(); 2639231ac8b6f2c3f9877bdb7a223f7392061258ab6Reid Spencer SymbolTable::plane_iterator PI = ST.find(Type::LabelTy); 2649231ac8b6f2c3f9877bdb7a223f7392061258ab6Reid Spencer if (PI != ST.plane_end() && PI->second.count(BlockInfo[i].second)) 2659231ac8b6f2c3f9877bdb7a223f7392061258ab6Reid Spencer BBs.push_back(cast<BasicBlock>(PI->second[BlockInfo[i].second])); 266286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner } 267286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner return true; 268286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner } 26906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner delete M; // It didn't crash, try something else. 270286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner return false; 271286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner} 272286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner 2738b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// DebugACrash - Given a predicate that determines whether a component crashes 2748b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// on a program, try to destructively reduce the program while still keeping 2758b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// the predicate true. 2768b189277bde5f617405dded0bbd6583e6665f4dfChris Lattnerstatic bool DebugACrash(BugDriver &BD, bool (*TestFn)(BugDriver &, Module *)) { 2775f73e38548c57636ad0ef8c719d040e166761962Chris Lattner // See if we can get away with nuking all of the global variable initializers 2785f73e38548c57636ad0ef8c719d040e166761962Chris Lattner // in the program... 279852b4d4bf4aa6b80298a60f76092b80c8bd1efadChris Lattner if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) { 2808b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner Module *M = CloneModule(BD.getProgram()); 2815f73e38548c57636ad0ef8c719d040e166761962Chris Lattner bool DeletedInit = false; 282852b4d4bf4aa6b80298a60f76092b80c8bd1efadChris Lattner for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) 2835f73e38548c57636ad0ef8c719d040e166761962Chris Lattner if (I->hasInitializer()) { 2845f73e38548c57636ad0ef8c719d040e166761962Chris Lattner I->setInitializer(0); 2855f73e38548c57636ad0ef8c719d040e166761962Chris Lattner I->setLinkage(GlobalValue::ExternalLinkage); 2865f73e38548c57636ad0ef8c719d040e166761962Chris Lattner DeletedInit = true; 2875f73e38548c57636ad0ef8c719d040e166761962Chris Lattner } 2883da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 2895f73e38548c57636ad0ef8c719d040e166761962Chris Lattner if (!DeletedInit) { 2905f73e38548c57636ad0ef8c719d040e166761962Chris Lattner delete M; // No change made... 2915f73e38548c57636ad0ef8c719d040e166761962Chris Lattner } else { 2925f73e38548c57636ad0ef8c719d040e166761962Chris Lattner // See if the program still causes a crash... 2935f73e38548c57636ad0ef8c719d040e166761962Chris Lattner std::cout << "\nChecking to see if we can delete global inits: "; 2948b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner if (TestFn(BD, M)) { // Still crashes? 2958b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner BD.setNewProgram(M); 2965f73e38548c57636ad0ef8c719d040e166761962Chris Lattner std::cout << "\n*** Able to remove all global initializers!\n"; 2975f73e38548c57636ad0ef8c719d040e166761962Chris Lattner } else { // No longer crashes? 2985f73e38548c57636ad0ef8c719d040e166761962Chris Lattner std::cout << " - Removing all global inits hides problem!\n"; 29906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner delete M; 3005f73e38548c57636ad0ef8c719d040e166761962Chris Lattner } 3015f73e38548c57636ad0ef8c719d040e166761962Chris Lattner } 3025f73e38548c57636ad0ef8c719d040e166761962Chris Lattner } 3033da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 304aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // Now try to reduce the number of functions in the module to something small. 305efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::vector<Function*> Functions; 306efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner for (Module::iterator I = BD.getProgram()->begin(), 3078b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner E = BD.getProgram()->end(); I != E; ++I) 308afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner if (!I->isExternal()) 309aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner Functions.push_back(I); 310afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 311f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (Functions.size() > 1 && !BugpointIsInterrupted) { 312aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner std::cout << "\n*** Attempting to reduce the number of functions " 313aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner "in the testcase\n"; 314afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 3158b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner unsigned OldSize = Functions.size(); 3168b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner ReduceCrashingFunctions(BD, TestFn).reduceList(Functions); 317afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 318f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (Functions.size() < OldSize) 3198b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner BD.EmitProgressBytecode("reduced-function"); 320218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner } 321218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 322286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // Attempt to delete entire basic blocks at a time to speed up 323286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // convergence... this actually works by setting the terminator of the blocks 324286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // to a return instruction then running simplifycfg, which can potentially 325286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // shrinks the code dramatically quickly 326286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner // 327f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (!DisableSimplifyCFG && !BugpointIsInterrupted) { 3288b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner std::vector<const BasicBlock*> Blocks; 3298b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner for (Module::const_iterator I = BD.getProgram()->begin(), 3308b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner E = BD.getProgram()->end(); I != E; ++I) 3318b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner for (Function::const_iterator FI = I->begin(), E = I->end(); FI !=E; ++FI) 33247ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner Blocks.push_back(FI); 3338b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks); 33447ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner } 3356520785dcd22012535934098942d57c07c7631c2Chris Lattner 336aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // FIXME: This should use the list reducer to converge faster by deleting 337aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // larger chunks of instructions at a time! 338b2c180f04e4f71a29c8c4a2478179cb1ddd5d859Chris Lattner unsigned Simplification = 2; 3396520785dcd22012535934098942d57c07c7631c2Chris Lattner do { 340f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (BugpointIsInterrupted) break; 3416520785dcd22012535934098942d57c07c7631c2Chris Lattner --Simplification; 3426520785dcd22012535934098942d57c07c7631c2Chris Lattner std::cout << "\n*** Attempting to reduce testcase by deleting instruc" 343eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman << "tions: Simplification Level #" << Simplification << '\n'; 3446520785dcd22012535934098942d57c07c7631c2Chris Lattner 3455560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman // Now that we have deleted the functions that are unnecessary for the 3465560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman // program, try to remove instructions that are not necessary to cause the 3476520785dcd22012535934098942d57c07c7631c2Chris Lattner // crash. To do this, we loop through all of the instructions in the 3486520785dcd22012535934098942d57c07c7631c2Chris Lattner // remaining functions, deleting them (replacing any values produced with 3496520785dcd22012535934098942d57c07c7631c2Chris Lattner // nulls), and then running ADCE and SimplifyCFG. If the transformed input 3506520785dcd22012535934098942d57c07c7631c2Chris Lattner // still triggers failure, keep deleting until we cannot trigger failure 3516520785dcd22012535934098942d57c07c7631c2Chris Lattner // anymore. 3526520785dcd22012535934098942d57c07c7631c2Chris Lattner // 353f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner unsigned InstructionsToSkipBeforeDeleting = 0; 3546520785dcd22012535934098942d57c07c7631c2Chris Lattner TryAgain: 3553da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 3566520785dcd22012535934098942d57c07c7631c2Chris Lattner // Loop over all of the (non-terminator) instructions remaining in the 3576520785dcd22012535934098942d57c07c7631c2Chris Lattner // function, attempting to delete them. 358f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner unsigned CurInstructionNum = 0; 3598b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner for (Module::const_iterator FI = BD.getProgram()->begin(), 3608b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner E = BD.getProgram()->end(); FI != E; ++FI) 361f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner if (!FI->isExternal()) 3628b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E; 3638b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner ++BI) 3648b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end(); 365f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner I != E; ++I, ++CurInstructionNum) 366f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner if (InstructionsToSkipBeforeDeleting) { 367f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner --InstructionsToSkipBeforeDeleting; 368f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner } else { 369f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (BugpointIsInterrupted) goto ExitLoops; 370f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner 371f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner std::cout << "Checking instruction '" << I->getName() << "': "; 372f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner Module *M = BD.deleteInstructionFromProgram(I, Simplification); 3733da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 374f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner // Find out if the pass still crashes on this pass... 375f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner if (TestFn(BD, M)) { 376f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner // Yup, it does, we delete the old module, and continue trying 377f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner // to reduce the testcase... 378f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner BD.setNewProgram(M); 379f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner InstructionsToSkipBeforeDeleting = CurInstructionNum; 380f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner goto TryAgain; // I wish I had a multi-level break here! 381f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner } 3823da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 383f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner // This pass didn't crash without this instruction, try the next 384f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner // one. 385f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner delete M; 3866520785dcd22012535934098942d57c07c7631c2Chris Lattner } 387f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner 388f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner if (InstructionsToSkipBeforeDeleting) { 389f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner InstructionsToSkipBeforeDeleting = 0; 390f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner goto TryAgain; 391f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner } 3923da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 3936520785dcd22012535934098942d57c07c7631c2Chris Lattner } while (Simplification); 394f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris LattnerExitLoops: 395ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner 396ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner // Try to clean up the testcase by running funcresolve and globaldce... 397f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (!BugpointIsInterrupted) { 398f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner std::cout << "\n*** Attempting to perform final cleanups: "; 399f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner Module *M = CloneModule(BD.getProgram()); 400f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner M = BD.performFinalCleanups(M, true); 4013da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 402f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner // Find out if the pass still crashes on the cleaned up program... 403f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (TestFn(BD, M)) { 404f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner BD.setNewProgram(M); // Yup, it does, keep the reduced version... 405f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner } else { 406f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner delete M; 407f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner } 408ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner } 409ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner 410f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner BD.EmitProgressBytecode("reduced-simplified"); 411ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner 4123da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman return false; 4138b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner} 4148b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner 4158b189277bde5f617405dded0bbd6583e6665f4dfChris Lattnerstatic bool TestForOptimizerCrash(BugDriver &BD, Module *M) { 4168b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner return BD.runPasses(M); 417afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 418d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 4198b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// debugOptimizerCrash - This method is called when some pass crashes on input. 4208b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// It attempts to prune down the testcase to something reasonable, and figure 4218b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// out exactly which pass is crashing. 4228b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// 4238b189277bde5f617405dded0bbd6583e6665f4dfChris Lattnerbool BugDriver::debugOptimizerCrash() { 4248b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner std::cout << "\n*** Debugging optimizer crash!\n"; 4258b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner 4268b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner // Reduce the list of passes which causes the optimizer to crash... 4278b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner unsigned OldSize = PassesToRun.size(); 428f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner if (!BugpointIsInterrupted) 429f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner ReducePassList(*this).reduceList(PassesToRun); 4308b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner 4318b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner std::cout << "\n*** Found crashing pass" 4328b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner << (PassesToRun.size() == 1 ? ": " : "es: ") 433eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman << getPassesString(PassesToRun) << '\n'; 434025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner 4358b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner EmitProgressBytecode("passinput"); 4368b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner 4378b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner return DebugACrash(*this, TestForOptimizerCrash); 4388b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner} 4398b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner 4408b189277bde5f617405dded0bbd6583e6665f4dfChris Lattnerstatic bool TestForCodeGenCrash(BugDriver &BD, Module *M) { 4418b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner try { 442eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman std::cerr << '\n'; 4438b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner BD.compileProgram(M); 444eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman std::cerr << '\n'; 4458b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner return false; 44683881957edee0b1cb89428fa1a3b022d7d84ee13Jeff Cohen } catch (ToolExecutionError &) { 4478b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner std::cerr << "<crash>\n"; 4488b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner return true; // Tool is still crashing. 4498b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner } 4508b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner} 451025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner 452025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner/// debugCodeGeneratorCrash - This method is called when the code generator 453025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner/// crashes on an input. It attempts to reduce the input as much as possible 454025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner/// while still causing the code generator to crash. 455025262692a6710de29a48e2b3905672cd12d13d2Chris Lattnerbool BugDriver::debugCodeGeneratorCrash() { 45606905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner std::cerr << "*** Debugging code generator crash!\n"; 457025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner 4588b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner return DebugACrash(*this, TestForCodeGenCrash); 459025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner} 460