A bit more debugging printf's.
[oota-llvm.git] / tools / bugpoint / ToolRunner.cpp
1 //===-- ToolRunner.cpp ----------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
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.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the interfaces described in the ToolRunner.h file.
11 //
12 //===----------------------------------------------------------------------===//
13
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/Debug.h"
19 #include "llvm/Support/FileUtilities.h"
20 #include <fstream>
21 #include <sstream>
22 #include <iostream>
23 using namespace llvm;
24
25 ToolExecutionError::~ToolExecutionError() throw() { }
26
27 /// RunProgramWithTimeout - This function provides an alternate interface to the
28 /// sys::Program::ExecuteAndWait interface.
29 /// @see sys:Program::ExecuteAndWait
30 static int RunProgramWithTimeout(const sys::Path &ProgramPath,
31                                  const char **Args,
32                                  const sys::Path &StdInFile,
33                                  const sys::Path &StdOutFile,
34                                  const sys::Path &StdErrFile,
35                                  unsigned NumSeconds = 0) {
36   const sys::Path* redirects[3];
37   redirects[0] = &StdInFile;
38   redirects[1] = &StdOutFile;
39   redirects[2] = &StdErrFile;
40                                    
41   if (0) {
42     std::cerr << "RUN:";
43     for (unsigned i = 0; Args[i]; ++i)
44       std::cerr << " " << Args[i];
45     std::cerr << "\n";
46   }
47
48   return
49     sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, NumSeconds);
50 }
51
52
53
54 static void ProcessFailure(sys::Path ProgPath, const char** Args) {
55   std::ostringstream OS;
56   OS << "\nError running tool:\n ";
57   for (const char **Arg = Args; *Arg; ++Arg)
58     OS << " " << *Arg;
59   OS << "\n";
60
61   // Rerun the compiler, capturing any error messages to print them.
62   sys::Path ErrorFilename("error_messages");
63   std::string ErrMsg;
64   if (ErrorFilename.makeUnique(true, &ErrMsg)) {
65     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
66     exit(1);
67   }
68   RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
69                         ErrorFilename); // FIXME: check return code ?
70
71   // Print out the error messages generated by GCC if possible...
72   std::ifstream ErrorFile(ErrorFilename.c_str());
73   if (ErrorFile) {
74     std::copy(std::istreambuf_iterator<char>(ErrorFile),
75               std::istreambuf_iterator<char>(),
76               std::ostreambuf_iterator<char>(OS));
77     ErrorFile.close();
78   }
79
80   ErrorFilename.eraseFromDisk();
81   throw ToolExecutionError(OS.str());
82 }
83
84 //===---------------------------------------------------------------------===//
85 // LLI Implementation of AbstractIntepreter interface
86 //
87 namespace {
88   class LLI : public AbstractInterpreter {
89     std::string LLIPath;          // The path to the LLI executable
90     std::vector<std::string> ToolArgs; // Args to pass to LLI
91   public:
92     LLI(const std::string &Path, const std::vector<std::string> *Args)
93       : LLIPath(Path) {
94       ToolArgs.clear ();
95       if (Args) { ToolArgs = *Args; }
96     }
97
98     virtual int ExecuteProgram(const std::string &Bytecode,
99                                const std::vector<std::string> &Args,
100                                const std::string &InputFile,
101                                const std::string &OutputFile,
102                                const std::vector<std::string> &GCCArgs,
103                                const std::vector<std::string> &SharedLibs =
104                                std::vector<std::string>(),
105                                unsigned Timeout = 0);
106   };
107 }
108
109 int LLI::ExecuteProgram(const std::string &Bytecode,
110                         const std::vector<std::string> &Args,
111                         const std::string &InputFile,
112                         const std::string &OutputFile,
113                         const std::vector<std::string> &GCCArgs,
114                         const std::vector<std::string> &SharedLibs,
115                         unsigned Timeout) {
116   if (!SharedLibs.empty())
117     throw ToolExecutionError("LLI currently does not support "
118                              "loading shared libraries.");
119
120   if (!GCCArgs.empty())
121     throw ToolExecutionError("LLI currently does not support "
122                              "GCC Arguments.");
123   std::vector<const char*> LLIArgs;
124   LLIArgs.push_back(LLIPath.c_str());
125   LLIArgs.push_back("-force-interpreter=true");
126
127   // Add any extra LLI args.
128   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
129     LLIArgs.push_back(ToolArgs[i].c_str());
130
131   LLIArgs.push_back(Bytecode.c_str());
132   // Add optional parameters to the running program from Argv
133   for (unsigned i=0, e = Args.size(); i != e; ++i)
134     LLIArgs.push_back(Args[i].c_str());
135   LLIArgs.push_back(0);
136
137   std::cout << "<lli>" << std::flush;
138   DEBUG(std::cerr << "\nAbout to run:\t";
139         for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
140           std::cerr << " " << LLIArgs[i];
141         std::cerr << "\n";
142         );
143   return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
144       sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
145       Timeout);
146 }
147
148 // LLI create method - Try to find the LLI executable
149 AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath,
150                                                     std::string &Message,
151                                      const std::vector<std::string> *ToolArgs) {
152   std::string LLIPath = FindExecutable("lli", ProgPath).toString();
153   if (!LLIPath.empty()) {
154     Message = "Found lli: " + LLIPath + "\n";
155     return new LLI(LLIPath, ToolArgs);
156   }
157
158   Message = "Cannot find `lli' in executable directory or PATH!\n";
159   return 0;
160 }
161
162 //===----------------------------------------------------------------------===//
163 // LLC Implementation of AbstractIntepreter interface
164 //
165 GCC::FileType LLC::OutputCode(const std::string &Bytecode, 
166                               sys::Path &OutputAsmFile) {
167   sys::Path uniqueFile(Bytecode+".llc.s");
168   std::string ErrMsg;
169   if (uniqueFile.makeUnique(true, &ErrMsg)) {
170     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
171     exit(1);
172   }
173   OutputAsmFile = uniqueFile;
174   std::vector<const char *> LLCArgs;
175   LLCArgs.push_back (LLCPath.c_str());
176
177   // Add any extra LLC args.
178   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
179     LLCArgs.push_back(ToolArgs[i].c_str());
180
181   LLCArgs.push_back ("-o");
182   LLCArgs.push_back (OutputAsmFile.c_str()); // Output to the Asm file
183   LLCArgs.push_back ("-f");                  // Overwrite as necessary...
184   LLCArgs.push_back (Bytecode.c_str());      // This is the input bytecode
185   LLCArgs.push_back (0);
186
187   std::cout << "<llc>" << std::flush;
188   DEBUG(std::cerr << "\nAbout to run:\t";
189         for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
190           std::cerr << " " << LLCArgs[i];
191         std::cerr << "\n";
192         );
193   if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
194                             sys::Path(), sys::Path(), sys::Path()))
195     ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
196
197   return GCC::AsmFile;                              
198 }
199
200 void LLC::compileProgram(const std::string &Bytecode) {
201   sys::Path OutputAsmFile;
202   OutputCode(Bytecode, OutputAsmFile);
203   OutputAsmFile.eraseFromDisk();
204 }
205
206 int LLC::ExecuteProgram(const std::string &Bytecode,
207                         const std::vector<std::string> &Args,
208                         const std::string &InputFile,
209                         const std::string &OutputFile,
210                         const std::vector<std::string> &ArgsForGCC,
211                         const std::vector<std::string> &SharedLibs,
212                         unsigned Timeout) {
213
214   sys::Path OutputAsmFile;
215   OutputCode(Bytecode, OutputAsmFile);
216   FileRemover OutFileRemover(OutputAsmFile);
217
218   std::vector<std::string> GCCArgs(ArgsForGCC);
219   GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
220
221   // Assuming LLC worked, compile the result with GCC and run it.
222   return gcc->ExecuteProgram(OutputAsmFile.toString(), Args, GCC::AsmFile,
223                              InputFile, OutputFile, GCCArgs, Timeout);
224 }
225
226 /// createLLC - Try to find the LLC executable
227 ///
228 LLC *AbstractInterpreter::createLLC(const std::string &ProgramPath,
229                                     std::string &Message,
230                                     const std::vector<std::string> *Args) {
231   std::string LLCPath = FindExecutable("llc", ProgramPath).toString();
232   if (LLCPath.empty()) {
233     Message = "Cannot find `llc' in executable directory or PATH!\n";
234     return 0;
235   }
236
237   Message = "Found llc: " + LLCPath + "\n";
238   GCC *gcc = GCC::create(ProgramPath, Message);
239   if (!gcc) {
240     std::cerr << Message << "\n";
241     exit(1);
242   }
243   return new LLC(LLCPath, gcc, Args);
244 }
245
246 //===---------------------------------------------------------------------===//
247 // JIT Implementation of AbstractIntepreter interface
248 //
249 namespace {
250   class JIT : public AbstractInterpreter {
251     std::string LLIPath;          // The path to the LLI executable
252     std::vector<std::string> ToolArgs; // Args to pass to LLI
253   public:
254     JIT(const std::string &Path, const std::vector<std::string> *Args)
255       : LLIPath(Path) {
256       ToolArgs.clear ();
257       if (Args) { ToolArgs = *Args; }
258     }
259
260     virtual int ExecuteProgram(const std::string &Bytecode,
261                                const std::vector<std::string> &Args,
262                                const std::string &InputFile,
263                                const std::string &OutputFile,
264                                const std::vector<std::string> &GCCArgs =
265                                  std::vector<std::string>(),
266                                const std::vector<std::string> &SharedLibs =
267                                  std::vector<std::string>(), 
268                                unsigned Timeout =0 );
269   };
270 }
271
272 int JIT::ExecuteProgram(const std::string &Bytecode,
273                         const std::vector<std::string> &Args,
274                         const std::string &InputFile,
275                         const std::string &OutputFile,
276                         const std::vector<std::string> &GCCArgs,
277                         const std::vector<std::string> &SharedLibs,
278                         unsigned Timeout) {
279   if (!GCCArgs.empty())
280     throw ToolExecutionError("JIT does not support GCC Arguments.");
281   // Construct a vector of parameters, incorporating those from the command-line
282   std::vector<const char*> JITArgs;
283   JITArgs.push_back(LLIPath.c_str());
284   JITArgs.push_back("-force-interpreter=false");
285
286   // Add any extra LLI args.
287   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
288     JITArgs.push_back(ToolArgs[i].c_str());
289
290   for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
291     JITArgs.push_back("-load");
292     JITArgs.push_back(SharedLibs[i].c_str());
293   }
294   JITArgs.push_back(Bytecode.c_str());
295   // Add optional parameters to the running program from Argv
296   for (unsigned i=0, e = Args.size(); i != e; ++i)
297     JITArgs.push_back(Args[i].c_str());
298   JITArgs.push_back(0);
299
300   std::cout << "<jit>" << std::flush;
301   DEBUG(std::cerr << "\nAbout to run:\t";
302         for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
303           std::cerr << " " << JITArgs[i];
304         std::cerr << "\n";
305         );
306   DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
307   return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
308       sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
309       Timeout);
310 }
311
312 /// createJIT - Try to find the LLI executable
313 ///
314 AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
315                    std::string &Message, const std::vector<std::string> *Args) {
316   std::string LLIPath = FindExecutable("lli", ProgPath).toString();
317   if (!LLIPath.empty()) {
318     Message = "Found lli: " + LLIPath + "\n";
319     return new JIT(LLIPath, Args);
320   }
321
322   Message = "Cannot find `lli' in executable directory or PATH!\n";
323   return 0;
324 }
325
326 GCC::FileType CBE::OutputCode(const std::string &Bytecode,
327                               sys::Path &OutputCFile) {
328   sys::Path uniqueFile(Bytecode+".cbe.c");
329   std::string ErrMsg;
330   if (uniqueFile.makeUnique(true, &ErrMsg)) {
331     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
332     exit(1);
333   }
334   OutputCFile = uniqueFile;
335   std::vector<const char *> LLCArgs;
336   LLCArgs.push_back (LLCPath.c_str());
337
338   // Add any extra LLC args.
339   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
340     LLCArgs.push_back(ToolArgs[i].c_str());
341
342   LLCArgs.push_back ("-o");
343   LLCArgs.push_back (OutputCFile.c_str());   // Output to the C file
344   LLCArgs.push_back ("-march=c");            // Output C language
345   LLCArgs.push_back ("-f");                  // Overwrite as necessary...
346   LLCArgs.push_back (Bytecode.c_str());      // This is the input bytecode
347   LLCArgs.push_back (0);
348
349   std::cout << "<cbe>" << std::flush;
350   DEBUG(std::cerr << "\nAbout to run:\t";
351         for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
352           std::cerr << " " << LLCArgs[i];
353         std::cerr << "\n";
354         );
355   if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
356                             sys::Path()))
357     ProcessFailure(LLCPath, &LLCArgs[0]);
358   return GCC::CFile;
359 }
360
361 void CBE::compileProgram(const std::string &Bytecode) {
362   sys::Path OutputCFile;
363   OutputCode(Bytecode, OutputCFile);
364   OutputCFile.eraseFromDisk();
365 }
366
367 int CBE::ExecuteProgram(const std::string &Bytecode,
368                         const std::vector<std::string> &Args,
369                         const std::string &InputFile,
370                         const std::string &OutputFile,
371                         const std::vector<std::string> &ArgsForGCC,
372                         const std::vector<std::string> &SharedLibs,
373                         unsigned Timeout) {
374   sys::Path OutputCFile;
375   OutputCode(Bytecode, OutputCFile);
376
377   FileRemover CFileRemove(OutputCFile);
378
379   std::vector<std::string> GCCArgs(ArgsForGCC);
380   GCCArgs.insert(GCCArgs.end(),SharedLibs.begin(),SharedLibs.end());
381   return gcc->ExecuteProgram(OutputCFile.toString(), Args, GCC::CFile,
382                              InputFile, OutputFile, GCCArgs, Timeout);
383 }
384
385 /// createCBE - Try to find the 'llc' executable
386 ///
387 CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath,
388                                     std::string &Message,
389                                     const std::vector<std::string> *Args) {
390   sys::Path LLCPath = FindExecutable("llc", ProgramPath);
391   if (LLCPath.isEmpty()) {
392     Message =
393       "Cannot find `llc' in executable directory or PATH!\n";
394     return 0;
395   }
396
397   Message = "Found llc: " + LLCPath.toString() + "\n";
398   GCC *gcc = GCC::create(ProgramPath, Message);
399   if (!gcc) {
400     std::cerr << Message << "\n";
401     exit(1);
402   }
403   return new CBE(LLCPath, gcc, Args);
404 }
405
406 //===---------------------------------------------------------------------===//
407 // GCC abstraction
408 //
409 int GCC::ExecuteProgram(const std::string &ProgramFile,
410                         const std::vector<std::string> &Args,
411                         FileType fileType,
412                         const std::string &InputFile,
413                         const std::string &OutputFile,
414                         const std::vector<std::string> &ArgsForGCC,
415                         unsigned Timeout ) {
416   std::vector<const char*> GCCArgs;
417
418   GCCArgs.push_back(GCCPath.c_str());
419
420   // Specify -x explicitly in case the extension is wonky
421   GCCArgs.push_back("-x");
422   if (fileType == CFile) {
423     GCCArgs.push_back("c");
424     GCCArgs.push_back("-fno-strict-aliasing");
425   } else {
426     GCCArgs.push_back("assembler");
427 #ifdef __APPLE__
428     GCCArgs.push_back("-force_cpusubtype_ALL");
429 #endif
430   }
431   GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename...
432   GCCArgs.push_back("-x");
433   GCCArgs.push_back("none");
434   GCCArgs.push_back("-o");
435   sys::Path OutputBinary (ProgramFile+".gcc.exe");
436   std::string ErrMsg;
437   if (OutputBinary.makeUnique(true, &ErrMsg)) {
438     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
439     exit(1);
440   }
441   GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
442
443   // Add any arguments intended for GCC. We locate them here because this is
444   // most likely -L and -l options that need to come before other libraries but
445   // after the source. Other options won't be sensitive to placement on the
446   // command line, so this should be safe.
447   for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
448     GCCArgs.push_back(ArgsForGCC[i].c_str());
449
450   GCCArgs.push_back("-lm");                // Hard-code the math library...
451   GCCArgs.push_back("-O2");                // Optimize the program a bit...
452 #if defined (HAVE_LINK_R)
453   GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
454 #endif
455 #ifdef __sparc__
456   GCCArgs.push_back("-mcpu=v9");
457 #endif
458   GCCArgs.push_back(0);                    // NULL terminator
459
460   std::cout << "<gcc>" << std::flush;
461   DEBUG(std::cerr << "\nAbout to run:\t";
462         for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
463           std::cerr << " " << GCCArgs[i];
464         std::cerr << "\n";
465         );
466   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
467         sys::Path())) {
468     ProcessFailure(GCCPath, &GCCArgs[0]);
469     exit(1);
470   }
471
472   std::vector<const char*> ProgramArgs;
473
474   ProgramArgs.push_back(OutputBinary.c_str());
475   // Add optional parameters to the running program from Argv
476   for (unsigned i=0, e = Args.size(); i != e; ++i)
477     ProgramArgs.push_back(Args[i].c_str());
478   ProgramArgs.push_back(0);                // NULL terminator
479
480   // Now that we have a binary, run it!
481   std::cout << "<program>" << std::flush;
482   DEBUG(std::cerr << "\nAbout to run:\t";
483         for (unsigned i=0, e = ProgramArgs.size()-1; i != e; ++i)
484           std::cerr << " " << ProgramArgs[i];
485         std::cerr << "\n";
486         );
487
488   FileRemover OutputBinaryRemover(OutputBinary);
489   return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
490       sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
491       Timeout);
492 }
493
494 int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
495                           std::string &OutputFile,
496                           const std::vector<std::string> &ArgsForGCC) {
497   sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
498   std::string ErrMsg;
499   if (uniqueFilename.makeUnique(true, &ErrMsg)) {
500     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
501     exit(1);
502   }
503   OutputFile = uniqueFilename.toString();
504
505   std::vector<const char*> GCCArgs;
506   
507   GCCArgs.push_back(GCCPath.c_str());
508   
509   
510   // Compile the C/asm file into a shared object
511   GCCArgs.push_back("-x");
512   GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
513   GCCArgs.push_back("-fno-strict-aliasing");
514   GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
515 #if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
516   GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
517 #elif defined(__APPLE__)
518   // link all source files into a single module in data segment, rather than
519   // generating blocks. dynamic_lookup requires that you set 
520   // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
521   // bugpoint to just pass that in the environment of GCC.
522   GCCArgs.push_back("-single_module");
523   GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
524   GCCArgs.push_back("-undefined");
525   GCCArgs.push_back("dynamic_lookup");
526 #else
527   GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
528 #endif
529
530 #if defined(__ia64__) || defined(__alpha__)
531   GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
532 #endif
533 #ifdef __sparc__
534   GCCArgs.push_back("-mcpu=v9");
535 #endif
536   GCCArgs.push_back("-o");
537   GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
538   GCCArgs.push_back("-O2");              // Optimize the program a bit.
539
540   
541   
542   // Add any arguments intended for GCC. We locate them here because this is
543   // most likely -L and -l options that need to come before other libraries but
544   // after the source. Other options won't be sensitive to placement on the
545   // command line, so this should be safe.
546   for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
547     GCCArgs.push_back(ArgsForGCC[i].c_str());
548   GCCArgs.push_back(0);                    // NULL terminator
549
550   
551
552   std::cout << "<gcc>" << std::flush;
553   DEBUG(std::cerr << "\nAbout to run:\t";
554         for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
555           std::cerr << " " << GCCArgs[i];
556         std::cerr << "\n";
557         );
558   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
559                             sys::Path())) {
560     ProcessFailure(GCCPath, &GCCArgs[0]);
561     return 1;
562   }
563   return 0;
564 }
565
566 /// create - Try to find the `gcc' executable
567 ///
568 GCC *GCC::create(const std::string &ProgramPath, std::string &Message) {
569   sys::Path GCCPath = FindExecutable("gcc", ProgramPath);
570   if (GCCPath.isEmpty()) {
571     Message = "Cannot find `gcc' in executable directory or PATH!\n";
572     return 0;
573   }
574
575   Message = "Found gcc: " + GCCPath.toString() + "\n";
576   return new GCC(GCCPath);
577 }