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