ToolRunner.cpp revision 199481
1193323Sed//===-- ToolRunner.cpp ----------------------------------------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements the interfaces described in the ToolRunner.h file.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#define DEBUG_TYPE "toolrunner"
15193323Sed#include "ToolRunner.h"
16193323Sed#include "llvm/System/Program.h"
17193323Sed#include "llvm/Support/CommandLine.h"
18193323Sed#include "llvm/Support/Debug.h"
19193323Sed#include "llvm/Support/FileUtilities.h"
20198090Srdivacky#include "llvm/Support/raw_ostream.h"
21198090Srdivacky#include "llvm/Config/config.h"   // for HAVE_LINK_R
22193323Sed#include <fstream>
23193323Sed#include <sstream>
24193323Sedusing namespace llvm;
25193323Sed
26198090Srdivackynamespace llvm {
27198090Srdivacky  cl::opt<bool>
28198090Srdivacky  SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files"));
29198090Srdivacky}
30198090Srdivacky
31193323Sednamespace {
32193323Sed  cl::opt<std::string>
33193323Sed  RemoteClient("remote-client",
34193323Sed               cl::desc("Remote execution client (rsh/ssh)"));
35193323Sed
36193323Sed  cl::opt<std::string>
37193323Sed  RemoteHost("remote-host",
38193323Sed             cl::desc("Remote execution (rsh/ssh) host"));
39193323Sed
40193323Sed  cl::opt<std::string>
41198090Srdivacky  RemotePort("remote-port",
42198090Srdivacky             cl::desc("Remote execution (rsh/ssh) port"));
43198090Srdivacky
44198090Srdivacky  cl::opt<std::string>
45193323Sed  RemoteUser("remote-user",
46193323Sed             cl::desc("Remote execution (rsh/ssh) user id"));
47193323Sed
48193323Sed  cl::opt<std::string>
49193323Sed  RemoteExtra("remote-extra-options",
50193323Sed          cl::desc("Remote execution (rsh/ssh) extra options"));
51193323Sed}
52193323Sed
53193323SedToolExecutionError::~ToolExecutionError() throw() { }
54193323Sed
55198090Srdivacky/// RunProgramWithTimeout - This function provides an alternate interface
56198090Srdivacky/// to the sys::Program::ExecuteAndWait interface.
57193323Sed/// @see sys:Program::ExecuteAndWait
58193323Sedstatic int RunProgramWithTimeout(const sys::Path &ProgramPath,
59193323Sed                                 const char **Args,
60193323Sed                                 const sys::Path &StdInFile,
61193323Sed                                 const sys::Path &StdOutFile,
62193323Sed                                 const sys::Path &StdErrFile,
63193323Sed                                 unsigned NumSeconds = 0,
64193323Sed                                 unsigned MemoryLimit = 0) {
65193323Sed  const sys::Path* redirects[3];
66193323Sed  redirects[0] = &StdInFile;
67193323Sed  redirects[1] = &StdOutFile;
68193323Sed  redirects[2] = &StdErrFile;
69198090Srdivacky
70198090Srdivacky#if 0 // For debug purposes
71198090Srdivacky  {
72198090Srdivacky    errs() << "RUN:";
73193323Sed    for (unsigned i = 0; Args[i]; ++i)
74198090Srdivacky      errs() << " " << Args[i];
75198090Srdivacky    errs() << "\n";
76193323Sed  }
77198090Srdivacky#endif
78193323Sed
79193323Sed  return
80193323Sed    sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
81193323Sed                                 NumSeconds, MemoryLimit);
82193323Sed}
83193323Sed
84198090Srdivacky/// RunProgramRemotelyWithTimeout - This function runs the given program
85198090Srdivacky/// remotely using the given remote client and the sys::Program::ExecuteAndWait.
86198090Srdivacky/// Returns the remote program exit code or reports a remote client error if it
87198090Srdivacky/// fails. Remote client is required to return 255 if it failed or program exit
88198090Srdivacky/// code otherwise.
89198090Srdivacky/// @see sys:Program::ExecuteAndWait
90198090Srdivackystatic int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath,
91198090Srdivacky                                         const char **Args,
92198090Srdivacky                                         const sys::Path &StdInFile,
93198090Srdivacky                                         const sys::Path &StdOutFile,
94198090Srdivacky                                         const sys::Path &StdErrFile,
95198090Srdivacky                                         unsigned NumSeconds = 0,
96198090Srdivacky                                         unsigned MemoryLimit = 0) {
97198090Srdivacky  const sys::Path* redirects[3];
98198090Srdivacky  redirects[0] = &StdInFile;
99198090Srdivacky  redirects[1] = &StdOutFile;
100198090Srdivacky  redirects[2] = &StdErrFile;
101193323Sed
102198090Srdivacky#if 0 // For debug purposes
103198090Srdivacky  {
104198090Srdivacky    errs() << "RUN:";
105198090Srdivacky    for (unsigned i = 0; Args[i]; ++i)
106198090Srdivacky      errs() << " " << Args[i];
107198090Srdivacky    errs() << "\n";
108198090Srdivacky  }
109198090Srdivacky#endif
110193323Sed
111198090Srdivacky  // Run the program remotely with the remote client
112198090Srdivacky  int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args,
113198090Srdivacky                                 0, redirects, NumSeconds, MemoryLimit);
114198090Srdivacky
115198090Srdivacky  // Has the remote client fail?
116198090Srdivacky  if (255 == ReturnCode) {
117198090Srdivacky    std::ostringstream OS;
118198090Srdivacky    OS << "\nError running remote client:\n ";
119198090Srdivacky    for (const char **Arg = Args; *Arg; ++Arg)
120198090Srdivacky      OS << " " << *Arg;
121198090Srdivacky    OS << "\n";
122198090Srdivacky
123198090Srdivacky    // The error message is in the output file, let's print it out from there.
124198090Srdivacky    std::ifstream ErrorFile(StdOutFile.c_str());
125198090Srdivacky    if (ErrorFile) {
126198090Srdivacky      std::copy(std::istreambuf_iterator<char>(ErrorFile),
127198090Srdivacky                std::istreambuf_iterator<char>(),
128198090Srdivacky                std::ostreambuf_iterator<char>(OS));
129198090Srdivacky      ErrorFile.close();
130198090Srdivacky    }
131198090Srdivacky
132198090Srdivacky    throw ToolExecutionError(OS.str());
133198090Srdivacky  }
134198090Srdivacky
135198090Srdivacky  return ReturnCode;
136198090Srdivacky}
137198090Srdivacky
138193323Sedstatic void ProcessFailure(sys::Path ProgPath, const char** Args) {
139193323Sed  std::ostringstream OS;
140193323Sed  OS << "\nError running tool:\n ";
141193323Sed  for (const char **Arg = Args; *Arg; ++Arg)
142193323Sed    OS << " " << *Arg;
143193323Sed  OS << "\n";
144193323Sed
145193323Sed  // Rerun the compiler, capturing any error messages to print them.
146193323Sed  sys::Path ErrorFilename("bugpoint.program_error_messages");
147193323Sed  std::string ErrMsg;
148193323Sed  if (ErrorFilename.makeUnique(true, &ErrMsg)) {
149198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
150193323Sed    exit(1);
151193323Sed  }
152193323Sed  RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
153193323Sed                        ErrorFilename); // FIXME: check return code ?
154193323Sed
155193323Sed  // Print out the error messages generated by GCC if possible...
156193323Sed  std::ifstream ErrorFile(ErrorFilename.c_str());
157193323Sed  if (ErrorFile) {
158193323Sed    std::copy(std::istreambuf_iterator<char>(ErrorFile),
159193323Sed              std::istreambuf_iterator<char>(),
160193323Sed              std::ostreambuf_iterator<char>(OS));
161193323Sed    ErrorFile.close();
162193323Sed  }
163193323Sed
164193323Sed  ErrorFilename.eraseFromDisk();
165193323Sed  throw ToolExecutionError(OS.str());
166193323Sed}
167193323Sed
168193323Sed//===---------------------------------------------------------------------===//
169193323Sed// LLI Implementation of AbstractIntepreter interface
170193323Sed//
171193323Sednamespace {
172193323Sed  class LLI : public AbstractInterpreter {
173193323Sed    std::string LLIPath;          // The path to the LLI executable
174193323Sed    std::vector<std::string> ToolArgs; // Args to pass to LLI
175193323Sed  public:
176193323Sed    LLI(const std::string &Path, const std::vector<std::string> *Args)
177193323Sed      : LLIPath(Path) {
178193323Sed      ToolArgs.clear ();
179193323Sed      if (Args) { ToolArgs = *Args; }
180193323Sed    }
181193323Sed
182193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
183193323Sed                               const std::vector<std::string> &Args,
184193323Sed                               const std::string &InputFile,
185193323Sed                               const std::string &OutputFile,
186193323Sed                               const std::vector<std::string> &GCCArgs,
187193323Sed                               const std::vector<std::string> &SharedLibs =
188193323Sed                               std::vector<std::string>(),
189193323Sed                               unsigned Timeout = 0,
190193323Sed                               unsigned MemoryLimit = 0);
191193323Sed  };
192193323Sed}
193193323Sed
194193323Sedint LLI::ExecuteProgram(const std::string &Bitcode,
195193323Sed                        const std::vector<std::string> &Args,
196193323Sed                        const std::string &InputFile,
197193323Sed                        const std::string &OutputFile,
198193323Sed                        const std::vector<std::string> &GCCArgs,
199193323Sed                        const std::vector<std::string> &SharedLibs,
200193323Sed                        unsigned Timeout,
201193323Sed                        unsigned MemoryLimit) {
202193323Sed  std::vector<const char*> LLIArgs;
203193323Sed  LLIArgs.push_back(LLIPath.c_str());
204193323Sed  LLIArgs.push_back("-force-interpreter=true");
205193323Sed
206199481Srdivacky  for (std::vector<std::string>::const_iterator i = SharedLibs.begin(), e = SharedLibs.end(); i != e; ++i) {
207199481Srdivacky    LLIArgs.push_back("-load");
208199481Srdivacky    LLIArgs.push_back((*i).c_str());
209199481Srdivacky  }
210199481Srdivacky
211193323Sed  // Add any extra LLI args.
212193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
213193323Sed    LLIArgs.push_back(ToolArgs[i].c_str());
214193323Sed
215193323Sed  LLIArgs.push_back(Bitcode.c_str());
216193323Sed  // Add optional parameters to the running program from Argv
217193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
218193323Sed    LLIArgs.push_back(Args[i].c_str());
219193323Sed  LLIArgs.push_back(0);
220193323Sed
221198090Srdivacky  outs() << "<lli>"; outs().flush();
222198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
223193323Sed        for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
224198090Srdivacky          errs() << " " << LLIArgs[i];
225198090Srdivacky        errs() << "\n";
226193323Sed        );
227193323Sed  return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
228193323Sed      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
229193323Sed      Timeout, MemoryLimit);
230193323Sed}
231193323Sed
232193323Sed// LLI create method - Try to find the LLI executable
233198090SrdivackyAbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
234193323Sed                                                    std::string &Message,
235193323Sed                                     const std::vector<std::string> *ToolArgs) {
236198090Srdivacky  std::string LLIPath =
237198090Srdivacky    FindExecutable("lli", Argv0, (void *)(intptr_t)&createLLI).str();
238193323Sed  if (!LLIPath.empty()) {
239193323Sed    Message = "Found lli: " + LLIPath + "\n";
240193323Sed    return new LLI(LLIPath, ToolArgs);
241193323Sed  }
242193323Sed
243193323Sed  Message = "Cannot find `lli' in executable directory or PATH!\n";
244193323Sed  return 0;
245193323Sed}
246193323Sed
247193323Sed//===---------------------------------------------------------------------===//
248193323Sed// Custom execution command implementation of AbstractIntepreter interface
249193323Sed//
250193323Sed// Allows using a custom command for executing the bitcode, thus allows,
251193323Sed// for example, to invoke a cross compiler for code generation followed by
252193323Sed// a simulator that executes the generated binary.
253193323Sednamespace {
254193323Sed  class CustomExecutor : public AbstractInterpreter {
255193323Sed    std::string ExecutionCommand;
256193323Sed    std::vector<std::string> ExecutorArgs;
257193323Sed  public:
258193323Sed    CustomExecutor(
259193323Sed      const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) :
260193323Sed      ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {}
261193323Sed
262193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
263193323Sed                               const std::vector<std::string> &Args,
264193323Sed                               const std::string &InputFile,
265193323Sed                               const std::string &OutputFile,
266193323Sed                               const std::vector<std::string> &GCCArgs,
267193323Sed                               const std::vector<std::string> &SharedLibs =
268193323Sed                               std::vector<std::string>(),
269193323Sed                               unsigned Timeout = 0,
270193323Sed                               unsigned MemoryLimit = 0);
271193323Sed  };
272193323Sed}
273193323Sed
274193323Sedint CustomExecutor::ExecuteProgram(const std::string &Bitcode,
275193323Sed                        const std::vector<std::string> &Args,
276193323Sed                        const std::string &InputFile,
277193323Sed                        const std::string &OutputFile,
278193323Sed                        const std::vector<std::string> &GCCArgs,
279193323Sed                        const std::vector<std::string> &SharedLibs,
280193323Sed                        unsigned Timeout,
281193323Sed                        unsigned MemoryLimit) {
282193323Sed
283193323Sed  std::vector<const char*> ProgramArgs;
284193323Sed  ProgramArgs.push_back(ExecutionCommand.c_str());
285193323Sed
286193323Sed  for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
287193323Sed    ProgramArgs.push_back(ExecutorArgs.at(i).c_str());
288193323Sed  ProgramArgs.push_back(Bitcode.c_str());
289193323Sed  ProgramArgs.push_back(0);
290193323Sed
291193323Sed  // Add optional parameters to the running program from Argv
292193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
293193323Sed    ProgramArgs.push_back(Args[i].c_str());
294193323Sed
295193323Sed  return RunProgramWithTimeout(
296193323Sed    sys::Path(ExecutionCommand),
297193323Sed    &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
298193323Sed    sys::Path(OutputFile), Timeout, MemoryLimit);
299193323Sed}
300193323Sed
301193323Sed// Custom execution environment create method, takes the execution command
302193323Sed// as arguments
303193323SedAbstractInterpreter *AbstractInterpreter::createCustom(
304193323Sed                    std::string &Message,
305193323Sed                    const std::string &ExecCommandLine) {
306193323Sed
307193323Sed  std::string Command = "";
308193323Sed  std::vector<std::string> Args;
309193323Sed  std::string delimiters = " ";
310193323Sed
311193323Sed  // Tokenize the ExecCommandLine to the command and the args to allow
312193323Sed  // defining a full command line as the command instead of just the
313193323Sed  // executed program. We cannot just pass the whole string after the command
314193323Sed  // as a single argument because then program sees only a single
315193323Sed  // command line argument (with spaces in it: "foo bar" instead
316193323Sed  // of "foo" and "bar").
317193323Sed
318193323Sed  // code borrowed from:
319193323Sed  // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
320193323Sed  std::string::size_type lastPos =
321193323Sed    ExecCommandLine.find_first_not_of(delimiters, 0);
322193323Sed  std::string::size_type pos =
323193323Sed    ExecCommandLine.find_first_of(delimiters, lastPos);
324193323Sed
325193323Sed  while (std::string::npos != pos || std::string::npos != lastPos) {
326193323Sed    std::string token = ExecCommandLine.substr(lastPos, pos - lastPos);
327193323Sed    if (Command == "")
328193323Sed       Command = token;
329193323Sed    else
330193323Sed       Args.push_back(token);
331193323Sed    // Skip delimiters.  Note the "not_of"
332193323Sed    lastPos = ExecCommandLine.find_first_not_of(delimiters, pos);
333193323Sed    // Find next "non-delimiter"
334193323Sed    pos = ExecCommandLine.find_first_of(delimiters, lastPos);
335193323Sed  }
336193323Sed
337198090Srdivacky  std::string CmdPath = sys::Program::FindProgramByName(Command).str();
338193323Sed  if (CmdPath.empty()) {
339193323Sed    Message =
340193323Sed      std::string("Cannot find '") + Command +
341193323Sed      "' in executable directory or PATH!\n";
342193323Sed    return 0;
343193323Sed  }
344193323Sed
345193323Sed  Message = "Found command in: " + CmdPath + "\n";
346193323Sed
347193323Sed  return new CustomExecutor(CmdPath, Args);
348193323Sed}
349193323Sed
350193323Sed//===----------------------------------------------------------------------===//
351193323Sed// LLC Implementation of AbstractIntepreter interface
352193323Sed//
353193323SedGCC::FileType LLC::OutputCode(const std::string &Bitcode,
354193323Sed                              sys::Path &OutputAsmFile) {
355193323Sed  sys::Path uniqueFile(Bitcode+".llc.s");
356193323Sed  std::string ErrMsg;
357193323Sed  if (uniqueFile.makeUnique(true, &ErrMsg)) {
358198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
359193323Sed    exit(1);
360193323Sed  }
361193323Sed  OutputAsmFile = uniqueFile;
362193323Sed  std::vector<const char *> LLCArgs;
363193323Sed  LLCArgs.push_back (LLCPath.c_str());
364193323Sed
365193323Sed  // Add any extra LLC args.
366193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
367193323Sed    LLCArgs.push_back(ToolArgs[i].c_str());
368193323Sed
369193323Sed  LLCArgs.push_back ("-o");
370193323Sed  LLCArgs.push_back (OutputAsmFile.c_str()); // Output to the Asm file
371193323Sed  LLCArgs.push_back (Bitcode.c_str());      // This is the input bitcode
372193323Sed  LLCArgs.push_back (0);
373193323Sed
374198090Srdivacky  outs() << "<llc>"; outs().flush();
375198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
376193323Sed        for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
377198090Srdivacky          errs() << " " << LLCArgs[i];
378198090Srdivacky        errs() << "\n";
379193323Sed        );
380193323Sed  if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
381193323Sed                            sys::Path(), sys::Path(), sys::Path()))
382193323Sed    ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
383193323Sed
384193323Sed  return GCC::AsmFile;
385193323Sed}
386193323Sed
387193323Sedvoid LLC::compileProgram(const std::string &Bitcode) {
388193323Sed  sys::Path OutputAsmFile;
389193323Sed  OutputCode(Bitcode, OutputAsmFile);
390193323Sed  OutputAsmFile.eraseFromDisk();
391193323Sed}
392193323Sed
393193323Sedint LLC::ExecuteProgram(const std::string &Bitcode,
394193323Sed                        const std::vector<std::string> &Args,
395193323Sed                        const std::string &InputFile,
396193323Sed                        const std::string &OutputFile,
397193323Sed                        const std::vector<std::string> &ArgsForGCC,
398193323Sed                        const std::vector<std::string> &SharedLibs,
399193323Sed                        unsigned Timeout,
400193323Sed                        unsigned MemoryLimit) {
401193323Sed
402193323Sed  sys::Path OutputAsmFile;
403193323Sed  OutputCode(Bitcode, OutputAsmFile);
404198090Srdivacky  FileRemover OutFileRemover(OutputAsmFile, !SaveTemps);
405193323Sed
406193323Sed  std::vector<std::string> GCCArgs(ArgsForGCC);
407193323Sed  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
408193323Sed  GCCArgs.insert(GCCArgs.end(), gccArgs.begin(), gccArgs.end());
409193323Sed
410193323Sed  // Assuming LLC worked, compile the result with GCC and run it.
411198090Srdivacky  return gcc->ExecuteProgram(OutputAsmFile.str(), Args, GCC::AsmFile,
412193323Sed                             InputFile, OutputFile, GCCArgs,
413193323Sed                             Timeout, MemoryLimit);
414193323Sed}
415193323Sed
416193323Sed/// createLLC - Try to find the LLC executable
417193323Sed///
418198090SrdivackyLLC *AbstractInterpreter::createLLC(const char *Argv0,
419193323Sed                                    std::string &Message,
420193323Sed                                    const std::vector<std::string> *Args,
421193323Sed                                    const std::vector<std::string> *GCCArgs) {
422198090Srdivacky  std::string LLCPath =
423198090Srdivacky    FindExecutable("llc", Argv0, (void *)(intptr_t)&createLLC).str();
424193323Sed  if (LLCPath.empty()) {
425193323Sed    Message = "Cannot find `llc' in executable directory or PATH!\n";
426193323Sed    return 0;
427193323Sed  }
428193323Sed
429193323Sed  Message = "Found llc: " + LLCPath + "\n";
430198090Srdivacky  GCC *gcc = GCC::create(Message, GCCArgs);
431193323Sed  if (!gcc) {
432198090Srdivacky    errs() << Message << "\n";
433193323Sed    exit(1);
434193323Sed  }
435193323Sed  return new LLC(LLCPath, gcc, Args, GCCArgs);
436193323Sed}
437193323Sed
438193323Sed//===---------------------------------------------------------------------===//
439193323Sed// JIT Implementation of AbstractIntepreter interface
440193323Sed//
441193323Sednamespace {
442193323Sed  class JIT : public AbstractInterpreter {
443193323Sed    std::string LLIPath;          // The path to the LLI executable
444193323Sed    std::vector<std::string> ToolArgs; // Args to pass to LLI
445193323Sed  public:
446193323Sed    JIT(const std::string &Path, const std::vector<std::string> *Args)
447193323Sed      : LLIPath(Path) {
448193323Sed      ToolArgs.clear ();
449193323Sed      if (Args) { ToolArgs = *Args; }
450193323Sed    }
451193323Sed
452193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
453193323Sed                               const std::vector<std::string> &Args,
454193323Sed                               const std::string &InputFile,
455193323Sed                               const std::string &OutputFile,
456193323Sed                               const std::vector<std::string> &GCCArgs =
457193323Sed                                 std::vector<std::string>(),
458193323Sed                               const std::vector<std::string> &SharedLibs =
459193323Sed                                 std::vector<std::string>(),
460193323Sed                               unsigned Timeout =0,
461193323Sed                               unsigned MemoryLimit =0);
462193323Sed  };
463193323Sed}
464193323Sed
465193323Sedint JIT::ExecuteProgram(const std::string &Bitcode,
466193323Sed                        const std::vector<std::string> &Args,
467193323Sed                        const std::string &InputFile,
468193323Sed                        const std::string &OutputFile,
469193323Sed                        const std::vector<std::string> &GCCArgs,
470193323Sed                        const std::vector<std::string> &SharedLibs,
471193323Sed                        unsigned Timeout,
472193323Sed                        unsigned MemoryLimit) {
473193323Sed  // Construct a vector of parameters, incorporating those from the command-line
474193323Sed  std::vector<const char*> JITArgs;
475193323Sed  JITArgs.push_back(LLIPath.c_str());
476193323Sed  JITArgs.push_back("-force-interpreter=false");
477193323Sed
478193323Sed  // Add any extra LLI args.
479193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
480193323Sed    JITArgs.push_back(ToolArgs[i].c_str());
481193323Sed
482193323Sed  for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
483193323Sed    JITArgs.push_back("-load");
484193323Sed    JITArgs.push_back(SharedLibs[i].c_str());
485193323Sed  }
486193323Sed  JITArgs.push_back(Bitcode.c_str());
487193323Sed  // Add optional parameters to the running program from Argv
488193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
489193323Sed    JITArgs.push_back(Args[i].c_str());
490193323Sed  JITArgs.push_back(0);
491193323Sed
492198090Srdivacky  outs() << "<jit>"; outs().flush();
493198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
494193323Sed        for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
495198090Srdivacky          errs() << " " << JITArgs[i];
496198090Srdivacky        errs() << "\n";
497193323Sed        );
498198090Srdivacky  DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
499193323Sed  return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
500193323Sed      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
501193323Sed      Timeout, MemoryLimit);
502193323Sed}
503193323Sed
504193323Sed/// createJIT - Try to find the LLI executable
505193323Sed///
506198090SrdivackyAbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
507193323Sed                   std::string &Message, const std::vector<std::string> *Args) {
508198090Srdivacky  std::string LLIPath =
509198090Srdivacky    FindExecutable("lli", Argv0, (void *)(intptr_t)&createJIT).str();
510193323Sed  if (!LLIPath.empty()) {
511193323Sed    Message = "Found lli: " + LLIPath + "\n";
512193323Sed    return new JIT(LLIPath, Args);
513193323Sed  }
514193323Sed
515193323Sed  Message = "Cannot find `lli' in executable directory or PATH!\n";
516193323Sed  return 0;
517193323Sed}
518193323Sed
519193323SedGCC::FileType CBE::OutputCode(const std::string &Bitcode,
520193323Sed                              sys::Path &OutputCFile) {
521193323Sed  sys::Path uniqueFile(Bitcode+".cbe.c");
522193323Sed  std::string ErrMsg;
523193323Sed  if (uniqueFile.makeUnique(true, &ErrMsg)) {
524198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
525193323Sed    exit(1);
526193323Sed  }
527193323Sed  OutputCFile = uniqueFile;
528193323Sed  std::vector<const char *> LLCArgs;
529193323Sed  LLCArgs.push_back (LLCPath.c_str());
530193323Sed
531193323Sed  // Add any extra LLC args.
532193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
533193323Sed    LLCArgs.push_back(ToolArgs[i].c_str());
534193323Sed
535193323Sed  LLCArgs.push_back ("-o");
536193323Sed  LLCArgs.push_back (OutputCFile.c_str());   // Output to the C file
537193323Sed  LLCArgs.push_back ("-march=c");            // Output C language
538193323Sed  LLCArgs.push_back ("-f");                  // Overwrite as necessary...
539193323Sed  LLCArgs.push_back (Bitcode.c_str());      // This is the input bitcode
540193323Sed  LLCArgs.push_back (0);
541193323Sed
542198090Srdivacky  outs() << "<cbe>"; outs().flush();
543198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
544193323Sed        for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
545198090Srdivacky          errs() << " " << LLCArgs[i];
546198090Srdivacky        errs() << "\n";
547193323Sed        );
548193323Sed  if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
549193323Sed                            sys::Path()))
550193323Sed    ProcessFailure(LLCPath, &LLCArgs[0]);
551193323Sed  return GCC::CFile;
552193323Sed}
553193323Sed
554193323Sedvoid CBE::compileProgram(const std::string &Bitcode) {
555193323Sed  sys::Path OutputCFile;
556193323Sed  OutputCode(Bitcode, OutputCFile);
557193323Sed  OutputCFile.eraseFromDisk();
558193323Sed}
559193323Sed
560193323Sedint CBE::ExecuteProgram(const std::string &Bitcode,
561193323Sed                        const std::vector<std::string> &Args,
562193323Sed                        const std::string &InputFile,
563193323Sed                        const std::string &OutputFile,
564193323Sed                        const std::vector<std::string> &ArgsForGCC,
565193323Sed                        const std::vector<std::string> &SharedLibs,
566193323Sed                        unsigned Timeout,
567193323Sed                        unsigned MemoryLimit) {
568193323Sed  sys::Path OutputCFile;
569193323Sed  OutputCode(Bitcode, OutputCFile);
570193323Sed
571198090Srdivacky  FileRemover CFileRemove(OutputCFile, !SaveTemps);
572193323Sed
573193323Sed  std::vector<std::string> GCCArgs(ArgsForGCC);
574193323Sed  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
575193323Sed
576198090Srdivacky  return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile,
577193323Sed                             InputFile, OutputFile, GCCArgs,
578193323Sed                             Timeout, MemoryLimit);
579193323Sed}
580193323Sed
581193323Sed/// createCBE - Try to find the 'llc' executable
582193323Sed///
583198090SrdivackyCBE *AbstractInterpreter::createCBE(const char *Argv0,
584193323Sed                                    std::string &Message,
585193323Sed                                    const std::vector<std::string> *Args,
586193323Sed                                    const std::vector<std::string> *GCCArgs) {
587198090Srdivacky  sys::Path LLCPath =
588198090Srdivacky    FindExecutable("llc", Argv0, (void *)(intptr_t)&createCBE);
589193323Sed  if (LLCPath.isEmpty()) {
590193323Sed    Message =
591193323Sed      "Cannot find `llc' in executable directory or PATH!\n";
592193323Sed    return 0;
593193323Sed  }
594193323Sed
595198090Srdivacky  Message = "Found llc: " + LLCPath.str() + "\n";
596198090Srdivacky  GCC *gcc = GCC::create(Message, GCCArgs);
597193323Sed  if (!gcc) {
598198090Srdivacky    errs() << Message << "\n";
599193323Sed    exit(1);
600193323Sed  }
601193323Sed  return new CBE(LLCPath, gcc, Args);
602193323Sed}
603193323Sed
604193323Sed//===---------------------------------------------------------------------===//
605193323Sed// GCC abstraction
606193323Sed//
607198090Srdivacky
608198090Srdivackystatic bool
609198090SrdivackyIsARMArchitecture(std::vector<std::string> Args)
610198090Srdivacky{
611198090Srdivacky  for (std::vector<std::string>::const_iterator
612198090Srdivacky         I = Args.begin(), E = Args.end(); I != E; ++I) {
613199481Srdivacky    StringRef S(*I);
614199481Srdivacky    if (!S.equals_lower("-arch")) {
615198090Srdivacky      ++I;
616199481Srdivacky      if (I != E && !S.substr(0, strlen("arm")).equals_lower("arm")) {
617198090Srdivacky        return true;
618198090Srdivacky      }
619198090Srdivacky    }
620198090Srdivacky  }
621198090Srdivacky
622198090Srdivacky  return false;
623198090Srdivacky}
624198090Srdivacky
625193323Sedint GCC::ExecuteProgram(const std::string &ProgramFile,
626193323Sed                        const std::vector<std::string> &Args,
627193323Sed                        FileType fileType,
628193323Sed                        const std::string &InputFile,
629193323Sed                        const std::string &OutputFile,
630193323Sed                        const std::vector<std::string> &ArgsForGCC,
631193323Sed                        unsigned Timeout,
632193323Sed                        unsigned MemoryLimit) {
633193323Sed  std::vector<const char*> GCCArgs;
634193323Sed
635193323Sed  GCCArgs.push_back(GCCPath.c_str());
636193323Sed
637193323Sed  for (std::vector<std::string>::const_iterator
638193323Sed         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
639193323Sed    GCCArgs.push_back(I->c_str());
640193323Sed
641193323Sed  // Specify -x explicitly in case the extension is wonky
642193323Sed  GCCArgs.push_back("-x");
643193323Sed  if (fileType == CFile) {
644193323Sed    GCCArgs.push_back("c");
645193323Sed    GCCArgs.push_back("-fno-strict-aliasing");
646193323Sed  } else {
647193323Sed    GCCArgs.push_back("assembler");
648198090Srdivacky
649198090Srdivacky    // For ARM architectures we don't want this flag. bugpoint isn't
650198090Srdivacky    // explicitly told what architecture it is working on, so we get
651198090Srdivacky    // it from gcc flags
652198090Srdivacky    if ((TargetTriple.getOS() == Triple::Darwin) &&
653198090Srdivacky        !IsARMArchitecture(ArgsForGCC))
654198090Srdivacky      GCCArgs.push_back("-force_cpusubtype_ALL");
655193323Sed  }
656193323Sed  GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename...
657193323Sed  GCCArgs.push_back("-x");
658193323Sed  GCCArgs.push_back("none");
659193323Sed  GCCArgs.push_back("-o");
660193323Sed  sys::Path OutputBinary (ProgramFile+".gcc.exe");
661193323Sed  std::string ErrMsg;
662193323Sed  if (OutputBinary.makeUnique(true, &ErrMsg)) {
663198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
664193323Sed    exit(1);
665193323Sed  }
666193323Sed  GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
667193323Sed
668193323Sed  // Add any arguments intended for GCC. We locate them here because this is
669193323Sed  // most likely -L and -l options that need to come before other libraries but
670193323Sed  // after the source. Other options won't be sensitive to placement on the
671193323Sed  // command line, so this should be safe.
672193323Sed  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
673193323Sed    GCCArgs.push_back(ArgsForGCC[i].c_str());
674193323Sed
675193323Sed  GCCArgs.push_back("-lm");                // Hard-code the math library...
676193323Sed  GCCArgs.push_back("-O2");                // Optimize the program a bit...
677193323Sed#if defined (HAVE_LINK_R)
678193323Sed  GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
679193323Sed#endif
680198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
681198090Srdivacky    GCCArgs.push_back("-mcpu=v9");
682193323Sed  GCCArgs.push_back(0);                    // NULL terminator
683193323Sed
684198090Srdivacky  outs() << "<gcc>"; outs().flush();
685198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
686193323Sed        for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
687198090Srdivacky          errs() << " " << GCCArgs[i];
688198090Srdivacky        errs() << "\n";
689193323Sed        );
690193323Sed  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
691193323Sed        sys::Path())) {
692193323Sed    ProcessFailure(GCCPath, &GCCArgs[0]);
693193323Sed    exit(1);
694193323Sed  }
695193323Sed
696193323Sed  std::vector<const char*> ProgramArgs;
697193323Sed
698193323Sed  if (RemoteClientPath.isEmpty())
699193323Sed    ProgramArgs.push_back(OutputBinary.c_str());
700193323Sed  else {
701193323Sed    ProgramArgs.push_back(RemoteClientPath.c_str());
702193323Sed    ProgramArgs.push_back(RemoteHost.c_str());
703198090Srdivacky    if (!RemoteUser.empty()) {
704198090Srdivacky      ProgramArgs.push_back("-l");
705198090Srdivacky      ProgramArgs.push_back(RemoteUser.c_str());
706198090Srdivacky    }
707198090Srdivacky    if (!RemotePort.empty()) {
708198090Srdivacky      ProgramArgs.push_back("-p");
709198090Srdivacky      ProgramArgs.push_back(RemotePort.c_str());
710198090Srdivacky    }
711193323Sed    if (!RemoteExtra.empty()) {
712193323Sed      ProgramArgs.push_back(RemoteExtra.c_str());
713193323Sed    }
714193323Sed
715198090Srdivacky    // Full path to the binary. We need to cd to the exec directory because
716198090Srdivacky    // there is a dylib there that the exec expects to find in the CWD
717193323Sed    char* env_pwd = getenv("PWD");
718193323Sed    std::string Exec = "cd ";
719193323Sed    Exec += env_pwd;
720193323Sed    Exec += "; ./";
721193323Sed    Exec += OutputBinary.c_str();
722193323Sed    ProgramArgs.push_back(Exec.c_str());
723193323Sed  }
724193323Sed
725193323Sed  // Add optional parameters to the running program from Argv
726193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
727193323Sed    ProgramArgs.push_back(Args[i].c_str());
728193323Sed  ProgramArgs.push_back(0);                // NULL terminator
729193323Sed
730193323Sed  // Now that we have a binary, run it!
731198090Srdivacky  outs() << "<program>"; outs().flush();
732198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
733193323Sed        for (unsigned i=0, e = ProgramArgs.size()-1; i != e; ++i)
734198090Srdivacky          errs() << " " << ProgramArgs[i];
735198090Srdivacky        errs() << "\n";
736193323Sed        );
737193323Sed
738198090Srdivacky  FileRemover OutputBinaryRemover(OutputBinary, !SaveTemps);
739193323Sed
740198090Srdivacky  if (RemoteClientPath.isEmpty()) {
741198090Srdivacky    DEBUG(errs() << "<run locally>";);
742193323Sed    return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
743193323Sed        sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
744193323Sed        Timeout, MemoryLimit);
745198090Srdivacky  } else {
746198090Srdivacky    outs() << "<run remotely>"; outs().flush();
747198090Srdivacky    return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
748198090Srdivacky        &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
749198090Srdivacky        sys::Path(OutputFile), Timeout, MemoryLimit);
750198090Srdivacky  }
751193323Sed}
752193323Sed
753193323Sedint GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
754193323Sed                          std::string &OutputFile,
755193323Sed                          const std::vector<std::string> &ArgsForGCC) {
756193323Sed  sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
757193323Sed  std::string ErrMsg;
758193323Sed  if (uniqueFilename.makeUnique(true, &ErrMsg)) {
759198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
760193323Sed    exit(1);
761193323Sed  }
762198090Srdivacky  OutputFile = uniqueFilename.str();
763193323Sed
764193323Sed  std::vector<const char*> GCCArgs;
765193323Sed
766193323Sed  GCCArgs.push_back(GCCPath.c_str());
767193323Sed
768193323Sed  for (std::vector<std::string>::const_iterator
769193323Sed         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
770193323Sed    GCCArgs.push_back(I->c_str());
771193323Sed
772193323Sed  // Compile the C/asm file into a shared object
773193323Sed  GCCArgs.push_back("-x");
774193323Sed  GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
775193323Sed  GCCArgs.push_back("-fno-strict-aliasing");
776193323Sed  GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
777193323Sed  GCCArgs.push_back("-x");
778193323Sed  GCCArgs.push_back("none");
779198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
780198090Srdivacky    GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
781198090Srdivacky  else if (TargetTriple.getOS() == Triple::Darwin) {
782198090Srdivacky    // link all source files into a single module in data segment, rather than
783198090Srdivacky    // generating blocks. dynamic_lookup requires that you set
784198090Srdivacky    // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
785198090Srdivacky    // bugpoint to just pass that in the environment of GCC.
786198090Srdivacky    GCCArgs.push_back("-single_module");
787198090Srdivacky    GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
788198090Srdivacky    GCCArgs.push_back("-undefined");
789198090Srdivacky    GCCArgs.push_back("dynamic_lookup");
790198090Srdivacky  } else
791198090Srdivacky    GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
792193323Sed
793198090Srdivacky  if ((TargetTriple.getArch() == Triple::alpha) ||
794198090Srdivacky      (TargetTriple.getArch() == Triple::x86_64))
795198090Srdivacky    GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
796198090Srdivacky
797198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
798198090Srdivacky    GCCArgs.push_back("-mcpu=v9");
799198090Srdivacky
800193323Sed  GCCArgs.push_back("-o");
801193323Sed  GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
802193323Sed  GCCArgs.push_back("-O2");              // Optimize the program a bit.
803193323Sed
804193323Sed
805193323Sed
806193323Sed  // Add any arguments intended for GCC. We locate them here because this is
807193323Sed  // most likely -L and -l options that need to come before other libraries but
808193323Sed  // after the source. Other options won't be sensitive to placement on the
809193323Sed  // command line, so this should be safe.
810193323Sed  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
811193323Sed    GCCArgs.push_back(ArgsForGCC[i].c_str());
812193323Sed  GCCArgs.push_back(0);                    // NULL terminator
813193323Sed
814193323Sed
815193323Sed
816198090Srdivacky  outs() << "<gcc>"; outs().flush();
817198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
818193323Sed        for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
819198090Srdivacky          errs() << " " << GCCArgs[i];
820198090Srdivacky        errs() << "\n";
821193323Sed        );
822193323Sed  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
823193323Sed                            sys::Path())) {
824193323Sed    ProcessFailure(GCCPath, &GCCArgs[0]);
825193323Sed    return 1;
826193323Sed  }
827193323Sed  return 0;
828193323Sed}
829193323Sed
830193323Sed/// create - Try to find the `gcc' executable
831193323Sed///
832198090SrdivackyGCC *GCC::create(std::string &Message,
833193323Sed                 const std::vector<std::string> *Args) {
834198090Srdivacky  sys::Path GCCPath = sys::Program::FindProgramByName("gcc");
835193323Sed  if (GCCPath.isEmpty()) {
836193323Sed    Message = "Cannot find `gcc' in executable directory or PATH!\n";
837193323Sed    return 0;
838193323Sed  }
839193323Sed
840193323Sed  sys::Path RemoteClientPath;
841193323Sed  if (!RemoteClient.empty())
842198090Srdivacky    RemoteClientPath = sys::Program::FindProgramByName(RemoteClient);
843193323Sed
844198090Srdivacky  Message = "Found gcc: " + GCCPath.str() + "\n";
845193323Sed  return new GCC(GCCPath, RemoteClientPath, Args);
846193323Sed}
847