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 using legacy::PassManager;
32 
33 } // end namespace llvm
34 
35 namespace bcc {
36 
37 class CompilerConfig;
38 class OutputFile;
39 class 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.
53 class Compiler {
54 public:
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 
74   static const char *GetErrorString(enum ErrorCode pErrCode);
75 
76 private:
77   llvm::TargetMachine *mTarget;
78   // Optimization is enabled by default.
79   bool mEnableOpt;
80 
81   enum ErrorCode runPasses(Script &pScript, llvm::raw_pwrite_stream &pResult);
82 
83   bool addCustomPasses(Script &pScript, llvm::legacy::PassManager &pPM);
84   bool addInternalizeSymbolsPass(Script &pScript, llvm::legacy::PassManager &pPM);
85   bool addExpandForEachPass(Script &pScript, llvm::legacy::PassManager &pPM);
86   bool addGlobalInfoPass(Script &pScript, llvm::legacy::PassManager &pPM);
87   bool addInvariantPass(llvm::legacy::PassManager &pPM);
88   bool addInvokeHelperPass(llvm::legacy::PassManager &pPM);
89   bool addPostLTOCustomPasses(llvm::legacy::PassManager &pPM);
90 
91 public:
92   Compiler();
93   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 
104   // Compile a script and output the result to a file.
105   enum ErrorCode compile(Script &pScript, OutputFile &pResult,
106                          llvm::raw_ostream *IRStream = 0);
107 
getTargetMachine()108   const llvm::TargetMachine& getTargetMachine() const
109   { return *mTarget; }
110 
111   void enableOpt(bool pEnable = true)
112   { mEnableOpt = pEnable; }
113 
114   ~Compiler();
115 
116   // Compare undefined external functions in pScript against a 'whitelist' of
117   // all RenderScript functions.  Returns error if any external function that is
118   // not in this whitelist is callable from the script.
119   enum ErrorCode screenGlobalFunctions(Script &pScript);
120 };
121 
122 } // end namespace bcc
123 
124 #endif // BCC_COMPILER_H
125