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 20 namespace llvm { 21 22 class raw_ostream; 23 class PassManager; 24 class DataLayout; 25 class TargetMachine; 26 27 } // end namespace llvm 28 29 namespace bcc { 30 31 class CompilerConfig; 32 class OutputFile; 33 class 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. 47 class Compiler { 48 public: 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 kMaxErrorCode, 73 }; 74 75 static const char *GetErrorString(enum ErrorCode pErrCode); 76 77 private: 78 llvm::TargetMachine *mTarget; 79 // LTO is enabled by default. 80 bool mEnableLTO; 81 82 enum ErrorCode runLTO(Script &pScript); 83 enum ErrorCode runCodeGen(Script &pScript, llvm::raw_ostream &pResult); 84 85 public: 86 Compiler(); 87 Compiler(const CompilerConfig &pConfig); 88 89 enum ErrorCode config(const CompilerConfig &pConfig); 90 91 // Compile a script and output the result to a LLVM stream. 92 enum ErrorCode compile(Script &pScript, llvm::raw_ostream &pResult); 93 94 // Compile a script and output the result to a file. 95 enum ErrorCode compile(Script &pScript, OutputFile &pResult); 96 getTargetMachine()97 const llvm::TargetMachine& getTargetMachine() const 98 { return *mTarget; } 99 100 void enableLTO(bool pEnable = true) 101 { mEnableLTO = pEnable; } 102 103 virtual ~Compiler(); 104 105 protected: 106 //===--------------------------------------------------------------------===// 107 // Plugin callbacks for sub-class. 108 //===--------------------------------------------------------------------===// 109 // Called before adding first pass to code-generation passes. beforeAddLTOPasses(Script & pScript,llvm::PassManager & pPM)110 virtual bool beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM) 111 { return true; } 112 113 // Called after adding last pass to code-generation passes. afterAddLTOPasses(Script & pScript,llvm::PassManager & pPM)114 virtual bool afterAddLTOPasses(Script &pScript, llvm::PassManager &pPM) 115 { return true; } 116 117 // Called before executing code-generation passes. beforeExecuteLTOPasses(Script & pScript,llvm::PassManager & pPM)118 virtual bool beforeExecuteLTOPasses(Script &pScript, 119 llvm::PassManager &pPM) 120 { return true; } 121 122 // Called after executing code-generation passes. afterExecuteLTOPasses(Script & pScript)123 virtual bool afterExecuteLTOPasses(Script &pScript) 124 { return true; } 125 126 // Called before adding first pass to code-generation passes. beforeAddCodeGenPasses(Script & pScript,llvm::PassManager & pPM)127 virtual bool beforeAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM) 128 { return true; } 129 130 // Called after adding last pass to code-generation passes. afterAddCodeGenPasses(Script & pScript,llvm::PassManager & pPM)131 virtual bool afterAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM) 132 { return true; } 133 134 // Called before executing code-generation passes. beforeExecuteCodeGenPasses(Script & pScript,llvm::PassManager & pPM)135 virtual bool beforeExecuteCodeGenPasses(Script &pScript, 136 llvm::PassManager &pPM) 137 { return true; } 138 139 // Called after executing code-generation passes. afterExecuteCodeGenPasses(Script & pScript)140 virtual bool afterExecuteCodeGenPasses(Script &pScript) 141 { return true; } 142 }; 143 144 } // end namespace bcc 145 146 #endif // BCC_COMPILER_H 147