1 //===-- ToolRunner.cpp ----------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the interfaces described in the ToolRunner.h file.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "toolrunner"
15 #include "ToolRunner.h"
16 #include "llvm/Config/config.h" // for HAVE_LINK_R
17 #include "llvm/System/Program.h"
18 #include "llvm/Support/CommandLine.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/FileUtilities.h"
29 cl::desc("Remote execution (rsh) host"));
33 cl::desc("Remote execution (rsh) user id"));
36 ToolExecutionError::~ToolExecutionError() throw() { }
38 /// RunProgramWithTimeout - This function provides an alternate interface to the
39 /// sys::Program::ExecuteAndWait interface.
40 /// @see sys:Program::ExecuteAndWait
41 static int RunProgramWithTimeout(const sys::Path &ProgramPath,
43 const sys::Path &StdInFile,
44 const sys::Path &StdOutFile,
45 const sys::Path &StdErrFile,
46 unsigned NumSeconds = 0,
47 unsigned MemoryLimit = 0) {
48 const sys::Path* redirects[3];
49 redirects[0] = &StdInFile;
50 redirects[1] = &StdOutFile;
51 redirects[2] = &StdErrFile;
55 for (unsigned i = 0; Args[i]; ++i)
56 std::cerr << " " << Args[i];
61 sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
62 NumSeconds, MemoryLimit);
67 static void ProcessFailure(sys::Path ProgPath, const char** Args) {
68 std::ostringstream OS;
69 OS << "\nError running tool:\n ";
70 for (const char **Arg = Args; *Arg; ++Arg)
74 // Rerun the compiler, capturing any error messages to print them.
75 sys::Path ErrorFilename("error_messages");
77 if (ErrorFilename.makeUnique(true, &ErrMsg)) {
78 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
81 RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
82 ErrorFilename); // FIXME: check return code ?
84 // Print out the error messages generated by GCC if possible...
85 std::ifstream ErrorFile(ErrorFilename.c_str());
87 std::copy(std::istreambuf_iterator<char>(ErrorFile),
88 std::istreambuf_iterator<char>(),
89 std::ostreambuf_iterator<char>(OS));
93 ErrorFilename.eraseFromDisk();
94 throw ToolExecutionError(OS.str());
97 //===---------------------------------------------------------------------===//
98 // LLI Implementation of AbstractIntepreter interface
101 class LLI : public AbstractInterpreter {
102 std::string LLIPath; // The path to the LLI executable
103 std::vector<std::string> ToolArgs; // Args to pass to LLI
105 LLI(const std::string &Path, const std::vector<std::string> *Args)
108 if (Args) { ToolArgs = *Args; }
111 virtual int ExecuteProgram(const std::string &Bytecode,
112 const std::vector<std::string> &Args,
113 const std::string &InputFile,
114 const std::string &OutputFile,
115 const std::vector<std::string> &GCCArgs,
116 const std::vector<std::string> &SharedLibs =
117 std::vector<std::string>(),
118 unsigned Timeout = 0,
119 unsigned MemoryLimit = 0);
123 int LLI::ExecuteProgram(const std::string &Bytecode,
124 const std::vector<std::string> &Args,
125 const std::string &InputFile,
126 const std::string &OutputFile,
127 const std::vector<std::string> &GCCArgs,
128 const std::vector<std::string> &SharedLibs,
130 unsigned MemoryLimit) {
131 if (!SharedLibs.empty())
132 throw ToolExecutionError("LLI currently does not support "
133 "loading shared libraries.");
135 if (!GCCArgs.empty())
136 throw ToolExecutionError("LLI currently does not support "
138 std::vector<const char*> LLIArgs;
139 LLIArgs.push_back(LLIPath.c_str());
140 LLIArgs.push_back("-force-interpreter=true");
142 // Add any extra LLI args.
143 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
144 LLIArgs.push_back(ToolArgs[i].c_str());
146 LLIArgs.push_back(Bytecode.c_str());
147 // Add optional parameters to the running program from Argv
148 for (unsigned i=0, e = Args.size(); i != e; ++i)
149 LLIArgs.push_back(Args[i].c_str());
150 LLIArgs.push_back(0);
152 std::cout << "<lli>" << std::flush;
153 DEBUG(std::cerr << "\nAbout to run:\t";
154 for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
155 std::cerr << " " << LLIArgs[i];
158 return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
159 sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
160 Timeout, MemoryLimit);
163 // LLI create method - Try to find the LLI executable
164 AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath,
165 std::string &Message,
166 const std::vector<std::string> *ToolArgs) {
167 std::string LLIPath = FindExecutable("lli", ProgPath).toString();
168 if (!LLIPath.empty()) {
169 Message = "Found lli: " + LLIPath + "\n";
170 return new LLI(LLIPath, ToolArgs);
173 Message = "Cannot find `lli' in executable directory or PATH!\n";
177 //===----------------------------------------------------------------------===//
178 // LLC Implementation of AbstractIntepreter interface
180 GCC::FileType LLC::OutputCode(const std::string &Bytecode,
181 sys::Path &OutputAsmFile) {
182 sys::Path uniqueFile(Bytecode+".llc.s");
184 if (uniqueFile.makeUnique(true, &ErrMsg)) {
185 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
188 OutputAsmFile = uniqueFile;
189 std::vector<const char *> LLCArgs;
190 LLCArgs.push_back (LLCPath.c_str());
192 // Add any extra LLC args.
193 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
194 LLCArgs.push_back(ToolArgs[i].c_str());
196 LLCArgs.push_back ("-o");
197 LLCArgs.push_back (OutputAsmFile.c_str()); // Output to the Asm file
198 LLCArgs.push_back ("-f"); // Overwrite as necessary...
199 LLCArgs.push_back (Bytecode.c_str()); // This is the input bytecode
200 LLCArgs.push_back (0);
202 std::cout << "<llc>" << std::flush;
203 DEBUG(std::cerr << "\nAbout to run:\t";
204 for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
205 std::cerr << " " << LLCArgs[i];
208 if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
209 sys::Path(), sys::Path(), sys::Path()))
210 ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
215 void LLC::compileProgram(const std::string &Bytecode) {
216 sys::Path OutputAsmFile;
217 OutputCode(Bytecode, OutputAsmFile);
218 OutputAsmFile.eraseFromDisk();
221 int LLC::ExecuteProgram(const std::string &Bytecode,
222 const std::vector<std::string> &Args,
223 const std::string &InputFile,
224 const std::string &OutputFile,
225 const std::vector<std::string> &ArgsForGCC,
226 const std::vector<std::string> &SharedLibs,
228 unsigned MemoryLimit) {
230 sys::Path OutputAsmFile;
231 OutputCode(Bytecode, OutputAsmFile);
232 FileRemover OutFileRemover(OutputAsmFile);
234 std::vector<std::string> GCCArgs(ArgsForGCC);
235 GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
237 // Assuming LLC worked, compile the result with GCC and run it.
238 return gcc->ExecuteProgram(OutputAsmFile.toString(), Args, GCC::AsmFile,
239 InputFile, OutputFile, GCCArgs,
240 Timeout, MemoryLimit);
243 /// createLLC - Try to find the LLC executable
245 LLC *AbstractInterpreter::createLLC(const std::string &ProgramPath,
246 std::string &Message,
247 const std::vector<std::string> *Args) {
248 std::string LLCPath = FindExecutable("llc", ProgramPath).toString();
249 if (LLCPath.empty()) {
250 Message = "Cannot find `llc' in executable directory or PATH!\n";
254 Message = "Found llc: " + LLCPath + "\n";
255 GCC *gcc = GCC::create(ProgramPath, Message);
257 std::cerr << Message << "\n";
260 return new LLC(LLCPath, gcc, Args);
263 //===---------------------------------------------------------------------===//
264 // JIT Implementation of AbstractIntepreter interface
267 class JIT : public AbstractInterpreter {
268 std::string LLIPath; // The path to the LLI executable
269 std::vector<std::string> ToolArgs; // Args to pass to LLI
271 JIT(const std::string &Path, const std::vector<std::string> *Args)
274 if (Args) { ToolArgs = *Args; }
277 virtual int ExecuteProgram(const std::string &Bytecode,
278 const std::vector<std::string> &Args,
279 const std::string &InputFile,
280 const std::string &OutputFile,
281 const std::vector<std::string> &GCCArgs =
282 std::vector<std::string>(),
283 const std::vector<std::string> &SharedLibs =
284 std::vector<std::string>(),
286 unsigned MemoryLimit =0);
290 int JIT::ExecuteProgram(const std::string &Bytecode,
291 const std::vector<std::string> &Args,
292 const std::string &InputFile,
293 const std::string &OutputFile,
294 const std::vector<std::string> &GCCArgs,
295 const std::vector<std::string> &SharedLibs,
297 unsigned MemoryLimit) {
298 if (!GCCArgs.empty())
299 throw ToolExecutionError("JIT does not support GCC Arguments.");
300 // Construct a vector of parameters, incorporating those from the command-line
301 std::vector<const char*> JITArgs;
302 JITArgs.push_back(LLIPath.c_str());
303 JITArgs.push_back("-force-interpreter=false");
305 // Add any extra LLI args.
306 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
307 JITArgs.push_back(ToolArgs[i].c_str());
309 for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
310 JITArgs.push_back("-load");
311 JITArgs.push_back(SharedLibs[i].c_str());
313 JITArgs.push_back(Bytecode.c_str());
314 // Add optional parameters to the running program from Argv
315 for (unsigned i=0, e = Args.size(); i != e; ++i)
316 JITArgs.push_back(Args[i].c_str());
317 JITArgs.push_back(0);
319 std::cout << "<jit>" << std::flush;
320 DEBUG(std::cerr << "\nAbout to run:\t";
321 for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
322 std::cerr << " " << JITArgs[i];
325 DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
326 return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
327 sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
328 Timeout, MemoryLimit);
331 /// createJIT - Try to find the LLI executable
333 AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
334 std::string &Message, const std::vector<std::string> *Args) {
335 std::string LLIPath = FindExecutable("lli", ProgPath).toString();
336 if (!LLIPath.empty()) {
337 Message = "Found lli: " + LLIPath + "\n";
338 return new JIT(LLIPath, Args);
341 Message = "Cannot find `lli' in executable directory or PATH!\n";
345 GCC::FileType CBE::OutputCode(const std::string &Bytecode,
346 sys::Path &OutputCFile) {
347 sys::Path uniqueFile(Bytecode+".cbe.c");
349 if (uniqueFile.makeUnique(true, &ErrMsg)) {
350 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
353 OutputCFile = uniqueFile;
354 std::vector<const char *> LLCArgs;
355 LLCArgs.push_back (LLCPath.c_str());
357 // Add any extra LLC args.
358 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
359 LLCArgs.push_back(ToolArgs[i].c_str());
361 LLCArgs.push_back ("-o");
362 LLCArgs.push_back (OutputCFile.c_str()); // Output to the C file
363 LLCArgs.push_back ("-march=c"); // Output C language
364 LLCArgs.push_back ("-f"); // Overwrite as necessary...
365 LLCArgs.push_back (Bytecode.c_str()); // This is the input bytecode
366 LLCArgs.push_back (0);
368 std::cout << "<cbe>" << std::flush;
369 DEBUG(std::cerr << "\nAbout to run:\t";
370 for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
371 std::cerr << " " << LLCArgs[i];
374 if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
376 ProcessFailure(LLCPath, &LLCArgs[0]);
380 void CBE::compileProgram(const std::string &Bytecode) {
381 sys::Path OutputCFile;
382 OutputCode(Bytecode, OutputCFile);
383 OutputCFile.eraseFromDisk();
386 int CBE::ExecuteProgram(const std::string &Bytecode,
387 const std::vector<std::string> &Args,
388 const std::string &InputFile,
389 const std::string &OutputFile,
390 const std::vector<std::string> &ArgsForGCC,
391 const std::vector<std::string> &SharedLibs,
393 unsigned MemoryLimit) {
394 sys::Path OutputCFile;
395 OutputCode(Bytecode, OutputCFile);
397 FileRemover CFileRemove(OutputCFile);
399 std::vector<std::string> GCCArgs(ArgsForGCC);
400 GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
401 return gcc->ExecuteProgram(OutputCFile.toString(), Args, GCC::CFile,
402 InputFile, OutputFile, GCCArgs,
403 Timeout, MemoryLimit);
406 /// createCBE - Try to find the 'llc' executable
408 CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath,
409 std::string &Message,
410 const std::vector<std::string> *Args) {
411 sys::Path LLCPath = FindExecutable("llc", ProgramPath);
412 if (LLCPath.isEmpty()) {
414 "Cannot find `llc' in executable directory or PATH!\n";
418 Message = "Found llc: " + LLCPath.toString() + "\n";
419 GCC *gcc = GCC::create(ProgramPath, Message);
421 std::cerr << Message << "\n";
424 return new CBE(LLCPath, gcc, Args);
427 //===---------------------------------------------------------------------===//
430 int GCC::ExecuteProgram(const std::string &ProgramFile,
431 const std::vector<std::string> &Args,
433 const std::string &InputFile,
434 const std::string &OutputFile,
435 const std::vector<std::string> &ArgsForGCC,
437 unsigned MemoryLimit) {
438 std::vector<const char*> GCCArgs;
440 GCCArgs.push_back(GCCPath.c_str());
442 // Specify -x explicitly in case the extension is wonky
443 GCCArgs.push_back("-x");
444 if (fileType == CFile) {
445 GCCArgs.push_back("c");
446 GCCArgs.push_back("-fno-strict-aliasing");
448 GCCArgs.push_back("assembler");
450 GCCArgs.push_back("-force_cpusubtype_ALL");
453 GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename...
454 GCCArgs.push_back("-x");
455 GCCArgs.push_back("none");
456 GCCArgs.push_back("-o");
457 sys::Path OutputBinary (ProgramFile+".gcc.exe");
459 if (OutputBinary.makeUnique(true, &ErrMsg)) {
460 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
463 GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
465 // Add any arguments intended for GCC. We locate them here because this is
466 // most likely -L and -l options that need to come before other libraries but
467 // after the source. Other options won't be sensitive to placement on the
468 // command line, so this should be safe.
469 for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
470 GCCArgs.push_back(ArgsForGCC[i].c_str());
472 GCCArgs.push_back("-lm"); // Hard-code the math library...
473 GCCArgs.push_back("-O2"); // Optimize the program a bit...
474 #if defined (HAVE_LINK_R)
475 GCCArgs.push_back("-Wl,-R."); // Search this dir for .so files
478 GCCArgs.push_back("-mcpu=v9");
480 GCCArgs.push_back(0); // NULL terminator
482 std::cout << "<gcc>" << std::flush;
483 DEBUG(std::cerr << "\nAbout to run:\t";
484 for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
485 std::cerr << " " << GCCArgs[i];
488 if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
490 ProcessFailure(GCCPath, &GCCArgs[0]);
494 std::vector<const char*> ProgramArgs;
496 if (RSHPath.isEmpty())
497 ProgramArgs.push_back(OutputBinary.c_str());
499 ProgramArgs.push_back(RSHPath.c_str());
500 ProgramArgs.push_back(RSHHost.c_str());
501 ProgramArgs.push_back("-l");
502 ProgramArgs.push_back(RSHUser.c_str());
504 char* env_pwd = getenv("PWD");
505 std::string Exec = "cd ";
508 Exec += OutputBinary.c_str();
509 ProgramArgs.push_back(Exec.c_str());
512 // Add optional parameters to the running program from Argv
513 for (unsigned i=0, e = Args.size(); i != e; ++i)
514 ProgramArgs.push_back(Args[i].c_str());
515 ProgramArgs.push_back(0); // NULL terminator
517 // Now that we have a binary, run it!
518 std::cout << "<program>" << std::flush;
519 DEBUG(std::cerr << "\nAbout to run:\t";
520 for (unsigned i=0, e = ProgramArgs.size()-1; i != e; ++i)
521 std::cerr << " " << ProgramArgs[i];
525 FileRemover OutputBinaryRemover(OutputBinary);
527 if (RSHPath.isEmpty())
528 return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
529 sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
530 Timeout, MemoryLimit);
532 return RunProgramWithTimeout(sys::Path(RSHPath), &ProgramArgs[0],
533 sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
534 Timeout, MemoryLimit);
537 int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
538 std::string &OutputFile,
539 const std::vector<std::string> &ArgsForGCC) {
540 sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
542 if (uniqueFilename.makeUnique(true, &ErrMsg)) {
543 std::cerr << "Error making unique filename: " << ErrMsg << "\n";
546 OutputFile = uniqueFilename.toString();
548 std::vector<const char*> GCCArgs;
550 GCCArgs.push_back(GCCPath.c_str());
553 // Compile the C/asm file into a shared object
554 GCCArgs.push_back("-x");
555 GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
556 GCCArgs.push_back("-fno-strict-aliasing");
557 GCCArgs.push_back(InputFile.c_str()); // Specify the input filename.
558 GCCArgs.push_back("-x");
559 GCCArgs.push_back("none");
560 #if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
561 GCCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc
562 #elif defined(__APPLE__)
563 // link all source files into a single module in data segment, rather than
564 // generating blocks. dynamic_lookup requires that you set
565 // MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
566 // bugpoint to just pass that in the environment of GCC.
567 GCCArgs.push_back("-single_module");
568 GCCArgs.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC
569 GCCArgs.push_back("-undefined");
570 GCCArgs.push_back("dynamic_lookup");
572 GCCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others
575 #if defined(__ia64__) || defined(__alpha__)
576 GCCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC
579 GCCArgs.push_back("-mcpu=v9");
581 GCCArgs.push_back("-o");
582 GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
583 GCCArgs.push_back("-O2"); // Optimize the program a bit.
587 // Add any arguments intended for GCC. We locate them here because this is
588 // most likely -L and -l options that need to come before other libraries but
589 // after the source. Other options won't be sensitive to placement on the
590 // command line, so this should be safe.
591 for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
592 GCCArgs.push_back(ArgsForGCC[i].c_str());
593 GCCArgs.push_back(0); // NULL terminator
597 std::cout << "<gcc>" << std::flush;
598 DEBUG(std::cerr << "\nAbout to run:\t";
599 for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
600 std::cerr << " " << GCCArgs[i];
603 if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
605 ProcessFailure(GCCPath, &GCCArgs[0]);
611 /// create - Try to find the `gcc' executable
613 GCC *GCC::create(const std::string &ProgramPath, std::string &Message) {
614 sys::Path GCCPath = FindExecutable("gcc", ProgramPath);
615 if (GCCPath.isEmpty()) {
616 Message = "Cannot find `gcc' in executable directory or PATH!\n";
621 if (!RSHHost.empty())
622 RSHPath = FindExecutable("rsh", ProgramPath);
624 Message = "Found gcc: " + GCCPath.toString() + "\n";
625 return new GCC(GCCPath, RSHPath);