summaryrefslogtreecommitdiffstats
path: root/llvm/tools/bugpoint/OptimizerDriver.cpp
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2005-12-22 20:02:55 +0000
committerReid Spencer <rspencer@reidspencer.com>2005-12-22 20:02:55 +0000
commit842118ce952aa5ff1f3fbf8a30e071248097ad46 (patch)
treea7570eacd9d50f9422f2cd001954050ad7ad3ae5 /llvm/tools/bugpoint/OptimizerDriver.cpp
parentccd5b90f5874bfa4f92046f3ecac625b898efdaa (diff)
downloadbcm5719-llvm-842118ce952aa5ff1f3fbf8a30e071248097ad46.tar.gz
bcm5719-llvm-842118ce952aa5ff1f3fbf8a30e071248097ad46.zip
For PR351:
Generally, remove use of fork/exec from bugpoint in favor of the portable sys::Program::ExecuteAndWait method. This change requires two new options to bugpoint to tell it that it is running in "child" mode. In this mode, it reads its input and runs the passes. The result code signals to the parent instance of bugpoint what happened (success, fail, crash). This change should make bugpoint usable on Win32 systems. llvm-svn: 24961
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