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