BugDriver.cpp revision 6a3f31cb707972ebde1e45a61fa8f5bcff132eba
1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===// 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 class contains all of the shared state and information that is used by 11afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// the BugPoint tool to track down errors in optimizations. This class is the 12afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// main driver class that invokes all sub-functionality. 13afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 14afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===----------------------------------------------------------------------===// 15afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 16afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "BugDriver.h" 17f1b20d8620b05abaa52f40ac6d21f839b265fb00Chris Lattner#include "ToolRunner.h" 18605b9e2c5bd1b0c151a0b15d01e6df3aba93d52fReid Spencer#include "llvm/Linker.h" 19afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "llvm/Module.h" 20e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Pass.h" 21afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "llvm/Assembly/Parser.h" 22e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Bytecode/Reader.h" 23551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 24551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/FileUtilities.h" 2586f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <iostream> 26afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <memory> 2786f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer 28d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm; 29d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 305073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// Anonymous namespace to define command line options for debugging. 315073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// 325073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmannamespace { 335073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Output - The user can specify a file containing the expected output of the 345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // program. If this filename is set, it is used as the reference diff source, 355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // otherwise the raw input run through an interpreter is used as the reference 365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // source. 375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 383da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman cl::opt<std::string> 395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman OutputFile("output", cl::desc("Specify a reference program output " 405073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "(for miscompilation detection)")); 415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 4306905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner/// setNewProgram - If we reduce or update the program somehow, call this method 4406905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner/// to update bugdriver with it. This deletes the old module and sets the 4506905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner/// specified one as the current program. 4606905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattnervoid BugDriver::setNewProgram(Module *M) { 4706905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner delete Program; 4806905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner Program = M; 4906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner} 5006905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner 5106905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner 52640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// getPassesString - Turn a list of passes into a string which indicates the 53640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// command line options that must be passed to add the passes. 54640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// 55fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattnerstd::string llvm::getPassesString(const std::vector<const PassInfo*> &Passes) { 56640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner std::string Result; 57640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner for (unsigned i = 0, e = Passes.size(); i != e; ++i) { 58640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner if (i) Result += " "; 59640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner Result += "-"; 60640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner Result += Passes[i]->getPassArgument(); 61640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 62640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner return Result; 63640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner} 64640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 656a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick JenkinsBugDriver::BugDriver(const char *toolname, bool as_child, bool find_bugs, 666a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins unsigned timeout) 675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman : ToolName(toolname), ReferenceOutputFile(OutputFile), 689686ae7f4ea5f19ce77e31e64e0916db41a82662Chris Lattner Program(0), Interpreter(0), cbe(0), gcc(0), run_as_child(as_child), 696a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins run_find_bugs(find_bugs), Timeout(timeout) {} 705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 72afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// ParseInputFile - Given a bytecode or assembly input filename, parse and 73afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// return it, or return null if not possible. 74afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 75efdc0b505712d1ca4460def27e51c430f033d58dChris LattnerModule *llvm::ParseInputFile(const std::string &InputFilename) { 76afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Module *Result = 0; 77afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner try { 78afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Result = ParseBytecodeFile(InputFilename); 79afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner if (!Result && !(Result = ParseAssemblyFile(InputFilename))){ 80efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::cerr << "bugpoint: could not read input file '" 81afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner << InputFilename << "'!\n"; 82afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 83afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } catch (const ParseException &E) { 84eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman std::cerr << "bugpoint: " << E.getMessage() << '\n'; 85afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Result = 0; 86afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 87afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return Result; 88afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 89afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 90afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This method takes the specified list of LLVM input files, attempts to load 91dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// them, either as assembly or bytecode, then link them together. It returns 92dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// true on failure (if, for example, an input bytecode file could not be 93dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// parsed), and false on success. 94afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 95afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::addSources(const std::vector<std::string> &Filenames) { 96afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(Program == 0 && "Cannot call addSources multiple times!"); 97afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(!Filenames.empty() && "Must specify at least on input filename!"); 98afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 9953bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner try { 10053bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner // Load the first input file. 10153bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner Program = ParseInputFile(Filenames[0]); 10253bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (Program == 0) return true; 103c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer if (!run_as_child) 10453bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cout << "Read input file : '" << Filenames[0] << "'\n"; 10553bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 10653bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { 10753bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::auto_ptr<Module> M(ParseInputFile(Filenames[i])); 10853bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (M.get() == 0) return true; 10953bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 11053bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (!run_as_child) 11153bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cout << "Linking in input file: '" << Filenames[i] << "'\n"; 11253bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::string ErrorMessage; 11353bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (Linker::LinkModules(Program, M.get(), &ErrorMessage)) { 11453bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cerr << ToolName << ": error linking in '" << Filenames[i] << "': " 11553bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner << ErrorMessage << '\n'; 11653bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner return true; 11753bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner } 118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 11953bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner } catch (const std::string &Error) { 12053bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cerr << ToolName << ": error reading input '" << Error << "'\n"; 12153bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner return true; 122afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 123afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 124c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer if (!run_as_child) 125c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer std::cout << "*** All input ok\n"; 126afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 127afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // All input files read successfully! 128afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return false; 129afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 130afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 131afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 132afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 133afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// run - The top level method that is invoked after all of the instance 134afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// variables are set up from command line arguments. 135afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 136afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::run() { 137c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // The first thing to do is determine if we're running as a child. If we are, 138c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // then what to do is very narrow. This form of invocation is only called 139c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // from the runPasses method to actually run those passes in a child process. 140c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer if (run_as_child) { 141c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // Execute the passes 142c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer return runPassesAsChild(PassesToRun); 143c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer } 1446a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins 1456a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins if (run_find_bugs) { 1466a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // Rearrange the passes and apply them to the program. Repeat this process 1476a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // until the user kills the program or we find a bug. 1486a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins return runManyPasses(PassesToRun); 1496a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins } 150c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer 151c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // If we're not running as a child, the first thing that we must do is 152c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // determine what the problem is. Does the optimization series crash the 153c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // compiler, or does it produce illegal code? We make the top-level 154c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // decision by trying to run all of the passes on the the input program, 155c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // which should generate a bytecode file. If it does generate a bytecode 156c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // file, then we know the compiler didn't crash, so try to diagnose a 157c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // miscompilation. 15899b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (!PassesToRun.empty()) { 15999b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner std::cout << "Running selected passes on program to test for crash: "; 16099b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (runPasses(PassesToRun)) 161025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugOptimizerCrash(); 16299b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner } 1635073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1645073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Set up the execution environment, selecting a method to run LLVM bytecode. 1655073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (initializeExecutionEnvironment()) return true; 1665073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1677c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner // Test to see if we have a code generator crash. 1687c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner std::cout << "Running the code generator to test for a crash: "; 1697c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner try { 1707c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner compileProgram(Program); 171eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman std::cout << '\n'; 1727c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } catch (ToolExecutionError &TEE) { 1737c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner std::cout << TEE.what(); 1747c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner return debugCodeGeneratorCrash(); 1757c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 1767c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner 1777c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner 1785073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Run the raw input to see where we are coming from. If a reference output 1795073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // was specified, make sure that the raw output matches it. If not, it's a 1805073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // problem in the front-end or the code generator. 1815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 182c28c1d3cd19bbfcc8eec44f25c5890f8e3ed8bdcChris Lattner bool CreatedOutput = false; 1835073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (ReferenceOutputFile.empty()) { 1847d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner std::cout << "Generating reference output from raw program: "; 1856a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins if(!createReferenceFile(Program)){ 1866a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins return debugCodeGeneratorCrash(); 187025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 1886a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins CreatedOutput = true; 189a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner } 1905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 191a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Make sure the reference output file gets deleted on exit from this 192a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // function, if appropriate. 1935d282185f517d651d965e86dab1b383e0cb5e919Reid Spencer sys::Path ROF(ReferenceOutputFile); 1945d282185f517d651d965e86dab1b383e0cb5e919Reid Spencer FileRemover RemoverInstance(ROF, CreatedOutput); 195a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner 196a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Diff the output of the raw program against the reference output. If it 1976a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // matches, then we assume there is a miscompilation bug and try to 1986a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // diagnose it. 199a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "*** Checking the code generator...\n"; 200025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner try { 201025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner if (!diffProgram()) { 202025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner std::cout << "\n*** Debugging miscompilation!\n"; 203025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugMiscompilation(); 204025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 205025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } catch (ToolExecutionError &TEE) { 2061d29a6d6c7a7f6203065c003d3d2d002870e38a1Alkis Evlogimenos std::cerr << TEE.what(); 207025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugCodeGeneratorCrash(); 2085073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2095073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 210a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "\n*** Input program does not match reference diff!\n"; 211a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "Debugging code generator problem!\n"; 2127c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner try { 2137c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner return debugCodeGenerator(); 2147c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } catch (ToolExecutionError &TEE) { 2157c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner std::cerr << TEE.what(); 2167c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner return debugCodeGeneratorCrash(); 2177c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 2185073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 2195073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 220efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnervoid llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { 221efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner unsigned NumPrint = Funcs.size(); 222efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint > 10) NumPrint = 10; 223efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner for (unsigned i = 0; i != NumPrint; ++i) 224efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::cout << " " << Funcs[i]->getName(); 225efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint < Funcs.size()) 226efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::cout << "... <" << Funcs.size() << " total>"; 227b6c3a88dc4c749e88fdd68368d74ccfb37d506a3Brian Gaeke std::cout << std::flush; 228afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 229