Compiler.h revision da5e0c369ad20bf70556c7e7cf86807cf171730d
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
22c4395235b212be7a626becb0c03020eab4859739Logan#include "CodeEmitter.h"
23c4395235b212be7a626becb0c03020eab4859739Logan#include "CodeMemoryManager.h"
241f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
25da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#include "librsloader.h"
26da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
271f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/ADT/OwningPtr.h"
281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/ADT/StringRef.h"
29da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#include "llvm/ADT/SmallVector.h"
301f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/Target/TargetMachine.h"
311f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
321f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <stddef.h>
331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <list>
351f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <string>
361f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <vector>
371f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <utility>
381f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
391f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
401f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logannamespace llvm {
411f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class LLVMContext;
421f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class Module;
43474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  class MemoryBuffer;
444cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  class NamedMDNode;
454cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien  class TargetData;
461f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
471f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
481f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
491f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logannamespace bcc {
502a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan  class ScriptCompiled;
511f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
521f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class Compiler {
53de2ca79b82b533bae32176c84378d7082788e9eeLogan  private:
541f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    //////////////////////////////////////////////////////////////////////////
551f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The variable section below (e.g., Triple, CodeGenOptLevel)
561f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // is initialized in GlobalInitialization()
571f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    //
581f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static bool GlobalInitialized;
591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
601f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If given, this will be the name of the target triple to compile for.
611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If not given, the initial values defined in this file will be used.
621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::string Triple;
631f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
641f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static llvm::CodeGenOpt::Level CodeGenOptLevel;
651f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
661f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // End of section of GlobalInitializing variables
671f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    /////////////////////////////////////////////////////////////////////////
681f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If given, the name of the target CPU to generate code for.
691f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::string CPU;
701f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
711f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The list of target specific features to enable or disable -- this should
721f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // be a list of strings starting with '+' (enable) or '-' (disable).
731f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::vector<std::string> Features;
741f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
751f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static void LLVMErrorHandler(void *UserData, const std::string &Message);
761f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
771f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef PragmaMetadataName;
781f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef ExportVarMetadataName;
791f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef ExportFuncMetadataName;
80071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines    static const llvm::StringRef ObjectSlotMetadataName;
811f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
821f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    friend class CodeEmitter;
831f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    friend class CodeMemoryManager;
841f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
85de2ca79b82b533bae32176c84378d7082788e9eeLogan
861f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  private:
875c00f4f46a22d9fa8f3eb0ce90aec5eb40d30a9dShih-wei Liao    const char *mCachePath;
88898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao
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
1225c00f4f46a22d9fa8f3eb0ce90aec5eb40d30a9dShih-wei Liao    void setCachePath(const char *cachePath) {
1235c00f4f46a22d9fa8f3eb0ce90aec5eb40d30a9dShih-wei Liao      mCachePath = cachePath;
124898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao      return;
125898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao    }
126898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao
127f340bf71ff377979d279132dcf5a801d76747d1fLogan    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
1281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mpSymbolLookupFn = pFn;
1291f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mpSymbolLookupContext = pContext;
1301f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1311f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
132da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_OLD_JIT
133de2ca79b82b533bae32176c84378d7082788e9eeLogan    CodeMemoryManager *createCodeMemoryManager();
134de2ca79b82b533bae32176c84378d7082788e9eeLogan
135de2ca79b82b533bae32176c84378d7082788e9eeLogan    CodeEmitter *createCodeEmitter();
136da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
137de2ca79b82b533bae32176c84378d7082788e9eeLogan
138da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
139de0ba06cf9f96118261e8d242c0ac08869a54442Shih-wei Liao    bool getObjPath(std::string &objPath);
140898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao
141da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    void *getSymbolAddress(char const *name);
142da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
143da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
144474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM);
145474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
1461f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    int readModule(llvm::Module *module) {
1471f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mModule = module;
1481f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      return hasError();
1491f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1501f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
151474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    int linkModule(llvm::Module *module);
1521f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1531f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    int compile();
1541f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
15538d0607284fc6fdc52b4a3337b2bf9c1f1b0aaa1Logan    char const *getErrorMessage() {
15638d0607284fc6fdc52b4a3337b2bf9c1f1b0aaa1Logan      return mError.c_str();
1571f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1581f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    const llvm::Module *getModule() const {
1601f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      return mModule;
1611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1631f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    ~Compiler();
1641f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1651f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  private:
166de2ca79b82b533bae32176c84378d7082788e9eeLogan
167da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    int runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
168da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                   llvm::NamedMDNode const *ExportVarMetadata,
169da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                   llvm::NamedMDNode const *ExportFuncMetadata);
170da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
171da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
172da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                     llvm::NamedMDNode const *ExportVarMetadata,
173da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien                     llvm::NamedMDNode const *ExportFuncMetadata);
174da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
175da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#if USE_MCJIT
176da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    static void *resolveSymbolAdapter(void *context, char const *name);
177da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien#endif
178da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
179da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    int runLTO(llvm::TargetData *TD,
180da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien               llvm::NamedMDNode const *ExportVarMetadata,
181da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien               llvm::NamedMDNode const *ExportFuncMetadata);
182da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien
183da5e0c369ad20bf70556c7e7cf86807cf171730dLogan Chien    int writeELFExecToFile();
1844cc0033ef37fc28501d2e337c5bd3b072b9edad0Logan Chien
185de2ca79b82b533bae32176c84378d7082788e9eeLogan    bool hasError() const {
186de2ca79b82b533bae32176c84378d7082788e9eeLogan      return !mError.empty();
187de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
188de2ca79b82b533bae32176c84378d7082788e9eeLogan
189de2ca79b82b533bae32176c84378d7082788e9eeLogan    void setError(const char *Error) {
190de2ca79b82b533bae32176c84378d7082788e9eeLogan      mError.assign(Error);  // Copying
191de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
192de2ca79b82b533bae32176c84378d7082788e9eeLogan
193de2ca79b82b533bae32176c84378d7082788e9eeLogan    void setError(const std::string &Error) {
194de2ca79b82b533bae32176c84378d7082788e9eeLogan      mError = Error;
195de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
196de2ca79b82b533bae32176c84378d7082788e9eeLogan
1972417cef58cd051c0b43ce9f9cdc01a17d83ef95aShih-wei Liao  };  // End of class Compiler
1981f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1999b504ebbab0ed81121fdba22617ea4f6cf4a467fLogan} // namespace bcc
2001f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
2011f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#endif // BCC_COMPILER_H
202