Compiler.h revision 5c00f4f46a22d9fa8f3eb0ce90aec5eb40d30a9d
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
251f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/ADT/OwningPtr.h"
261f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/ADT/StringRef.h"
271f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include "llvm/Target/TargetMachine.h"
281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
291f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <stddef.h>
301f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
311f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <list>
321f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <string>
331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <vector>
341f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#include <utility>
351f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
361f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
371f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logannamespace llvm {
381f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class LLVMContext;
391f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class Module;
40474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  class MemoryBuffer;
411f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan}
421f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
431f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
441f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logannamespace bcc {
452a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan  class ScriptCompiled;
461f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
471f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  class Compiler {
48de2ca79b82b533bae32176c84378d7082788e9eeLogan  private:
491f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    //////////////////////////////////////////////////////////////////////////
501f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The variable section below (e.g., Triple, CodeGenOptLevel)
511f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // is initialized in GlobalInitialization()
521f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    //
531f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static bool GlobalInitialized;
541f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
551f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If given, this will be the name of the target triple to compile for.
561f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If not given, the initial values defined in this file will be used.
571f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::string Triple;
581f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static llvm::CodeGenOpt::Level CodeGenOptLevel;
601f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // End of section of GlobalInitializing variables
621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    /////////////////////////////////////////////////////////////////////////
631f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // If given, the name of the target CPU to generate code for.
641f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::string CPU;
651f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
661f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The list of target specific features to enable or disable -- this should
671f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // be a list of strings starting with '+' (enable) or '-' (disable).
681f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static std::vector<std::string> Features;
691f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
701f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static void LLVMErrorHandler(void *UserData, const std::string &Message);
711f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
721f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef PragmaMetadataName;
731f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef ExportVarMetadataName;
741f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    static const llvm::StringRef ExportFuncMetadataName;
75071288a0a3bbc3c4a6e161ea7474a5c06bd15ae0Stephen Hines    static const llvm::StringRef ObjectSlotMetadataName;
761f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
771f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    friend class CodeEmitter;
781f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    friend class CodeMemoryManager;
791f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
80de2ca79b82b533bae32176c84378d7082788e9eeLogan
811f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  private:
825c00f4f46a22d9fa8f3eb0ce90aec5eb40d30a9dShih-wei Liao    const char *mCachePath;
83898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao
842a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan    ScriptCompiled *mpResult;
852a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan
861f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    std::string mError;
871f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
881f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The memory manager for code emitter
891f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
901f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
911f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    // The CodeEmitter
921f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::OwningPtr<CodeEmitter> mCodeEmitter;
931f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
941f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    BCCSymbolLookupFn mpSymbolLookupFn;
951f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    void *mpSymbolLookupContext;
961f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
971f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::LLVMContext *mContext;
981f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    llvm::Module *mModule;
991f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1001f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    bool mHasLinked;
1011f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1021f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  public:
1032a6dc82a465631f82fc589c6bc68c15ed264f7ebLogan    Compiler(ScriptCompiled *result);
1041f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
105ecf4cbd022f72436fa7c7e2eb5f920ab6cba4a83Logan    static void GlobalInitialization();
106ecf4cbd022f72436fa7c7e2eb5f920ab6cba4a83Logan
1075c00f4f46a22d9fa8f3eb0ce90aec5eb40d30a9dShih-wei Liao    void setCachePath(const char *cachePath) {
1085c00f4f46a22d9fa8f3eb0ce90aec5eb40d30a9dShih-wei Liao      mCachePath = cachePath;
109898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao      return;
110898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao    }
111898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao
112f340bf71ff377979d279132dcf5a801d76747d1fLogan    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
1131f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mpSymbolLookupFn = pFn;
1141f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mpSymbolLookupContext = pContext;
1151f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1161f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
117de2ca79b82b533bae32176c84378d7082788e9eeLogan    CodeMemoryManager *createCodeMemoryManager();
118de2ca79b82b533bae32176c84378d7082788e9eeLogan
119de2ca79b82b533bae32176c84378d7082788e9eeLogan    CodeEmitter *createCodeEmitter();
120de2ca79b82b533bae32176c84378d7082788e9eeLogan
121de0ba06cf9f96118261e8d242c0ac08869a54442Shih-wei Liao    bool getObjPath(std::string &objPath);
122898c5a90f3a63248d236161130003b3315e03956Shih-wei Liao
123474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    llvm::Module *parseBitcodeFile(llvm::MemoryBuffer *MEM);
124474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
1251f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    int readModule(llvm::Module *module) {
1261f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      mModule = module;
1271f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      return hasError();
1281f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1291f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
130474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    int linkModule(llvm::Module *module);
1311f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1321f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    int compile();
1331f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
13438d0607284fc6fdc52b4a3337b2bf9c1f1b0aaa1Logan    char const *getErrorMessage() {
13538d0607284fc6fdc52b4a3337b2bf9c1f1b0aaa1Logan      return mError.c_str();
1361f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1371f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1381f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    const llvm::Module *getModule() const {
1391f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan      return mModule;
1401f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    }
1411f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1421f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan    ~Compiler();
1431f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1441f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan  private:
145de2ca79b82b533bae32176c84378d7082788e9eeLogan
146de2ca79b82b533bae32176c84378d7082788e9eeLogan    bool hasError() const {
147de2ca79b82b533bae32176c84378d7082788e9eeLogan      return !mError.empty();
148de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
149de2ca79b82b533bae32176c84378d7082788e9eeLogan
150de2ca79b82b533bae32176c84378d7082788e9eeLogan    void setError(const char *Error) {
151de2ca79b82b533bae32176c84378d7082788e9eeLogan      mError.assign(Error);  // Copying
152de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
153de2ca79b82b533bae32176c84378d7082788e9eeLogan
154de2ca79b82b533bae32176c84378d7082788e9eeLogan    void setError(const std::string &Error) {
155de2ca79b82b533bae32176c84378d7082788e9eeLogan      mError = Error;
156de2ca79b82b533bae32176c84378d7082788e9eeLogan    }
157de2ca79b82b533bae32176c84378d7082788e9eeLogan
1582417cef58cd051c0b43ce9f9cdc01a17d83ef95aShih-wei Liao  };  // End of class Compiler
1591f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1609b504ebbab0ed81121fdba22617ea4f6cf4a467fLogan} // namespace bcc
1611f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan
1621f028c027b1df7fde0cd1a1eef9730856e8e5ae9Logan#endif // BCC_COMPILER_H
163