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 122 static std::string const &getTargetTriple() { 123 return Triple; 124 } 125 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 140 const llvm::SmallVector<char, 1024> &getELF() const { 141 return mEmittedELFExecutable; 142 } 143 #endif 144 145 llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM); 146 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 156 char const *getErrorMessage() { 157 return mError.c_str(); 158 } 159 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 182 bool hasError() const { 183 return !mError.empty(); 184 } 185 186 void setError(const char *Error) { 187 mError.assign(Error); // Copying 188 } 189 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