ToolRunner.cpp revision 207618
190075Sobrien//===-- ToolRunner.cpp ----------------------------------------------------===//
2169689Skan//
3169689Skan//                     The LLVM Compiler Infrastructure
490075Sobrien//
590075Sobrien// This file is distributed under the University of Illinois Open Source
690075Sobrien// License. See LICENSE.TXT for details.
790075Sobrien//
890075Sobrien//===----------------------------------------------------------------------===//
990075Sobrien//
1090075Sobrien// This file implements the interfaces described in the ToolRunner.h file.
1190075Sobrien//
1290075Sobrien//===----------------------------------------------------------------------===//
1390075Sobrien
1490075Sobrien#define DEBUG_TYPE "toolrunner"
1590075Sobrien#include "ToolRunner.h"
1690075Sobrien#include "llvm/System/Program.h"
1790075Sobrien#include "llvm/Support/CommandLine.h"
1890075Sobrien#include "llvm/Support/Debug.h"
19169689Skan#include "llvm/Support/FileUtilities.h"
20169689Skan#include "llvm/Support/raw_ostream.h"
2190075Sobrien#include "llvm/Config/config.h"   // for HAVE_LINK_R
2290075Sobrien#include <fstream>
2390075Sobrien#include <sstream>
24132718Skanusing namespace llvm;
25132718Skan
2690075Sobriennamespace llvm {
2790075Sobrien  cl::opt<bool>
2890075Sobrien  SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files"));
2990075Sobrien}
3090075Sobrien
3190075Sobriennamespace {
3290075Sobrien  cl::opt<std::string>
3396263Sobrien  RemoteClient("remote-client",
3490075Sobrien               cl::desc("Remote execution client (rsh/ssh)"));
3590075Sobrien
3690075Sobrien  cl::opt<std::string>
3790075Sobrien  RemoteHost("remote-host",
3890075Sobrien             cl::desc("Remote execution (rsh/ssh) host"));
39132718Skan
4090075Sobrien  cl::opt<std::string>
4190075Sobrien  RemotePort("remote-port",
42132718Skan             cl::desc("Remote execution (rsh/ssh) port"));
43132718Skan
44169689Skan  cl::opt<std::string>
45169689Skan  RemoteUser("remote-user",
4690075Sobrien             cl::desc("Remote execution (rsh/ssh) user id"));
4790075Sobrien
4890075Sobrien  cl::opt<std::string>
4990075Sobrien  RemoteExtra("remote-extra-options",
5090075Sobrien          cl::desc("Remote execution (rsh/ssh) extra options"));
5190075Sobrien}
5290075Sobrien
5390075Sobrien/// RunProgramWithTimeout - This function provides an alternate interface
5490075Sobrien/// to the sys::Program::ExecuteAndWait interface.
5590075Sobrien/// @see sys::Program::ExecuteAndWait
5690075Sobrienstatic int RunProgramWithTimeout(const sys::Path &ProgramPath,
5790075Sobrien                                 const char **Args,
5890075Sobrien                                 const sys::Path &StdInFile,
5990075Sobrien                                 const sys::Path &StdOutFile,
6090075Sobrien                                 const sys::Path &StdErrFile,
6190075Sobrien                                 unsigned NumSeconds = 0,
6290075Sobrien                                 unsigned MemoryLimit = 0) {
6390075Sobrien  const sys::Path* redirects[3];
6490075Sobrien  redirects[0] = &StdInFile;
6590075Sobrien  redirects[1] = &StdOutFile;
6690075Sobrien  redirects[2] = &StdErrFile;
6790075Sobrien
6890075Sobrien#if 0 // For debug purposes
6990075Sobrien  {
7090075Sobrien    errs() << "RUN:";
71169689Skan    for (unsigned i = 0; Args[i]; ++i)
7290075Sobrien      errs() << " " << Args[i];
7390075Sobrien    errs() << "\n";
7490075Sobrien  }
7590075Sobrien#endif
7690075Sobrien
7790075Sobrien  return
7890075Sobrien    sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
7990075Sobrien                                 NumSeconds, MemoryLimit);
80132718Skan}
81132718Skan
8290075Sobrien/// RunProgramRemotelyWithTimeout - This function runs the given program
83117395Skan/// remotely using the given remote client and the sys::Program::ExecuteAndWait.
84117395Skan/// Returns the remote program exit code or reports a remote client error if it
85117395Skan/// fails. Remote client is required to return 255 if it failed or program exit
8690075Sobrien/// code otherwise.
8790075Sobrien/// @see sys::Program::ExecuteAndWait
8890075Sobrienstatic int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath,
8990075Sobrien                                         const char **Args,
90132718Skan                                         const sys::Path &StdInFile,
91169689Skan                                         const sys::Path &StdOutFile,
92132718Skan                                         const sys::Path &StdErrFile,
93132718Skan                                         unsigned NumSeconds = 0,
94132718Skan                                         unsigned MemoryLimit = 0) {
95132718Skan  const sys::Path* redirects[3];
96132718Skan  redirects[0] = &StdInFile;
97132718Skan  redirects[1] = &StdOutFile;
98132718Skan  redirects[2] = &StdErrFile;
99132718Skan
100132718Skan#if 0 // For debug purposes
101132718Skan  {
102132718Skan    errs() << "RUN:";
103132718Skan    for (unsigned i = 0; Args[i]; ++i)
104132718Skan      errs() << " " << Args[i];
105132718Skan    errs() << "\n";
106132718Skan  }
107132718Skan#endif
108132718Skan
109132718Skan  // Run the program remotely with the remote client
110132718Skan  int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args,
111132718Skan                                 0, redirects, NumSeconds, MemoryLimit);
112132718Skan
113132718Skan  // Has the remote client fail?
11490075Sobrien  if (255 == ReturnCode) {
115169689Skan    std::ostringstream OS;
116169689Skan    OS << "\nError running remote client:\n ";
117169689Skan    for (const char **Arg = Args; *Arg; ++Arg)
118169689Skan      OS << " " << *Arg;
119132718Skan    OS << "\n";
120169689Skan
121169689Skan    // The error message is in the output file, let's print it out from there.
122169689Skan    std::ifstream ErrorFile(StdOutFile.c_str());
123169689Skan    if (ErrorFile) {
124132718Skan      std::copy(std::istreambuf_iterator<char>(ErrorFile),
125169689Skan                std::istreambuf_iterator<char>(),
126169689Skan                std::ostreambuf_iterator<char>(OS));
127169689Skan      ErrorFile.close();
128169689Skan    }
129169689Skan
130169689Skan    errs() << OS;
131132718Skan  }
132132718Skan
133169689Skan  return ReturnCode;
134132718Skan}
135132718Skan
136169689Skanstatic std::string ProcessFailure(sys::Path ProgPath, const char** Args) {
137169689Skan  std::ostringstream OS;
138169689Skan  OS << "\nError running tool:\n ";
13990075Sobrien  for (const char **Arg = Args; *Arg; ++Arg)
140169689Skan    OS << " " << *Arg;
141169689Skan  OS << "\n";
14290075Sobrien
14390075Sobrien  // Rerun the compiler, capturing any error messages to print them.
144132718Skan  sys::Path ErrorFilename("bugpoint.program_error_messages");
14590075Sobrien  std::string ErrMsg;
14690075Sobrien  if (ErrorFilename.makeUnique(true, &ErrMsg)) {
14790075Sobrien    errs() << "Error making unique filename: " << ErrMsg << "\n";
148169689Skan    exit(1);
149169689Skan  }
150169689Skan  RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
151169689Skan                        ErrorFilename); // FIXME: check return code ?
152169689Skan
15390075Sobrien  // Print out the error messages generated by GCC if possible...
154169689Skan  std::ifstream ErrorFile(ErrorFilename.c_str());
155169689Skan  if (ErrorFile) {
156169689Skan    std::copy(std::istreambuf_iterator<char>(ErrorFile),
157169689Skan              std::istreambuf_iterator<char>(),
158169689Skan              std::ostreambuf_iterator<char>(OS));
159169689Skan    ErrorFile.close();
160169689Skan  }
161169689Skan
162169689Skan  ErrorFilename.eraseFromDisk();
163169689Skan  return OS.str();
164169689Skan}
165169689Skan
166169689Skan//===---------------------------------------------------------------------===//
167169689Skan// LLI Implementation of AbstractIntepreter interface
168169689Skan//
169169689Skannamespace {
170169689Skan  class LLI : public AbstractInterpreter {
171169689Skan    std::string LLIPath;          // The path to the LLI executable
172169689Skan    std::vector<std::string> ToolArgs; // Args to pass to LLI
173169689Skan  public:
174169689Skan    LLI(const std::string &Path, const std::vector<std::string> *Args)
175169689Skan      : LLIPath(Path) {
176132718Skan      ToolArgs.clear ();
17790075Sobrien      if (Args) { ToolArgs = *Args; }
17890075Sobrien    }
17990075Sobrien
18090075Sobrien    virtual int ExecuteProgram(const std::string &Bitcode,
181169689Skan                               const std::vector<std::string> &Args,
18290075Sobrien                               const std::string &InputFile,
18390075Sobrien                               const std::string &OutputFile,
18490075Sobrien                               std::string *Error,
18590075Sobrien                               const std::vector<std::string> &GCCArgs,
18690075Sobrien                               const std::vector<std::string> &SharedLibs =
187132718Skan                               std::vector<std::string>(),
18890075Sobrien                               unsigned Timeout = 0,
189132718Skan                               unsigned MemoryLimit = 0);
19090075Sobrien  };
191169689Skan}
19290075Sobrien
193132718Skanint LLI::ExecuteProgram(const std::string &Bitcode,
19490075Sobrien                        const std::vector<std::string> &Args,
19590075Sobrien                        const std::string &InputFile,
19690075Sobrien                        const std::string &OutputFile,
19790075Sobrien                        std::string *Error,
198169689Skan                        const std::vector<std::string> &GCCArgs,
19990075Sobrien                        const std::vector<std::string> &SharedLibs,
200132718Skan                        unsigned Timeout,
20190075Sobrien                        unsigned MemoryLimit) {
20290075Sobrien  std::vector<const char*> LLIArgs;
20390075Sobrien  LLIArgs.push_back(LLIPath.c_str());
20490075Sobrien  LLIArgs.push_back("-force-interpreter=true");
205169689Skan
20690075Sobrien  for (std::vector<std::string>::const_iterator i = SharedLibs.begin(), e = SharedLibs.end(); i != e; ++i) {
20790075Sobrien    LLIArgs.push_back("-load");
20890075Sobrien    LLIArgs.push_back((*i).c_str());
20990075Sobrien  }
21090075Sobrien
211117395Skan  // Add any extra LLI args.
21290075Sobrien  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
213117395Skan    LLIArgs.push_back(ToolArgs[i].c_str());
214132718Skan
21590075Sobrien  LLIArgs.push_back(Bitcode.c_str());
216132718Skan  // Add optional parameters to the running program from Argv
217132718Skan  for (unsigned i=0, e = Args.size(); i != e; ++i)
218117395Skan    LLIArgs.push_back(Args[i].c_str());
219169689Skan  LLIArgs.push_back(0);
220169689Skan
221117395Skan  outs() << "<lli>"; outs().flush();
222169689Skan  DEBUG(errs() << "\nAbout to run:\t";
223117395Skan        for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
22490075Sobrien          errs() << " " << LLIArgs[i];
225117395Skan        errs() << "\n";
226117395Skan        );
227117395Skan  return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
22890075Sobrien      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
22990075Sobrien      Timeout, MemoryLimit);
230169689Skan}
231117395Skan
232117395Skan// LLI create method - Try to find the LLI executable
233117395SkanAbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
23490075Sobrien                                                    std::string &Message,
23590075Sobrien                                     const std::vector<std::string> *ToolArgs) {
236169689Skan  std::string LLIPath =
23790075Sobrien    FindExecutable("lli", Argv0, (void *)(intptr_t)&createLLI).str();
238117395Skan  if (!LLIPath.empty()) {
239132718Skan    Message = "Found lli: " + LLIPath + "\n";
240117395Skan    return new LLI(LLIPath, ToolArgs);
241117395Skan  }
242169689Skan
243117395Skan  Message = "Cannot find `lli' in executable directory or PATH!\n";
244169689Skan  return 0;
245169689Skan}
246169689Skan
247117395Skan//===---------------------------------------------------------------------===//
248117395Skan// Custom execution command implementation of AbstractIntepreter interface
249117395Skan//
25090075Sobrien// Allows using a custom command for executing the bitcode, thus allows,
25190075Sobrien// for example, to invoke a cross compiler for code generation followed by
25290075Sobrien// a simulator that executes the generated binary.
25390075Sobriennamespace {
25490075Sobrien  class CustomExecutor : public AbstractInterpreter {
25590075Sobrien    std::string ExecutionCommand;
256132718Skan    std::vector<std::string> ExecutorArgs;
257132718Skan  public:
258132718Skan    CustomExecutor(
259132718Skan      const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) :
260132718Skan      ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {}
261132718Skan
26290075Sobrien    virtual int ExecuteProgram(const std::string &Bitcode,
26390075Sobrien                               const std::vector<std::string> &Args,
26490075Sobrien                               const std::string &InputFile,
265117395Skan                               const std::string &OutputFile,
26690075Sobrien                               std::string *Error,
26790075Sobrien                               const std::vector<std::string> &GCCArgs,
268117395Skan                               const std::vector<std::string> &SharedLibs =
269117395Skan                                 std::vector<std::string>(),
270117395Skan                               unsigned Timeout = 0,
27190075Sobrien                               unsigned MemoryLimit = 0);
27290075Sobrien  };
273169689Skan}
27490075Sobrien
27590075Sobrienint CustomExecutor::ExecuteProgram(const std::string &Bitcode,
276169689Skan                        const std::vector<std::string> &Args,
27790075Sobrien                        const std::string &InputFile,
27890075Sobrien                        const std::string &OutputFile,
27990075Sobrien                        std::string *Error,
28090075Sobrien                        const std::vector<std::string> &GCCArgs,
281132718Skan                        const std::vector<std::string> &SharedLibs,
28290075Sobrien                        unsigned Timeout,
283169689Skan                        unsigned MemoryLimit) {
28490075Sobrien
28590075Sobrien  std::vector<const char*> ProgramArgs;
28690075Sobrien  ProgramArgs.push_back(ExecutionCommand.c_str());
28790075Sobrien
28890075Sobrien  for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
28990075Sobrien    ProgramArgs.push_back(ExecutorArgs.at(i).c_str());
29090075Sobrien  ProgramArgs.push_back(Bitcode.c_str());
29190075Sobrien  ProgramArgs.push_back(0);
29290075Sobrien
29390075Sobrien  // Add optional parameters to the running program from Argv
29490075Sobrien  for (unsigned i = 0, e = Args.size(); i != e; ++i)
29590075Sobrien    ProgramArgs.push_back(Args[i].c_str());
29690075Sobrien
29790075Sobrien  return RunProgramWithTimeout(
29890075Sobrien    sys::Path(ExecutionCommand),
29990075Sobrien    &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
300117395Skan    sys::Path(OutputFile), Timeout, MemoryLimit);
30190075Sobrien}
302117395Skan
303117395Skan// Custom execution environment create method, takes the execution command
304117395Skan// as arguments
305117395SkanAbstractInterpreter *AbstractInterpreter::createCustom(
306117395Skan                    std::string &Message,
307117395Skan                    const std::string &ExecCommandLine) {
308117395Skan
309117395Skan  std::string Command = "";
310117395Skan  std::vector<std::string> Args;
311117395Skan  std::string delimiters = " ";
312117395Skan
313117395Skan  // Tokenize the ExecCommandLine to the command and the args to allow
314117395Skan  // defining a full command line as the command instead of just the
315117395Skan  // executed program. We cannot just pass the whole string after the command
31690075Sobrien  // as a single argument because then program sees only a single
31790075Sobrien  // command line argument (with spaces in it: "foo bar" instead
31890075Sobrien  // of "foo" and "bar").
31990075Sobrien
320117395Skan  // code borrowed from:
32190075Sobrien  // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
32290075Sobrien  std::string::size_type lastPos =
32390075Sobrien    ExecCommandLine.find_first_not_of(delimiters, 0);
32490075Sobrien  std::string::size_type pos =
325117395Skan    ExecCommandLine.find_first_of(delimiters, lastPos);
32690075Sobrien
327169689Skan  while (std::string::npos != pos || std::string::npos != lastPos) {
32890075Sobrien    std::string token = ExecCommandLine.substr(lastPos, pos - lastPos);
32990075Sobrien    if (Command == "")
33090075Sobrien       Command = token;
33190075Sobrien    else
33290075Sobrien       Args.push_back(token);
33390075Sobrien    // Skip delimiters.  Note the "not_of"
33490075Sobrien    lastPos = ExecCommandLine.find_first_not_of(delimiters, pos);
33590075Sobrien    // Find next "non-delimiter"
33690075Sobrien    pos = ExecCommandLine.find_first_of(delimiters, lastPos);
33790075Sobrien  }
33890075Sobrien
33990075Sobrien  std::string CmdPath = sys::Program::FindProgramByName(Command).str();
34090075Sobrien  if (CmdPath.empty()) {
34190075Sobrien    Message =
34290075Sobrien      std::string("Cannot find '") + Command +
343132718Skan      "' in executable directory or PATH!\n";
34490075Sobrien    return 0;
34590075Sobrien  }
34690075Sobrien
34790075Sobrien  Message = "Found command in: " + CmdPath + "\n";
34890075Sobrien
34990075Sobrien  return new CustomExecutor(CmdPath, Args);
35090075Sobrien}
35190075Sobrien
35290075Sobrien//===----------------------------------------------------------------------===//
35390075Sobrien// LLC Implementation of AbstractIntepreter interface
35490075Sobrien//
35590075SobrienGCC::FileType LLC::OutputCode(const std::string &Bitcode,
35690075Sobrien                              sys::Path &OutputAsmFile, std::string &Error) {
35790075Sobrien  const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
35890075Sobrien  sys::Path uniqueFile(Bitcode + Suffix);
35990075Sobrien  std::string ErrMsg;
36090075Sobrien  if (uniqueFile.makeUnique(true, &ErrMsg)) {
36190075Sobrien    errs() << "Error making unique filename: " << ErrMsg << "\n";
36290075Sobrien    exit(1);
36390075Sobrien  }
36490075Sobrien  OutputAsmFile = uniqueFile;
36590075Sobrien  std::vector<const char *> LLCArgs;
36690075Sobrien  LLCArgs.push_back(LLCPath.c_str());
36790075Sobrien
36890075Sobrien  // Add any extra LLC args.
36990075Sobrien  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
37090075Sobrien    LLCArgs.push_back(ToolArgs[i].c_str());
371117395Skan
37290075Sobrien  LLCArgs.push_back("-o");
37390075Sobrien  LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
374132718Skan  LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
375132718Skan
37690075Sobrien  if (UseIntegratedAssembler)
377117395Skan    LLCArgs.push_back("-filetype=obj");
378117395Skan
379117395Skan  LLCArgs.push_back (0);
38090075Sobrien
38190075Sobrien  outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
38290075Sobrien  outs().flush();
38390075Sobrien  DEBUG(errs() << "\nAbout to run:\t";
38490075Sobrien        for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
38590075Sobrien          errs() << " " << LLCArgs[i];
38690075Sobrien        errs() << "\n";
38790075Sobrien        );
38890075Sobrien  if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
38990075Sobrien                            sys::Path(), sys::Path(), sys::Path()))
39090075Sobrien    Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
39190075Sobrien  return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
39290075Sobrien}
39390075Sobrien
394117395Skanvoid LLC::compileProgram(const std::string &Bitcode, std::string *Error) {
395117395Skan  sys::Path OutputAsmFile;
396117395Skan  OutputCode(Bitcode, OutputAsmFile, *Error);
397117395Skan  OutputAsmFile.eraseFromDisk();
398117395Skan}
399117395Skan
400117395Skanint LLC::ExecuteProgram(const std::string &Bitcode,
401117395Skan                        const std::vector<std::string> &Args,
402117395Skan                        const std::string &InputFile,
403117395Skan                        const std::string &OutputFile,
404117395Skan                        std::string *Error,
405117395Skan                        const std::vector<std::string> &ArgsForGCC,
406117395Skan                        const std::vector<std::string> &SharedLibs,
407117395Skan                        unsigned Timeout,
40890075Sobrien                        unsigned MemoryLimit) {
40990075Sobrien
410132718Skan  sys::Path OutputAsmFile;
41190075Sobrien  GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error);
41290075Sobrien  FileRemover OutFileRemover(OutputAsmFile, !SaveTemps);
41390075Sobrien
41490075Sobrien  std::vector<std::string> GCCArgs(ArgsForGCC);
41590075Sobrien  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
416132718Skan  GCCArgs.insert(GCCArgs.end(), gccArgs.begin(), gccArgs.end());
41790075Sobrien
41890075Sobrien  // Assuming LLC worked, compile the result with GCC and run it.
419117395Skan  return gcc->ExecuteProgram(OutputAsmFile.str(), Args, FileKind,
420117395Skan                             InputFile, OutputFile, Error, GCCArgs,
421117395Skan                             Timeout, MemoryLimit);
422117395Skan}
423117395Skan
424117395Skan/// createLLC - Try to find the LLC executable
425117395Skan///
42690075SobrienLLC *AbstractInterpreter::createLLC(const char *Argv0,
42790075Sobrien                                    std::string &Message,
42890075Sobrien                                    const std::vector<std::string> *Args,
429117395Skan                                    const std::vector<std::string> *GCCArgs,
430117395Skan                                    bool UseIntegratedAssembler) {
431117395Skan  std::string LLCPath =
432117395Skan    FindExecutable("llc", Argv0, (void *)(intptr_t)&createLLC).str();
43390075Sobrien  if (LLCPath.empty()) {
43490075Sobrien    Message = "Cannot find `llc' in executable directory or PATH!\n";
43590075Sobrien    return 0;
43690075Sobrien  }
43790075Sobrien
43890075Sobrien  Message = "Found llc: " + LLCPath + "\n";
43990075Sobrien  GCC *gcc = GCC::create(Message, GCCArgs);
440132718Skan  if (!gcc) {
44190075Sobrien    errs() << Message << "\n";
44290075Sobrien    exit(1);
443132718Skan  }
44490075Sobrien  return new LLC(LLCPath, gcc, Args, GCCArgs, UseIntegratedAssembler);
44590075Sobrien}
44690075Sobrien
44790075Sobrien//===---------------------------------------------------------------------===//
44890075Sobrien// JIT Implementation of AbstractIntepreter interface
44990075Sobrien//
45090075Sobriennamespace {
45190075Sobrien  class JIT : public AbstractInterpreter {
45290075Sobrien    std::string LLIPath;          // The path to the LLI executable
453117395Skan    std::vector<std::string> ToolArgs; // Args to pass to LLI
45490075Sobrien  public:
455132718Skan    JIT(const std::string &Path, const std::vector<std::string> *Args)
45690075Sobrien      : LLIPath(Path) {
45790075Sobrien      ToolArgs.clear ();
45890075Sobrien      if (Args) { ToolArgs = *Args; }
45990075Sobrien    }
460132718Skan
46190075Sobrien    virtual int ExecuteProgram(const std::string &Bitcode,
46290075Sobrien                               const std::vector<std::string> &Args,
46390075Sobrien                               const std::string &InputFile,
46490075Sobrien                               const std::string &OutputFile,
46590075Sobrien                               std::string *Error,
46690075Sobrien                               const std::vector<std::string> &GCCArgs =
46790075Sobrien                                 std::vector<std::string>(),
46890075Sobrien                               const std::vector<std::string> &SharedLibs =
469117395Skan                                 std::vector<std::string>(),
470117395Skan                               unsigned Timeout = 0,
471117395Skan                               unsigned MemoryLimit = 0);
472117395Skan  };
473117395Skan}
474117395Skan
475117395Skanint JIT::ExecuteProgram(const std::string &Bitcode,
476117395Skan                        const std::vector<std::string> &Args,
477117395Skan                        const std::string &InputFile,
478117395Skan                        const std::string &OutputFile,
479117395Skan                        std::string *Error,
480117395Skan                        const std::vector<std::string> &GCCArgs,
481117395Skan                        const std::vector<std::string> &SharedLibs,
482117395Skan                        unsigned Timeout,
483169689Skan                        unsigned MemoryLimit) {
484117395Skan  // Construct a vector of parameters, incorporating those from the command-line
485117395Skan  std::vector<const char*> JITArgs;
486117395Skan  JITArgs.push_back(LLIPath.c_str());
487117395Skan  JITArgs.push_back("-force-interpreter=false");
488117395Skan
489117395Skan  // Add any extra LLI args.
490117395Skan  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
491117395Skan    JITArgs.push_back(ToolArgs[i].c_str());
492117395Skan
493117395Skan  for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
494117395Skan    JITArgs.push_back("-load");
495132718Skan    JITArgs.push_back(SharedLibs[i].c_str());
496117395Skan  }
497117395Skan  JITArgs.push_back(Bitcode.c_str());
498117395Skan  // Add optional parameters to the running program from Argv
499132718Skan  for (unsigned i=0, e = Args.size(); i != e; ++i)
500117395Skan    JITArgs.push_back(Args[i].c_str());
501117395Skan  JITArgs.push_back(0);
502117395Skan
503169689Skan  outs() << "<jit>"; outs().flush();
504169689Skan  DEBUG(errs() << "\nAbout to run:\t";
505169689Skan        for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
506117395Skan          errs() << " " << JITArgs[i];
507169689Skan        errs() << "\n";
508117395Skan        );
509117395Skan  DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
510117395Skan  return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
511117395Skan      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
512117395Skan      Timeout, MemoryLimit);
513117395Skan}
514117395Skan
515117395Skan/// createJIT - Try to find the LLI executable
516117395Skan///
517117395SkanAbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
518117395Skan                   std::string &Message, const std::vector<std::string> *Args) {
519117395Skan  std::string LLIPath =
520117395Skan    FindExecutable("lli", Argv0, (void *)(intptr_t)&createJIT).str();
521117395Skan  if (!LLIPath.empty()) {
522117395Skan    Message = "Found lli: " + LLIPath + "\n";
523117395Skan    return new JIT(LLIPath, Args);
524117395Skan  }
525132718Skan
526117395Skan  Message = "Cannot find `lli' in executable directory or PATH!\n";
527117395Skan  return 0;
528117395Skan}
529117395Skan
530117395SkanGCC::FileType CBE::OutputCode(const std::string &Bitcode,
531117395Skan                              sys::Path &OutputCFile, std::string &Error) {
532117395Skan  sys::Path uniqueFile(Bitcode+".cbe.c");
533117395Skan  std::string ErrMsg;
534117395Skan  if (uniqueFile.makeUnique(true, &ErrMsg)) {
535117395Skan    errs() << "Error making unique filename: " << ErrMsg << "\n";
53690075Sobrien    exit(1);
53790075Sobrien  }
53890075Sobrien  OutputCFile = uniqueFile;
53990075Sobrien  std::vector<const char *> LLCArgs;
54090075Sobrien  LLCArgs.push_back(LLCPath.c_str());
54190075Sobrien
54290075Sobrien  // Add any extra LLC args.
54390075Sobrien  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
54490075Sobrien    LLCArgs.push_back(ToolArgs[i].c_str());
545117395Skan
546117395Skan  LLCArgs.push_back("-o");
547117395Skan  LLCArgs.push_back(OutputCFile.c_str());   // Output to the C file
54890075Sobrien  LLCArgs.push_back("-march=c");            // Output C language
54990075Sobrien  LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
550117395Skan  LLCArgs.push_back(0);
551117395Skan
55290075Sobrien  outs() << "<cbe>"; outs().flush();
55390075Sobrien  DEBUG(errs() << "\nAbout to run:\t";
55490075Sobrien        for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
555117395Skan          errs() << " " << LLCArgs[i];
556117395Skan        errs() << "\n";
55790075Sobrien        );
558117395Skan  if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
559117395Skan                            sys::Path()))
560117395Skan    Error = ProcessFailure(LLCPath, &LLCArgs[0]);
561117395Skan  return GCC::CFile;
562117395Skan}
563117395Skan
564117395Skanvoid CBE::compileProgram(const std::string &Bitcode, std::string *Error) {
56590075Sobrien  sys::Path OutputCFile;
56690075Sobrien  OutputCode(Bitcode, OutputCFile, *Error);
567132718Skan  OutputCFile.eraseFromDisk();
568117395Skan}
56990075Sobrien
57090075Sobrienint CBE::ExecuteProgram(const std::string &Bitcode,
57190075Sobrien                        const std::vector<std::string> &Args,
572169689Skan                        const std::string &InputFile,
573169689Skan                        const std::string &OutputFile,
57490075Sobrien                        std::string *Error,
57590075Sobrien                        const std::vector<std::string> &ArgsForGCC,
57690075Sobrien                        const std::vector<std::string> &SharedLibs,
577117395Skan                        unsigned Timeout,
578117395Skan                        unsigned MemoryLimit) {
57990075Sobrien  sys::Path OutputCFile;
58090075Sobrien  OutputCode(Bitcode, OutputCFile, *Error);
58190075Sobrien
58290075Sobrien  FileRemover CFileRemove(OutputCFile, !SaveTemps);
58390075Sobrien
584117395Skan  std::vector<std::string> GCCArgs(ArgsForGCC);
58590075Sobrien  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
58690075Sobrien
58790075Sobrien  return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile,
58890075Sobrien                             InputFile, OutputFile, Error, GCCArgs,
58990075Sobrien                             Timeout, MemoryLimit);
59090075Sobrien}
591132718Skan
59290075Sobrien/// createCBE - Try to find the 'llc' executable
59390075Sobrien///
594132718SkanCBE *AbstractInterpreter::createCBE(const char *Argv0,
59590075Sobrien                                    std::string &Message,
59690075Sobrien                                    const std::vector<std::string> *Args,
59790075Sobrien                                    const std::vector<std::string> *GCCArgs) {
59890075Sobrien  sys::Path LLCPath =
59990075Sobrien    FindExecutable("llc", Argv0, (void *)(intptr_t)&createCBE);
60090075Sobrien  if (LLCPath.isEmpty()) {
60190075Sobrien    Message =
60290075Sobrien      "Cannot find `llc' in executable directory or PATH!\n";
603169689Skan    return 0;
604169689Skan  }
60590075Sobrien
60690075Sobrien  Message = "Found llc: " + LLCPath.str() + "\n";
607132718Skan  GCC *gcc = GCC::create(Message, GCCArgs);
608132718Skan  if (!gcc) {
609132718Skan    errs() << Message << "\n";
610132718Skan    exit(1);
611132718Skan  }
612132718Skan  return new CBE(LLCPath, gcc, Args);
613132718Skan}
614132718Skan
615132718Skan//===---------------------------------------------------------------------===//
616132718Skan// GCC abstraction
617132718Skan//
618132718Skan
619132718Skanstatic bool IsARMArchitecture(std::vector<std::string> Args) {
620169689Skan  for (std::vector<std::string>::const_iterator
62190075Sobrien         I = Args.begin(), E = Args.end(); I != E; ++I) {
62290075Sobrien    StringRef S(*I);
62390075Sobrien    if (!S.equals_lower("-arch")) {
62490075Sobrien      ++I;
625132718Skan      if (I != E && !S.substr(0, strlen("arm")).equals_lower("arm"))
626132718Skan        return true;
62790075Sobrien    }
62890075Sobrien  }
62990075Sobrien
63090075Sobrien  return false;
63190075Sobrien}
63290075Sobrien
63390075Sobrienint GCC::ExecuteProgram(const std::string &ProgramFile,
63490075Sobrien                        const std::vector<std::string> &Args,
63590075Sobrien                        FileType fileType,
63690075Sobrien                        const std::string &InputFile,
63790075Sobrien                        const std::string &OutputFile,
63890075Sobrien                        std::string *Error,
63990075Sobrien                        const std::vector<std::string> &ArgsForGCC,
64090075Sobrien                        unsigned Timeout,
64190075Sobrien                        unsigned MemoryLimit) {
64290075Sobrien  std::vector<const char*> GCCArgs;
64390075Sobrien
64490075Sobrien  GCCArgs.push_back(GCCPath.c_str());
64590075Sobrien
64690075Sobrien  if (TargetTriple.getArch() == Triple::x86)
64790075Sobrien    GCCArgs.push_back("-m32");
64890075Sobrien
64990075Sobrien  for (std::vector<std::string>::const_iterator
65090075Sobrien         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
65190075Sobrien    GCCArgs.push_back(I->c_str());
65290075Sobrien
65390075Sobrien  // Specify -x explicitly in case the extension is wonky
65490075Sobrien  if (fileType != ObjectFile) {
65590075Sobrien    GCCArgs.push_back("-x");
65690075Sobrien    if (fileType == CFile) {
65790075Sobrien      GCCArgs.push_back("c");
65890075Sobrien      GCCArgs.push_back("-fno-strict-aliasing");
65990075Sobrien    } else {
66090075Sobrien      GCCArgs.push_back("assembler");
66190075Sobrien
662117395Skan      // For ARM architectures we don't want this flag. bugpoint isn't
66390075Sobrien      // explicitly told what architecture it is working on, so we get
66490075Sobrien      // it from gcc flags
66590075Sobrien      if ((TargetTriple.getOS() == Triple::Darwin) &&
66690075Sobrien          !IsARMArchitecture(ArgsForGCC))
66790075Sobrien        GCCArgs.push_back("-force_cpusubtype_ALL");
66890075Sobrien    }
66990075Sobrien  }
67090075Sobrien
67190075Sobrien  GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename.
672117395Skan
673117395Skan  GCCArgs.push_back("-x");
67490075Sobrien  GCCArgs.push_back("none");
67590075Sobrien  GCCArgs.push_back("-o");
67690075Sobrien  sys::Path OutputBinary (ProgramFile+".gcc.exe");
67790075Sobrien  std::string ErrMsg;
67890075Sobrien  if (OutputBinary.makeUnique(true, &ErrMsg)) {
67990075Sobrien    errs() << "Error making unique filename: " << ErrMsg << "\n";
68090075Sobrien    exit(1);
68190075Sobrien  }
682132718Skan  GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
683132718Skan
684132718Skan  // Add any arguments intended for GCC. We locate them here because this is
68590075Sobrien  // most likely -L and -l options that need to come before other libraries but
686132718Skan  // after the source. Other options won't be sensitive to placement on the
68790075Sobrien  // command line, so this should be safe.
688169689Skan  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
68990075Sobrien    GCCArgs.push_back(ArgsForGCC[i].c_str());
69090075Sobrien
69190075Sobrien  GCCArgs.push_back("-lm");                // Hard-code the math library...
69290075Sobrien  GCCArgs.push_back("-O2");                // Optimize the program a bit...
69390075Sobrien#if defined (HAVE_LINK_R)
694169689Skan  GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
695169689Skan#endif
696169689Skan  if (TargetTriple.getArch() == Triple::sparc)
697169689Skan    GCCArgs.push_back("-mcpu=v9");
698169689Skan  GCCArgs.push_back(0);                    // NULL terminator
699169689Skan
700169689Skan  outs() << "<gcc>"; outs().flush();
701169689Skan  DEBUG(errs() << "\nAbout to run:\t";
702169689Skan        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
703169689Skan          errs() << " " << GCCArgs[i];
704169689Skan        errs() << "\n";
705169689Skan        );
706169689Skan  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
707169689Skan        sys::Path())) {
708169689Skan    *Error = ProcessFailure(GCCPath, &GCCArgs[0]);
709169689Skan    return -1;
710169689Skan  }
711169689Skan
712169689Skan  std::vector<const char*> ProgramArgs;
713169689Skan
714169689Skan  if (RemoteClientPath.isEmpty())
715169689Skan    ProgramArgs.push_back(OutputBinary.c_str());
716169689Skan  else {
717169689Skan    ProgramArgs.push_back(RemoteClientPath.c_str());
718169689Skan    ProgramArgs.push_back(RemoteHost.c_str());
719169689Skan    if (!RemoteUser.empty()) {
720169689Skan      ProgramArgs.push_back("-l");
721169689Skan      ProgramArgs.push_back(RemoteUser.c_str());
722169689Skan    }
723169689Skan    if (!RemotePort.empty()) {
724169689Skan      ProgramArgs.push_back("-p");
725169689Skan      ProgramArgs.push_back(RemotePort.c_str());
726169689Skan    }
727169689Skan    if (!RemoteExtra.empty()) {
728169689Skan      ProgramArgs.push_back(RemoteExtra.c_str());
729169689Skan    }
730169689Skan
731169689Skan    // Full path to the binary. We need to cd to the exec directory because
732169689Skan    // there is a dylib there that the exec expects to find in the CWD
733169689Skan    char* env_pwd = getenv("PWD");
734169689Skan    std::string Exec = "cd ";
735169689Skan    Exec += env_pwd;
736169689Skan    Exec += "; ./";
737169689Skan    Exec += OutputBinary.c_str();
738169689Skan    ProgramArgs.push_back(Exec.c_str());
739169689Skan  }
740169689Skan
741169689Skan  // Add optional parameters to the running program from Argv
742169689Skan  for (unsigned i = 0, e = Args.size(); i != e; ++i)
743169689Skan    ProgramArgs.push_back(Args[i].c_str());
744169689Skan  ProgramArgs.push_back(0);                // NULL terminator
745169689Skan
746169689Skan  // Now that we have a binary, run it!
747169689Skan  outs() << "<program>"; outs().flush();
748169689Skan  DEBUG(errs() << "\nAbout to run:\t";
749169689Skan        for (unsigned i = 0, e = ProgramArgs.size()-1; i != e; ++i)
750169689Skan          errs() << " " << ProgramArgs[i];
751169689Skan        errs() << "\n";
752169689Skan        );
753169689Skan
754169689Skan  FileRemover OutputBinaryRemover(OutputBinary, !SaveTemps);
755169689Skan
756169689Skan  if (RemoteClientPath.isEmpty()) {
757169689Skan    DEBUG(errs() << "<run locally>");
758169689Skan    return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
759169689Skan        sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
760169689Skan        Timeout, MemoryLimit);
761169689Skan  } else {
762169689Skan    outs() << "<run remotely>"; outs().flush();
763169689Skan    return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
764169689Skan        &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
765169689Skan        sys::Path(OutputFile), Timeout, MemoryLimit);
766169689Skan  }
767169689Skan}
768169689Skan
769169689Skanint GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
770169689Skan                          std::string &OutputFile,
771169689Skan                          const std::vector<std::string> &ArgsForGCC,
772169689Skan                          std::string &Error) {
773169689Skan  sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
774169689Skan  std::string ErrMsg;
775169689Skan  if (uniqueFilename.makeUnique(true, &ErrMsg)) {
776169689Skan    errs() << "Error making unique filename: " << ErrMsg << "\n";
777169689Skan    exit(1);
77890075Sobrien  }
77990075Sobrien  OutputFile = uniqueFilename.str();
78090075Sobrien
78190075Sobrien  std::vector<const char*> GCCArgs;
78290075Sobrien
78390075Sobrien  GCCArgs.push_back(GCCPath.c_str());
78490075Sobrien
785169689Skan  if (TargetTriple.getArch() == Triple::x86)
78690075Sobrien    GCCArgs.push_back("-m32");
78790075Sobrien
788169689Skan  for (std::vector<std::string>::const_iterator
789169689Skan         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
790169689Skan    GCCArgs.push_back(I->c_str());
791169689Skan
792169689Skan  // Compile the C/asm file into a shared object
793169689Skan  if (fileType != ObjectFile) {
794169689Skan    GCCArgs.push_back("-x");
795132718Skan    GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
796169689Skan  }
797169689Skan  GCCArgs.push_back("-fno-strict-aliasing");
798169689Skan  GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
799132718Skan  GCCArgs.push_back("-x");
800132718Skan  GCCArgs.push_back("none");
801132718Skan  if (TargetTriple.getArch() == Triple::sparc)
802169689Skan    GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
803169689Skan  else if (TargetTriple.getOS() == Triple::Darwin) {
804169689Skan    // link all source files into a single module in data segment, rather than
805169689Skan    // generating blocks. dynamic_lookup requires that you set
806169689Skan    // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
807169689Skan    // bugpoint to just pass that in the environment of GCC.
808169689Skan    GCCArgs.push_back("-single_module");
809169689Skan    GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
810169689Skan    GCCArgs.push_back("-undefined");
811169689Skan    GCCArgs.push_back("dynamic_lookup");
812169689Skan  } else
813169689Skan    GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
814132718Skan
815132718Skan  if ((TargetTriple.getArch() == Triple::alpha) ||
816132718Skan      (TargetTriple.getArch() == Triple::x86_64))
817132718Skan    GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
818132718Skan
819132718Skan  if (TargetTriple.getArch() == Triple::sparc)
820132718Skan    GCCArgs.push_back("-mcpu=v9");
821132718Skan
822132718Skan  GCCArgs.push_back("-o");
823132718Skan  GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
824132718Skan  GCCArgs.push_back("-O2");              // Optimize the program a bit.
825132718Skan
826132718Skan
827132718Skan
828132718Skan  // Add any arguments intended for GCC. We locate them here because this is
829132718Skan  // most likely -L and -l options that need to come before other libraries but
830132718Skan  // after the source. Other options won't be sensitive to placement on the
831132718Skan  // command line, so this should be safe.
832132718Skan  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
833132718Skan    GCCArgs.push_back(ArgsForGCC[i].c_str());
834132718Skan  GCCArgs.push_back(0);                    // NULL terminator
835132718Skan
836132718Skan
837132718Skan
838132718Skan  outs() << "<gcc>"; outs().flush();
839132718Skan  DEBUG(errs() << "\nAbout to run:\t";
840132718Skan        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
841132718Skan          errs() << " " << GCCArgs[i];
842132718Skan        errs() << "\n";
843132718Skan        );
844132718Skan  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
845132718Skan                            sys::Path())) {
846132718Skan    Error = ProcessFailure(GCCPath, &GCCArgs[0]);
847132718Skan    return 1;
848132718Skan  }
849169689Skan  return 0;
850169689Skan}
851169689Skan
852132718Skan/// create - Try to find the `gcc' executable
853132718Skan///
854132718SkanGCC *GCC::create(std::string &Message,
855132718Skan                 const std::vector<std::string> *Args) {
856132718Skan  sys::Path GCCPath = sys::Program::FindProgramByName("gcc");
857132718Skan  if (GCCPath.isEmpty()) {
858132718Skan    Message = "Cannot find `gcc' in executable directory or PATH!\n";
859132718Skan    return 0;
860132718Skan  }
86190075Sobrien
86290075Sobrien  sys::Path RemoteClientPath;
86390075Sobrien  if (!RemoteClient.empty())
86490075Sobrien    RemoteClientPath = sys::Program::FindProgramByName(RemoteClient);
86590075Sobrien
86690075Sobrien  Message = "Found gcc: " + GCCPath.str() + "\n";
86790075Sobrien  return new GCC(GCCPath, RemoteClientPath, Args);
868132718Skan}
86990075Sobrien