Compiler.h revision 27fb7edfd3f53f52fba6ee81267c02f7896198a3
1/* 2 * Copyright 2010-2012, 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 20namespace llvm { 21 22class raw_ostream; 23class PassManager; 24class DataLayout; 25class TargetMachine; 26 27} // end namespace llvm 28 29namespace bcc { 30 31class CompilerConfig; 32class OutputFile; 33class Script; 34 35//===----------------------------------------------------------------------===// 36// Design of Compiler 37//===----------------------------------------------------------------------===// 38// 1. A compiler instance can be constructed provided an "initial config." 39// 2. A compiler can later be re-configured using config(). 40// 3. Once config() is invoked, it'll re-create TargetMachine instance (i.e., 41// mTarget) according to the configuration supplied. TargetMachine instance 42// is *shared* across the different calls to compile() before the next call 43// to config(). 44// 4. Once a compiler instance is created, you can use the compile() service 45// to compile the file over and over again. Each call uses TargetMachine 46// instance to construct the compilation passes. 47class Compiler { 48public: 49 enum ErrorCode { 50 kSuccess, 51 52 kInvalidConfigNoTarget, 53 kErrCreateTargetMachine, 54 kErrSwitchTargetMachine, 55 kErrNoTargetMachine, 56 kErrDataLayoutNoMemory, 57 kErrMaterialization, 58 kErrInvalidOutputFileState, 59 kErrPrepareOutput, 60 kPrepareCodeGenPass, 61 62 kErrHookBeforeAddLTOPasses, 63 kErrHookAfterAddLTOPasses, 64 kErrHookBeforeExecuteLTOPasses, 65 kErrHookAfterExecuteLTOPasses, 66 67 kErrHookBeforeAddCodeGenPasses, 68 kErrHookAfterAddCodeGenPasses, 69 kErrHookBeforeExecuteCodeGenPasses, 70 kErrHookAfterExecuteCodeGenPasses, 71 72 kErrInvalidSource, 73 74 kMaxErrorCode 75 }; 76 77 static const char *GetErrorString(enum ErrorCode pErrCode); 78 79private: 80 llvm::TargetMachine *mTarget; 81 // LTO is enabled by default. 82 bool mEnableLTO; 83 84 enum ErrorCode runLTO(Script &pScript); 85 enum ErrorCode runCodeGen(Script &pScript, llvm::raw_ostream &pResult); 86 87public: 88 Compiler(); 89 Compiler(const CompilerConfig &pConfig); 90 91 enum ErrorCode config(const CompilerConfig &pConfig); 92 93 // Compile a script and output the result to a LLVM stream. 94 // 95 // @param IRStream If not NULL, the LLVM-IR that is fed to code generation 96 // will be written to IRStream. 97 enum ErrorCode compile(Script &pScript, llvm::raw_ostream &pResult, 98 llvm::raw_ostream *IRStream); 99 100 // Compile a script and output the result to a file. 101 enum ErrorCode compile(Script &pScript, OutputFile &pResult, 102 llvm::raw_ostream *IRStream = 0); 103 104 const llvm::TargetMachine& getTargetMachine() const 105 { return *mTarget; } 106 107 void enableLTO(bool pEnable = true) 108 { mEnableLTO = pEnable; } 109 110 virtual ~Compiler(); 111 112protected: 113 //===--------------------------------------------------------------------===// 114 // Plugin callbacks for sub-class. 115 //===--------------------------------------------------------------------===// 116 // Called before adding first pass to code-generation passes. 117 virtual bool beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM) 118 { return true; } 119 120 // Called after adding last pass to code-generation passes. 121 virtual bool afterAddLTOPasses(Script &pScript, llvm::PassManager &pPM) 122 { return true; } 123 124 // Called before executing code-generation passes. 125 virtual bool beforeExecuteLTOPasses(Script &pScript, 126 llvm::PassManager &pPM) 127 { return true; } 128 129 // Called after executing code-generation passes. 130 virtual bool afterExecuteLTOPasses(Script &pScript) 131 { return true; } 132 133 // Called before adding first pass to code-generation passes. 134 virtual bool beforeAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM) 135 { return true; } 136 137 // Called after adding last pass to code-generation passes. 138 virtual bool afterAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM) 139 { return true; } 140 141 // Called before executing code-generation passes. 142 virtual bool beforeExecuteCodeGenPasses(Script &pScript, 143 llvm::PassManager &pPM) 144 { return true; } 145 146 // Called after executing code-generation passes. 147 virtual bool afterExecuteCodeGenPasses(Script &pScript) 148 { return true; } 149}; 150 151} // end namespace bcc 152 153#endif // BCC_COMPILER_H 154