summaryrefslogtreecommitdiffstats
path: root/llvm/tools/bugpoint/ExecutionDriver.cpp
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2016-09-06 17:18:22 +0000
committerJustin Bogner <mail@justinbogner.com>2016-09-06 17:18:22 +0000
commit1c039155009c04f4efc37fd76ad75d1342edfccd (patch)
tree9038c8830ec86482c0142418b537d74f36015303 /llvm/tools/bugpoint/ExecutionDriver.cpp
parent18ea094df15dfb8b41d4798bb1cbb14c434fa98d (diff)
downloadbcm5719-llvm-1c039155009c04f4efc37fd76ad75d1342edfccd.tar.gz
bcm5719-llvm-1c039155009c04f4efc37fd76ad75d1342edfccd.zip
bugpoint: Return Errors instead of passing around strings
This replaces the threading of `std::string &Error` through all of these APIs with checked Error returns instead. There are very few places here that actually emit any errors right now, but threading the APIs through will allow us to replace a bunch of exit(1)'s that are scattered through this code with proper error handling. This is more or less NFC, but does move around where a couple of error messages are printed out. llvm-svn: 280720
Diffstat (limited to 'llvm/tools/bugpoint/ExecutionDriver.cpp')
-rw-r--r--llvm/tools/bugpoint/ExecutionDriver.cpp112
1 files changed, 58 insertions, 54 deletions
diff --git a/llvm/tools/bugpoint/ExecutionDriver.cpp b/llvm/tools/bugpoint/ExecutionDriver.cpp
index 695461e2d50..b0f3880fa74 100644
--- a/llvm/tools/bugpoint/ExecutionDriver.cpp
+++ b/llvm/tools/bugpoint/ExecutionDriver.cpp
@@ -141,7 +141,7 @@ cl::list<std::string> CCToolArgv("gcc-tool-args", cl::Positional,
/// initializeExecutionEnvironment - This method is used to set up the
/// environment for executing LLVM programs.
///
-bool BugDriver::initializeExecutionEnvironment() {
+Error BugDriver::initializeExecutionEnvironment() {
outs() << "Initializing execution environment: ";
// Create an instance of the AbstractInterpreter interface as specified on
@@ -261,14 +261,17 @@ bool BugDriver::initializeExecutionEnvironment() {
}
// If there was an error creating the selected interpreter, quit with error.
- return Interpreter == nullptr;
+ if (Interpreter == nullptr)
+ return make_error<StringError>("Failed to init execution environment",
+ inconvertibleErrorCode());
+ return Error::success();
}
/// compileProgram - Try to compile the specified module, returning false and
/// setting Error if an error occurs. This is used for code generation
/// crash testing.
///
-void BugDriver::compileProgram(Module *M, std::string *Error) const {
+Error BugDriver::compileProgram(Module *M) const {
// Emit the program to a bitcode file...
SmallString<128> BitcodeFile;
int BitcodeFD;
@@ -289,17 +292,18 @@ void BugDriver::compileProgram(Module *M, std::string *Error) const {
FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps);
// Actually compile the program!
- Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit);
+ return Interpreter->compileProgram(BitcodeFile.str(), Timeout, MemoryLimit);
}
/// executeProgram - This method runs "Program", capturing the output of the
/// program to a file, returning the filename of the file. A recommended
/// filename may be optionally specified.
///
-std::string
-BugDriver::executeProgram(const Module *Program, std::string OutputFile,
- std::string BitcodeFile, const std::string &SharedObj,
- AbstractInterpreter *AI, std::string *Error) const {
+Expected<std::string> BugDriver::executeProgram(const Module *Program,
+ std::string OutputFile,
+ std::string BitcodeFile,
+ const std::string &SharedObj,
+ AbstractInterpreter *AI) const {
if (!AI)
AI = Interpreter;
assert(AI && "Interpreter should have been created already!");
@@ -347,13 +351,13 @@ BugDriver::executeProgram(const Module *Program, std::string OutputFile,
if (!SharedObj.empty())
SharedObjs.push_back(SharedObj);
- int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, OutputFile,
- Error, AdditionalLinkerArgs, SharedObjs,
- Timeout, MemoryLimit);
- if (!Error->empty())
- return OutputFile;
+ Expected<int> RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile,
+ OutputFile, AdditionalLinkerArgs,
+ SharedObjs, Timeout, MemoryLimit);
+ if (Error E = RetVal.takeError())
+ return std::move(E);
- if (RetVal == -1) {
+ if (*RetVal == -1) {
errs() << "<timeout>";
static bool FirstTimeout = true;
if (FirstTimeout) {
@@ -372,7 +376,7 @@ BugDriver::executeProgram(const Module *Program, std::string OutputFile,
if (AppendProgramExitCode) {
std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
- outFile << "exit " << RetVal << '\n';
+ outFile << "exit " << *RetVal << '\n';
outFile.close();
}
@@ -383,29 +387,27 @@ BugDriver::executeProgram(const Module *Program, std::string OutputFile,
/// executeProgramSafely - Used to create reference output with the "safe"
/// backend, if reference output is not provided.
///
-std::string BugDriver::executeProgramSafely(const Module *Program,
- const std::string &OutputFile,
- std::string *Error) const {
- return executeProgram(Program, OutputFile, "", "", SafeInterpreter, Error);
+Expected<std::string>
+BugDriver::executeProgramSafely(const Module *Program,
+ const std::string &OutputFile) const {
+ return executeProgram(Program, OutputFile, "", "", SafeInterpreter);
}
-std::string BugDriver::compileSharedObject(const std::string &BitcodeFile,
- std::string &Error) {
+Expected<std::string>
+BugDriver::compileSharedObject(const std::string &BitcodeFile) {
assert(Interpreter && "Interpreter should have been created already!");
std::string OutputFile;
// Using the known-good backend.
- CC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, Error);
- if (!Error.empty())
- return "";
+ Expected<CC::FileType> FT =
+ SafeInterpreter->OutputCode(BitcodeFile, OutputFile);
+ if (Error E = FT.takeError())
+ return std::move(E);
std::string SharedObjectFile;
- bool Failure = cc->MakeSharedObject(OutputFile, FT, SharedObjectFile,
- AdditionalLinkerArgs, Error);
- if (!Error.empty())
- return "";
- if (Failure)
- exit(1);
+ if (Error E = cc->MakeSharedObject(OutputFile, *FT, SharedObjectFile,
+ AdditionalLinkerArgs))
+ return std::move(E);
// Remove the intermediate C file
sys::fs::remove(OutputFile);
@@ -418,25 +420,27 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile,
/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
/// this function.
///
-bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
- std::string Error;
- compileProgram(Program, &Error);
- if (!Error.empty())
- return false;
+Error BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
+ if (Error E = compileProgram(Program))
+ return E;
- ReferenceOutputFile = executeProgramSafely(Program, Filename, &Error);
- if (!Error.empty()) {
- errs() << Error;
+ Expected<std::string> Result = executeProgramSafely(Program, Filename);
+ if (Error E = Result.takeError()) {
if (Interpreter != SafeInterpreter) {
- errs() << "*** There is a bug running the \"safe\" backend. Either"
- << " debug it (for example with the -run-jit bugpoint option,"
- << " if JIT is being used as the \"safe\" backend), or fix the"
- << " error some other way.\n";
+ E = joinErrors(
+ std::move(E),
+ make_error<StringError>(
+ "*** There is a bug running the \"safe\" backend. Either"
+ " debug it (for example with the -run-jit bugpoint option,"
+ " if JIT is being used as the \"safe\" backend), or fix the"
+ " error some other way.\n",
+ inconvertibleErrorCode()));
}
- return false;
+ return E;
}
+ ReferenceOutputFile = *Result;
outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n";
- return true;
+ return Error::success();
}
/// diffProgram - This method executes the specified module and diffs the
@@ -444,19 +448,19 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
/// is different, 1 is returned. If there is a problem with the code
/// generator (e.g., llc crashes), this will set ErrMsg.
///
-bool BugDriver::diffProgram(const Module *Program,
- const std::string &BitcodeFile,
- const std::string &SharedObject, bool RemoveBitcode,
- std::string *ErrMsg) const {
+Expected<bool> BugDriver::diffProgram(const Module *Program,
+ const std::string &BitcodeFile,
+ const std::string &SharedObject,
+ bool RemoveBitcode) const {
// Execute the program, generating an output file...
- std::string Output(
- executeProgram(Program, "", BitcodeFile, SharedObject, nullptr, ErrMsg));
- if (!ErrMsg->empty())
- return false;
+ Expected<std::string> Output =
+ executeProgram(Program, "", BitcodeFile, SharedObject, nullptr);
+ if (Error E = Output.takeError())
+ return std::move(E);
std::string Error;
bool FilesDifferent = false;
- if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, Output,
+ if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, *Output,
AbsTolerance, RelTolerance, &Error)) {
if (Diff == 2) {
errs() << "While diffing output: " << Error << '\n';
@@ -465,7 +469,7 @@ bool BugDriver::diffProgram(const Module *Program,
FilesDifferent = true;
} else {
// Remove the generated output if there are no differences.
- sys::fs::remove(Output);
+ sys::fs::remove(*Output);
}
// Remove the bitcode file if we are supposed to.
OpenPOWER on IntegriCloud