Home | History | Annotate | Download | only in bcinfo
      1 /*
      2  * Copyright 2011-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 __ANDROID_BCINFO_METADATAEXTRACTOR_H__
     18 #define __ANDROID_BCINFO_METADATAEXTRACTOR_H__
     19 
     20 #include <cstddef>
     21 #include <memory>
     22 
     23 #include <stdint.h>
     24 
     25 namespace llvm {
     26   class Function;
     27   class Module;
     28   class NamedMDNode;
     29 }
     30 
     31 namespace bcinfo {
     32 
     33 enum RSFloatPrecision {
     34   RS_FP_Full = 0,
     35   RS_FP_Relaxed = 1,
     36 };
     37 
     38 enum MetadataSignatureBitval {
     39   MD_SIG_None        = 0,
     40   MD_SIG_In          = 0x000001,
     41   MD_SIG_Out         = 0x000002,
     42   MD_SIG_Usr         = 0x000004,
     43   MD_SIG_X           = 0x000008,
     44   MD_SIG_Y           = 0x000010,
     45   MD_SIG_Kernel      = 0x000020,
     46   MD_SIG_Z           = 0x000040,
     47   MD_SIG_Ctxt        = 0x000080,
     48 };
     49 
     50 class MetadataExtractor {
     51  public:
     52   struct Reduce {
     53     // These strings are owned by the Reduce instance, and deleted upon its destruction.
     54     // They are assumed to have been allocated by "new []" and hence are deleted by "delete []".
     55     const char *mReduceName;
     56     const char *mInitializerName;
     57     const char *mAccumulatorName;
     58     const char *mCombinerName;
     59     const char *mOutConverterName;
     60     const char *mHalterName;
     61 
     62     uint32_t mSignature;   // of accumulator function
     63     uint32_t mInputCount;  // of accumulator function (and of kernel itself)
     64     uint32_t mAccumulatorDataSize;  // in bytes
     65 
     66     Reduce() :
     67         mReduceName(nullptr),
     68         mInitializerName(nullptr), mAccumulatorName(nullptr), mCombinerName(nullptr),
     69         mOutConverterName(nullptr), mHalterName(nullptr),
     70         mSignature(0), mInputCount(0), mAccumulatorDataSize(0) {
     71     }
     72     ~Reduce() {
     73       delete [] mReduceName;
     74       delete [] mInitializerName;
     75       delete [] mAccumulatorName;
     76       delete [] mCombinerName;
     77       delete [] mOutConverterName;
     78       delete [] mHalterName;
     79     }
     80 
     81     Reduce(const Reduce &) = delete;
     82     void operator=(const Reduce &) = delete;
     83   };
     84 
     85  private:
     86   const llvm::Module *mModule;
     87   const char *mBitcode;
     88   size_t mBitcodeSize;
     89 
     90   size_t mExportVarCount;
     91   size_t mExportFuncCount;
     92   size_t mExportForEachSignatureCount;
     93   size_t mExportReduceCount;
     94   const char **mExportVarNameList;
     95   const char **mExportFuncNameList;
     96   const char **mExportForEachNameList;
     97   const uint32_t *mExportForEachSignatureList;
     98   const uint32_t *mExportForEachInputCountList;
     99   const Reduce *mExportReduceList;
    100 
    101   size_t mPragmaCount;
    102   const char **mPragmaKeyList;
    103   const char **mPragmaValueList;
    104 
    105   size_t mObjectSlotCount;
    106   const uint32_t *mObjectSlotList;
    107 
    108   uint32_t mTargetAPI;
    109   uint32_t mCompilerVersion;
    110   uint32_t mOptimizationLevel;
    111 
    112   enum RSFloatPrecision mRSFloatPrecision;
    113 
    114   // Flag to mark that script is threadable.  True by default.
    115   bool mIsThreadable;
    116 
    117   const char *mBuildChecksum;
    118 
    119   bool mHasDebugInfo;
    120 
    121   // Helper functions for extraction
    122   bool populateForEachMetadata(const llvm::NamedMDNode *Names,
    123                                const llvm::NamedMDNode *Signatures);
    124   bool populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata);
    125   bool populateObjectSlotMetadata(const llvm::NamedMDNode *ObjectSlotMetadata);
    126   void populatePragmaMetadata(const llvm::NamedMDNode *PragmaMetadata);
    127   void readThreadableFlag(const llvm::NamedMDNode *ThreadableMetadata);
    128   void readBuildChecksumMetadata(const llvm::NamedMDNode *ChecksumMetadata);
    129 
    130   uint32_t calculateNumInputs(const llvm::Function *Function,
    131                               uint32_t Signature);
    132 
    133  public:
    134   /**
    135    * Reads metadata from \p bitcode.
    136    *
    137    * \param bitcode - input bitcode string.
    138    * \param bitcodeSize - length of \p bitcode string (in bytes).
    139    */
    140   MetadataExtractor(const char *bitcode, size_t bitcodeSize);
    141 
    142   /**
    143    * Reads metadata from \p module.
    144    *
    145    * \param module - input module.
    146    */
    147   MetadataExtractor(const llvm::Module *module);
    148 
    149   ~MetadataExtractor();
    150 
    151   /**
    152    * Extract the actual metadata from the supplied bitcode.
    153    *
    154    * \return true on success and false if an error occurred.
    155    */
    156   bool extract();
    157 
    158   /**
    159    * \return target API level of this bitcode.
    160    *
    161    * The target API is used during the SDK compilation to provide proper
    162    * visibility of the RenderScript runtime API functions.
    163    */
    164   uint32_t getTargetAPI() const {
    165     return mTargetAPI;
    166   }
    167 
    168   /**
    169    * \return number of exported global variables (slots) in this script/module.
    170    */
    171   size_t getExportVarCount() const {
    172     return mExportVarCount;
    173   }
    174 
    175   /**
    176    * \return array of exported variable names.
    177    */
    178   const char **getExportVarNameList() const {
    179     return mExportVarNameList;
    180   }
    181 
    182   /**
    183    * \return number of exported global functions (slots) in this script/module.
    184    */
    185   size_t getExportFuncCount() const {
    186     return mExportFuncCount;
    187   }
    188 
    189   /**
    190    * \return array of exported function names.
    191    */
    192   const char **getExportFuncNameList() const {
    193     return mExportFuncNameList;
    194   }
    195 
    196   /**
    197    * \return number of exported ForEach functions in this script/module.
    198    */
    199   size_t getExportForEachSignatureCount() const {
    200     return mExportForEachSignatureCount;
    201   }
    202 
    203   /**
    204    * \return array of exported ForEach function signatures.
    205    */
    206   const uint32_t *getExportForEachSignatureList() const {
    207     return mExportForEachSignatureList;
    208   }
    209 
    210   /**
    211    * \return array of exported ForEach function names.
    212    */
    213   const char **getExportForEachNameList() const {
    214     return mExportForEachNameList;
    215   }
    216 
    217   /**
    218    * \return array of input parameter counts.
    219    */
    220   const uint32_t *getExportForEachInputCountList() const {
    221     return mExportForEachInputCountList;
    222   }
    223 
    224   /**
    225    * \return number of exported general reduce kernels (slots) in this script/module.
    226    */
    227   size_t getExportReduceCount() const {
    228     return mExportReduceCount;
    229   }
    230 
    231   /**
    232    * \return array of exported general reduce kernel descriptions.
    233    */
    234   const Reduce *getExportReduceList() const {
    235     return mExportReduceList;
    236   }
    237 
    238   /**
    239    * \return number of pragmas contained in pragmaKeyList and pragmaValueList.
    240    */
    241   size_t getPragmaCount() const {
    242     return mPragmaCount;
    243   }
    244 
    245   /**
    246    * \return pragma keys (the name for the pragma).
    247    */
    248   const char **getPragmaKeyList() const {
    249     return mPragmaKeyList;
    250   }
    251 
    252   /**
    253    * \return pragma values (contents corresponding to a particular pragma key).
    254    */
    255   const char **getPragmaValueList() const {
    256     return mPragmaValueList;
    257   }
    258 
    259   /**
    260    * \return number of object slots contained in objectSlotList.
    261    */
    262   size_t getObjectSlotCount() const {
    263     return mObjectSlotCount;
    264   }
    265 
    266   /**
    267    * \return array of object slot numbers that must be cleaned up by driver
    268    *         on script teardown.
    269    */
    270   const uint32_t *getObjectSlotList() const {
    271     return mObjectSlotList;
    272   }
    273 
    274   /**
    275    * \return compiler version that generated this bitcode.
    276    */
    277   uint32_t getCompilerVersion() const {
    278     return mCompilerVersion;
    279   }
    280 
    281   /**
    282    * \return compiler optimization level for this bitcode.
    283    */
    284   uint32_t getOptimizationLevel() const {
    285     return mOptimizationLevel;
    286   }
    287 
    288   /**
    289    * \return minimal floating point precision that the script requires.
    290    */
    291   enum RSFloatPrecision getRSFloatPrecision() const {
    292     return mRSFloatPrecision;
    293   }
    294 
    295   /**
    296    * \return whether or not this ForEach function signature has an "In"
    297    * parameter.
    298    *
    299    * \param sig - ForEach function signature to check.
    300    */
    301   static bool hasForEachSignatureIn(uint32_t sig) {
    302     return sig & MD_SIG_In;
    303   }
    304 
    305   /**
    306    * \return whether or not this ForEach function signature has an "Out"
    307    * parameter.
    308    *
    309    * \param sig - ForEach function signature to check.
    310    */
    311   static bool hasForEachSignatureOut(uint32_t sig) {
    312     return sig & MD_SIG_Out;
    313   }
    314 
    315   /**
    316    * \return whether or not this ForEach function signature has a "UsrData"
    317    * parameter.
    318    *
    319    * \param sig - ForEach function signature to check.
    320    */
    321   static bool hasForEachSignatureUsrData(uint32_t sig) {
    322     return sig & MD_SIG_Usr;
    323   }
    324 
    325   /**
    326    * \return whether or not this ForEach function signature has an "X"
    327    * parameter.
    328    *
    329    * \param sig - ForEach function signature to check.
    330    */
    331   static bool hasForEachSignatureX(uint32_t sig) {
    332     return sig & MD_SIG_X;
    333   }
    334 
    335   /**
    336    * \return whether or not this ForEach function signature has a "Y"
    337    * parameter.
    338    *
    339    * \param sig - ForEach function signature to check.
    340    */
    341   static bool hasForEachSignatureY(uint32_t sig) {
    342     return sig & MD_SIG_Y;
    343   }
    344 
    345   /**
    346    * \return whether or not this ForEach function signature is a
    347    * pass-by-value "Kernel".
    348    *
    349    * \param sig - ForEach function signature to check.
    350    */
    351   static bool hasForEachSignatureKernel(uint32_t sig) {
    352     return sig & MD_SIG_Kernel;
    353   }
    354 
    355   /**
    356    * \return whether or not this ForEach function signature has a "Z"
    357    * parameter.
    358    *
    359    * \param sig - ForEach function signature to check.
    360    */
    361   static bool hasForEachSignatureZ(uint32_t sig) {
    362     return sig & MD_SIG_Z;
    363   }
    364 
    365   /**
    366    * \return whether or not this ForEach function signature has a "Ctxt"
    367    * parameter.
    368    *
    369    * \param sig - ForEach function signature to check.
    370    */
    371   static bool hasForEachSignatureCtxt(uint32_t sig) {
    372     return sig & MD_SIG_Ctxt;
    373   }
    374 
    375   /**
    376    * \return whether "Kernels" in this script can be processed
    377    * by multiple threads
    378    */
    379 
    380   bool isThreadable() const {
    381     return mIsThreadable;
    382   }
    383 
    384   /**
    385    * \return the build checksum extracted from the LLVM metadata
    386    */
    387   const char *getBuildChecksum() const {
    388     return mBuildChecksum;
    389   }
    390 
    391   /**
    392    * \return whether the module contains debug metadata
    393    */
    394   bool hasDebugInfo() const {
    395     return mHasDebugInfo;
    396   }
    397 };
    398 
    399 }  // namespace bcinfo
    400 
    401 #endif  // __ANDROID_BCINFO_METADATAEXTRACTOR_H__
    402