summaryrefslogtreecommitdiffstats
path: root/llvm/tools/bugpoint/OptimizerDriver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/bugpoint/OptimizerDriver.cpp')
-rw-r--r--llvm/tools/bugpoint/OptimizerDriver.cpp110
1 files changed, 59 insertions, 51 deletions
diff --git a/llvm/tools/bugpoint/OptimizerDriver.cpp b/llvm/tools/bugpoint/OptimizerDriver.cpp
index 3a77e16d4ef..bac7f51de83 100644
--- a/llvm/tools/bugpoint/OptimizerDriver.cpp
+++ b/llvm/tools/bugpoint/OptimizerDriver.cpp
@@ -19,10 +19,6 @@
// independent code co-exist via conditional compilation until it is verified
// that the new code works correctly on Unix.
-#ifdef _MSC_VER
-#define PLATFORMINDEPENDENT
-#endif
-
#include "BugDriver.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
@@ -30,15 +26,18 @@
#include "llvm/Bytecode/WriteBytecodePass.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
#include <fstream>
-#ifndef PLATFORMINDEPENDENT
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#endif
using namespace llvm;
+namespace {
+ // ChildOutput - This option captures the name of the child output file that
+ // is set up by the parent bugpoint process
+ cl::opt<std::string> ChildOutput("child-output", cl::ReallyHidden);
+}
+
/// writeProgramToFile - This writes the current "Program" to the named bytecode
/// file. If an error occurs, true is returned.
///
@@ -86,14 +85,14 @@ void BugDriver::EmitProgressBytecode(const std::string &ID, bool NoFlyer) {
std::cout << getPassesString(PassesToRun) << "\n";
}
-static void RunChild(Module *Program,const std::vector<const PassInfo*> &Passes,
- const std::string &OutFilename) {
+int BugDriver::runPassesAsChild(const std::vector<const PassInfo*> &Passes) {
+
std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
std::ios::binary;
- std::ofstream OutFile(OutFilename.c_str(), io_mode);
+ std::ofstream OutFile(ChildOutput.c_str(), io_mode);
if (!OutFile.good()) {
- std::cerr << "Error opening bytecode file: " << OutFilename << "\n";
- exit(1);
+ std::cerr << "Error opening bytecode file: " << ChildOutput << "\n";
+ return 1;
}
PassManager PM;
@@ -115,6 +114,8 @@ static void RunChild(Module *Program,const std::vector<const PassInfo*> &Passes,
// Run all queued passes.
PM.run(*Program);
+
+ return 0;
}
/// runPasses - Run the specified passes on Program, outputting a bytecode file
@@ -128,60 +129,67 @@ static void RunChild(Module *Program,const std::vector<const PassInfo*> &Passes,
bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
std::string &OutputFilename, bool DeleteOutput,
bool Quiet) const{
+ // setup the output file name
std::cout << std::flush;
sys::Path uniqueFilename("bugpoint-output.bc");
uniqueFilename.makeUnique();
OutputFilename = uniqueFilename.toString();
-#ifndef PLATFORMINDEPENDENT
- pid_t child_pid;
- switch (child_pid = fork()) {
- case -1: // Error occurred
- std::cerr << ToolName << ": Error forking!\n";
- exit(1);
- case 0: // Child process runs passes.
- RunChild(Program, Passes, OutputFilename);
- exit(0); // If we finish successfully, return 0!
- default: // Parent continues...
- break;
- }
-
- // Wait for the child process to get done.
- int Status;
- if (wait(&Status) != child_pid) {
- std::cerr << "Error waiting for child process!\n";
- exit(1);
+ // set up the input file name
+ sys::Path inputFilename("bugpoint-input.bc");
+ inputFilename.makeUnique();
+ std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
+ std::ios::binary;
+ std::ofstream InFile(inputFilename.c_str(), io_mode);
+ if (!InFile.good()) {
+ std::cerr << "Error opening bytecode file: " << inputFilename << "\n";
+ return(1);
}
-
- bool ExitedOK = WIFEXITED(Status) && WEXITSTATUS(Status) == 0;
-#else
- bool ExitedOK = false;
-#endif
+ WriteBytecodeToFile(Program,InFile,false);
+ InFile.close();
+
+ // setup the child process' arguments
+ const char** args = (const char**)
+ alloca(sizeof(const char*)*(Passes.size()+10));
+ int n = 0;
+ args[n++] = ToolName.c_str();
+ args[n++] = "-as-child";
+ args[n++] = "-child-output";
+ args[n++] = OutputFilename.c_str();
+ std::vector<std::string> pass_args;
+ for (std::vector<const PassInfo*>::const_iterator I = Passes.begin(),
+ E = Passes.end(); I != E; ++I )
+ pass_args.push_back( std::string("-") + (*I)->getPassArgument() );
+ for (std::vector<std::string>::const_iterator I = pass_args.begin(),
+ E = pass_args.end(); I != E; ++I )
+ args[n++] = I->c_str();
+ args[n++] = inputFilename.c_str();
+ args[n++] = 0;
+
+ sys::Path prog(sys::Program::FindProgramByName(ToolName));
+ int result = sys::Program::ExecuteAndWait(prog,args);
// If we are supposed to delete the bytecode file or if the passes crashed,
// remove it now. This may fail if the file was never created, but that's ok.
- if (DeleteOutput || !ExitedOK)
+ if (DeleteOutput || result != 0)
sys::Path(OutputFilename).eraseFromDisk();
-#ifndef PLATFORMINDEPENDENT
+ // Remove the temporary input file as well
+ inputFilename.eraseFromDisk();
+
if (!Quiet) {
- if (ExitedOK)
+ if (result == 0)
std::cout << "Success!\n";
- else if (WIFEXITED(Status))
- std::cout << "Exited with error code '" << WEXITSTATUS(Status) << "'\n";
- else if (WIFSIGNALED(Status))
- std::cout << "Crashed with signal #" << WTERMSIG(Status) << "\n";
-#ifdef WCOREDUMP
- else if (WCOREDUMP(Status))
+ else if (result > 0)
+ std::cout << "Exited with error code '" << result << "'\n";
+ else if (result < 0)
+ std::cout << "Crashed with signal #" << abs(result) << "\n";
+ if (result & 0x01000000)
std::cout << "Dumped core\n";
-#endif
- else
- std::cout << "Failed for unknown reason!\n";
}
-#endif
// Was the child successful?
- return !ExitedOK;
+ return result != 0;
}
OpenPOWER on IntegriCloud