11f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan/*
21f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Copyright 2010, The Android Open Source Project
31f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *
41f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Licensed under the Apache License, Version 2.0 (the "License");
51f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * you may not use this file except in compliance with the License.
61f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * You may obtain a copy of the License at
71f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *
81f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *     http://www.apache.org/licenses/LICENSE-2.0
91f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan *
101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * Unless required by applicable law or agreed to in writing, software
111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * distributed under the License is distributed on an "AS IS" BASIS,
121f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * See the License for the specific language governing permissions and
141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan * limitations under the License.
151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan */
161f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
171f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#ifndef BCC_COMPILER_H
181f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#define BCC_COMPILER_H
191f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
201f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <bcc/bcc.h>
211f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
228d3b5e184b776dbf0b4af8a1c95f027d8653ca66Logan Chien#include "CodeGen/CodeEmitter.h"
238d3b5e184b776dbf0b4af8a1c95f027d8653ca66Logan Chien#include "CodeGen/CodeMemoryManager.h"
241f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
25320b5499c78f8b94bc61f609a5fc9053a91d3c18Shih-wei Liao#if USE_MCJIT
26da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#include "librsloader.h"
27320b5499c78f8b94bc61f609a5fc9053a91d3c18Shih-wei Liao#endif
28da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
291f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/ADT/OwningPtr.h"
301f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/ADT/StringRef.h"
31da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#include "llvm/ADT/SmallVector.h"
321f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/Target/TargetMachine.h"
331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <stddef.h>
351f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
361f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <list>
371f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <string>
381f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <vector>
391f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <utility>
401f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
411f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
421f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logannamespace llvm {
431f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class LLVMContext;
441f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class Module;
45474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  class MemoryBuffer;
464cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  class NamedMDNode;
474cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  class TargetData;
481f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
491f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
501f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
511f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logannamespace bcc {
522a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan  class ScriptCompiled;
531f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
541f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class Compiler {
55de2ca79b82b533bae32176c84378d7082788e9eeLogan  private:
561f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    //////////////////////////////////////////////////////////////////////////
571f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The variable section below (e.g., Triple, CodeGenOptLevel)
581f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // is initialized in GlobalInitialization()
591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    //
601f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static bool GlobalInitialized;
611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If given, this will be the name of the target triple to compile for.
631f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If not given, the initial values defined in this file will be used.
641f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::string Triple;
651f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
661f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static llvm::CodeGenOpt::Level CodeGenOptLevel;
671f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
681f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // End of section of GlobalInitializing variables
691f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    /////////////////////////////////////////////////////////////////////////
701f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If given, the name of the target CPU to generate code for.
711f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::string CPU;
721f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
731f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The list of target specific features to enable or disable -- this should
741f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // be a list of strings starting with '+' (enable) or '-' (disable).
751f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::vector<std::string> Features;
761f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
771f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static void LLVMErrorHandler(void *UserData, const std::string &Message);
781f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
791f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef PragmaMetadataName;
801f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef ExportVarMetadataName;
811f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef ExportFuncMetadataName;
82071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines    static const llvm::StringRef ObjectSlotMetadataName;
831f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
841f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    friend class CodeEmitter;
851f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    friend class CodeMemoryManager;
861f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
87de2ca79b82b533bae32176c84378d7082788e9eeLogan
881f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  private:
892a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan    ScriptCompiled *mpResult;
902a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan
911f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    std::string mError;
921f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
93da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_OLD_JIT
941f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The memory manager for code emitter
951f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
961f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
971f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The CodeEmitter
981f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::OwningPtr<CodeEmitter> mCodeEmitter;
99da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
100da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
101da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
102da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    // Compilation buffer for MCJIT
103da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    llvm::SmallVector<char, 1024> mEmittedELFExecutable;
104da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
105da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    // Loaded and relocated executable
106da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    RSExecRef mRSExecutable;
107da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
1081f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1091f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    BCCSymbolLookupFn mpSymbolLookupFn;
1101f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    void *mpSymbolLookupContext;
1111f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1121f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::LLVMContext *mContext;
1131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::Module *mModule;
1141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    bool mHasLinked;
1161f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1171f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  public:
1182a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan    Compiler(ScriptCompiled *result);
1191f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
120ecf4cbd022f72436fa7c7e2eb5f920ab6cba4a83Logan    static void GlobalInitialization();
121ecf4cbd022f72436fa7c7e2eb5f920ab6cba4a83Logan
1229347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    static std::string const &getTargetTriple() {
1239347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien      return Triple;
1249347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien    }
1259347e0bdf9d9cb691c3681ea06c87716b6251af4Logan Chien
126f340bf71ff377979d279132dcf5a801d76747d1fLogan    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
1271f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mpSymbolLookupFn = pFn;
1281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mpSymbolLookupContext = pContext;
1291f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1301f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
131da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_OLD_JIT
132de2ca79b82b533bae32176c84378d7082788e9eeLogan    CodeMemoryManager *createCodeMemoryManager();
133de2ca79b82b533bae32176c84378d7082788e9eeLogan
134de2ca79b82b533bae32176c84378d7082788e9eeLogan    CodeEmitter *createCodeEmitter();
135da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
136de2ca79b82b533bae32176c84378d7082788e9eeLogan
137da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
138da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    void *getSymbolAddress(char const *name);
1395e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao
1405e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    const llvm::SmallVector<char, 1024> &getELF() const {
1415e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao      return mEmittedELFExecutable;
1425e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao    }
143da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
144da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
145474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM);
146474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
1471f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    int readModule(llvm::Module *module) {
1481f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mModule = module;
1491f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      return hasError();
1501f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1511f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
152474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    int linkModule(llvm::Module *module);
1531f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
15434c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    int compile(bool compileOnly);
1551f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
15638d0607284fc6fdc52b4a3337b2bf9c1f1b0aaa1Logan    char const *getErrorMessage() {
15738d0607284fc6fdc52b4a3337b2bf9c1f1b0aaa1Logan      return mError.c_str();
1581f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1601f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    const llvm::Module *getModule() const {
1611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      return mModule;
1621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1631f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1641f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    ~Compiler();
1651f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1661f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  private:
167de2ca79b82b533bae32176c84378d7082788e9eeLogan
168da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    int runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
169da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                   llvm::NamedMDNode const *ExportVarMetadata,
170da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                   llvm::NamedMDNode const *ExportFuncMetadata);
171da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
17234c600a77b0dd2f27fabbc4b6b3b94ed12af2a57Joseph Wen    int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM);
173da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
174da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
175da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    static void *resolveSymbolAdapter(void *context, char const *name);
176da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
177da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
178da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    int runLTO(llvm::TargetData *TD,
179da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien               llvm::NamedMDNode const *ExportVarMetadata,
180da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien               llvm::NamedMDNode const *ExportFuncMetadata);
181da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
182de2ca79b82b533bae32176c84378d7082788e9eeLogan    bool hasError() const {
183de2ca79b82b533bae32176c84378d7082788e9eeLogan      return !mError.empty();
184de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
185de2ca79b82b533bae32176c84378d7082788e9eeLogan
186de2ca79b82b533bae32176c84378d7082788e9eeLogan    void setError(const char *Error) {
187de2ca79b82b533bae32176c84378d7082788e9eeLogan      mError.assign(Error);  // Copying
188de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
189de2ca79b82b533bae32176c84378d7082788e9eeLogan
190de2ca79b82b533bae32176c84378d7082788e9eeLogan    void setError(const std::string &Error) {
191de2ca79b82b533bae32176c84378d7082788e9eeLogan      mError = Error;
192de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
193de2ca79b82b533bae32176c84378d7082788e9eeLogan
1942417cef58cd051c0b43ce9f9cdc01a17d83ef95aShih-wei Liao  };  // End of class Compiler
1951f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1969b504ebbab0ed81121fdba22617ea4f6cf4a467fLogan} // namespace bcc
1971f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1981f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#endif // BCC_COMPILER_H
199