/* * Copyright 2010, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BCC_COMPILER_H #define BCC_COMPILER_H #include #include "CodeGen/CodeEmitter.h" #include "CodeGen/CodeMemoryManager.h" #if USE_MCJIT #include "librsloader.h" #endif #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Target/TargetMachine.h" #include #include #include #include #include namespace llvm { class LLVMContext; class Module; class MemoryBuffer; class NamedMDNode; class TargetData; } namespace bcc { class ScriptCompiled; class Compiler { private: ////////////////////////////////////////////////////////////////////////// // The variable section below (e.g., Triple, CodeGenOptLevel) // is initialized in GlobalInitialization() // static bool GlobalInitialized; // If given, this will be the name of the target triple to compile for. // If not given, the initial values defined in this file will be used. static std::string Triple; static llvm::CodeGenOpt::Level CodeGenOptLevel; // End of section of GlobalInitializing variables ///////////////////////////////////////////////////////////////////////// // If given, the name of the target CPU to generate code for. static std::string CPU; // The list of target specific features to enable or disable -- this should // be a list of strings starting with '+' (enable) or '-' (disable). static std::vector Features; static void LLVMErrorHandler(void *UserData, const std::string &Message); static const llvm::StringRef PragmaMetadataName; static const llvm::StringRef ExportVarMetadataName; static const llvm::StringRef ExportFuncMetadataName; static const llvm::StringRef ObjectSlotMetadataName; friend class CodeEmitter; friend class CodeMemoryManager; private: ScriptCompiled *mpResult; std::string mError; #if USE_OLD_JIT // The memory manager for code emitter llvm::OwningPtr mCodeMemMgr; // The CodeEmitter llvm::OwningPtr mCodeEmitter; #endif #if USE_MCJIT // Compilation buffer for MCJIT llvm::SmallVector mEmittedELFExecutable; // Loaded and relocated executable RSExecRef mRSExecutable; #endif BCCSymbolLookupFn mpSymbolLookupFn; void *mpSymbolLookupContext; llvm::LLVMContext *mContext; llvm::Module *mModule; bool mHasLinked; public: Compiler(ScriptCompiled *result); static void GlobalInitialization(); static std::string const &getTargetTriple() { return Triple; } void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) { mpSymbolLookupFn = pFn; mpSymbolLookupContext = pContext; } #if USE_OLD_JIT CodeMemoryManager *createCodeMemoryManager(); CodeEmitter *createCodeEmitter(); #endif #if USE_MCJIT void *getSymbolAddress(char const *name); const llvm::SmallVector &getELF() const { return mEmittedELFExecutable; } #endif llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM); int readModule(llvm::Module *module) { mModule = module; return hasError(); } int linkModule(llvm::Module *module); int compile(bool compileOnly); char const *getErrorMessage() { return mError.c_str(); } const llvm::Module *getModule() const { return mModule; } ~Compiler(); private: int runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM, llvm::NamedMDNode const *ExportVarMetadata, llvm::NamedMDNode const *ExportFuncMetadata); int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM); #if USE_MCJIT static void *resolveSymbolAdapter(void *context, char const *name); #endif int runLTO(llvm::TargetData *TD, llvm::NamedMDNode const *ExportVarMetadata, llvm::NamedMDNode const *ExportFuncMetadata); bool hasError() const { return !mError.empty(); } void setError(const char *Error) { mError.assign(Error); // Copying } void setError(const std::string &Error) { mError = Error; } }; // End of class Compiler } // namespace bcc #endif // BCC_COMPILER_H