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 ReduceReduce66 Reduce() : 67 mReduceName(nullptr), 68 mInitializerName(nullptr), mAccumulatorName(nullptr), mCombinerName(nullptr), 69 mOutConverterName(nullptr), mHalterName(nullptr), 70 mSignature(0), mInputCount(0), mAccumulatorDataSize(0) { 71 } ~ReduceReduce72 ~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 */ getTargetAPI()164 uint32_t getTargetAPI() const { 165 return mTargetAPI; 166 } 167 168 /** 169 * \return number of exported global variables (slots) in this script/module. 170 */ getExportVarCount()171 size_t getExportVarCount() const { 172 return mExportVarCount; 173 } 174 175 /** 176 * \return array of exported variable names. 177 */ getExportVarNameList()178 const char **getExportVarNameList() const { 179 return mExportVarNameList; 180 } 181 182 /** 183 * \return number of exported global functions (slots) in this script/module. 184 */ getExportFuncCount()185 size_t getExportFuncCount() const { 186 return mExportFuncCount; 187 } 188 189 /** 190 * \return array of exported function names. 191 */ getExportFuncNameList()192 const char **getExportFuncNameList() const { 193 return mExportFuncNameList; 194 } 195 196 /** 197 * \return number of exported ForEach functions in this script/module. 198 */ getExportForEachSignatureCount()199 size_t getExportForEachSignatureCount() const { 200 return mExportForEachSignatureCount; 201 } 202 203 /** 204 * \return array of exported ForEach function signatures. 205 */ getExportForEachSignatureList()206 const uint32_t *getExportForEachSignatureList() const { 207 return mExportForEachSignatureList; 208 } 209 210 /** 211 * \return array of exported ForEach function names. 212 */ getExportForEachNameList()213 const char **getExportForEachNameList() const { 214 return mExportForEachNameList; 215 } 216 217 /** 218 * \return array of input parameter counts. 219 */ getExportForEachInputCountList()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 */ getExportReduceCount()227 size_t getExportReduceCount() const { 228 return mExportReduceCount; 229 } 230 231 /** 232 * \return array of exported general reduce kernel descriptions. 233 */ getExportReduceList()234 const Reduce *getExportReduceList() const { 235 return mExportReduceList; 236 } 237 238 /** 239 * \return number of pragmas contained in pragmaKeyList and pragmaValueList. 240 */ getPragmaCount()241 size_t getPragmaCount() const { 242 return mPragmaCount; 243 } 244 245 /** 246 * \return pragma keys (the name for the pragma). 247 */ getPragmaKeyList()248 const char **getPragmaKeyList() const { 249 return mPragmaKeyList; 250 } 251 252 /** 253 * \return pragma values (contents corresponding to a particular pragma key). 254 */ getPragmaValueList()255 const char **getPragmaValueList() const { 256 return mPragmaValueList; 257 } 258 259 /** 260 * \return number of object slots contained in objectSlotList. 261 */ getObjectSlotCount()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 */ getObjectSlotList()270 const uint32_t *getObjectSlotList() const { 271 return mObjectSlotList; 272 } 273 274 /** 275 * \return compiler version that generated this bitcode. 276 */ getCompilerVersion()277 uint32_t getCompilerVersion() const { 278 return mCompilerVersion; 279 } 280 281 /** 282 * \return compiler optimization level for this bitcode. 283 */ getOptimizationLevel()284 uint32_t getOptimizationLevel() const { 285 return mOptimizationLevel; 286 } 287 288 /** 289 * \return minimal floating point precision that the script requires. 290 */ getRSFloatPrecision()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 */ hasForEachSignatureIn(uint32_t sig)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 */ hasForEachSignatureOut(uint32_t sig)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 */ hasForEachSignatureUsrData(uint32_t sig)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 */ hasForEachSignatureX(uint32_t sig)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 */ hasForEachSignatureY(uint32_t sig)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 */ hasForEachSignatureKernel(uint32_t sig)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 */ hasForEachSignatureZ(uint32_t sig)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 */ hasForEachSignatureCtxt(uint32_t sig)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 isThreadable()380 bool isThreadable() const { 381 return mIsThreadable; 382 } 383 384 /** 385 * \return the build checksum extracted from the LLVM metadata 386 */ getBuildChecksum()387 const char *getBuildChecksum() const { 388 return mBuildChecksum; 389 } 390 391 /** 392 * \return whether the module contains debug metadata 393 */ hasDebugInfo()394 bool hasDebugInfo() const { 395 return mHasDebugInfo; 396 } 397 }; 398 399 } // namespace bcinfo 400 401 #endif // __ANDROID_BCINFO_METADATAEXTRACTOR_H__ 402