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