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 mCompilerVersion;
    109   uint32_t mOptimizationLevel;
    110 
    111   enum RSFloatPrecision mRSFloatPrecision;
    112 
    113   // Flag to mark that script is threadable.  True by default.
    114   bool mIsThreadable;
    115 
    116   const char *mBuildChecksum;
    117 
    118   bool mHasDebugInfo;
    119 
    120   // Helper functions for extraction
    121   bool populateForEachMetadata(const llvm::NamedMDNode *Names,
    122                                const llvm::NamedMDNode *Signatures);
    123   bool populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata);
    124   bool populateObjectSlotMetadata(const llvm::NamedMDNode *ObjectSlotMetadata);
    125   void populatePragmaMetadata(const llvm::NamedMDNode *PragmaMetadata);
    126   void readThreadableFlag(const llvm::NamedMDNode *ThreadableMetadata);
    127   void readBuildChecksumMetadata(const llvm::NamedMDNode *ChecksumMetadata);
    128 
    129   uint32_t calculateNumInputs(const llvm::Function *Function,
    130                               uint32_t Signature);
    131 
    132  public:
    133 
    134   // Name of metadata node where information extracted from the
    135   // bitcode wrapper should have been stored when we use the
    136   // MetadataExtractor constructor that takes a Module as a parameter.
    137   static const char kWrapperMetadataName[];
    138 
    139   /**
    140    * Reads metadata from \p bitcode.
    141    *
    142    * \param bitcode - input bitcode string.
    143    * \param bitcodeSize - length of \p bitcode string (in bytes).
    144    */
    145   MetadataExtractor(const char *bitcode, size_t bitcodeSize);
    146 
    147   /**
    148    * Reads metadata from \p module.
    149    *
    150    * \param module - input module.
    151    *
    152    * module must contain a metadata node named kWrapperMetadataName.
    153    */
    154   explicit MetadataExtractor(const llvm::Module *module);
    155 
    156   ~MetadataExtractor();
    157 
    158   /**
    159    * Extract the actual metadata from the supplied bitcode.
    160    *
    161    * \return true on success and false if an error occurred.
    162    */
    163   bool extract();
    164 
    165   /**
    166    * \return number of exported global variables (slots) in this script/module.
    167    */
    168   size_t getExportVarCount() const {
    169     return mExportVarCount;
    170   }
    171 
    172   /**
    173    * \return array of exported variable names.
    174    */
    175   const char **getExportVarNameList() const {
    176     return mExportVarNameList;
    177   }
    178 
    179   /**
    180    * \return number of exported global functions (slots) in this script/module.
    181    */
    182   size_t getExportFuncCount() const {
    183     return mExportFuncCount;
    184   }
    185 
    186   /**
    187    * \return array of exported function names.
    188    */
    189   const char **getExportFuncNameList() const {
    190     return mExportFuncNameList;
    191   }
    192 
    193   /**
    194    * \return number of exported ForEach functions in this script/module.
    195    */
    196   size_t getExportForEachSignatureCount() const {
    197     return mExportForEachSignatureCount;
    198   }
    199 
    200   /**
    201    * \return array of exported ForEach function signatures.
    202    */
    203   const uint32_t *getExportForEachSignatureList() const {
    204     return mExportForEachSignatureList;
    205   }
    206 
    207   /**
    208    * \return array of exported ForEach function names.
    209    */
    210   const char **getExportForEachNameList() const {
    211     return mExportForEachNameList;
    212   }
    213 
    214   /**
    215    * \return array of input parameter counts.
    216    */
    217   const uint32_t *getExportForEachInputCountList() const {
    218     return mExportForEachInputCountList;
    219   }
    220 
    221   /**
    222    * \return number of exported general reduce kernels (slots) in this script/module.
    223    */
    224   size_t getExportReduceCount() const {
    225     return mExportReduceCount;
    226   }
    227 
    228   /**
    229    * \return array of exported general reduce kernel descriptions.
    230    */
    231   const Reduce *getExportReduceList() const {
    232     return mExportReduceList;
    233   }
    234 
    235   /**
    236    * \return number of pragmas contained in pragmaKeyList and pragmaValueList.
    237    */
    238   size_t getPragmaCount() const {
    239     return mPragmaCount;
    240   }
    241 
    242   /**
    243    * \return pragma keys (the name for the pragma).
    244    */
    245   const char **getPragmaKeyList() const {
    246     return mPragmaKeyList;
    247   }
    248 
    249   /**
    250    * \return pragma values (contents corresponding to a particular pragma key).
    251    */
    252   const char **getPragmaValueList() const {
    253     return mPragmaValueList;
    254   }
    255 
    256   /**
    257    * \return number of object slots contained in objectSlotList.
    258    */
    259   size_t getObjectSlotCount() const {
    260     return mObjectSlotCount;
    261   }
    262 
    263   /**
    264    * \return array of object slot numbers that must be cleaned up by driver
    265    *         on script teardown.
    266    */
    267   const uint32_t *getObjectSlotList() const {
    268     return mObjectSlotList;
    269   }
    270 
    271   /**
    272    * \return compiler version indicating which guarantees this bitcode is
    273    *         known to obey.
    274    */
    275   uint32_t getCompilerVersion() const {
    276     return mCompilerVersion;
    277   }
    278 
    279   /**
    280    * \return compiler optimization level for this bitcode.  In the case of
    281    *         linked bitcode (user_bitcode + libclcore_bitcode), this is the
    282    *         optimization level of user_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