BugDriver.cpp revision 4e3be89cb5cde6e2df294c64db3bc28133b67594
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) { 7661c83e023fe618ca7b4fdc846039933e61a00ec9Reid Spencer ParseError Err; 7761c83e023fe618ca7b4fdc846039933e61a00ec9Reid Spencer Module *Result = ParseBytecodeFile(InputFilename); 7861c83e023fe618ca7b4fdc846039933e61a00ec9Reid Spencer if (!Result && !(Result = ParseAssemblyFile(InputFilename,&Err))) { 7961c83e023fe618ca7b4fdc846039933e61a00ec9Reid Spencer std::cerr << "bugpoint: " << Err.getMessage() << "\n"; 80afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Result = 0; 81afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 82afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return Result; 83afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 84afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 85afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This method takes the specified list of LLVM input files, attempts to load 86dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// them, either as assembly or bytecode, then link them together. It returns 87dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// true on failure (if, for example, an input bytecode file could not be 88dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// parsed), and false on success. 89afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 90afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::addSources(const std::vector<std::string> &Filenames) { 91afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(Program == 0 && "Cannot call addSources multiple times!"); 92afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(!Filenames.empty() && "Must specify at least on input filename!"); 93afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 9453bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner try { 9553bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner // Load the first input file. 9653bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner Program = ParseInputFile(Filenames[0]); 9753bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (Program == 0) return true; 98c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer if (!run_as_child) 9953bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cout << "Read input file : '" << Filenames[0] << "'\n"; 10053bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 10153bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { 10253bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::auto_ptr<Module> M(ParseInputFile(Filenames[i])); 10353bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (M.get() == 0) return true; 10453bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner 10553bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (!run_as_child) 10653bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cout << "Linking in input file: '" << Filenames[i] << "'\n"; 10753bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::string ErrorMessage; 10853bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner if (Linker::LinkModules(Program, M.get(), &ErrorMessage)) { 10953bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cerr << ToolName << ": error linking in '" << Filenames[i] << "': " 11053bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner << ErrorMessage << '\n'; 11153bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner return true; 11253bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner } 113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 11453bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner } catch (const std::string &Error) { 11553bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner std::cerr << ToolName << ": error reading input '" << Error << "'\n"; 11653bd1b9de74247acae27328cef95bd3888f6cd4dChris Lattner return true; 117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 119c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer if (!run_as_child) 120c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer std::cout << "*** All input ok\n"; 121afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 122afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // All input files read successfully! 123afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return false; 124afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 125afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 126afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 127afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 128afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// run - The top level method that is invoked after all of the instance 129afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// variables are set up from command line arguments. 130afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 131afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::run() { 132c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // The first thing to do is determine if we're running as a child. If we are, 133c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // then what to do is very narrow. This form of invocation is only called 134c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // from the runPasses method to actually run those passes in a child process. 135c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer if (run_as_child) { 136c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // Execute the passes 137c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer return runPassesAsChild(PassesToRun); 138c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer } 1396a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins 1406a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins if (run_find_bugs) { 1416a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // Rearrange the passes and apply them to the program. Repeat this process 1426a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // until the user kills the program or we find a bug. 1436a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins return runManyPasses(PassesToRun); 1446a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins } 145c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer 146c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // If we're not running as a child, the first thing that we must do is 147c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // determine what the problem is. Does the optimization series crash the 148c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // compiler, or does it produce illegal code? We make the top-level 149c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // decision by trying to run all of the passes on the the input program, 150c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // which should generate a bytecode file. If it does generate a bytecode 151c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // file, then we know the compiler didn't crash, so try to diagnose a 152c4bb052ecccfafa0ffa928d0b061db35734ee2eeReid Spencer // miscompilation. 15399b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (!PassesToRun.empty()) { 15499b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner std::cout << "Running selected passes on program to test for crash: "; 15599b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (runPasses(PassesToRun)) 156025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugOptimizerCrash(); 15799b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner } 1585073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1595073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Set up the execution environment, selecting a method to run LLVM bytecode. 1605073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (initializeExecutionEnvironment()) return true; 1615073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1627c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner // Test to see if we have a code generator crash. 1637c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner std::cout << "Running the code generator to test for a crash: "; 1647c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner try { 1657c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner compileProgram(Program); 166eed80e23751ecc50c1fa5604f67be4b826d5b417Misha Brukman std::cout << '\n'; 1677c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } catch (ToolExecutionError &TEE) { 1687c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner std::cout << TEE.what(); 1697c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner return debugCodeGeneratorCrash(); 1707c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 1717c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner 1727c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner 1735073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Run the raw input to see where we are coming from. If a reference output 1745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // was specified, make sure that the raw output matches it. If not, it's a 1755073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // problem in the front-end or the code generator. 1765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 177c28c1d3cd19bbfcc8eec44f25c5890f8e3ed8bdcChris Lattner bool CreatedOutput = false; 1785073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (ReferenceOutputFile.empty()) { 1797d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner std::cout << "Generating reference output from raw program: "; 1806a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins if(!createReferenceFile(Program)){ 1816a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins return debugCodeGeneratorCrash(); 182025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 1836a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins CreatedOutput = true; 184a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner } 1855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 186a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Make sure the reference output file gets deleted on exit from this 187a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // function, if appropriate. 1885d282185f517d651d965e86dab1b383e0cb5e919Reid Spencer sys::Path ROF(ReferenceOutputFile); 1895d282185f517d651d965e86dab1b383e0cb5e919Reid Spencer FileRemover RemoverInstance(ROF, CreatedOutput); 190a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner 191a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Diff the output of the raw program against the reference output. If it 1926a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // matches, then we assume there is a miscompilation bug and try to 1936a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins // diagnose it. 194a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "*** Checking the code generator...\n"; 195025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner try { 196025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner if (!diffProgram()) { 197025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner std::cout << "\n*** Debugging miscompilation!\n"; 198025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugMiscompilation(); 199025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } 200025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner } catch (ToolExecutionError &TEE) { 2011d29a6d6c7a7f6203065c003d3d2d002870e38a1Alkis Evlogimenos std::cerr << TEE.what(); 202025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner return debugCodeGeneratorCrash(); 2035073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2045073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 205a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "\n*** Input program does not match reference diff!\n"; 206a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "Debugging code generator problem!\n"; 2077c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner try { 2087c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner return debugCodeGenerator(); 2097c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } catch (ToolExecutionError &TEE) { 2107c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner std::cerr << TEE.what(); 2117c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner return debugCodeGeneratorCrash(); 2127c955fdb446fa0629e1341f88f4541ee9a929942Chris Lattner } 2135073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 2145073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 215efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnervoid llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { 216efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner unsigned NumPrint = Funcs.size(); 217efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint > 10) NumPrint = 10; 218efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner for (unsigned i = 0; i != NumPrint; ++i) 219efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::cout << " " << Funcs[i]->getName(); 220efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner if (NumPrint < Funcs.size()) 221efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner std::cout << "... <" << Funcs.size() << " total>"; 222b6c3a88dc4c749e88fdd68368d74ccfb37d506a3Brian Gaeke std::cout << std::flush; 223afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 2244e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling 2254e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendlingvoid llvm::PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs) { 2264e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling unsigned NumPrint = GVs.size(); 2274e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling if (NumPrint > 10) NumPrint = 10; 2284e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling for (unsigned i = 0; i != NumPrint; ++i) 2294e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling std::cout << " " << GVs[i]->getName(); 2304e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling if (NumPrint < GVs.size()) 2314e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling std::cout << "... <" << GVs.size() << " total>"; 2324e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling std::cout << std::flush; 2334e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling} 234