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 raw_pwrite_stream;
24class DataLayout;
25class TargetMachine;
26
27namespace legacy {
28class PassManager;
29} // end namespace legacy
30
31using legacy::PassManager;
32
33} // end namespace llvm
34
35namespace bcc {
36
37class CompilerConfig;
38class OutputFile;
39class Script;
40
41//===----------------------------------------------------------------------===//
42// Design of Compiler
43//===----------------------------------------------------------------------===//
44// 1. A compiler instance can be constructed provided an "initial config."
45// 2. A compiler can later be re-configured using config().
46// 3. Once config() is invoked, it'll re-create TargetMachine instance (i.e.,
47//    mTarget) according to the configuration supplied. TargetMachine instance
48//    is *shared* across the different calls to compile() before the next call
49//    to config().
50// 4. Once a compiler instance is created, you can use the compile() service
51//    to compile the file over and over again. Each call uses TargetMachine
52//    instance to construct the compilation passes.
53class Compiler {
54public:
55  enum ErrorCode {
56    kSuccess,
57
58    kInvalidConfigNoTarget,
59    kErrCreateTargetMachine,
60    kErrSwitchTargetMachine,
61    kErrNoTargetMachine,
62    kErrMaterialization,
63    kErrInvalidOutputFileState,
64    kErrPrepareOutput,
65    kPrepareCodeGenPass,
66
67    kErrCustomPasses,
68
69    kErrInvalidSource,
70
71    kIllegalGlobalFunction,
72
73    kErrInvalidTargetMachine
74  };
75
76  static const char *GetErrorString(enum ErrorCode pErrCode);
77
78private:
79  llvm::TargetMachine *mTarget;
80  // Optimization is enabled by default.
81  bool mEnableOpt;
82
83  enum ErrorCode runPasses(Script &pScript, llvm::raw_pwrite_stream &pResult);
84
85  bool addInternalizeSymbolsPass(Script &pScript, llvm::legacy::PassManager &pPM);
86  void addExpandKernelPass(llvm::legacy::PassManager &pPM);
87  void addDebugInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
88  void addGlobalInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
89  void addInvariantPass(llvm::legacy::PassManager &pPM);
90  void addInvokeHelperPass(llvm::legacy::PassManager &pPM);
91
92public:
93  Compiler();
94  Compiler(const CompilerConfig &pConfig);
95
96  enum ErrorCode config(const CompilerConfig &pConfig);
97
98  // Compile a script and output the result to a LLVM stream.
99  //
100  // @param IRStream If not NULL, the LLVM-IR that is fed to code generation
101  //                 will be written to IRStream.
102  enum ErrorCode compile(Script &pScript, llvm::raw_pwrite_stream &pResult,
103                         llvm::raw_ostream *IRStream);
104
105  // Compile a script and output the result to a file.
106  enum ErrorCode compile(Script &pScript, OutputFile &pResult,
107                         llvm::raw_ostream *IRStream = 0);
108
109  const llvm::TargetMachine& getTargetMachine() const
110  { return *mTarget; }
111
112  void enableOpt(bool pEnable = true)
113  { mEnableOpt = pEnable; }
114
115  ~Compiler();
116
117  // Compare undefined external functions in pScript against a 'whitelist' of
118  // all RenderScript functions.  Returns error if any external function that is
119  // not in this whitelist is callable from the script.
120  enum ErrorCode screenGlobalFunctions(Script &pScript);
121
122  void translateGEPs(Script &pScript);
123};
124
125} // end namespace bcc
126
127#endif // BCC_COMPILER_H
128