#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/raw_ostream.h"
#include <fstream>
-#include <iostream>
using namespace llvm;
cl::opt<OutputType>
SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"),
- cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"),
- clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"),
- clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"),
- clEnumValN(Custom, "safe-run-custom",
- "Use -exec-command to define a command to execute "
- "the bitcode. Useful for cross-compilation."),
- clEnumValEnd),
+ cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"),
+ clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"),
+ clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"),
+ clEnumValN(Custom, "safe-run-custom",
+ "Use -exec-command to define a command to execute "
+ "the bitcode. Useful for cross-compilation."),
+ clEnumValEnd),
cl::init(AutoPick));
cl::opt<std::string>
SafeInterpreterPath("safe-path",
- cl::desc("Specify the path to the \"safe\" backend program"),
- cl::init(""));
+ cl::desc("Specify the path to the \"safe\" backend program"),
+ cl::init(""));
cl::opt<bool>
AppendProgramExitCode("append-exit-code",
cl::list<std::string>
InputArgv("args", cl::Positional, cl::desc("<program arguments>..."),
cl::ZeroOrMore, cl::PositionalEatsArgs);
+
+ cl::opt<std::string>
+ OutputPrefix("output-prefix", cl::init("bugpoint"),
+ cl::desc("Prefix to use for outputs (default: 'bugpoint')"));
}
namespace {
/// environment for executing LLVM programs.
///
bool BugDriver::initializeExecutionEnvironment() {
- std::cout << "Initializing execution environment: ";
+ outs() << "Initializing execution environment: ";
// Create an instance of the AbstractInterpreter interface as specified on
// the command line
&ToolArgv, &GCCToolArgv);
break;
case Custom:
- Interpreter = AbstractInterpreter::createCustom(getToolName(), Message,
- CustomExecCommand);
+ Interpreter = AbstractInterpreter::createCustom(Message, CustomExecCommand);
break;
default:
Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
if (!Interpreter)
errs() << Message;
else // Display informational messages on stdout instead of stderr
- std::cout << Message;
+ outs() << Message;
std::string Path = SafeInterpreterPath;
if (Path.empty())
InterpreterSel == CBE_bug) {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
- SafeInterpreter = AbstractInterpreter::createLLC(Path, Message,
+ SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs,
&GCCToolArgv);
}
InterpreterSel == LLC_Safe) {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
- SafeInterpreter = AbstractInterpreter::createLLC(Path, Message,
+ SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs,
&GCCToolArgv);
}
if (!SafeInterpreter &&
InterpreterSel != RunCBE) {
SafeInterpreterSel = RunCBE;
- SafeInterpreter = AbstractInterpreter::createCBE(Path, Message,
+ SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
&SafeToolArgs,
&GCCToolArgv);
}
InterpreterSel != RunJIT) {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
- SafeInterpreter = AbstractInterpreter::createLLC(Path, Message,
+ SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs,
&GCCToolArgv);
}
break;
case RunLLC:
SafeToolArgs.push_back("--relocation-model=pic");
- SafeInterpreter = AbstractInterpreter::createLLC(Path, Message,
+ SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
&SafeToolArgs,
&GCCToolArgv);
break;
case RunCBE:
- SafeInterpreter = AbstractInterpreter::createCBE(Path, Message,
+ SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
&SafeToolArgs,
&GCCToolArgv);
break;
case Custom:
- SafeInterpreter = AbstractInterpreter::createCustom(Path, Message,
+ SafeInterpreter = AbstractInterpreter::createCustom(Message,
CustomExecCommand);
break;
default:
"\"safe\" backend right now!\n";
break;
}
- if (!SafeInterpreter) { std::cout << Message << "\nExiting.\n"; exit(1); }
+ if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); }
- gcc = GCC::create(getToolName(), Message, &GCCToolArgv);
- if (!gcc) { std::cout << Message << "\nExiting.\n"; exit(1); }
+ gcc = GCC::create(Message, &GCCToolArgv);
+ if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); }
// If there was an error creating the selected interpreter, quit with error.
return Interpreter == 0;
///
void BugDriver::compileProgram(Module *M) {
// Emit the program to a bitcode file...
- sys::Path BitcodeFile ("bugpoint-test-program.bc");
+ sys::Path BitcodeFile (OutputPrefix + "-test-program.bc");
std::string ErrMsg;
if (BitcodeFile.makeUnique(true,&ErrMsg)) {
errs() << ToolName << ": Error making unique filename: " << ErrMsg
<< "\n";
exit(1);
}
- if (writeProgramToFile(BitcodeFile.toString(), M)) {
+ if (writeProgramToFile(BitcodeFile.str(), M)) {
errs() << ToolName << ": Error emitting bitcode to file '"
- << BitcodeFile << "'!\n";
+ << BitcodeFile.str() << "'!\n";
exit(1);
}
// Remove the temporary bitcode file when we are done.
- FileRemover BitcodeFileRemover(BitcodeFile);
+ FileRemover BitcodeFileRemover(BitcodeFile, !SaveTemps);
// Actually compile the program!
- Interpreter->compileProgram(BitcodeFile.toString());
+ Interpreter->compileProgram(BitcodeFile.str());
}
std::string ErrMsg;
if (BitcodeFile.empty()) {
// Emit the program to a bitcode file...
- sys::Path uniqueFilename("bugpoint-test-program.bc");
+ sys::Path uniqueFilename(OutputPrefix + "-test-program.bc");
if (uniqueFilename.makeUnique(true, &ErrMsg)) {
errs() << ToolName << ": Error making unique filename: "
<< ErrMsg << "!\n";
exit(1);
}
- BitcodeFile = uniqueFilename.toString();
+ BitcodeFile = uniqueFilename.str();
if (writeProgramToFile(BitcodeFile, Program)) {
errs() << ToolName << ": Error emitting bitcode to file '"
// Remove the temporary bitcode file when we are done.
sys::Path BitcodePath (BitcodeFile);
- FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode);
+ FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode && !SaveTemps);
- if (OutputFile.empty()) OutputFile = "bugpoint-execution-output";
+ if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output";
// Check to see if this is a valid output filename...
sys::Path uniqueFile(OutputFile);
<< ErrMsg << "\n";
exit(1);
}
- OutputFile = uniqueFile.toString();
+ OutputFile = uniqueFile.str();
// Figure out which shared objects to run, if any.
std::vector<std::string> SharedObjs(AdditionalSOs);
errs() << "<timeout>";
static bool FirstTimeout = true;
if (FirstTimeout) {
- std::cout << "\n"
+ outs() << "\n"
"*** Program execution timed out! This mechanism is designed to handle\n"
" programs stuck in infinite loops gracefully. The -timeout option\n"
" can be used to change the timeout threshold or disable it completely\n"
GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile);
std::string SharedObjectFile;
- if (gcc->MakeSharedObject(OutputFile.toString(), FT,
+ if (gcc->MakeSharedObject(OutputFile.str(), FT,
SharedObjectFile, AdditionalLinkerArgs))
exit(1);
}
try {
ReferenceOutputFile = executeProgramSafely(Filename);
- std::cout << "\nReference output is: " << ReferenceOutputFile << "\n\n";
+ outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n";
} catch (ToolExecutionError &TEE) {
errs() << TEE.what();
if (Interpreter != SafeInterpreter) {
std::string Error;
bool FilesDifferent = false;
if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile),
- sys::Path(Output.toString()),
+ sys::Path(Output.str()),
AbsTolerance, RelTolerance, &Error)) {
if (Diff == 2) {
errs() << "While diffing output: " << Error << '\n';