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