ToolRunner.cpp revision 221337
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"
16218885Sdim#include "llvm/Support/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
53198090Srdivacky/// RunProgramWithTimeout - This function provides an alternate interface
54198090Srdivacky/// to the sys::Program::ExecuteAndWait interface.
55207618Srdivacky/// @see sys::Program::ExecuteAndWait
56193323Sedstatic int RunProgramWithTimeout(const sys::Path &ProgramPath,
57193323Sed                                 const char **Args,
58193323Sed                                 const sys::Path &StdInFile,
59193323Sed                                 const sys::Path &StdOutFile,
60193323Sed                                 const sys::Path &StdErrFile,
61193323Sed                                 unsigned NumSeconds = 0,
62218885Sdim                                 unsigned MemoryLimit = 0,
63218885Sdim                                 std::string *ErrMsg = 0) {
64193323Sed  const sys::Path* redirects[3];
65193323Sed  redirects[0] = &StdInFile;
66193323Sed  redirects[1] = &StdOutFile;
67193323Sed  redirects[2] = &StdErrFile;
68198090Srdivacky
69198090Srdivacky#if 0 // For debug purposes
70198090Srdivacky  {
71198090Srdivacky    errs() << "RUN:";
72193323Sed    for (unsigned i = 0; Args[i]; ++i)
73198090Srdivacky      errs() << " " << Args[i];
74198090Srdivacky    errs() << "\n";
75193323Sed  }
76198090Srdivacky#endif
77193323Sed
78193323Sed  return
79193323Sed    sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
80218885Sdim                                 NumSeconds, MemoryLimit, ErrMsg);
81193323Sed}
82193323Sed
83198090Srdivacky/// RunProgramRemotelyWithTimeout - This function runs the given program
84198090Srdivacky/// remotely using the given remote client and the sys::Program::ExecuteAndWait.
85198090Srdivacky/// Returns the remote program exit code or reports a remote client error if it
86198090Srdivacky/// fails. Remote client is required to return 255 if it failed or program exit
87198090Srdivacky/// code otherwise.
88207618Srdivacky/// @see sys::Program::ExecuteAndWait
89198090Srdivackystatic int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath,
90198090Srdivacky                                         const char **Args,
91198090Srdivacky                                         const sys::Path &StdInFile,
92198090Srdivacky                                         const sys::Path &StdOutFile,
93198090Srdivacky                                         const sys::Path &StdErrFile,
94198090Srdivacky                                         unsigned NumSeconds = 0,
95198090Srdivacky                                         unsigned MemoryLimit = 0) {
96198090Srdivacky  const sys::Path* redirects[3];
97198090Srdivacky  redirects[0] = &StdInFile;
98198090Srdivacky  redirects[1] = &StdOutFile;
99198090Srdivacky  redirects[2] = &StdErrFile;
100193323Sed
101198090Srdivacky#if 0 // For debug purposes
102198090Srdivacky  {
103198090Srdivacky    errs() << "RUN:";
104198090Srdivacky    for (unsigned i = 0; Args[i]; ++i)
105198090Srdivacky      errs() << " " << Args[i];
106198090Srdivacky    errs() << "\n";
107198090Srdivacky  }
108198090Srdivacky#endif
109193323Sed
110198090Srdivacky  // Run the program remotely with the remote client
111198090Srdivacky  int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args,
112198090Srdivacky                                 0, redirects, NumSeconds, MemoryLimit);
113198090Srdivacky
114198090Srdivacky  // Has the remote client fail?
115198090Srdivacky  if (255 == ReturnCode) {
116198090Srdivacky    std::ostringstream OS;
117198090Srdivacky    OS << "\nError running remote client:\n ";
118198090Srdivacky    for (const char **Arg = Args; *Arg; ++Arg)
119198090Srdivacky      OS << " " << *Arg;
120198090Srdivacky    OS << "\n";
121198090Srdivacky
122198090Srdivacky    // The error message is in the output file, let's print it out from there.
123198090Srdivacky    std::ifstream ErrorFile(StdOutFile.c_str());
124198090Srdivacky    if (ErrorFile) {
125198090Srdivacky      std::copy(std::istreambuf_iterator<char>(ErrorFile),
126198090Srdivacky                std::istreambuf_iterator<char>(),
127198090Srdivacky                std::ostreambuf_iterator<char>(OS));
128198090Srdivacky      ErrorFile.close();
129198090Srdivacky    }
130198090Srdivacky
131207618Srdivacky    errs() << OS;
132198090Srdivacky  }
133198090Srdivacky
134198090Srdivacky  return ReturnCode;
135198090Srdivacky}
136198090Srdivacky
137208599Srdivackystatic std::string ProcessFailure(sys::Path ProgPath, const char** Args,
138208599Srdivacky                                  unsigned Timeout = 0,
139208599Srdivacky                                  unsigned MemoryLimit = 0) {
140193323Sed  std::ostringstream OS;
141193323Sed  OS << "\nError running tool:\n ";
142193323Sed  for (const char **Arg = Args; *Arg; ++Arg)
143193323Sed    OS << " " << *Arg;
144193323Sed  OS << "\n";
145218885Sdim
146193323Sed  // Rerun the compiler, capturing any error messages to print them.
147193323Sed  sys::Path ErrorFilename("bugpoint.program_error_messages");
148193323Sed  std::string ErrMsg;
149193323Sed  if (ErrorFilename.makeUnique(true, &ErrMsg)) {
150198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
151193323Sed    exit(1);
152193323Sed  }
153193323Sed  RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
154208599Srdivacky                        ErrorFilename, Timeout, MemoryLimit);
155208599Srdivacky  // FIXME: check return code ?
156193323Sed
157193323Sed  // Print out the error messages generated by GCC if possible...
158193323Sed  std::ifstream ErrorFile(ErrorFilename.c_str());
159193323Sed  if (ErrorFile) {
160193323Sed    std::copy(std::istreambuf_iterator<char>(ErrorFile),
161193323Sed              std::istreambuf_iterator<char>(),
162193323Sed              std::ostreambuf_iterator<char>(OS));
163193323Sed    ErrorFile.close();
164193323Sed  }
165193323Sed
166193323Sed  ErrorFilename.eraseFromDisk();
167207618Srdivacky  return OS.str();
168193323Sed}
169193323Sed
170193323Sed//===---------------------------------------------------------------------===//
171193323Sed// LLI Implementation of AbstractIntepreter interface
172193323Sed//
173193323Sednamespace {
174193323Sed  class LLI : public AbstractInterpreter {
175193323Sed    std::string LLIPath;          // The path to the LLI executable
176193323Sed    std::vector<std::string> ToolArgs; // Args to pass to LLI
177193323Sed  public:
178193323Sed    LLI(const std::string &Path, const std::vector<std::string> *Args)
179193323Sed      : LLIPath(Path) {
180193323Sed      ToolArgs.clear ();
181193323Sed      if (Args) { ToolArgs = *Args; }
182193323Sed    }
183193323Sed
184193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
185193323Sed                               const std::vector<std::string> &Args,
186193323Sed                               const std::string &InputFile,
187193323Sed                               const std::string &OutputFile,
188207618Srdivacky                               std::string *Error,
189193323Sed                               const std::vector<std::string> &GCCArgs,
190193323Sed                               const std::vector<std::string> &SharedLibs =
191193323Sed                               std::vector<std::string>(),
192193323Sed                               unsigned Timeout = 0,
193193323Sed                               unsigned MemoryLimit = 0);
194193323Sed  };
195193323Sed}
196193323Sed
197193323Sedint LLI::ExecuteProgram(const std::string &Bitcode,
198193323Sed                        const std::vector<std::string> &Args,
199193323Sed                        const std::string &InputFile,
200193323Sed                        const std::string &OutputFile,
201207618Srdivacky                        std::string *Error,
202193323Sed                        const std::vector<std::string> &GCCArgs,
203193323Sed                        const std::vector<std::string> &SharedLibs,
204193323Sed                        unsigned Timeout,
205193323Sed                        unsigned MemoryLimit) {
206193323Sed  std::vector<const char*> LLIArgs;
207193323Sed  LLIArgs.push_back(LLIPath.c_str());
208193323Sed  LLIArgs.push_back("-force-interpreter=true");
209193323Sed
210218885Sdim  for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
211218885Sdim         e = SharedLibs.end(); i != e; ++i) {
212199481Srdivacky    LLIArgs.push_back("-load");
213199481Srdivacky    LLIArgs.push_back((*i).c_str());
214199481Srdivacky  }
215199481Srdivacky
216193323Sed  // Add any extra LLI args.
217193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
218193323Sed    LLIArgs.push_back(ToolArgs[i].c_str());
219193323Sed
220193323Sed  LLIArgs.push_back(Bitcode.c_str());
221193323Sed  // Add optional parameters to the running program from Argv
222193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
223193323Sed    LLIArgs.push_back(Args[i].c_str());
224193323Sed  LLIArgs.push_back(0);
225193323Sed
226198090Srdivacky  outs() << "<lli>"; outs().flush();
227198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
228193323Sed        for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
229198090Srdivacky          errs() << " " << LLIArgs[i];
230198090Srdivacky        errs() << "\n";
231193323Sed        );
232193323Sed  return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
233193323Sed      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
234218885Sdim      Timeout, MemoryLimit, Error);
235193323Sed}
236193323Sed
237193323Sed// LLI create method - Try to find the LLI executable
238198090SrdivackyAbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
239193323Sed                                                    std::string &Message,
240193323Sed                                     const std::vector<std::string> *ToolArgs) {
241198090Srdivacky  std::string LLIPath =
242218885Sdim    PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI).str();
243193323Sed  if (!LLIPath.empty()) {
244193323Sed    Message = "Found lli: " + LLIPath + "\n";
245193323Sed    return new LLI(LLIPath, ToolArgs);
246193323Sed  }
247193323Sed
248218885Sdim  Message = "Cannot find `lli' in executable directory!\n";
249193323Sed  return 0;
250193323Sed}
251193323Sed
252193323Sed//===---------------------------------------------------------------------===//
253218885Sdim// Custom compiler command implementation of AbstractIntepreter interface
254218885Sdim//
255218885Sdim// Allows using a custom command for compiling the bitcode, thus allows, for
256218885Sdim// example, to compile a bitcode fragment without linking or executing, then
257218885Sdim// using a custom wrapper script to check for compiler errors.
258218885Sdimnamespace {
259218885Sdim  class CustomCompiler : public AbstractInterpreter {
260218885Sdim    std::string CompilerCommand;
261218885Sdim    std::vector<std::string> CompilerArgs;
262218885Sdim  public:
263218885Sdim    CustomCompiler(
264218885Sdim      const std::string &CompilerCmd, std::vector<std::string> CompArgs) :
265218885Sdim      CompilerCommand(CompilerCmd), CompilerArgs(CompArgs) {}
266218885Sdim
267218885Sdim    virtual void compileProgram(const std::string &Bitcode,
268218885Sdim                                std::string *Error,
269218885Sdim                                unsigned Timeout = 0,
270218885Sdim                                unsigned MemoryLimit = 0);
271218885Sdim
272218885Sdim    virtual int ExecuteProgram(const std::string &Bitcode,
273218885Sdim                               const std::vector<std::string> &Args,
274218885Sdim                               const std::string &InputFile,
275218885Sdim                               const std::string &OutputFile,
276218885Sdim                               std::string *Error,
277218885Sdim                               const std::vector<std::string> &GCCArgs =
278218885Sdim                               std::vector<std::string>(),
279218885Sdim                               const std::vector<std::string> &SharedLibs =
280218885Sdim                               std::vector<std::string>(),
281218885Sdim                               unsigned Timeout = 0,
282218885Sdim                               unsigned MemoryLimit = 0) {
283218885Sdim      *Error = "Execution not supported with -compile-custom";
284218885Sdim      return -1;
285218885Sdim    }
286218885Sdim  };
287218885Sdim}
288218885Sdim
289218885Sdimvoid CustomCompiler::compileProgram(const std::string &Bitcode,
290218885Sdim                                    std::string *Error,
291218885Sdim                                    unsigned Timeout,
292218885Sdim                                    unsigned MemoryLimit) {
293218885Sdim
294218885Sdim  std::vector<const char*> ProgramArgs;
295218885Sdim  ProgramArgs.push_back(CompilerCommand.c_str());
296218885Sdim
297218885Sdim  for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
298218885Sdim    ProgramArgs.push_back(CompilerArgs.at(i).c_str());
299218885Sdim  ProgramArgs.push_back(Bitcode.c_str());
300218885Sdim  ProgramArgs.push_back(0);
301218885Sdim
302218885Sdim  // Add optional parameters to the running program from Argv
303218885Sdim  for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
304218885Sdim    ProgramArgs.push_back(CompilerArgs[i].c_str());
305218885Sdim
306218885Sdim  if (RunProgramWithTimeout( sys::Path(CompilerCommand), &ProgramArgs[0],
307218885Sdim                             sys::Path(), sys::Path(), sys::Path(),
308218885Sdim                             Timeout, MemoryLimit, Error))
309218885Sdim    *Error = ProcessFailure(sys::Path(CompilerCommand), &ProgramArgs[0],
310218885Sdim                           Timeout, MemoryLimit);
311218885Sdim}
312218885Sdim
313218885Sdim//===---------------------------------------------------------------------===//
314193323Sed// Custom execution command implementation of AbstractIntepreter interface
315193323Sed//
316193323Sed// Allows using a custom command for executing the bitcode, thus allows,
317218885Sdim// for example, to invoke a cross compiler for code generation followed by
318193323Sed// a simulator that executes the generated binary.
319193323Sednamespace {
320193323Sed  class CustomExecutor : public AbstractInterpreter {
321193323Sed    std::string ExecutionCommand;
322193323Sed    std::vector<std::string> ExecutorArgs;
323193323Sed  public:
324193323Sed    CustomExecutor(
325193323Sed      const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) :
326193323Sed      ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {}
327193323Sed
328193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
329193323Sed                               const std::vector<std::string> &Args,
330193323Sed                               const std::string &InputFile,
331193323Sed                               const std::string &OutputFile,
332207618Srdivacky                               std::string *Error,
333193323Sed                               const std::vector<std::string> &GCCArgs,
334193323Sed                               const std::vector<std::string> &SharedLibs =
335207618Srdivacky                                 std::vector<std::string>(),
336193323Sed                               unsigned Timeout = 0,
337193323Sed                               unsigned MemoryLimit = 0);
338193323Sed  };
339193323Sed}
340193323Sed
341193323Sedint CustomExecutor::ExecuteProgram(const std::string &Bitcode,
342193323Sed                        const std::vector<std::string> &Args,
343193323Sed                        const std::string &InputFile,
344193323Sed                        const std::string &OutputFile,
345207618Srdivacky                        std::string *Error,
346193323Sed                        const std::vector<std::string> &GCCArgs,
347193323Sed                        const std::vector<std::string> &SharedLibs,
348193323Sed                        unsigned Timeout,
349193323Sed                        unsigned MemoryLimit) {
350193323Sed
351193323Sed  std::vector<const char*> ProgramArgs;
352193323Sed  ProgramArgs.push_back(ExecutionCommand.c_str());
353193323Sed
354193323Sed  for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
355193323Sed    ProgramArgs.push_back(ExecutorArgs.at(i).c_str());
356193323Sed  ProgramArgs.push_back(Bitcode.c_str());
357193323Sed  ProgramArgs.push_back(0);
358193323Sed
359193323Sed  // Add optional parameters to the running program from Argv
360207618Srdivacky  for (unsigned i = 0, e = Args.size(); i != e; ++i)
361193323Sed    ProgramArgs.push_back(Args[i].c_str());
362193323Sed
363193323Sed  return RunProgramWithTimeout(
364193323Sed    sys::Path(ExecutionCommand),
365218885Sdim    &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
366218885Sdim    sys::Path(OutputFile), Timeout, MemoryLimit, Error);
367193323Sed}
368193323Sed
369218885Sdim// Tokenize the CommandLine to the command and the args to allow
370218885Sdim// defining a full command line as the command instead of just the
371218885Sdim// executed program. We cannot just pass the whole string after the command
372218885Sdim// as a single argument because then program sees only a single
373218885Sdim// command line argument (with spaces in it: "foo bar" instead
374218885Sdim// of "foo" and "bar").
375218885Sdim//
376218885Sdim// code borrowed from:
377218885Sdim// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
378218885Sdimstatic void lexCommand(std::string &Message, const std::string &CommandLine,
379218885Sdim                       std::string &CmdPath, std::vector<std::string> Args) {
380193323Sed
381193323Sed  std::string Command = "";
382193323Sed  std::string delimiters = " ";
383193323Sed
384218885Sdim  std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
385218885Sdim  std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
386193323Sed
387193323Sed  while (std::string::npos != pos || std::string::npos != lastPos) {
388218885Sdim    std::string token = CommandLine.substr(lastPos, pos - lastPos);
389193323Sed    if (Command == "")
390193323Sed       Command = token;
391193323Sed    else
392193323Sed       Args.push_back(token);
393193323Sed    // Skip delimiters.  Note the "not_of"
394218885Sdim    lastPos = CommandLine.find_first_not_of(delimiters, pos);
395193323Sed    // Find next "non-delimiter"
396218885Sdim    pos = CommandLine.find_first_of(delimiters, lastPos);
397193323Sed  }
398193323Sed
399218885Sdim  CmdPath = sys::Program::FindProgramByName(Command).str();
400193323Sed  if (CmdPath.empty()) {
401218885Sdim    Message =
402218885Sdim      std::string("Cannot find '") + Command +
403218885Sdim      "' in PATH!\n";
404218885Sdim    return;
405193323Sed  }
406193323Sed
407193323Sed  Message = "Found command in: " + CmdPath + "\n";
408218885Sdim}
409193323Sed
410218885Sdim// Custom execution environment create method, takes the execution command
411218885Sdim// as arguments
412218885SdimAbstractInterpreter *AbstractInterpreter::createCustomCompiler(
413218885Sdim                    std::string &Message,
414218885Sdim                    const std::string &CompileCommandLine) {
415218885Sdim
416218885Sdim  std::string CmdPath;
417218885Sdim  std::vector<std::string> Args;
418218885Sdim  lexCommand(Message, CompileCommandLine, CmdPath, Args);
419218885Sdim  if (CmdPath.empty())
420218885Sdim    return 0;
421218885Sdim
422218885Sdim  return new CustomCompiler(CmdPath, Args);
423218885Sdim}
424218885Sdim
425218885Sdim// Custom execution environment create method, takes the execution command
426218885Sdim// as arguments
427218885SdimAbstractInterpreter *AbstractInterpreter::createCustomExecutor(
428218885Sdim                    std::string &Message,
429218885Sdim                    const std::string &ExecCommandLine) {
430218885Sdim
431218885Sdim
432218885Sdim  std::string CmdPath;
433218885Sdim  std::vector<std::string> Args;
434218885Sdim  lexCommand(Message, ExecCommandLine, CmdPath, Args);
435218885Sdim  if (CmdPath.empty())
436218885Sdim    return 0;
437218885Sdim
438193323Sed  return new CustomExecutor(CmdPath, Args);
439193323Sed}
440193323Sed
441193323Sed//===----------------------------------------------------------------------===//
442193323Sed// LLC Implementation of AbstractIntepreter interface
443193323Sed//
444218885SdimGCC::FileType LLC::OutputCode(const std::string &Bitcode,
445208599Srdivacky                              sys::Path &OutputAsmFile, std::string &Error,
446208599Srdivacky                              unsigned Timeout, unsigned MemoryLimit) {
447205218Srdivacky  const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
448205218Srdivacky  sys::Path uniqueFile(Bitcode + Suffix);
449193323Sed  std::string ErrMsg;
450193323Sed  if (uniqueFile.makeUnique(true, &ErrMsg)) {
451198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
452193323Sed    exit(1);
453193323Sed  }
454193323Sed  OutputAsmFile = uniqueFile;
455193323Sed  std::vector<const char *> LLCArgs;
456205218Srdivacky  LLCArgs.push_back(LLCPath.c_str());
457193323Sed
458193323Sed  // Add any extra LLC args.
459193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
460193323Sed    LLCArgs.push_back(ToolArgs[i].c_str());
461193323Sed
462205218Srdivacky  LLCArgs.push_back("-o");
463205218Srdivacky  LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
464205218Srdivacky  LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
465218885Sdim
466205218Srdivacky  if (UseIntegratedAssembler)
467205218Srdivacky    LLCArgs.push_back("-filetype=obj");
468218885Sdim
469193323Sed  LLCArgs.push_back (0);
470193323Sed
471205218Srdivacky  outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
472205218Srdivacky  outs().flush();
473198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
474207618Srdivacky        for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
475198090Srdivacky          errs() << " " << LLCArgs[i];
476198090Srdivacky        errs() << "\n";
477193323Sed        );
478193323Sed  if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
479208599Srdivacky                            sys::Path(), sys::Path(), sys::Path(),
480208599Srdivacky                            Timeout, MemoryLimit))
481208599Srdivacky    Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0],
482208599Srdivacky                           Timeout, MemoryLimit);
483218885Sdim  return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
484193323Sed}
485193323Sed
486208599Srdivackyvoid LLC::compileProgram(const std::string &Bitcode, std::string *Error,
487208599Srdivacky                         unsigned Timeout, unsigned MemoryLimit) {
488193323Sed  sys::Path OutputAsmFile;
489208599Srdivacky  OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit);
490193323Sed  OutputAsmFile.eraseFromDisk();
491193323Sed}
492193323Sed
493193323Sedint LLC::ExecuteProgram(const std::string &Bitcode,
494193323Sed                        const std::vector<std::string> &Args,
495193323Sed                        const std::string &InputFile,
496193323Sed                        const std::string &OutputFile,
497207618Srdivacky                        std::string *Error,
498193323Sed                        const std::vector<std::string> &ArgsForGCC,
499193323Sed                        const std::vector<std::string> &SharedLibs,
500193323Sed                        unsigned Timeout,
501193323Sed                        unsigned MemoryLimit) {
502193323Sed
503193323Sed  sys::Path OutputAsmFile;
504208599Srdivacky  GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout,
505208599Srdivacky                                      MemoryLimit);
506221337Sdim  FileRemover OutFileRemover(OutputAsmFile.str(), !SaveTemps);
507193323Sed
508193323Sed  std::vector<std::string> GCCArgs(ArgsForGCC);
509193323Sed  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
510193323Sed
511193323Sed  // Assuming LLC worked, compile the result with GCC and run it.
512205218Srdivacky  return gcc->ExecuteProgram(OutputAsmFile.str(), Args, FileKind,
513207618Srdivacky                             InputFile, OutputFile, Error, GCCArgs,
514193323Sed                             Timeout, MemoryLimit);
515193323Sed}
516193323Sed
517193323Sed/// createLLC - Try to find the LLC executable
518193323Sed///
519198090SrdivackyLLC *AbstractInterpreter::createLLC(const char *Argv0,
520193323Sed                                    std::string &Message,
521208599Srdivacky                                    const std::string &GCCBinary,
522193323Sed                                    const std::vector<std::string> *Args,
523205218Srdivacky                                    const std::vector<std::string> *GCCArgs,
524205218Srdivacky                                    bool UseIntegratedAssembler) {
525198090Srdivacky  std::string LLCPath =
526218885Sdim    PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC).str();
527193323Sed  if (LLCPath.empty()) {
528218885Sdim    Message = "Cannot find `llc' in executable directory!\n";
529193323Sed    return 0;
530193323Sed  }
531193323Sed
532193323Sed  Message = "Found llc: " + LLCPath + "\n";
533208599Srdivacky  GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
534193323Sed  if (!gcc) {
535198090Srdivacky    errs() << Message << "\n";
536193323Sed    exit(1);
537193323Sed  }
538208599Srdivacky  return new LLC(LLCPath, gcc, Args, UseIntegratedAssembler);
539193323Sed}
540193323Sed
541193323Sed//===---------------------------------------------------------------------===//
542193323Sed// JIT Implementation of AbstractIntepreter interface
543193323Sed//
544193323Sednamespace {
545193323Sed  class JIT : public AbstractInterpreter {
546193323Sed    std::string LLIPath;          // The path to the LLI executable
547193323Sed    std::vector<std::string> ToolArgs; // Args to pass to LLI
548193323Sed  public:
549193323Sed    JIT(const std::string &Path, const std::vector<std::string> *Args)
550193323Sed      : LLIPath(Path) {
551193323Sed      ToolArgs.clear ();
552193323Sed      if (Args) { ToolArgs = *Args; }
553193323Sed    }
554193323Sed
555193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
556193323Sed                               const std::vector<std::string> &Args,
557193323Sed                               const std::string &InputFile,
558193323Sed                               const std::string &OutputFile,
559207618Srdivacky                               std::string *Error,
560193323Sed                               const std::vector<std::string> &GCCArgs =
561193323Sed                                 std::vector<std::string>(),
562193323Sed                               const std::vector<std::string> &SharedLibs =
563218885Sdim                                 std::vector<std::string>(),
564207618Srdivacky                               unsigned Timeout = 0,
565207618Srdivacky                               unsigned MemoryLimit = 0);
566193323Sed  };
567193323Sed}
568193323Sed
569193323Sedint JIT::ExecuteProgram(const std::string &Bitcode,
570193323Sed                        const std::vector<std::string> &Args,
571193323Sed                        const std::string &InputFile,
572193323Sed                        const std::string &OutputFile,
573207618Srdivacky                        std::string *Error,
574193323Sed                        const std::vector<std::string> &GCCArgs,
575193323Sed                        const std::vector<std::string> &SharedLibs,
576193323Sed                        unsigned Timeout,
577193323Sed                        unsigned MemoryLimit) {
578193323Sed  // Construct a vector of parameters, incorporating those from the command-line
579193323Sed  std::vector<const char*> JITArgs;
580193323Sed  JITArgs.push_back(LLIPath.c_str());
581193323Sed  JITArgs.push_back("-force-interpreter=false");
582193323Sed
583193323Sed  // Add any extra LLI args.
584193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
585193323Sed    JITArgs.push_back(ToolArgs[i].c_str());
586193323Sed
587193323Sed  for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
588193323Sed    JITArgs.push_back("-load");
589193323Sed    JITArgs.push_back(SharedLibs[i].c_str());
590193323Sed  }
591193323Sed  JITArgs.push_back(Bitcode.c_str());
592193323Sed  // Add optional parameters to the running program from Argv
593193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
594193323Sed    JITArgs.push_back(Args[i].c_str());
595193323Sed  JITArgs.push_back(0);
596193323Sed
597198090Srdivacky  outs() << "<jit>"; outs().flush();
598198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
599193323Sed        for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
600198090Srdivacky          errs() << " " << JITArgs[i];
601198090Srdivacky        errs() << "\n";
602193323Sed        );
603198090Srdivacky  DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
604193323Sed  return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
605193323Sed      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
606218885Sdim      Timeout, MemoryLimit, Error);
607193323Sed}
608193323Sed
609193323Sed/// createJIT - Try to find the LLI executable
610193323Sed///
611198090SrdivackyAbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
612193323Sed                   std::string &Message, const std::vector<std::string> *Args) {
613198090Srdivacky  std::string LLIPath =
614218885Sdim    PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT).str();
615193323Sed  if (!LLIPath.empty()) {
616193323Sed    Message = "Found lli: " + LLIPath + "\n";
617193323Sed    return new JIT(LLIPath, Args);
618193323Sed  }
619193323Sed
620218885Sdim  Message = "Cannot find `lli' in executable directory!\n";
621193323Sed  return 0;
622193323Sed}
623193323Sed
624193323SedGCC::FileType CBE::OutputCode(const std::string &Bitcode,
625208599Srdivacky                              sys::Path &OutputCFile, std::string &Error,
626208599Srdivacky                              unsigned Timeout, unsigned MemoryLimit) {
627193323Sed  sys::Path uniqueFile(Bitcode+".cbe.c");
628193323Sed  std::string ErrMsg;
629193323Sed  if (uniqueFile.makeUnique(true, &ErrMsg)) {
630198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
631193323Sed    exit(1);
632193323Sed  }
633193323Sed  OutputCFile = uniqueFile;
634193323Sed  std::vector<const char *> LLCArgs;
635207618Srdivacky  LLCArgs.push_back(LLCPath.c_str());
636193323Sed
637193323Sed  // Add any extra LLC args.
638193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
639193323Sed    LLCArgs.push_back(ToolArgs[i].c_str());
640193323Sed
641207618Srdivacky  LLCArgs.push_back("-o");
642207618Srdivacky  LLCArgs.push_back(OutputCFile.c_str());   // Output to the C file
643207618Srdivacky  LLCArgs.push_back("-march=c");            // Output C language
644207618Srdivacky  LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
645207618Srdivacky  LLCArgs.push_back(0);
646193323Sed
647198090Srdivacky  outs() << "<cbe>"; outs().flush();
648198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
649207618Srdivacky        for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
650198090Srdivacky          errs() << " " << LLCArgs[i];
651198090Srdivacky        errs() << "\n";
652193323Sed        );
653193323Sed  if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
654208599Srdivacky                            sys::Path(), Timeout, MemoryLimit))
655208599Srdivacky    Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit);
656193323Sed  return GCC::CFile;
657193323Sed}
658193323Sed
659208599Srdivackyvoid CBE::compileProgram(const std::string &Bitcode, std::string *Error,
660208599Srdivacky                         unsigned Timeout, unsigned MemoryLimit) {
661193323Sed  sys::Path OutputCFile;
662208599Srdivacky  OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
663193323Sed  OutputCFile.eraseFromDisk();
664193323Sed}
665193323Sed
666193323Sedint CBE::ExecuteProgram(const std::string &Bitcode,
667193323Sed                        const std::vector<std::string> &Args,
668193323Sed                        const std::string &InputFile,
669193323Sed                        const std::string &OutputFile,
670207618Srdivacky                        std::string *Error,
671193323Sed                        const std::vector<std::string> &ArgsForGCC,
672193323Sed                        const std::vector<std::string> &SharedLibs,
673193323Sed                        unsigned Timeout,
674193323Sed                        unsigned MemoryLimit) {
675193323Sed  sys::Path OutputCFile;
676208599Srdivacky  OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
677193323Sed
678221337Sdim  FileRemover CFileRemove(OutputCFile.str(), !SaveTemps);
679193323Sed
680193323Sed  std::vector<std::string> GCCArgs(ArgsForGCC);
681193323Sed  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
682193323Sed
683198090Srdivacky  return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile,
684207618Srdivacky                             InputFile, OutputFile, Error, GCCArgs,
685193323Sed                             Timeout, MemoryLimit);
686193323Sed}
687193323Sed
688193323Sed/// createCBE - Try to find the 'llc' executable
689193323Sed///
690198090SrdivackyCBE *AbstractInterpreter::createCBE(const char *Argv0,
691193323Sed                                    std::string &Message,
692218885Sdim                                    const std::string &GCCBinary,
693193323Sed                                    const std::vector<std::string> *Args,
694193323Sed                                    const std::vector<std::string> *GCCArgs) {
695198090Srdivacky  sys::Path LLCPath =
696218885Sdim    PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE);
697193323Sed  if (LLCPath.isEmpty()) {
698193323Sed    Message =
699218885Sdim      "Cannot find `llc' in executable directory!\n";
700193323Sed    return 0;
701193323Sed  }
702193323Sed
703198090Srdivacky  Message = "Found llc: " + LLCPath.str() + "\n";
704208599Srdivacky  GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
705193323Sed  if (!gcc) {
706198090Srdivacky    errs() << Message << "\n";
707193323Sed    exit(1);
708193323Sed  }
709193323Sed  return new CBE(LLCPath, gcc, Args);
710193323Sed}
711193323Sed
712193323Sed//===---------------------------------------------------------------------===//
713193323Sed// GCC abstraction
714193323Sed//
715198090Srdivacky
716212793Sdimstatic bool IsARMArchitecture(std::vector<const char*> Args) {
717212793Sdim  for (std::vector<const char*>::const_iterator
718198090Srdivacky         I = Args.begin(), E = Args.end(); I != E; ++I) {
719208599Srdivacky    if (StringRef(*I).equals_lower("-arch")) {
720198090Srdivacky      ++I;
721208599Srdivacky      if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm"))
722198090Srdivacky        return true;
723198090Srdivacky    }
724198090Srdivacky  }
725198090Srdivacky
726198090Srdivacky  return false;
727198090Srdivacky}
728198090Srdivacky
729193323Sedint GCC::ExecuteProgram(const std::string &ProgramFile,
730193323Sed                        const std::vector<std::string> &Args,
731193323Sed                        FileType fileType,
732193323Sed                        const std::string &InputFile,
733193323Sed                        const std::string &OutputFile,
734207618Srdivacky                        std::string *Error,
735193323Sed                        const std::vector<std::string> &ArgsForGCC,
736193323Sed                        unsigned Timeout,
737193323Sed                        unsigned MemoryLimit) {
738193323Sed  std::vector<const char*> GCCArgs;
739193323Sed
740193323Sed  GCCArgs.push_back(GCCPath.c_str());
741193323Sed
742205218Srdivacky  if (TargetTriple.getArch() == Triple::x86)
743205218Srdivacky    GCCArgs.push_back("-m32");
744205218Srdivacky
745193323Sed  for (std::vector<std::string>::const_iterator
746193323Sed         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
747193323Sed    GCCArgs.push_back(I->c_str());
748193323Sed
749193323Sed  // Specify -x explicitly in case the extension is wonky
750205218Srdivacky  if (fileType != ObjectFile) {
751205218Srdivacky    GCCArgs.push_back("-x");
752205218Srdivacky    if (fileType == CFile) {
753205218Srdivacky      GCCArgs.push_back("c");
754205218Srdivacky      GCCArgs.push_back("-fno-strict-aliasing");
755205218Srdivacky    } else {
756205218Srdivacky      GCCArgs.push_back("assembler");
757198090Srdivacky
758205218Srdivacky      // For ARM architectures we don't want this flag. bugpoint isn't
759205218Srdivacky      // explicitly told what architecture it is working on, so we get
760205218Srdivacky      // it from gcc flags
761221337Sdim      if (TargetTriple.isOSDarwin() && !IsARMArchitecture(GCCArgs))
762205218Srdivacky        GCCArgs.push_back("-force_cpusubtype_ALL");
763205218Srdivacky    }
764193323Sed  }
765218885Sdim
766205218Srdivacky  GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename.
767218885Sdim
768193323Sed  GCCArgs.push_back("-x");
769193323Sed  GCCArgs.push_back("none");
770193323Sed  GCCArgs.push_back("-o");
771193323Sed  sys::Path OutputBinary (ProgramFile+".gcc.exe");
772193323Sed  std::string ErrMsg;
773193323Sed  if (OutputBinary.makeUnique(true, &ErrMsg)) {
774198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
775193323Sed    exit(1);
776193323Sed  }
777193323Sed  GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
778193323Sed
779193323Sed  // Add any arguments intended for GCC. We locate them here because this is
780193323Sed  // most likely -L and -l options that need to come before other libraries but
781193323Sed  // after the source. Other options won't be sensitive to placement on the
782193323Sed  // command line, so this should be safe.
783193323Sed  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
784193323Sed    GCCArgs.push_back(ArgsForGCC[i].c_str());
785193323Sed
786193323Sed  GCCArgs.push_back("-lm");                // Hard-code the math library...
787193323Sed  GCCArgs.push_back("-O2");                // Optimize the program a bit...
788193323Sed#if defined (HAVE_LINK_R)
789193323Sed  GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
790193323Sed#endif
791198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
792198090Srdivacky    GCCArgs.push_back("-mcpu=v9");
793193323Sed  GCCArgs.push_back(0);                    // NULL terminator
794193323Sed
795198090Srdivacky  outs() << "<gcc>"; outs().flush();
796198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
797207618Srdivacky        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
798198090Srdivacky          errs() << " " << GCCArgs[i];
799198090Srdivacky        errs() << "\n";
800193323Sed        );
801193323Sed  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
802193323Sed        sys::Path())) {
803207618Srdivacky    *Error = ProcessFailure(GCCPath, &GCCArgs[0]);
804207618Srdivacky    return -1;
805193323Sed  }
806193323Sed
807193323Sed  std::vector<const char*> ProgramArgs;
808193323Sed
809212793Sdim  // Declared here so that the destructor only runs after
810212793Sdim  // ProgramArgs is used.
811212793Sdim  std::string Exec;
812212793Sdim
813193323Sed  if (RemoteClientPath.isEmpty())
814193323Sed    ProgramArgs.push_back(OutputBinary.c_str());
815193323Sed  else {
816193323Sed    ProgramArgs.push_back(RemoteClientPath.c_str());
817193323Sed    ProgramArgs.push_back(RemoteHost.c_str());
818198090Srdivacky    if (!RemoteUser.empty()) {
819198090Srdivacky      ProgramArgs.push_back("-l");
820198090Srdivacky      ProgramArgs.push_back(RemoteUser.c_str());
821198090Srdivacky    }
822198090Srdivacky    if (!RemotePort.empty()) {
823198090Srdivacky      ProgramArgs.push_back("-p");
824198090Srdivacky      ProgramArgs.push_back(RemotePort.c_str());
825198090Srdivacky    }
826193323Sed    if (!RemoteExtra.empty()) {
827193323Sed      ProgramArgs.push_back(RemoteExtra.c_str());
828193323Sed    }
829193323Sed
830198090Srdivacky    // Full path to the binary. We need to cd to the exec directory because
831198090Srdivacky    // there is a dylib there that the exec expects to find in the CWD
832193323Sed    char* env_pwd = getenv("PWD");
833212793Sdim    Exec = "cd ";
834193323Sed    Exec += env_pwd;
835193323Sed    Exec += "; ./";
836193323Sed    Exec += OutputBinary.c_str();
837193323Sed    ProgramArgs.push_back(Exec.c_str());
838193323Sed  }
839193323Sed
840193323Sed  // Add optional parameters to the running program from Argv
841207618Srdivacky  for (unsigned i = 0, e = Args.size(); i != e; ++i)
842193323Sed    ProgramArgs.push_back(Args[i].c_str());
843193323Sed  ProgramArgs.push_back(0);                // NULL terminator
844193323Sed
845193323Sed  // Now that we have a binary, run it!
846198090Srdivacky  outs() << "<program>"; outs().flush();
847198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
848207618Srdivacky        for (unsigned i = 0, e = ProgramArgs.size()-1; i != e; ++i)
849198090Srdivacky          errs() << " " << ProgramArgs[i];
850198090Srdivacky        errs() << "\n";
851193323Sed        );
852193323Sed
853221337Sdim  FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps);
854193323Sed
855198090Srdivacky  if (RemoteClientPath.isEmpty()) {
856207618Srdivacky    DEBUG(errs() << "<run locally>");
857193323Sed    return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
858193323Sed        sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
859218885Sdim        Timeout, MemoryLimit, Error);
860198090Srdivacky  } else {
861198090Srdivacky    outs() << "<run remotely>"; outs().flush();
862198090Srdivacky    return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
863198090Srdivacky        &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
864198090Srdivacky        sys::Path(OutputFile), Timeout, MemoryLimit);
865198090Srdivacky  }
866193323Sed}
867193323Sed
868193323Sedint GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
869193323Sed                          std::string &OutputFile,
870207618Srdivacky                          const std::vector<std::string> &ArgsForGCC,
871207618Srdivacky                          std::string &Error) {
872193323Sed  sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
873193323Sed  std::string ErrMsg;
874193323Sed  if (uniqueFilename.makeUnique(true, &ErrMsg)) {
875198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
876193323Sed    exit(1);
877193323Sed  }
878198090Srdivacky  OutputFile = uniqueFilename.str();
879193323Sed
880193323Sed  std::vector<const char*> GCCArgs;
881218885Sdim
882193323Sed  GCCArgs.push_back(GCCPath.c_str());
883193323Sed
884205218Srdivacky  if (TargetTriple.getArch() == Triple::x86)
885205218Srdivacky    GCCArgs.push_back("-m32");
886205218Srdivacky
887193323Sed  for (std::vector<std::string>::const_iterator
888193323Sed         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
889193323Sed    GCCArgs.push_back(I->c_str());
890193323Sed
891193323Sed  // Compile the C/asm file into a shared object
892205218Srdivacky  if (fileType != ObjectFile) {
893205218Srdivacky    GCCArgs.push_back("-x");
894205218Srdivacky    GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
895205218Srdivacky  }
896193323Sed  GCCArgs.push_back("-fno-strict-aliasing");
897193323Sed  GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
898193323Sed  GCCArgs.push_back("-x");
899193323Sed  GCCArgs.push_back("none");
900198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
901198090Srdivacky    GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
902221337Sdim  else if (TargetTriple.isOSDarwin()) {
903198090Srdivacky    // link all source files into a single module in data segment, rather than
904218885Sdim    // generating blocks. dynamic_lookup requires that you set
905198090Srdivacky    // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
906198090Srdivacky    // bugpoint to just pass that in the environment of GCC.
907198090Srdivacky    GCCArgs.push_back("-single_module");
908198090Srdivacky    GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
909198090Srdivacky    GCCArgs.push_back("-undefined");
910198090Srdivacky    GCCArgs.push_back("dynamic_lookup");
911198090Srdivacky  } else
912198090Srdivacky    GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
913193323Sed
914198090Srdivacky  if ((TargetTriple.getArch() == Triple::alpha) ||
915198090Srdivacky      (TargetTriple.getArch() == Triple::x86_64))
916198090Srdivacky    GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
917198090Srdivacky
918198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
919198090Srdivacky    GCCArgs.push_back("-mcpu=v9");
920198090Srdivacky
921193323Sed  GCCArgs.push_back("-o");
922193323Sed  GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
923193323Sed  GCCArgs.push_back("-O2");              // Optimize the program a bit.
924193323Sed
925218885Sdim
926218885Sdim
927193323Sed  // Add any arguments intended for GCC. We locate them here because this is
928193323Sed  // most likely -L and -l options that need to come before other libraries but
929193323Sed  // after the source. Other options won't be sensitive to placement on the
930193323Sed  // command line, so this should be safe.
931193323Sed  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
932193323Sed    GCCArgs.push_back(ArgsForGCC[i].c_str());
933193323Sed  GCCArgs.push_back(0);                    // NULL terminator
934193323Sed
935193323Sed
936218885Sdim
937198090Srdivacky  outs() << "<gcc>"; outs().flush();
938198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
939207618Srdivacky        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
940198090Srdivacky          errs() << " " << GCCArgs[i];
941198090Srdivacky        errs() << "\n";
942193323Sed        );
943193323Sed  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
944193323Sed                            sys::Path())) {
945207618Srdivacky    Error = ProcessFailure(GCCPath, &GCCArgs[0]);
946193323Sed    return 1;
947193323Sed  }
948193323Sed  return 0;
949193323Sed}
950193323Sed
951193323Sed/// create - Try to find the `gcc' executable
952193323Sed///
953198090SrdivackyGCC *GCC::create(std::string &Message,
954208599Srdivacky                 const std::string &GCCBinary,
955193323Sed                 const std::vector<std::string> *Args) {
956208599Srdivacky  sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary);
957193323Sed  if (GCCPath.isEmpty()) {
958218885Sdim    Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
959193323Sed    return 0;
960193323Sed  }
961193323Sed
962193323Sed  sys::Path RemoteClientPath;
963193323Sed  if (!RemoteClient.empty())
964198090Srdivacky    RemoteClientPath = sys::Program::FindProgramByName(RemoteClient);
965193323Sed
966198090Srdivacky  Message = "Found gcc: " + GCCPath.str() + "\n";
967193323Sed  return new GCC(GCCPath, RemoteClientPath, Args);
968193323Sed}
969