Add support for just compiling a program
[oota-llvm.git] / tools / bugpoint / ToolRunner.h
1 //===-- Support/ToolRunner.h ------------------------------------*- C++ -*-===//
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 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 TOOLRUNNER_H
18 #define TOOLRUNNER_H
19
20 #include "Support/SystemUtils.h"
21 #include <vector>
22
23 namespace llvm {
24
25 class CBE;
26 class LLC;
27
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 ///
33 class ToolExecutionError {
34   std::string Message;
35 public:
36   ToolExecutionError(const std::string &M) : Message(M) {}
37   const std::string getMessage() const { return Message; }
38 };
39
40
41 //===---------------------------------------------------------------------===//
42 // GCC abstraction
43 //
44 class GCC {
45   std::string GCCPath;          // The path to the gcc executable
46   GCC(const std::string &gccPath) : GCCPath(gccPath) { }
47 public:
48   enum FileType { AsmFile, CFile };
49
50   static GCC* create(const std::string &ProgramPath, std::string &Message);
51
52   /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
53   /// either a .s file, or a .c file, specified by FileType), with the specified
54   /// arguments.  Standard input is specified with InputFile, and standard
55   /// Output is captured to the specified OutputFile location.  The SharedLibs
56   /// option specifies optional native shared objects that can be loaded into
57   /// the program for execution.
58   ///
59   int ExecuteProgram(const std::string &ProgramFile,
60                      const std::vector<std::string> &Args,
61                      FileType fileType,
62                      const std::string &InputFile,
63                      const std::string &OutputFile,
64                      const std::vector<std::string> &SharedLibs = 
65                          std::vector<std::string>());
66
67   /// MakeSharedObject - This compiles the specified file (which is either a .c
68   /// file or a .s file) into a shared object.
69   ///
70   int MakeSharedObject(const std::string &InputFile, FileType fileType,
71                        std::string &OutputFile);
72 };
73
74
75 //===---------------------------------------------------------------------===//
76 /// AbstractInterpreter Class - Subclasses of this class are used to execute
77 /// LLVM bytecode in a variety of ways.  This abstract interface hides this
78 /// complexity behind a simple interface.
79 ///
80 struct AbstractInterpreter {
81   static CBE* createCBE(const std::string &ProgramPath, std::string &Message);
82   static LLC *createLLC(const std::string &ProgramPath, std::string &Message);
83
84   static AbstractInterpreter* createLLI(const std::string &ProgramPath,
85                                         std::string &Message);
86
87   static AbstractInterpreter* createJIT(const std::string &ProgramPath,
88                                         std::string &Message);
89
90
91   virtual ~AbstractInterpreter() {}
92
93   /// compileProgram - Compile the specified program from bytecode to executable
94   /// code.  This does not produce any output, it is only used when debugging
95   /// the code generator.  If the code generator fails, an exception should be
96   /// thrown, otherwise, this function will just return.
97   virtual void compileProgram(const std::string &Bytecode) {}
98
99   /// ExecuteProgram - Run the specified bytecode file, emitting output to the
100   /// specified filename.  This returns the exit code of the program.
101   ///
102   virtual int ExecuteProgram(const std::string &Bytecode,
103                              const std::vector<std::string> &Args,
104                              const std::string &InputFile,
105                              const std::string &OutputFile,
106                              const std::vector<std::string> &SharedLibs = 
107                                std::vector<std::string>()) = 0;
108 };
109
110 //===---------------------------------------------------------------------===//
111 // CBE Implementation of AbstractIntepreter interface
112 //
113 class CBE : public AbstractInterpreter {
114   std::string LLCPath;          // The path to the `llc' executable
115   GCC *gcc;
116 public:
117   CBE(const std::string &llcPath, GCC *Gcc) : LLCPath(llcPath), gcc(Gcc) { }
118   ~CBE() { delete gcc; }
119
120   /// compileProgram - Compile the specified program from bytecode to executable
121   /// code.  This does not produce any output, it is only used when debugging
122   /// the code generator.  If the code generator fails, an exception should be
123   /// thrown, otherwise, this function will just return.
124   virtual void compileProgram(const std::string &Bytecode);
125
126   virtual int ExecuteProgram(const std::string &Bytecode,
127                              const std::vector<std::string> &Args,
128                              const std::string &InputFile,
129                              const std::string &OutputFile,
130                              const std::vector<std::string> &SharedLibs = 
131                                std::vector<std::string>());
132
133   // Sometimes we just want to go half-way and only generate the .c file, not
134   // necessarily compile it with GCC and run the program.  This throws an
135   // exception if LLC crashes.
136   //
137   virtual void OutputC(const std::string &Bytecode, std::string &OutputCFile);
138 };
139
140
141 //===---------------------------------------------------------------------===//
142 // LLC Implementation of AbstractIntepreter interface
143 //
144 class LLC : public AbstractInterpreter {
145   std::string LLCPath;          // The path to the LLC executable
146   GCC *gcc;
147 public:
148   LLC(const std::string &llcPath, GCC *Gcc)
149     : LLCPath(llcPath), gcc(Gcc) { }
150   ~LLC() { delete gcc; }
151
152
153   /// compileProgram - Compile the specified program from bytecode 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 &Bytecode);
158
159   virtual int ExecuteProgram(const std::string &Bytecode,
160                              const std::vector<std::string> &Args,
161                              const std::string &InputFile,
162                              const std::string &OutputFile,
163                              const std::vector<std::string> &SharedLibs = 
164                                 std::vector<std::string>());
165
166   // Sometimes we just want to go half-way and only generate the .s file,
167   // not necessarily compile it all the way and run the program.  This throws
168   // an exception if execution of LLC fails.
169   //
170   void OutputAsm(const std::string &Bytecode, std::string &OutputAsmFile);
171 };
172
173 } // End llvm namespace
174
175 #endif