ToolRunner.h revision 70f684fcf92e5cdd11a3b3fc9bf3519f8b745857
1//===-- tools/bugpoint/ToolRunner.h -----------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file exposes an abstraction around a platform C compiler, used to
11// compile C and assembly code.  It also exposes an "AbstractIntepreter"
12// interface, which is used to execute code using one of the LLVM execution
13// engines.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef BUGPOINT_TOOLRUNNER_H
18#define BUGPOINT_TOOLRUNNER_H
19
20#include "llvm/Support/SystemUtils.h"
21#include <exception>
22#include <vector>
23
24namespace llvm {
25
26class CBE;
27class LLC;
28
29/// ToolExecutionError - An instance of this class is thrown by the
30/// AbstractInterpreter instances if there is an error running a tool (e.g., LLC
31/// crashes) which prevents execution of the program.
32///
33class ToolExecutionError : std::exception {
34  std::string Message;
35public:
36  explicit ToolExecutionError(const std::string &M) : Message(M) {}
37  virtual ~ToolExecutionError() throw();
38  virtual const char* what() const throw() { return Message.c_str(); }
39};
40
41
42//===---------------------------------------------------------------------===//
43// GCC abstraction
44//
45class GCC {
46  sys::Path GCCPath;          // The path to the gcc executable
47  sys::Path RemoteClientPath; // The path to the rsh / ssh executable
48  GCC(const sys::Path &gccPath, const sys::Path &RemotePath)
49    : GCCPath(gccPath), RemoteClientPath(RemotePath) { }
50public:
51  enum FileType { AsmFile, CFile };
52
53  static GCC *create(const std::string &ProgramPath, std::string &Message);
54
55  /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
56  /// either a .s file, or a .c file, specified by FileType), with the specified
57  /// arguments.  Standard input is specified with InputFile, and standard
58  /// Output is captured to the specified OutputFile location.  The SharedLibs
59  /// option specifies optional native shared objects that can be loaded into
60  /// the program for execution.
61  ///
62  int ExecuteProgram(const std::string &ProgramFile,
63                     const std::vector<std::string> &Args,
64                     FileType fileType,
65                     const std::string &InputFile,
66                     const std::string &OutputFile,
67                     const std::vector<std::string> &GCCArgs =
68                         std::vector<std::string>(),
69                     unsigned Timeout = 0,
70                     unsigned MemoryLimit = 0);
71
72  /// MakeSharedObject - This compiles the specified file (which is either a .c
73  /// file or a .s file) into a shared object.
74  ///
75  int MakeSharedObject(const std::string &InputFile, FileType fileType,
76                       std::string &OutputFile,
77                       const std::vector<std::string> &ArgsForGCC);
78};
79
80
81//===---------------------------------------------------------------------===//
82/// AbstractInterpreter Class - Subclasses of this class are used to execute
83/// LLVM bitcode in a variety of ways.  This abstract interface hides this
84/// complexity behind a simple interface.
85///
86class AbstractInterpreter {
87public:
88  static CBE *createCBE(const std::string &ProgramPath, std::string &Message,
89                        const std::vector<std::string> *Args = 0);
90  static LLC *createLLC(const std::string &ProgramPath, std::string &Message,
91                        const std::vector<std::string> *Args = 0);
92
93  static AbstractInterpreter* createLLI(const std::string &ProgramPath,
94                                        std::string &Message,
95                                        const std::vector<std::string> *Args=0);
96
97  static AbstractInterpreter* createJIT(const std::string &ProgramPath,
98                                        std::string &Message,
99                                        const std::vector<std::string> *Args=0);
100
101  static AbstractInterpreter* createCustom(const std::string &ProgramPath,
102                                           std::string &Message,
103                                           const std::string &ExecCommandLine);
104
105
106  virtual ~AbstractInterpreter() {}
107
108  /// compileProgram - Compile the specified program from bitcode to executable
109  /// code.  This does not produce any output, it is only used when debugging
110  /// the code generator.  If the code generator fails, an exception should be
111  /// thrown, otherwise, this function will just return.
112  virtual void compileProgram(const std::string &Bitcode) {}
113
114  /// OutputCode - Compile the specified program from bitcode to code
115  /// understood by the GCC driver (either C or asm).  If the code generator
116  /// fails, an exception should be thrown, otherwise, this function returns the
117  /// type of code emitted.
118  virtual GCC::FileType OutputCode(const std::string &Bitcode,
119                                   sys::Path &OutFile) {
120    throw std::string("OutputCode not supported by this AbstractInterpreter!");
121  }
122
123  /// ExecuteProgram - Run the specified bitcode file, emitting output to the
124  /// specified filename.  This returns the exit code of the program.
125  ///
126  virtual int ExecuteProgram(const std::string &Bitcode,
127                             const std::vector<std::string> &Args,
128                             const std::string &InputFile,
129                             const std::string &OutputFile,
130                             const std::vector<std::string> &GCCArgs =
131                               std::vector<std::string>(),
132                             const std::vector<std::string> &SharedLibs =
133                               std::vector<std::string>(),
134                             unsigned Timeout = 0,
135                             unsigned MemoryLimit = 0) = 0;
136};
137
138//===---------------------------------------------------------------------===//
139// CBE Implementation of AbstractIntepreter interface
140//
141class CBE : public AbstractInterpreter {
142  sys::Path LLCPath;          // The path to the `llc' executable
143  std::vector<std::string> ToolArgs; // Extra args to pass to LLC
144  GCC *gcc;
145public:
146  CBE(const sys::Path &llcPath, GCC *Gcc,
147      const std::vector<std::string> *Args) : LLCPath(llcPath), gcc(Gcc) {
148    ToolArgs.clear ();
149    if (Args) { ToolArgs = *Args; }
150  }
151  ~CBE() { delete gcc; }
152
153  /// compileProgram - Compile the specified program from bitcode to executable
154  /// code.  This does not produce any output, it is only used when debugging
155  /// the code generator.  If the code generator fails, an exception should be
156  /// thrown, otherwise, this function will just return.
157  virtual void compileProgram(const std::string &Bitcode);
158
159  virtual int ExecuteProgram(const std::string &Bitcode,
160                             const std::vector<std::string> &Args,
161                             const std::string &InputFile,
162                             const std::string &OutputFile,
163                             const std::vector<std::string> &GCCArgs =
164                               std::vector<std::string>(),
165                             const std::vector<std::string> &SharedLibs =
166                               std::vector<std::string>(),
167                             unsigned Timeout = 0,
168                             unsigned MemoryLimit = 0);
169
170  /// OutputCode - Compile the specified program from bitcode to code
171  /// understood by the GCC driver (either C or asm).  If the code generator
172  /// fails, an exception should be thrown, otherwise, this function returns the
173  /// type of code emitted.
174  virtual GCC::FileType OutputCode(const std::string &Bitcode,
175                                   sys::Path &OutFile);
176};
177
178
179//===---------------------------------------------------------------------===//
180// LLC Implementation of AbstractIntepreter interface
181//
182class LLC : public AbstractInterpreter {
183  std::string LLCPath;          // The path to the LLC executable
184  std::vector<std::string> ToolArgs; // Extra args to pass to LLC
185  GCC *gcc;
186public:
187  LLC(const std::string &llcPath, GCC *Gcc,
188    const std::vector<std::string> *Args) : LLCPath(llcPath), gcc(Gcc) {
189    ToolArgs.clear ();
190    if (Args) { ToolArgs = *Args; }
191  }
192  ~LLC() { delete gcc; }
193
194  /// compileProgram - Compile the specified program from bitcode to executable
195  /// code.  This does not produce any output, it is only used when debugging
196  /// the code generator.  If the code generator fails, an exception should be
197  /// thrown, otherwise, this function will just return.
198  virtual void compileProgram(const std::string &Bitcode);
199
200  virtual int ExecuteProgram(const std::string &Bitcode,
201                             const std::vector<std::string> &Args,
202                             const std::string &InputFile,
203                             const std::string &OutputFile,
204                             const std::vector<std::string> &GCCArgs =
205                               std::vector<std::string>(),
206                             const std::vector<std::string> &SharedLibs =
207                                std::vector<std::string>(),
208                             unsigned Timeout = 0,
209                             unsigned MemoryLimit = 0);
210
211  virtual GCC::FileType OutputCode(const std::string &Bitcode,
212                                   sys::Path &OutFile);
213
214};
215
216} // End llvm namespace
217
218#endif
219