• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2010, 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 #include <bcc/bcc.h>
21 
22 #include "CodeGen/CodeEmitter.h"
23 #include "CodeGen/CodeMemoryManager.h"
24 
25 #if USE_MCJIT
26 #include "librsloader.h"
27 #endif
28 
29 #include "llvm/ADT/OwningPtr.h"
30 #include "llvm/ADT/StringRef.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/Target/TargetMachine.h"
33 
34 #include <stddef.h>
35 
36 #include <list>
37 #include <string>
38 #include <vector>
39 #include <utility>
40 
41 
42 namespace llvm {
43   class LLVMContext;
44   class Module;
45   class MemoryBuffer;
46   class NamedMDNode;
47   class TargetData;
48 }
49 
50 
51 namespace bcc {
52   class ScriptCompiled;
53 
54   class Compiler {
55   private:
56     //////////////////////////////////////////////////////////////////////////
57     // The variable section below (e.g., Triple, CodeGenOptLevel)
58     // is initialized in GlobalInitialization()
59     //
60     static bool GlobalInitialized;
61 
62     // If given, this will be the name of the target triple to compile for.
63     // If not given, the initial values defined in this file will be used.
64     static std::string Triple;
65 
66     static llvm::CodeGenOpt::Level CodeGenOptLevel;
67 
68     // End of section of GlobalInitializing variables
69     /////////////////////////////////////////////////////////////////////////
70     // If given, the name of the target CPU to generate code for.
71     static std::string CPU;
72 
73     // The list of target specific features to enable or disable -- this should
74     // be a list of strings starting with '+' (enable) or '-' (disable).
75     static std::vector<std::string> Features;
76 
77     static void LLVMErrorHandler(void *UserData, const std::string &Message);
78 
79     static const llvm::StringRef PragmaMetadataName;
80     static const llvm::StringRef ExportVarMetadataName;
81     static const llvm::StringRef ExportFuncMetadataName;
82     static const llvm::StringRef ObjectSlotMetadataName;
83 
84     friend class CodeEmitter;
85     friend class CodeMemoryManager;
86 
87 
88   private:
89     ScriptCompiled *mpResult;
90 
91     std::string mError;
92 
93 #if USE_OLD_JIT
94     // The memory manager for code emitter
95     llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
96 
97     // The CodeEmitter
98     llvm::OwningPtr<CodeEmitter> mCodeEmitter;
99 #endif
100 
101 #if USE_MCJIT
102     // Compilation buffer for MCJIT
103     llvm::SmallVector<char, 1024> mEmittedELFExecutable;
104 
105     // Loaded and relocated executable
106     RSExecRef mRSExecutable;
107 #endif
108 
109     BCCSymbolLookupFn mpSymbolLookupFn;
110     void *mpSymbolLookupContext;
111 
112     llvm::LLVMContext *mContext;
113     llvm::Module *mModule;
114 
115     bool mHasLinked;
116 
117   public:
118     Compiler(ScriptCompiled *result);
119 
120     static void GlobalInitialization();
121 
getTargetTriple()122     static std::string const &getTargetTriple() {
123       return Triple;
124     }
125 
registerSymbolCallback(BCCSymbolLookupFn pFn,void * pContext)126     void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
127       mpSymbolLookupFn = pFn;
128       mpSymbolLookupContext = pContext;
129     }
130 
131 #if USE_OLD_JIT
132     CodeMemoryManager *createCodeMemoryManager();
133 
134     CodeEmitter *createCodeEmitter();
135 #endif
136 
137 #if USE_MCJIT
138     void *getSymbolAddress(char const *name);
139 
getELF()140     const llvm::SmallVector<char, 1024> &getELF() const {
141       return mEmittedELFExecutable;
142     }
143 #endif
144 
145     llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM);
146 
readModule(llvm::Module * module)147     int readModule(llvm::Module *module) {
148       mModule = module;
149       return hasError();
150     }
151 
152     int linkModule(llvm::Module *module);
153 
154     int compile(bool compileOnly);
155 
getErrorMessage()156     char const *getErrorMessage() {
157       return mError.c_str();
158     }
159 
getModule()160     const llvm::Module *getModule() const {
161       return mModule;
162     }
163 
164     ~Compiler();
165 
166   private:
167 
168     int runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
169                    llvm::NamedMDNode const *ExportVarMetadata,
170                    llvm::NamedMDNode const *ExportFuncMetadata);
171 
172     int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM);
173 
174 #if USE_MCJIT
175     static void *resolveSymbolAdapter(void *context, char const *name);
176 #endif
177 
178     int runLTO(llvm::TargetData *TD,
179                llvm::NamedMDNode const *ExportVarMetadata,
180                llvm::NamedMDNode const *ExportFuncMetadata);
181 
hasError()182     bool hasError() const {
183       return !mError.empty();
184     }
185 
setError(const char * Error)186     void setError(const char *Error) {
187       mError.assign(Error);  // Copying
188     }
189 
setError(const std::string & Error)190     void setError(const std::string &Error) {
191       mError = Error;
192     }
193 
194   };  // End of class Compiler
195 
196 } // namespace bcc
197 
198 #endif // BCC_COMPILER_H
199