Compiler.h revision 27fb7edfd3f53f52fba6ee81267c02f7896198a3
1/*
2 * Copyright 2010-2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef BCC_COMPILER_H
18#define BCC_COMPILER_H
19
20namespace llvm {
21
22class raw_ostream;
23class PassManager;
24class DataLayout;
25class TargetMachine;
26
27} // end namespace llvm
28
29namespace bcc {
30
31class CompilerConfig;
32class OutputFile;
33class Script;
34
35//===----------------------------------------------------------------------===//
36// Design of Compiler
37//===----------------------------------------------------------------------===//
38// 1. A compiler instance can be constructed provided an "initial config."
39// 2. A compiler can later be re-configured using config().
40// 3. Once config() is invoked, it'll re-create TargetMachine instance (i.e.,
41//    mTarget) according to the configuration supplied. TargetMachine instance
42//    is *shared* across the different calls to compile() before the next call
43//    to config().
44// 4. Once a compiler instance is created, you can use the compile() service
45//    to compile the file over and over again. Each call uses TargetMachine
46//    instance to construct the compilation passes.
47class Compiler {
48public:
49  enum ErrorCode {
50    kSuccess,
51
52    kInvalidConfigNoTarget,
53    kErrCreateTargetMachine,
54    kErrSwitchTargetMachine,
55    kErrNoTargetMachine,
56    kErrDataLayoutNoMemory,
57    kErrMaterialization,
58    kErrInvalidOutputFileState,
59    kErrPrepareOutput,
60    kPrepareCodeGenPass,
61
62    kErrHookBeforeAddLTOPasses,
63    kErrHookAfterAddLTOPasses,
64    kErrHookBeforeExecuteLTOPasses,
65    kErrHookAfterExecuteLTOPasses,
66
67    kErrHookBeforeAddCodeGenPasses,
68    kErrHookAfterAddCodeGenPasses,
69    kErrHookBeforeExecuteCodeGenPasses,
70    kErrHookAfterExecuteCodeGenPasses,
71
72    kErrInvalidSource,
73
74    kMaxErrorCode
75  };
76
77  static const char *GetErrorString(enum ErrorCode pErrCode);
78
79private:
80  llvm::TargetMachine *mTarget;
81  // LTO is enabled by default.
82  bool mEnableLTO;
83
84  enum ErrorCode runLTO(Script &pScript);
85  enum ErrorCode runCodeGen(Script &pScript, llvm::raw_ostream &pResult);
86
87public:
88  Compiler();
89  Compiler(const CompilerConfig &pConfig);
90
91  enum ErrorCode config(const CompilerConfig &pConfig);
92
93  // Compile a script and output the result to a LLVM stream.
94  //
95  // @param IRStream If not NULL, the LLVM-IR that is fed to code generation
96  //                 will be written to IRStream.
97  enum ErrorCode compile(Script &pScript, llvm::raw_ostream &pResult,
98                         llvm::raw_ostream *IRStream);
99
100  // Compile a script and output the result to a file.
101  enum ErrorCode compile(Script &pScript, OutputFile &pResult,
102                         llvm::raw_ostream *IRStream = 0);
103
104  const llvm::TargetMachine& getTargetMachine() const
105  { return *mTarget; }
106
107  void enableLTO(bool pEnable = true)
108  { mEnableLTO = pEnable; }
109
110  virtual ~Compiler();
111
112protected:
113  //===--------------------------------------------------------------------===//
114  // Plugin callbacks for sub-class.
115  //===--------------------------------------------------------------------===//
116  // Called before adding first pass to code-generation passes.
117  virtual bool beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
118  { return true; }
119
120  // Called after adding last pass to code-generation passes.
121  virtual bool afterAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
122  { return true; }
123
124  // Called before executing code-generation passes.
125  virtual bool beforeExecuteLTOPasses(Script &pScript,
126                                          llvm::PassManager &pPM)
127  { return true; }
128
129  // Called after executing code-generation passes.
130  virtual bool afterExecuteLTOPasses(Script &pScript)
131  { return true; }
132
133  // Called before adding first pass to code-generation passes.
134  virtual bool beforeAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
135  { return true; }
136
137  // Called after adding last pass to code-generation passes.
138  virtual bool afterAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
139  { return true; }
140
141  // Called before executing code-generation passes.
142  virtual bool beforeExecuteCodeGenPasses(Script &pScript,
143                                          llvm::PassManager &pPM)
144  { return true; }
145
146  // Called after executing code-generation passes.
147  virtual bool afterExecuteCodeGenPasses(Script &pScript)
148  { return true; }
149};
150
151} // end namespace bcc
152
153#endif // BCC_COMPILER_H
154