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" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 197fc162f893d67ffd96fdb19e2eb9a03b4621f0c0Chandler Carruth#include "llvm/IRReader/IRReader.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Linker/Linker.h" 21e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Pass.h" 22551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 23551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/FileUtilities.h" 24f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/Host.h" 2592bcb426c3e4503c99324afd4ed0a73521711a56Chris Lattner#include "llvm/Support/SourceMgr.h" 26df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner#include "llvm/Support/raw_ostream.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), 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Program(nullptr), Interpreter(nullptr), SafeInterpreter(nullptr), 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines gcc(nullptr), run_find_bugs(find_bugs), Timeout(timeout), 75c3e6859d8dc9014fee8023497153add9a2148f22Jeffrey Yasskin MemoryLimit(memlimit), UseValgrind(use_valgrind) {} 765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 77c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey YasskinBugDriver::~BugDriver() { 78c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin delete Program; 79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Interpreter != SafeInterpreter) 80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines delete Interpreter; 81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines delete SafeInterpreter; 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines delete gcc; 83c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin} 84c1dc0679706f7538cd17169b920967c54661e5b6Jeffrey Yasskin 855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 868ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif/// ParseInputFile - Given a bitcode or assembly input filename, parse and 87afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// return it, or return null if not possible. 88afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 8931895e73591d3c9ceae731a1274c8f56194b9616Owen AndersonModule *llvm::ParseInputFile(const std::string &Filename, 904434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& Ctxt) { 9192bcb426c3e4503c99324afd4ed0a73521711a56Chris Lattner SMDiagnostic Err; 92dad45ea56ea8419f51cefb3ff6d2c9ad886ccbbbDan Gohman Module *Result = ParseIRFile(Filename, Err, Ctxt); 93dad45ea56ea8419f51cefb3ff6d2c9ad886ccbbbDan Gohman if (!Result) 94d8b7aa26134d2abee777f745c32005e63dea2455Chris Lattner Err.print("bugpoint", errs()); 95dad45ea56ea8419f51cefb3ff6d2c9ad886ccbbbDan Gohman 96ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar // If we don't have an override triple, use the first one to configure 97ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar // bugpoint, or use the host triple if none provided. 98ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar if (Result) { 99ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar if (TargetTriple.getTriple().empty()) { 100ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar Triple TheTriple(Result->getTargetTriple()); 101ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar 102ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar if (TheTriple.getTriple().empty()) 1030173864d8a87d9243d304fbf91b556e20b5a32fcSebastian Pop TheTriple.setTriple(sys::getDefaultTargetTriple()); 10456584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 105ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar TargetTriple.setTriple(TheTriple.getTriple()); 106ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar } 107ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar 108ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar Result->setTargetTriple(TargetTriple.getTriple()); // override the triple 109ca7409664273fed4b473127295af3af0836b3077Daniel Dunbar } 110afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return Result; 111afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 112afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This method takes the specified list of LLVM input files, attempts to load 1148ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif// them, either as assembly or bitcode, then link them together. It returns 1158ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif// true on failure (if, for example, an input bitcode file could not be 116dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// parsed), and false on success. 117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::addSources(const std::vector<std::string> &Filenames) { 119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines assert(!Program && "Cannot call addSources multiple times!"); 120afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(!Filenames.empty() && "Must specify at least on input filename!"); 121afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 12222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky // Load the first input file. 12322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky Program = ParseInputFile(Filenames[0], Context); 124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Program) return true; 12556584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer 1267f99f74b7fc298dad4c61c15b064dc951d2b3cbbRafael Espindola outs() << "Read input file : '" << Filenames[0] << "'\n"; 12753bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 12822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> M(ParseInputFile(Filenames[i], Context)); 130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!M.get()) return true; 13153bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 1327f99f74b7fc298dad4c61c15b064dc951d2b3cbbRafael Espindola outs() << "Linking in input file: '" << Filenames[i] << "'\n"; 13322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string ErrorMessage; 134f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner if (Linker::LinkModules(Program, M.get(), Linker::DestroySource, 135f1f1a4f16128ffa2910f0b1d5c7052b3697f9fcdTanya Lattner &ErrorMessage)) { 13622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << ToolName << ": error linking in '" << Filenames[i] << "': " 13722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky << ErrorMessage << '\n'; 13822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return true; 139afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 140afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 141afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 1427f99f74b7fc298dad4c61c15b064dc951d2b3cbbRafael Espindola outs() << "*** All input ok\n"; 143afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 144afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // All input files read successfully! 145afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return false; 146afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 147afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 148afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 149afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 150afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// run - The top level method that is invoked after all of the instance 151afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// variables are set up from command line arguments. 152afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 15322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckybool BugDriver::run(std::string &ErrMsg) { 1546a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins if (run_find_bugs) { 1556a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // Rearrange the passes and apply them to the program. Repeat this process 1566a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // until the user kills the program or we find a bug. 15722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return runManyPasses(PassesToRun, ErrMsg); 1586a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins } 159c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer 16056584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // If we're not running as a child, the first thing that we must do is 16156584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // determine what the problem is. Does the optimization series crash the 16256584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // compiler, or does it produce illegal code? We make the top-level 163c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru // decision by trying to run all of the passes on the input program, 16456584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // which should generate a bitcode file. If it does generate a bitcode 16556584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // file, then we know the compiler didn't crash, so try to diagnose a 166c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // miscompilation. 16799b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (!PassesToRun.empty()) { 168ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Running selected passes on program to test for crash: "; 1695d8cace94a71169ce8493baa7f3305a27fe0cd84Rafael Espindola if (runPasses(Program, PassesToRun)) 170025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugOptimizerCrash(); 17199b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner } 1725073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1738ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif // Set up the execution environment, selecting a method to run LLVM bitcode. 1745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (initializeExecutionEnvironment()) return true; 1755073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1767c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner // Test to see if we have a code generator crash. 177ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Running the code generator to test for a crash: "; 17822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string Error; 17922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky compileProgram(Program, &Error); 18022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 18122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << Error; 18222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 1837c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 18422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << '\n'; 1857c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner 1865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Run the raw input to see where we are coming from. If a reference output 1875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // was specified, make sure that the raw output matches it. If not, it's a 1885073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // problem in the front-end or the code generator. 1895073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 190c28c1d3cd19bbfcc8eec44f25c5890f8e3ed8bdcChris Lattner bool CreatedOutput = false; 1915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (ReferenceOutputFile.empty()) { 192ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Generating reference output from raw program: "; 19322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!createReferenceFile(Program)) { 19422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 195025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 1966a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins CreatedOutput = true; 197a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner } 1985073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 199a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Make sure the reference output file gets deleted on exit from this 200a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // function, if appropriate. 2013b9eb80bd7c83ed819dfdc737d1b99a0bdaa3ff1Rafael Espindola std::string ROF(ReferenceOutputFile); 2023b9eb80bd7c83ed819dfdc737d1b99a0bdaa3ff1Rafael Espindola FileRemover RemoverInstance(ROF, CreatedOutput && !SaveTemps); 203a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner 204a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Diff the output of the raw program against the reference output. If it 20556584fcbfd541c20b914f7cb58a38bf1a16f55c0Michael J. Spencer // matches, then we assume there is a miscompilation bug and try to 2066a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // diagnose it. 207ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "*** Checking the code generator...\n"; 20810757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola bool Diff = diffProgram(Program, "", "", false, &Error); 20922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 21022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << Error; 21122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 21222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 21322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Diff) { 21422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << "\n*** Output matches: Debugging miscompilation!\n"; 21522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky debugMiscompilation(&Error); 21622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 21722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << Error; 21822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 219025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 22022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return false; 2215073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2225073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 223ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n*** Input program does not match reference diff!\n"; 224ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Debugging code generator problem!\n"; 22522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky bool Failure = debugCodeGenerator(&Error); 22622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 22722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << Error; 22822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 2297c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 23022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return Failure; 2315073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 2325073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 233efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnervoid llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { 234efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner unsigned NumPrint = Funcs.size(); 235efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint > 10) NumPrint = 10; 236efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner for (unsigned i = 0; i != NumPrint; ++i) 237ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " " << Funcs[i]->getName(); 238efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint < Funcs.size()) 239ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "... <" << Funcs.size() << " total>"; 240ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs().flush(); 241afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 2424e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling 2434e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendlingvoid llvm::PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs) { 2444e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling unsigned NumPrint = GVs.size(); 2454e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling if (NumPrint > 10) NumPrint = 10; 2464e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling for (unsigned i = 0; i != NumPrint; ++i) 247ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << " " << GVs[i]->getName(); 2484e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling if (NumPrint < GVs.size()) 249ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "... <" << GVs.size() << " total>"; 250ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs().flush(); 2514e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling} 252