Home | History | Annotate | Download | only in bcc
      1 /*
      2  * Copyright 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_RS_COMPILER_DRIVER_H
     18 #define BCC_RS_COMPILER_DRIVER_H
     19 
     20 #include "bcc/Compiler.h"
     21 #include "bcc/Script.h"
     22 
     23 #include "bcinfo/MetadataExtractor.h"
     24 
     25 #include <list>
     26 #include <string>
     27 #include <vector>
     28 
     29 namespace bcc {
     30 
     31 class BCCContext;
     32 class CompilerConfig;
     33 class RSCompilerDriver;
     34 class Source;
     35 
     36 // Type signature for dynamically loaded initialization of an RSCompilerDriver.
     37 typedef void (*RSCompilerDriverInit_t) (bcc::RSCompilerDriver *);
     38 // Name of the function that we attempt to dynamically load/execute.
     39 #define RS_COMPILER_DRIVER_INIT_FN rsCompilerDriverInit
     40 
     41 class RSCompilerDriver {
     42 private:
     43   CompilerConfig *mConfig;
     44   Compiler mCompiler;
     45 
     46   // Are we compiling under an RS debug context with additional checks?
     47   bool mDebugContext;
     48 
     49   // Callback before linking with the runtime library.
     50   RSLinkRuntimeCallback mLinkRuntimeCallback;
     51 
     52   // Do we merge global variables on ARM using LLVM's optimization pass?
     53   // Disabling LLVM's global merge pass allows static globals to be correctly
     54   // emitted to ELF. This can result in decreased performance due to increased
     55   // register pressure, but it does make the resulting code easier to debug
     56   // and work with.
     57   bool mEnableGlobalMerge;
     58 
     59   // Specifies whether we should embed global variable information in the
     60   // code via special RS variables that can be examined later by the driver.
     61   bool mEmbedGlobalInfo;
     62 
     63   // Specifies whether we should skip constant (immutable) global variables
     64   // when potentially embedding information about globals.
     65   bool mEmbedGlobalInfoSkipConstant;
     66 
     67   // Setup the compiler config for the given script. Return true if mConfig has
     68   // been changed and false if it remains unchanged.
     69   bool setupConfig(const Script &pScript);
     70 
     71   // Compiles the provided bitcode, placing the binary at pOutputPath.
     72   // - If pDumpIR is true, a ".ll" file will also be created.
     73   Compiler::ErrorCode compileScript(Script& pScript, const char* pScriptName,
     74                                     const char* pOutputPath,
     75                                     const char* pRuntimePath,
     76                                     const char* pBuildChecksum,
     77                                     bool pDumpIR);
     78 
     79 public:
     80   RSCompilerDriver();
     81   ~RSCompilerDriver();
     82 
     83   Compiler *getCompiler() {
     84     return &mCompiler;
     85   }
     86 
     87   void setConfig(CompilerConfig *config) {
     88     mConfig = config;
     89   }
     90 
     91   void setDebugContext(bool v) {
     92     mDebugContext = v;
     93   }
     94 
     95   void setLinkRuntimeCallback(RSLinkRuntimeCallback c) {
     96     mLinkRuntimeCallback = c;
     97   }
     98 
     99   RSLinkRuntimeCallback getLinkRuntimeCallback() const {
    100     return mLinkRuntimeCallback;
    101   }
    102 
    103   // This function enables/disables merging of global static variables.
    104   // Note that it only takes effect on ARM architectures (other architectures
    105   // do not offer this option).
    106   void setEnableGlobalMerge(bool v) {
    107     mEnableGlobalMerge = v;
    108   }
    109 
    110   bool getEnableGlobalMerge() const {
    111     return mEnableGlobalMerge;
    112   }
    113 
    114   const CompilerConfig * getConfig() const {
    115     return mConfig;
    116   }
    117 
    118   // Set to true if we should embed global variable information in the code.
    119   void setEmbedGlobalInfo(bool v) {
    120     mEmbedGlobalInfo = v;
    121   }
    122 
    123   // Returns true if we should embed global variable information in the code.
    124   bool getEmbedGlobalInfo() const {
    125     return mEmbedGlobalInfo;
    126   }
    127 
    128   // Set to true if we should skip constant (immutable) global variables when
    129   // potentially embedding information about globals.
    130   void setEmbedGlobalInfoSkipConstant(bool v) {
    131     mEmbedGlobalInfoSkipConstant = v;
    132   }
    133 
    134   // Returns true if we should skip constant (immutable) global variables when
    135   // potentially embedding information about globals.
    136   bool getEmbedGlobalInfoSkipConstant() const {
    137     return mEmbedGlobalInfoSkipConstant;
    138   }
    139 
    140   // FIXME: This method accompany with loadScript and compileScript should
    141   //        all be const-methods. They're not now because the getAddress() in
    142   //        SymbolResolverInterface is not a const-method.
    143   // Returns true if script is successfully compiled.
    144   bool build(BCCContext& pContext, const char* pCacheDir, const char* pResName,
    145              const char* pBitcode, size_t pBitcodeSize,
    146              const char *pBuildChecksum, const char* pRuntimePath,
    147              RSLinkRuntimeCallback pLinkRuntimeCallback = nullptr,
    148              bool pDumpIR = false);
    149 
    150   bool buildScriptGroup(
    151       BCCContext& Context, const char* pOutputFilepath, const char* pRuntimePath,
    152       const char* pRuntimeRelaxedPath, bool dumpIR, const char* buildChecksum,
    153       const std::vector<Source*>& sources,
    154       const std::list<std::list<std::pair<int, int>>>& toFuse,
    155       const std::list<std::string>& fused,
    156       const std::list<std::list<std::pair<int, int>>>& invokes,
    157       const std::list<std::string>& invokeBatchNames);
    158 
    159   // Returns true if script is successfully compiled.
    160   bool buildForCompatLib(Script &pScript, const char *pOut,
    161                          const char *pBuildChecksum, const char *pRuntimePath,
    162                          bool pDumpIR);
    163 };
    164 
    165 } // end namespace bcc
    166 
    167 #endif // BCC_RS_COMPILER_DRIVER_H
    168