ExecutionDriver.cpp revision 5073336cd4da5df4ae13a167582d1dc90f32e4e0
14a10645c70199c8d8567fbc46312158c419720abChris Lattner//===- ExecutionDriver.cpp - Allow execution of LLVM program --------------===// 24a10645c70199c8d8567fbc46312158c419720abChris Lattner// 34a10645c70199c8d8567fbc46312158c419720abChris Lattner// This file contains code used to execute the program utilizing one of the 44a10645c70199c8d8567fbc46312158c419720abChris Lattner// various ways of running LLVM bytecode. 54a10645c70199c8d8567fbc46312158c419720abChris Lattner// 64a10645c70199c8d8567fbc46312158c419720abChris Lattner//===----------------------------------------------------------------------===// 74a10645c70199c8d8567fbc46312158c419720abChris Lattner 84a10645c70199c8d8567fbc46312158c419720abChris Lattner/* 94a10645c70199c8d8567fbc46312158c419720abChris LattnerBUGPOINT NOTES: 104a10645c70199c8d8567fbc46312158c419720abChris Lattner 114a10645c70199c8d8567fbc46312158c419720abChris Lattner1. Bugpoint should not leave any files behind if the program works properly 124a10645c70199c8d8567fbc46312158c419720abChris Lattner2. There should be an option to specify the program name, which specifies a 134a10645c70199c8d8567fbc46312158c419720abChris Lattner unique string to put into output files. This allows operation in the 145073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman SingleSource directory, e.g. default to the first input filename. 154a10645c70199c8d8567fbc46312158c419720abChris Lattner*/ 164a10645c70199c8d8567fbc46312158c419720abChris Lattner 174a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "BugDriver.h" 184a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "SystemUtils.h" 194a10645c70199c8d8567fbc46312158c419720abChris Lattner#include "Support/CommandLine.h" 204a10645c70199c8d8567fbc46312158c419720abChris Lattner#include <fstream> 21e1b52b765675015eee5ce9efdb1b81c6c3eaefb1Chris Lattner#include <iostream> 224a10645c70199c8d8567fbc46312158c419720abChris Lattner 234a10645c70199c8d8567fbc46312158c419720abChris Lattnernamespace { 244a10645c70199c8d8567fbc46312158c419720abChris Lattner // OutputType - Allow the user to specify the way code should be run, to test 254a10645c70199c8d8567fbc46312158c419720abChris Lattner // for miscompilation. 264a10645c70199c8d8567fbc46312158c419720abChris Lattner // 274a10645c70199c8d8567fbc46312158c419720abChris Lattner enum OutputType { 284a10645c70199c8d8567fbc46312158c419720abChris Lattner RunLLI, RunJIT, RunLLC, RunCBE 294a10645c70199c8d8567fbc46312158c419720abChris Lattner }; 304a10645c70199c8d8567fbc46312158c419720abChris Lattner cl::opt<OutputType> 314a10645c70199c8d8567fbc46312158c419720abChris Lattner InterpreterSel(cl::desc("Specify how LLVM code should be executed:"), 325073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman cl::values(clEnumValN(RunLLI, "run-lli", "Execute with LLI"), 335073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman clEnumValN(RunJIT, "run-jit", "Execute with JIT"), 345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman clEnumValN(RunLLC, "run-llc", "Compile with LLC"), 355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman clEnumValN(RunCBE, "run-cbe", "Compile with CBE"), 365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0)); 373c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner 383c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner cl::opt<std::string> 393c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner InputFile("input", cl::init("/dev/null"), 403c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner cl::desc("Filename to pipe in as stdin (default: /dev/null)")); 414a10645c70199c8d8567fbc46312158c419720abChris Lattner} 424a10645c70199c8d8567fbc46312158c419720abChris Lattner 434a10645c70199c8d8567fbc46312158c419720abChris Lattner/// AbstractInterpreter Class - Subclasses of this class are used to execute 444a10645c70199c8d8567fbc46312158c419720abChris Lattner/// LLVM bytecode in a variety of ways. This abstract interface hides this 454a10645c70199c8d8567fbc46312158c419720abChris Lattner/// complexity behind a simple interface. 464a10645c70199c8d8567fbc46312158c419720abChris Lattner/// 474a10645c70199c8d8567fbc46312158c419720abChris Lattnerstruct AbstractInterpreter { 484a10645c70199c8d8567fbc46312158c419720abChris Lattner 494a10645c70199c8d8567fbc46312158c419720abChris Lattner virtual ~AbstractInterpreter() {} 504a10645c70199c8d8567fbc46312158c419720abChris Lattner 514a10645c70199c8d8567fbc46312158c419720abChris Lattner /// ExecuteProgram - Run the specified bytecode file, emitting output to the 524a10645c70199c8d8567fbc46312158c419720abChris Lattner /// specified filename. This returns the exit code of the program. 534a10645c70199c8d8567fbc46312158c419720abChris Lattner /// 544a10645c70199c8d8567fbc46312158c419720abChris Lattner virtual int ExecuteProgram(const std::string &Bytecode, 555073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 565073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib = "") = 0; 574a10645c70199c8d8567fbc46312158c419720abChris Lattner}; 584a10645c70199c8d8567fbc46312158c419720abChris Lattner 594a10645c70199c8d8567fbc46312158c419720abChris Lattner 604a10645c70199c8d8567fbc46312158c419720abChris Lattner//===----------------------------------------------------------------------===// 614a10645c70199c8d8567fbc46312158c419720abChris Lattner// LLI Implementation of AbstractIntepreter interface 624a10645c70199c8d8567fbc46312158c419720abChris Lattner// 634a10645c70199c8d8567fbc46312158c419720abChris Lattnerclass LLI : public AbstractInterpreter { 644a10645c70199c8d8567fbc46312158c419720abChris Lattner std::string LLIPath; // The path to the LLI executable 654a10645c70199c8d8567fbc46312158c419720abChris Lattnerpublic: 664a10645c70199c8d8567fbc46312158c419720abChris Lattner LLI(const std::string &Path) : LLIPath(Path) { } 674a10645c70199c8d8567fbc46312158c419720abChris Lattner 684a10645c70199c8d8567fbc46312158c419720abChris Lattner // LLI create method - Try to find the LLI executable 694a10645c70199c8d8567fbc46312158c419720abChris Lattner static LLI *create(BugDriver *BD, std::string &Message) { 704a10645c70199c8d8567fbc46312158c419720abChris Lattner std::string LLIPath = FindExecutable("lli", BD->getToolName()); 714a10645c70199c8d8567fbc46312158c419720abChris Lattner if (!LLIPath.empty()) { 724a10645c70199c8d8567fbc46312158c419720abChris Lattner Message = "Found lli: " + LLIPath + "\n"; 734a10645c70199c8d8567fbc46312158c419720abChris Lattner return new LLI(LLIPath); 744a10645c70199c8d8567fbc46312158c419720abChris Lattner } 754a10645c70199c8d8567fbc46312158c419720abChris Lattner 765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Message = "Cannot find `lli' in bugpoint executable directory or PATH!\n"; 774a10645c70199c8d8567fbc46312158c419720abChris Lattner return 0; 784a10645c70199c8d8567fbc46312158c419720abChris Lattner } 794a10645c70199c8d8567fbc46312158c419720abChris Lattner virtual int ExecuteProgram(const std::string &Bytecode, 805073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib = ""); 824a10645c70199c8d8567fbc46312158c419720abChris Lattner}; 834a10645c70199c8d8567fbc46312158c419720abChris Lattner 844a10645c70199c8d8567fbc46312158c419720abChris Lattnerint LLI::ExecuteProgram(const std::string &Bytecode, 855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib) { 875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (SharedLib != "") { 885073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "LLI currently does not support loading shared libraries.\n" 895073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman << "Exiting.\n"; 905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman exit(1); 915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 934a10645c70199c8d8567fbc46312158c419720abChris Lattner const char *Args[] = { 945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman LLIPath.c_str(), 954a10645c70199c8d8567fbc46312158c419720abChris Lattner "-abort-on-exception", 964a10645c70199c8d8567fbc46312158c419720abChris Lattner "-quiet", 97cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner "-force-interpreter=true", 984a10645c70199c8d8567fbc46312158c419720abChris Lattner Bytecode.c_str(), 994a10645c70199c8d8567fbc46312158c419720abChris Lattner 0 1004a10645c70199c8d8567fbc46312158c419720abChris Lattner }; 1015073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1024a10645c70199c8d8567fbc46312158c419720abChris Lattner return RunProgramWithTimeout(LLIPath, Args, 1035073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman InputFile, OutputFile, OutputFile); 1045073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 1055073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1065073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman//===----------------------------------------------------------------------===// 1075073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// GCC Implementation of AbstractIntepreter interface 1085073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// 1095073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// This is not a *real* AbstractInterpreter as it does not accept bytecode 1105073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// files, but only input acceptable to GCC, i.e. C, C++, and assembly files 1115073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// 1125073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanclass GCC : public AbstractInterpreter { 1135073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string GCCPath; // The path to the gcc executable 1145073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanpublic: 1155073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCC(const std::string &gccPath) : GCCPath(gccPath) { } 1165073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1175073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // GCC create method - Try to find the `gcc' executable 1185073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman static GCC *create(BugDriver *BD, std::string &Message) { 1195073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string GCCPath = FindExecutable("gcc", BD->getToolName()); 1205073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (GCCPath.empty()) { 1215073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Message = "Cannot find `gcc' in bugpoint executable directory or PATH!\n"; 1225073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return 0; 1235073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 1245073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1255073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Message = "Found gcc: " + GCCPath + "\n"; 1265073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return new GCC(GCCPath); 1275073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 1285073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1295073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman virtual int ExecuteProgram(const std::string &ProgramFile, 1305073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 1315073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib = ""); 1325073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1335073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman int MakeSharedObject(const std::string &InputFile, 1345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &OutputFile); 1355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman void ProcessFailure(const char **Args); 1375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman}; 1385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanint GCC::ExecuteProgram(const std::string &ProgramFile, 1405073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 1415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib) { 1425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string OutputBinary = "bugpoint.gcc.exe"; 1435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char **GCCArgs; 1445073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char *ArgsWithoutSO[] = { 1465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCCPath.c_str(), 1475073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ProgramFile.c_str(), // Specify the input filename... 1485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-o", OutputBinary.c_str(), // Output to the right filename... 1495073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-lm", // Hard-code the math library... 1505073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-O2", // Optimize the program a bit... 1515073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0 1525073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman }; 1535073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char *ArgsWithSO[] = { 1545073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCCPath.c_str(), 1555073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ProgramFile.c_str(), // Specify the input filename... 1565073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman SharedLib.c_str(), // Specify the shared library to link in... 1575073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-o", OutputBinary.c_str(), // Output to the right filename... 1585073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-lm", // Hard-code the math library... 1595073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-O2", // Optimize the program a bit... 1605073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0 1615073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman }; 1625073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1635073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCCArgs = (SharedLib == "") ? ArgsWithoutSO : ArgsWithSO; 1645073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "<gcc>"; 1655073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (RunProgramWithTimeout(GCCPath, GCCArgs, "/dev/null", 1665073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "/dev/null", "/dev/null")) { 1675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ProcessFailure(GCCArgs); 1685073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman exit(1); // Leave stuff around for the user to inspect or debug the CBE 1695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 1705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char *ProgramArgs[] = { 1725073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman OutputBinary.c_str(), 1735073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0 1745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman }; 1755073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "<program>"; 1775073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1785073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Now that we have a binary, run it! 1795073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman int ProgramResult = RunProgramWithTimeout(OutputBinary, ProgramArgs, 1805073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman InputFile, OutputFile, OutputFile); 1815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "\n"; 1825073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman removeFile(OutputBinary); 1835073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return ProgramResult; 1845073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 1855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanint GCC::MakeSharedObject(const std::string &InputFile, 1875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &OutputFile) { 1885073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman OutputFile = "./bugpoint.so"; 1895073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Compile the C/asm file into a shared object 1905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char* GCCArgs[] = { 1915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCCPath.c_str(), 1925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman InputFile.c_str(), // Specify the input filename... 1935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) 1945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-G", // Compile a shared library, `-G' for Sparc 1955073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman#else 1965073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-shared", // `-shared' for Linux/X86, maybe others 1975073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman#endif 1985073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-o", OutputFile.c_str(), // Output to the right filename... 1995073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-O2", // Optimize the program a bit... 2005073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0 2015073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman }; 2025073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2035073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "<gcc>"; 2045073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if(RunProgramWithTimeout(GCCPath, GCCArgs, "/dev/null", "/dev/null", 2055073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "/dev/null")) { 2065073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ProcessFailure(GCCArgs); 2075073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman exit(1); 2085073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2095073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return 0; 2105073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 2115073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2125073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanvoid GCC::ProcessFailure(const char** GCCArgs) { 2135073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "\n*** bugpoint error: invocation of the C compiler failed!\n"; 2145073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman for (const char **Arg = GCCArgs; *Arg; ++Arg) 2155073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << " " << *Arg; 2165073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "\n"; 2175073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2185073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Rerun the compiler, capturing any error messages to print them. 2195073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string ErrorFilename = getUniqueFilename("bugpoint.gcc.errors"); 2205073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman RunProgramWithTimeout(GCCPath, GCCArgs, "/dev/null", ErrorFilename.c_str(), 2215073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ErrorFilename.c_str()); 2225073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2235073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Print out the error messages generated by GCC if possible... 2245073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::ifstream ErrorFile(ErrorFilename.c_str()); 2255073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (ErrorFile) { 2265073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::copy(std::istreambuf_iterator<char>(ErrorFile), 2275073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::istreambuf_iterator<char>(), 2285073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::ostreambuf_iterator<char>(std::cerr)); 2295073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ErrorFile.close(); 2305073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "\n"; 2315073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2325073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2335073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman removeFile(ErrorFilename); 2345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 2355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman//===----------------------------------------------------------------------===// 2375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// LLC Implementation of AbstractIntepreter interface 2385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// 2395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanclass LLC : public AbstractInterpreter { 2405073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string LLCPath; // The path to the LLC executable 2415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCC *gcc; 2425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanpublic: 2435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman LLC(const std::string &llcPath, GCC *Gcc) 2445073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman : LLCPath(llcPath), gcc(Gcc) { } 2455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ~LLC() { delete gcc; } 2465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2475073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // LLC create method - Try to find the LLC executable 2485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman static LLC *create(BugDriver *BD, std::string &Message) { 2495073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string LLCPath = FindExecutable("llc", BD->getToolName()); 2505073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (LLCPath.empty()) { 2515073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Message = "Cannot find `llc' in bugpoint executable directory or PATH!\n"; 2525073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return 0; 2535073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2545073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2555073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Message = "Found llc: " + LLCPath + "\n"; 2565073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCC *gcc = GCC::create(BD, Message); 2575073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return new LLC(LLCPath, gcc); 2585073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2595073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2605073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman virtual int ExecuteProgram(const std::string &Bytecode, 2615073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 2625073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib = ""); 2635073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2645073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman int OutputAsm(const std::string &Bytecode, 2655073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &OutputAsmFile); 2665073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman}; 2685073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanint LLC::OutputAsm(const std::string &Bytecode, 2705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &OutputAsmFile) { 2715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman OutputAsmFile = "bugpoint.llc.s"; 2725073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char *LLCArgs[] = { 2735073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman LLCPath.c_str(), 2745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-o", OutputAsmFile.c_str(), // Output to the Asm file 2755073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "-f", // Overwrite as necessary... 2765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Bytecode.c_str(), // This is the input bytecode 2775073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0 2785073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman }; 2795073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2805073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "<llc>"; 2815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (RunProgramWithTimeout(LLCPath, LLCArgs, "/dev/null", "/dev/null", 2825073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "/dev/null")) { 2835073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // If LLC failed on the bytecode, print error... 2845073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "bugpoint error: `llc' failed!\n"; 2855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman removeFile(OutputAsmFile); 2865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return 1; 2875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 2885073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2895073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return 0; 2904a10645c70199c8d8567fbc46312158c419720abChris Lattner} 2914a10645c70199c8d8567fbc46312158c419720abChris Lattner 2925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanint LLC::ExecuteProgram(const std::string &Bytecode, 2935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 2945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib) { 2955073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 2965073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string OutputAsmFile; 2975073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (OutputAsm(Bytecode, OutputAsmFile)) { 2985073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "Could not generate asm code with `llc', exiting.\n"; 2995073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman exit(1); 3005073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 3015073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 3025073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Assuming LLC worked, compile the result with GCC and run it. 3035073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman int Result = gcc->ExecuteProgram(OutputAsmFile, OutputFile, SharedLib); 3045073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman removeFile(OutputAsmFile); 3055073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return Result; 3065073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 3075073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 3085073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 309cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner//===----------------------------------------------------------------------===// 310cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner// JIT Implementation of AbstractIntepreter interface 311cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner// 312cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattnerclass JIT : public AbstractInterpreter { 313cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner std::string LLIPath; // The path to the LLI executable 314cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattnerpublic: 315cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner JIT(const std::string &Path) : LLIPath(Path) { } 316cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 317cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner // JIT create method - Try to find the LLI executable 318cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner static JIT *create(BugDriver *BD, std::string &Message) { 319cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner std::string LLIPath = FindExecutable("lli", BD->getToolName()); 320cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner if (!LLIPath.empty()) { 321cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner Message = "Found lli: " + LLIPath + "\n"; 322cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner return new JIT(LLIPath); 323cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner } 324cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 3255073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Message = "Cannot find `lli' in bugpoint executable directory or PATH!\n"; 326cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner return 0; 327cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner } 328cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner virtual int ExecuteProgram(const std::string &Bytecode, 3295073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 3305073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib = ""); 331cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner}; 332cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 333cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattnerint JIT::ExecuteProgram(const std::string &Bytecode, 3345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 3355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib) { 3365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (SharedLib == "") { 3375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char* Args[] = { 3385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman LLIPath.c_str(), "-quiet", "-force-interpreter=false", Bytecode.c_str(), 3395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0 3405073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman }; 3415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return RunProgramWithTimeout(LLIPath, Args, 3425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman InputFile, OutputFile, OutputFile); 3435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } else { 3445073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string SharedLibOpt = "-load=" + SharedLib; 3455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const char* Args[] = { 3465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman LLIPath.c_str(), "-quiet", "-force-interpreter=false", 3475073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman SharedLibOpt.c_str(), 3485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Bytecode.c_str(), 3495073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 0 3505073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman }; 3515073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return RunProgramWithTimeout(LLIPath, Args, 3525073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman InputFile, OutputFile, OutputFile); 3535073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 354cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner} 355cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 356cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner//===----------------------------------------------------------------------===// 357cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner// CBE Implementation of AbstractIntepreter interface 358cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner// 359cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattnerclass CBE : public AbstractInterpreter { 360cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner std::string DISPath; // The path to the LLVM 'dis' executable 3615073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCC *gcc; 362cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattnerpublic: 3635073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman CBE(const std::string &disPath, GCC *Gcc) : DISPath(disPath), gcc(Gcc) { } 3645073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman ~CBE() { delete gcc; } 365cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 366cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner // CBE create method - Try to find the 'dis' executable 367cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner static CBE *create(BugDriver *BD, std::string &Message) { 368cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner std::string DISPath = FindExecutable("dis", BD->getToolName()); 369cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner if (DISPath.empty()) { 3705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Message = "Cannot find `dis' in bugpoint executable directory or PATH!\n"; 371cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner return 0; 372cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner } 373cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 374cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner Message = "Found dis: " + DISPath + "\n"; 375cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 3765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCC *gcc = GCC::create(BD, Message); 3775073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return new CBE(DISPath, gcc); 378cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner } 3795073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 380cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner virtual int ExecuteProgram(const std::string &Bytecode, 3815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 3825073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib = ""); 3835073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 3845073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Sometimes we just want to go half-way and only generate the C file, 3855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // not necessarily compile it with GCC and run the program 3865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman virtual int OutputC(const std::string &Bytecode, 3875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &OutputCFile); 3885073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 389cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner}; 390cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 3915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanint CBE::OutputC(const std::string &Bytecode, 3925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &OutputCFile) { 3935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman OutputCFile = "bugpoint.cbe.c"; 394cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner const char *DisArgs[] = { 395cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner DISPath.c_str(), 396cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner "-o", OutputCFile.c_str(), // Output to the C file 397cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner "-c", // Output to C 398cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner "-f", // Overwrite as necessary... 399cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner Bytecode.c_str(), // This is the input bytecode 400cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 0 401cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner }; 402cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 403cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner std::cout << "<cbe>"; 404cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner if (RunProgramWithTimeout(DISPath, DisArgs, "/dev/null", "/dev/null", 405cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner "/dev/null")) { 406cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner // If dis failed on the bytecode, print error... 4075073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "bugpoint error: `dis -c' failed!\n"; 408cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner return 1; 409cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner } 410cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 4115073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return 0; 4125073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 413cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 414cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 4155073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanint CBE::ExecuteProgram(const std::string &Bytecode, 4165073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &OutputFile, 4175073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedLib) { 4185073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string OutputCFile; 4195073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (OutputC(Bytecode, OutputCFile)) { 4205073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "Could not generate C code with `dis', exiting.\n"; 4215073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman exit(1); 422cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner } 423cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner 4245073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman int Result = gcc->ExecuteProgram(OutputCFile, OutputFile, SharedLib); 425cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner removeFile(OutputCFile); 4265073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 427cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner return Result; 428cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner} 4294a10645c70199c8d8567fbc46312158c419720abChris Lattner 4305073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 4314a10645c70199c8d8567fbc46312158c419720abChris Lattner//===----------------------------------------------------------------------===// 4324a10645c70199c8d8567fbc46312158c419720abChris Lattner// BugDriver method implementation 4334a10645c70199c8d8567fbc46312158c419720abChris Lattner// 4344a10645c70199c8d8567fbc46312158c419720abChris Lattner 4354a10645c70199c8d8567fbc46312158c419720abChris Lattner/// initializeExecutionEnvironment - This method is used to set up the 4364a10645c70199c8d8567fbc46312158c419720abChris Lattner/// environment for executing LLVM programs. 4374a10645c70199c8d8567fbc46312158c419720abChris Lattner/// 4384a10645c70199c8d8567fbc46312158c419720abChris Lattnerbool BugDriver::initializeExecutionEnvironment() { 4394a10645c70199c8d8567fbc46312158c419720abChris Lattner std::cout << "Initializing execution environment: "; 4404a10645c70199c8d8567fbc46312158c419720abChris Lattner 4414a10645c70199c8d8567fbc46312158c419720abChris Lattner // FIXME: This should default to searching for the best interpreter to use on 4424a10645c70199c8d8567fbc46312158c419720abChris Lattner // this platform, which would be JIT, then LLC, then CBE, then LLI. 4434a10645c70199c8d8567fbc46312158c419720abChris Lattner 4444a10645c70199c8d8567fbc46312158c419720abChris Lattner // Create an instance of the AbstractInterpreter interface as specified on the 4454a10645c70199c8d8567fbc46312158c419720abChris Lattner // command line 4464a10645c70199c8d8567fbc46312158c419720abChris Lattner std::string Message; 447cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner switch (InterpreterSel) { 448cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner case RunLLI: Interpreter = LLI::create(this, Message); break; 4495073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman case RunLLC: Interpreter = LLC::create(this, Message); break; 450cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner case RunJIT: Interpreter = JIT::create(this, Message); break; 451cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner case RunCBE: Interpreter = CBE::create(this, Message); break; 452cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner default: 453cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner Message = " Sorry, this back-end is not supported by bugpoint right now!\n"; 454cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner break; 4554a10645c70199c8d8567fbc46312158c419720abChris Lattner } 4564a10645c70199c8d8567fbc46312158c419720abChris Lattner 4574a10645c70199c8d8567fbc46312158c419720abChris Lattner std::cout << Message; 4584a10645c70199c8d8567fbc46312158c419720abChris Lattner 4594a10645c70199c8d8567fbc46312158c419720abChris Lattner // If there was an error creating the selected interpreter, quit with error. 4604a10645c70199c8d8567fbc46312158c419720abChris Lattner return Interpreter == 0; 4614a10645c70199c8d8567fbc46312158c419720abChris Lattner} 4624a10645c70199c8d8567fbc46312158c419720abChris Lattner 4634a10645c70199c8d8567fbc46312158c419720abChris Lattner 4644a10645c70199c8d8567fbc46312158c419720abChris Lattner/// executeProgram - This method runs "Program", capturing the output of the 4654a10645c70199c8d8567fbc46312158c419720abChris Lattner/// program to a file, returning the filename of the file. A recommended 4664a10645c70199c8d8567fbc46312158c419720abChris Lattner/// filename may be optionally specified. 4674a10645c70199c8d8567fbc46312158c419720abChris Lattner/// 4684a10645c70199c8d8567fbc46312158c419720abChris Lattnerstd::string BugDriver::executeProgram(std::string OutputFile, 4695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string BytecodeFile, 4705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string SharedObject, 4715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman AbstractInterpreter *AI) { 4725073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman assert((Interpreter || AI) &&"Interpreter should have been created already!"); 4734a10645c70199c8d8567fbc46312158c419720abChris Lattner bool CreatedBytecode = false; 4744a10645c70199c8d8567fbc46312158c419720abChris Lattner if (BytecodeFile.empty()) { 4754a10645c70199c8d8567fbc46312158c419720abChris Lattner // Emit the program to a bytecode file... 4764a10645c70199c8d8567fbc46312158c419720abChris Lattner BytecodeFile = getUniqueFilename("bugpoint-test-program.bc"); 4774a10645c70199c8d8567fbc46312158c419720abChris Lattner 4784a10645c70199c8d8567fbc46312158c419720abChris Lattner if (writeProgramToFile(BytecodeFile, Program)) { 4794a10645c70199c8d8567fbc46312158c419720abChris Lattner std::cerr << ToolName << ": Error emitting bytecode to file '" 4805073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman << BytecodeFile << "'!\n"; 4814a10645c70199c8d8567fbc46312158c419720abChris Lattner exit(1); 4824a10645c70199c8d8567fbc46312158c419720abChris Lattner } 4834a10645c70199c8d8567fbc46312158c419720abChris Lattner CreatedBytecode = true; 4844a10645c70199c8d8567fbc46312158c419720abChris Lattner } 4854a10645c70199c8d8567fbc46312158c419720abChris Lattner 4864a10645c70199c8d8567fbc46312158c419720abChris Lattner if (OutputFile.empty()) OutputFile = "bugpoint-execution-output"; 4875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 4884a10645c70199c8d8567fbc46312158c419720abChris Lattner // Check to see if this is a valid output filename... 4894a10645c70199c8d8567fbc46312158c419720abChris Lattner OutputFile = getUniqueFilename(OutputFile); 4904a10645c70199c8d8567fbc46312158c419720abChris Lattner 4914a10645c70199c8d8567fbc46312158c419720abChris Lattner // Actually execute the program! 4925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman int RetVal = (AI != 0) ? 4935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman AI->ExecuteProgram(BytecodeFile, OutputFile, SharedObject) : 4945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Interpreter->ExecuteProgram(BytecodeFile, OutputFile, SharedObject); 4954a10645c70199c8d8567fbc46312158c419720abChris Lattner 4964a10645c70199c8d8567fbc46312158c419720abChris Lattner // Remove the temporary bytecode file. 4975073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (CreatedBytecode) removeFile(BytecodeFile); 4984a10645c70199c8d8567fbc46312158c419720abChris Lattner 4994a10645c70199c8d8567fbc46312158c419720abChris Lattner // Return the filename we captured the output to. 5004a10645c70199c8d8567fbc46312158c419720abChris Lattner return OutputFile; 5014a10645c70199c8d8567fbc46312158c419720abChris Lattner} 5024a10645c70199c8d8567fbc46312158c419720abChris Lattner 5035073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanstd::string BugDriver::executeProgramWithCBE(std::string OutputFile, 5045073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string BytecodeFile, 5055073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string SharedObject) { 5065073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string Output; 5075073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman CBE *cbe = CBE::create(this, Output); 5085073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman Output = executeProgram(OutputFile, BytecodeFile, SharedObject, cbe); 5095073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman delete cbe; 5105073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return Output; 5115073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 5125073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5135073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanint BugDriver::compileSharedObject(const std::string &BytecodeFile, 5145073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &SharedObject) { 5155073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman assert(Interpreter && "Interpreter should have been created already!"); 5165073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string Message, OutputCFile; 5175073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5185073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Using CBE 5195073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman CBE *cbe = CBE::create(this, Message); 5205073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman cbe->OutputC(BytecodeFile, OutputCFile); 5215073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5225073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman#if 0 /* This is an alternative, as yet unimplemented */ 5235073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Using LLC 5245073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman LLC *llc = LLC::create(this, Message); 5255073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (llc->OutputAsm(BytecodeFile, OutputFile)) { 5265073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cerr << "Could not generate asm code with `llc', exiting.\n"; 5275073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman exit(1); 5285073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 5295073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman#endif 5305073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5315073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman GCC *gcc = GCC::create(this, Message); 5325073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman gcc->MakeSharedObject(OutputCFile, SharedObject); 5335073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Remove the intermediate C file 5355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman removeFile(OutputCFile); 5365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // We are done with the CBE & GCC 5385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman delete cbe; 5395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman delete gcc; 5405073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman return 0; 5425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 5435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5445073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 5454a10645c70199c8d8567fbc46312158c419720abChris Lattner/// diffProgram - This method executes the specified module and diffs the output 5464a10645c70199c8d8567fbc46312158c419720abChris Lattner/// against the file specified by ReferenceOutputFile. If the output is 5474a10645c70199c8d8567fbc46312158c419720abChris Lattner/// different, true is returned. 5484a10645c70199c8d8567fbc46312158c419720abChris Lattner/// 5495073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmanbool BugDriver::diffProgram(const std::string &BytecodeFile, 5505073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedObject, 551640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner bool RemoveBytecode) { 5524a10645c70199c8d8567fbc46312158c419720abChris Lattner // Execute the program, generating an output file... 5535073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string Output = executeProgram("", BytecodeFile, SharedObject); 5544a10645c70199c8d8567fbc46312158c419720abChris Lattner 5554a10645c70199c8d8567fbc46312158c419720abChris Lattner std::ifstream ReferenceFile(ReferenceOutputFile.c_str()); 5564a10645c70199c8d8567fbc46312158c419720abChris Lattner if (!ReferenceFile) { 5574a10645c70199c8d8567fbc46312158c419720abChris Lattner std::cerr << "Couldn't open reference output file '" 5585073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman << ReferenceOutputFile << "'\n"; 5594a10645c70199c8d8567fbc46312158c419720abChris Lattner exit(1); 5604a10645c70199c8d8567fbc46312158c419720abChris Lattner } 5614a10645c70199c8d8567fbc46312158c419720abChris Lattner 5624a10645c70199c8d8567fbc46312158c419720abChris Lattner std::ifstream OutputFile(Output.c_str()); 5634a10645c70199c8d8567fbc46312158c419720abChris Lattner if (!OutputFile) { 5644a10645c70199c8d8567fbc46312158c419720abChris Lattner std::cerr << "Couldn't open output file: " << Output << "'!\n"; 5654a10645c70199c8d8567fbc46312158c419720abChris Lattner exit(1); 5664a10645c70199c8d8567fbc46312158c419720abChris Lattner } 5674a10645c70199c8d8567fbc46312158c419720abChris Lattner 5684a10645c70199c8d8567fbc46312158c419720abChris Lattner bool FilesDifferent = false; 5694a10645c70199c8d8567fbc46312158c419720abChris Lattner 5704a10645c70199c8d8567fbc46312158c419720abChris Lattner // Compare the two files... 5714a10645c70199c8d8567fbc46312158c419720abChris Lattner int C1, C2; 5724a10645c70199c8d8567fbc46312158c419720abChris Lattner do { 5734a10645c70199c8d8567fbc46312158c419720abChris Lattner C1 = ReferenceFile.get(); 5744a10645c70199c8d8567fbc46312158c419720abChris Lattner C2 = OutputFile.get(); 5754a10645c70199c8d8567fbc46312158c419720abChris Lattner if (C1 != C2) { FilesDifferent = true; break; } 5764a10645c70199c8d8567fbc46312158c419720abChris Lattner } while (C1 != EOF); 5774a10645c70199c8d8567fbc46312158c419720abChris Lattner 5784a10645c70199c8d8567fbc46312158c419720abChris Lattner removeFile(Output); 579640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner if (RemoveBytecode) removeFile(BytecodeFile); 5804a10645c70199c8d8567fbc46312158c419720abChris Lattner return FilesDifferent; 5814a10645c70199c8d8567fbc46312158c419720abChris Lattner} 582