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