minor cleanups. Add provisions for a new standard BLOCKINFO_BLOCK
[oota-llvm.git] / tools / bugpoint / ToolRunner.cpp
index 589f5158d141449ded00c1c89d915b77e6a84b11..cc726676a31fdd1b4e00993fe2f8ac3e28cbca06 100644 (file)
@@ -15,6 +15,7 @@
 #include "ToolRunner.h"
 #include "llvm/Config/config.h"   // for HAVE_LINK_R
 #include "llvm/System/Program.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileUtilities.h"
 #include <fstream>
 #include <iostream>
 using namespace llvm;
 
+namespace {
+  cl::opt<std::string>
+  RSHHost("rsh-host",
+          cl::desc("Remote execution (rsh) host"));
+
+  cl::opt<std::string>
+  RSHUser("rsh-user",
+          cl::desc("Remote execution (rsh) user id"));
+}
+
 ToolExecutionError::~ToolExecutionError() throw() { }
 
 /// RunProgramWithTimeout - This function provides an alternate interface to the
@@ -32,14 +43,23 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
                                  const sys::Path &StdInFile,
                                  const sys::Path &StdOutFile,
                                  const sys::Path &StdErrFile,
-                                 unsigned NumSeconds = 0) {
+                                 unsigned NumSeconds = 0,
+                                 unsigned MemoryLimit = 0) {
   const sys::Path* redirects[3];
   redirects[0] = &StdInFile;
   redirects[1] = &StdOutFile;
   redirects[2] = &StdErrFile;
+                                   
+  if (0) {
+    std::cerr << "RUN:";
+    for (unsigned i = 0; Args[i]; ++i)
+      std::cerr << " " << Args[i];
+    std::cerr << "\n";
+  }
 
   return
-    sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, NumSeconds);
+    sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
+                                 NumSeconds, MemoryLimit);
 }
 
 
@@ -95,7 +115,8 @@ namespace {
                                const std::vector<std::string> &GCCArgs,
                                const std::vector<std::string> &SharedLibs =
                                std::vector<std::string>(),
-                               unsigned Timeout = 0);
+                               unsigned Timeout = 0,
+                               unsigned MemoryLimit = 0);
   };
 }
 
@@ -105,7 +126,8 @@ int LLI::ExecuteProgram(const std::string &Bytecode,
                         const std::string &OutputFile,
                         const std::vector<std::string> &GCCArgs,
                         const std::vector<std::string> &SharedLibs,
-                        unsigned Timeout) {
+                        unsigned Timeout,
+                        unsigned MemoryLimit) {
   if (!SharedLibs.empty())
     throw ToolExecutionError("LLI currently does not support "
                              "loading shared libraries.");
@@ -135,7 +157,7 @@ int LLI::ExecuteProgram(const std::string &Bytecode,
         );
   return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
       sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
-      Timeout);
+      Timeout, MemoryLimit);
 }
 
 // LLI create method - Try to find the LLI executable
@@ -155,7 +177,8 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath,
 //===----------------------------------------------------------------------===//
 // LLC Implementation of AbstractIntepreter interface
 //
-void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) {
+GCC::FileType LLC::OutputCode(const std::string &Bytecode, 
+                              sys::Path &OutputAsmFile) {
   sys::Path uniqueFile(Bytecode+".llc.s");
   std::string ErrMsg;
   if (uniqueFile.makeUnique(true, &ErrMsg)) {
@@ -185,11 +208,13 @@ void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) {
   if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
                             sys::Path(), sys::Path(), sys::Path()))
     ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
+
+  return GCC::AsmFile;                              
 }
 
 void LLC::compileProgram(const std::string &Bytecode) {
   sys::Path OutputAsmFile;
-  OutputAsm(Bytecode, OutputAsmFile);
+  OutputCode(Bytecode, OutputAsmFile);
   OutputAsmFile.eraseFromDisk();
 }
 
@@ -199,10 +224,11 @@ int LLC::ExecuteProgram(const std::string &Bytecode,
                         const std::string &OutputFile,
                         const std::vector<std::string> &ArgsForGCC,
                         const std::vector<std::string> &SharedLibs,
-                        unsigned Timeout) {
+                        unsigned Timeout,
+                        unsigned MemoryLimit) {
 
   sys::Path OutputAsmFile;
-  OutputAsm(Bytecode, OutputAsmFile);
+  OutputCode(Bytecode, OutputAsmFile);
   FileRemover OutFileRemover(OutputAsmFile);
 
   std::vector<std::string> GCCArgs(ArgsForGCC);
@@ -210,7 +236,8 @@ int LLC::ExecuteProgram(const std::string &Bytecode,
 
   // Assuming LLC worked, compile the result with GCC and run it.
   return gcc->ExecuteProgram(OutputAsmFile.toString(), Args, GCC::AsmFile,
-                             InputFile, OutputFile, GCCArgs, Timeout);
+                             InputFile, OutputFile, GCCArgs,
+                             Timeout, MemoryLimit);
 }
 
 /// createLLC - Try to find the LLC executable
@@ -255,7 +282,8 @@ namespace {
                                  std::vector<std::string>(),
                                const std::vector<std::string> &SharedLibs =
                                  std::vector<std::string>(), 
-                               unsigned Timeout =0 );
+                               unsigned Timeout =0,
+                               unsigned MemoryLimit =0);
   };
 }
 
@@ -265,7 +293,8 @@ int JIT::ExecuteProgram(const std::string &Bytecode,
                         const std::string &OutputFile,
                         const std::vector<std::string> &GCCArgs,
                         const std::vector<std::string> &SharedLibs,
-                        unsigned Timeout) {
+                        unsigned Timeout,
+                        unsigned MemoryLimit) {
   if (!GCCArgs.empty())
     throw ToolExecutionError("JIT does not support GCC Arguments.");
   // Construct a vector of parameters, incorporating those from the command-line
@@ -296,7 +325,7 @@ int JIT::ExecuteProgram(const std::string &Bytecode,
   DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
   return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
       sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
-      Timeout);
+      Timeout, MemoryLimit);
 }
 
 /// createJIT - Try to find the LLI executable
@@ -313,7 +342,8 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
   return 0;
 }
 
-void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) {
+GCC::FileType CBE::OutputCode(const std::string &Bytecode,
+                              sys::Path &OutputCFile) {
   sys::Path uniqueFile(Bytecode+".cbe.c");
   std::string ErrMsg;
   if (uniqueFile.makeUnique(true, &ErrMsg)) {
@@ -344,11 +374,12 @@ void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) {
   if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
                             sys::Path()))
     ProcessFailure(LLCPath, &LLCArgs[0]);
+  return GCC::CFile;
 }
 
 void CBE::compileProgram(const std::string &Bytecode) {
   sys::Path OutputCFile;
-  OutputC(Bytecode, OutputCFile);
+  OutputCode(Bytecode, OutputCFile);
   OutputCFile.eraseFromDisk();
 }
 
@@ -358,16 +389,18 @@ int CBE::ExecuteProgram(const std::string &Bytecode,
                         const std::string &OutputFile,
                         const std::vector<std::string> &ArgsForGCC,
                         const std::vector<std::string> &SharedLibs,
-                        unsigned Timeout) {
+                        unsigned Timeout,
+                        unsigned MemoryLimit) {
   sys::Path OutputCFile;
-  OutputC(Bytecode, OutputCFile);
+  OutputCode(Bytecode, OutputCFile);
 
   FileRemover CFileRemove(OutputCFile);
 
   std::vector<std::string> GCCArgs(ArgsForGCC);
   GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
   return gcc->ExecuteProgram(OutputCFile.toString(), Args, GCC::CFile,
-                             InputFile, OutputFile, GCCArgs, Timeout);
+                             InputFile, OutputFile, GCCArgs,
+                             Timeout, MemoryLimit);
 }
 
 /// createCBE - Try to find the 'llc' executable
@@ -400,7 +433,8 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
                         const std::string &InputFile,
                         const std::string &OutputFile,
                         const std::vector<std::string> &ArgsForGCC,
-                        unsigned Timeout ) {
+                        unsigned Timeout,
+                        unsigned MemoryLimit) {
   std::vector<const char*> GCCArgs;
 
   GCCArgs.push_back(GCCPath.c_str());
@@ -446,6 +480,11 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
   GCCArgs.push_back(0);                    // NULL terminator
 
   std::cout << "<gcc>" << std::flush;
+  DEBUG(std::cerr << "\nAbout to run:\t";
+        for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
+          std::cerr << " " << GCCArgs[i];
+        std::cerr << "\n";
+        );
   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
         sys::Path())) {
     ProcessFailure(GCCPath, &GCCArgs[0]);
@@ -454,7 +493,22 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
 
   std::vector<const char*> ProgramArgs;
 
-  ProgramArgs.push_back(OutputBinary.c_str());
+  if (RSHPath.isEmpty())
+    ProgramArgs.push_back(OutputBinary.c_str());
+  else {
+    ProgramArgs.push_back(RSHPath.c_str());
+    ProgramArgs.push_back(RSHHost.c_str());
+    ProgramArgs.push_back("-l");
+    ProgramArgs.push_back(RSHUser.c_str());
+
+    char* env_pwd = getenv("PWD");
+    std::string Exec = "cd ";
+    Exec += env_pwd;
+    Exec += "; ./";
+    Exec += OutputBinary.c_str();
+    ProgramArgs.push_back(Exec.c_str());
+  }
+
   // Add optional parameters to the running program from Argv
   for (unsigned i=0, e = Args.size(); i != e; ++i)
     ProgramArgs.push_back(Args[i].c_str());
@@ -469,9 +523,15 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
         );
 
   FileRemover OutputBinaryRemover(OutputBinary);
-  return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
-      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
-      Timeout);
+
+  if (RSHPath.isEmpty())
+    return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
+        sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
+        Timeout, MemoryLimit);
+  else
+    return RunProgramWithTimeout(sys::Path(RSHPath), &ProgramArgs[0],
+        sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
+        Timeout, MemoryLimit);
 }
 
 int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
@@ -533,6 +593,11 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
   
 
   std::cout << "<gcc>" << std::flush;
+  DEBUG(std::cerr << "\nAbout to run:\t";
+        for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
+          std::cerr << " " << GCCArgs[i];
+        std::cerr << "\n";
+        );
   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
                             sys::Path())) {
     ProcessFailure(GCCPath, &GCCArgs[0]);
@@ -550,6 +615,10 @@ GCC *GCC::create(const std::string &ProgramPath, std::string &Message) {
     return 0;
   }
 
+  sys::Path RSHPath;
+  if (!RSHHost.empty())
+    RSHPath = FindExecutable("rsh", ProgramPath);
+
   Message = "Found gcc: " + GCCPath.toString() + "\n";
-  return new GCC(GCCPath);
+  return new GCC(GCCPath, RSHPath);
 }