1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// The LLVM Compiler Infrastructure 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source 621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// 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" 21dad45ea56ea8419f51cefb3ff6d2c9ad886ccbbbDan Gohman#include "llvm/Support/IRReader.h" 22551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 23551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/FileUtilities.h" 2492bcb426c3e4503c99324afd4ed0a73521711a56Chris Lattner#include "llvm/Support/SourceMgr.h" 25df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner#include "llvm/Support/raw_ostream.h" 261f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Host.h" 27afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <memory> 28d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm; 29d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 30ca7409664273fed4b473127295af3af0836b3077Daniel Dunbarnamespace llvm { 31ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar Triple TargetTriple; 32ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar} 33ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar 345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// Anonymous namespace to define command line options for debugging. 355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// 365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmannamespace { 375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Output - The user can specify a file containing the expected output of the 385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // program. If this filename is set, it is used as the reference diff source, 395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // otherwise the raw input run through an interpreter is used as the reference 405073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // source. 415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 423da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman cl::opt<std::string> 435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman OutputFile("output", cl::desc("Specify a reference program output " 445073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "(for miscompilation detection)")); 455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 4706905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner/// setNewProgram - If we reduce or update the program somehow, call this method 4806905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner/// to update bugdriver with it. This deletes the old module and sets the 4906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner/// specified one as the current program. 5006905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattnervoid BugDriver::setNewProgram(Module *M) { 5106905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner delete Program; 5206905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner Program = M; 5306905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner} 5406905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner 5506905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner 56640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// getPassesString - Turn a list of passes into a string which indicates the 57640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// command line options that must be passed to add the passes. 58640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// 598261dfed05e32302469ef707cc881fed2c31f85fRafael Espindolastd::string llvm::getPassesString(const std::vector<std::string> &Passes) { 60640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner std::string Result; 61640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner for (unsigned i = 0, e = Passes.size(); i != e; ++i) { 62640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner if (i) Result += " "; 63640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner Result += "-"; 648261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola Result += Passes[i]; 65640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 66640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner return Result; 67640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner} 68640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 697f99f74b7fc298dad4c61c15b064dc951d2b3cbbRafael EspindolaBugDriver::BugDriver(const char *toolname, bool find_bugs, 70c3e6859d8dc9014fee8023497153add9a2148f22Jeffrey Yasskin unsigned timeout, unsigned memlimit, bool use_valgrind, 714434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& ctxt) 728b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile), 7370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman Program(0), Interpreter(0), SafeInterpreter(0), gcc(0), 7456584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer run_find_bugs(find_bugs), Timeout(timeout), 75c3e6859d8dc9014fee8023497153add9a2148f22Jeffrey Yasskin MemoryLimit(memlimit), UseValgrind(use_valgrind) {} 765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 77c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey YasskinBugDriver::~BugDriver() { 78c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin delete Program; 79c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin} 80c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin 815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 828ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif/// ParseInputFile - Given a bitcode or assembly input filename, parse and 83afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// return it, or return null if not possible. 84afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 8531895e73591d3c9ceae731a1274c8f56194b9616Owen AndersonModule *llvm::ParseInputFile(const std::string &Filename, 864434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& Ctxt) { 8792bcb426c3e4503c99324afd4ed0a73521711a56Chris Lattner SMDiagnostic Err; 88dad45ea56ea8419f51cefb3ff6d2c9ad886ccbbbDan Gohman Module *Result = ParseIRFile(Filename, Err, Ctxt); 89dad45ea56ea8419f51cefb3ff6d2c9ad886ccbbbDan Gohman if (!Result) 90d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner Err.print("bugpoint", errs()); 91dad45ea56ea8419f51cefb3ff6d2c9ad886ccbbbDan Gohman 92ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar // If we don't have an override triple, use the first one to configure 93ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar // bugpoint, or use the host triple if none provided. 94ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar if (Result) { 95ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar if (TargetTriple.getTriple().empty()) { 96ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar Triple TheTriple(Result->getTargetTriple()); 97ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar 98ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar if (TheTriple.getTriple().empty()) 99ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar TheTriple.setTriple(sys::getHostTriple()); 10056584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 101ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar TargetTriple.setTriple(TheTriple.getTriple()); 102ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar } 103ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar 104ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar Result->setTargetTriple(TargetTriple.getTriple()); // override the triple 105ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar } 106afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return Result; 107afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 108afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 109afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This method takes the specified list of LLVM input files, attempts to load 1108ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif// them, either as assembly or bitcode, then link them together. It returns 1118ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif// true on failure (if, for example, an input bitcode file could not be 112dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// parsed), and false on success. 113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 114afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::addSources(const std::vector<std::string> &Filenames) { 115afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(Program == 0 && "Cannot call addSources multiple times!"); 116afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(!Filenames.empty() && "Must specify at least on input filename!"); 117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 11822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // Load the first input file. 11922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky Program = ParseInputFile(Filenames[0], Context); 12022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Program == 0) return true; 12156584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 1227f99f74b7fc298dad4c61c15b064dc951d2b3cbbRafael Espindola outs() << "Read input file : '" << Filenames[0] << "'\n"; 12353bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 12422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { 12522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::auto_ptr<Module> M(ParseInputFile(Filenames[i], Context)); 12622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (M.get() == 0) return true; 12753bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 1287f99f74b7fc298dad4c61c15b064dc951d2b3cbbRafael Espindola outs() << "Linking in input file: '" << Filenames[i] << "'\n"; 12922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string ErrorMessage; 130f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner if (Linker::LinkModules(Program, M.get(), Linker::DestroySource, 131f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner &ErrorMessage)) { 13222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << ToolName << ": error linking in '" << Filenames[i] << "': " 13322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << ErrorMessage << '\n'; 13422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return true; 135afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 136afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 137afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 1387f99f74b7fc298dad4c61c15b064dc951d2b3cbbRafael Espindola outs() << "*** All input ok\n"; 139afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 140afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // All input files read successfully! 141afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return false; 142afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 143afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 144afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 145afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 146afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// run - The top level method that is invoked after all of the instance 147afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// variables are set up from command line arguments. 148afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 14922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckybool BugDriver::run(std::string &ErrMsg) { 1506a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins if (run_find_bugs) { 1516a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // Rearrange the passes and apply them to the program. Repeat this process 1526a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // until the user kills the program or we find a bug. 15322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return runManyPasses(PassesToRun, ErrMsg); 1546a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins } 155c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer 15656584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // If we're not running as a child, the first thing that we must do is 15756584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // determine what the problem is. Does the optimization series crash the 15856584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // compiler, or does it produce illegal code? We make the top-level 15956584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // decision by trying to run all of the passes on the the input program, 16056584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // which should generate a bitcode file. If it does generate a bitcode 16156584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // file, then we know the compiler didn't crash, so try to diagnose a 162c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // miscompilation. 16399b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (!PassesToRun.empty()) { 164ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Running selected passes on program to test for crash: "; 1655d8cace94a71169ce8493baa7f3305a27fe0cd84Rafael Espindola if (runPasses(Program, PassesToRun)) 166025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugOptimizerCrash(); 16799b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner } 1685073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1698ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif // Set up the execution environment, selecting a method to run LLVM bitcode. 1705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (initializeExecutionEnvironment()) return true; 1715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1727c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner // Test to see if we have a code generator crash. 173ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Running the code generator to test for a crash: "; 17422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string Error; 17522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky compileProgram(Program, &Error); 17622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 17722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << Error; 17822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 1797c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 18022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << '\n'; 1817c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner 1825073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Run the raw input to see where we are coming from. If a reference output 1835073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // was specified, make sure that the raw output matches it. If not, it's a 1845073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // problem in the front-end or the code generator. 1855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 186c28c1d3cd19bbfcc8eec44f25c5890f8e3ed8bdcChris Lattner bool CreatedOutput = false; 1875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (ReferenceOutputFile.empty()) { 188ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Generating reference output from raw program: "; 18922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!createReferenceFile(Program)) { 19022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 191025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 1926a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins CreatedOutput = true; 193a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner } 1945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 195a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Make sure the reference output file gets deleted on exit from this 196a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // function, if appropriate. 1975d282185f517d651d965e86dab1b383e0cb5e919Reid Spencer sys::Path ROF(ReferenceOutputFile); 198c9c08fb3a7fb5e8ea3e1477a88507704c7a70ba1Michael J. Spencer FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps); 199a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner 200a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Diff the output of the raw program against the reference output. If it 20156584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // matches, then we assume there is a miscompilation bug and try to 2026a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // diagnose it. 203ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "*** Checking the code generator...\n"; 20410757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola bool Diff = diffProgram(Program, "", "", false, &Error); 20522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 20622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << Error; 20722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 20822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 20922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Diff) { 21022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << "\n*** Output matches: Debugging miscompilation!\n"; 21122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky debugMiscompilation(&Error); 21222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 21322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << Error; 21422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 215025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 21622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return false; 2175073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2185073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 219ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n*** Input program does not match reference diff!\n"; 220ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Debugging code generator problem!\n"; 22122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Failure = debugCodeGenerator(&Error); 22222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 22322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << Error; 22422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 2257c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 22622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return Failure; 2275073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 2285073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 229efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnervoid llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { 230efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner unsigned NumPrint = Funcs.size(); 231efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint > 10) NumPrint = 10; 232efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner for (unsigned i = 0; i != NumPrint; ++i) 233ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " " << Funcs[i]->getName(); 234efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint < Funcs.size()) 235ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "... <" << Funcs.size() << " total>"; 236ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs().flush(); 237afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 2384e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling 2394e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendlingvoid llvm::PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs) { 2404e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling unsigned NumPrint = GVs.size(); 2414e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling if (NumPrint > 10) NumPrint = 10; 2424e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling for (unsigned i = 0; i != NumPrint; ++i) 243ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " " << GVs[i]->getName(); 2444e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling if (NumPrint < GVs.size()) 245ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "... <" << GVs.size() << " total>"; 246ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs().flush(); 2474e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling} 248