MetadataExtractor.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  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. #include "bcinfo/MetadataExtractor.h"
  17. #include "bcinfo/BitcodeWrapper.h"
  18. #include "rsDefines.h"
  19. #define LOG_TAG "bcinfo"
  20. #include <log/log.h>
  21. #include "Assert.h"
  22. #include "llvm/Bitcode/ReaderWriter.h"
  23. #include "llvm/IR/Constants.h"
  24. #include "llvm/IR/LLVMContext.h"
  25. #include "llvm/IR/Module.h"
  26. #include "llvm/IR/Function.h"
  27. #include "llvm/Support/MemoryBuffer.h"
  28. #ifdef __ANDROID__
  29. #include "Properties.h"
  30. #endif
  31. #include <cstdlib>
  32. namespace bcinfo {
  33. namespace {
  34. llvm::StringRef getStringOperand(const llvm::Metadata *node) {
  35. if (auto *mds = llvm::dyn_cast_or_null<const llvm::MDString>(node)) {
  36. return mds->getString();
  37. }
  38. return llvm::StringRef();
  39. }
  40. bool extractUIntFromMetadataString(uint32_t *value,
  41. const llvm::Metadata *m) {
  42. llvm::StringRef SigString = getStringOperand(m);
  43. if (SigString != "") {
  44. if (!SigString.getAsInteger(10, *value)) {
  45. return true;
  46. }
  47. }
  48. return false;
  49. }
  50. const char *createStringFromValue(llvm::Metadata *m) {
  51. auto ref = getStringOperand(m);
  52. char *c = new char[ref.size() + 1];
  53. memcpy(c, ref.data(), ref.size());
  54. c[ref.size()] = '\0';
  55. return c;
  56. }
  57. const char *createStringFromOptionalValue(llvm::MDNode *n, unsigned opndNum) {
  58. llvm::Metadata *opnd;
  59. if (opndNum >= n->getNumOperands() || !(opnd = n->getOperand(opndNum)))
  60. return nullptr;
  61. return createStringFromValue(opnd);
  62. }
  63. // Collect metadata from NamedMDNodes that contain a list of names
  64. // (strings).
  65. //
  66. // Inputs:
  67. //
  68. // NamedMetadata - An LLVM metadata node, each of whose operands have
  69. // a string as their first entry
  70. //
  71. // NameList - A reference that will hold an allocated array of strings
  72. //
  73. // Count - A reference that will hold the length of the allocated
  74. // array of strings
  75. //
  76. // Return value:
  77. //
  78. // Return true on success, false on error.
  79. //
  80. // Upon success, the function sets NameList to an array of strings
  81. // corresponding the names found in the metadata. The function sets
  82. // Count to the number of entries in NameList.
  83. //
  84. // An error occurs if one of the metadata operands doesn't have a
  85. // first entry.
  86. bool populateNameMetadata(const llvm::NamedMDNode *NameMetadata,
  87. const char **&NameList, size_t &Count) {
  88. if (!NameMetadata) {
  89. NameList = nullptr;
  90. Count = 0;
  91. return true;
  92. }
  93. Count = NameMetadata->getNumOperands();
  94. if (!Count) {
  95. NameList = nullptr;
  96. return true;
  97. }
  98. NameList = new const char *[Count];
  99. for (size_t i = 0; i < Count; i++) {
  100. llvm::MDNode *Name = NameMetadata->getOperand(i);
  101. if (Name && Name->getNumOperands() > 0) {
  102. NameList[i] = createStringFromValue(Name->getOperand(0));
  103. } else {
  104. ALOGE("Metadata operand does not contain a name string");
  105. for (size_t AllocatedIndex = 0; AllocatedIndex < i; AllocatedIndex++) {
  106. delete [] NameList[AllocatedIndex];
  107. }
  108. delete [] NameList;
  109. NameList = nullptr;
  110. Count = 0;
  111. return false;
  112. }
  113. }
  114. return true;
  115. }
  116. } // end anonymous namespace
  117. // Name of metadata node where pragma info resides (should be synced with
  118. // slang.cpp)
  119. static const llvm::StringRef PragmaMetadataName = "#pragma";
  120. // Name of metadata node where exported variable names reside (should be
  121. // synced with slang_rs_metadata.h)
  122. static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
  123. // Name of metadata node where exported function names reside (should be
  124. // synced with slang_rs_metadata.h)
  125. static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
  126. // Name of metadata node where exported ForEach name information resides
  127. // (should be synced with slang_rs_metadata.h)
  128. static const llvm::StringRef ExportForEachNameMetadataName =
  129. "#rs_export_foreach_name";
  130. // Name of metadata node where exported ForEach signature information resides
  131. // (should be synced with slang_rs_metadata.h)
  132. static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
  133. // Name of metadata node where exported general reduce information resides
  134. // (should be synced with slang_rs_metadata.h)
  135. static const llvm::StringRef ExportReduceMetadataName = "#rs_export_reduce";
  136. // Name of metadata node where RS object slot info resides (should be
  137. // synced with slang_rs_metadata.h)
  138. static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
  139. static const llvm::StringRef ThreadableMetadataName = "#rs_is_threadable";
  140. // Name of metadata node where the checksum for this build is stored. (should
  141. // be synced with libbcc/lib/Core/Source.cpp)
  142. static const llvm::StringRef ChecksumMetadataName = "#rs_build_checksum";
  143. // Name of metadata node which contains a list of compile units that have debug
  144. // metadata. If this is null then there is no debug metadata in the compile
  145. // unit.
  146. static const llvm::StringRef DebugInfoMetadataName = "llvm.dbg.cu";
  147. const char MetadataExtractor::kWrapperMetadataName[] = "#rs_wrapper";
  148. MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
  149. : mModule(nullptr), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
  150. mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
  151. mExportReduceCount(0), mExportVarNameList(nullptr),
  152. mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
  153. mExportForEachSignatureList(nullptr),
  154. mExportForEachInputCountList(nullptr),
  155. mExportReduceList(nullptr),
  156. mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
  157. mObjectSlotCount(0), mObjectSlotList(nullptr),
  158. mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
  159. mBuildChecksum(nullptr), mHasDebugInfo(false) {
  160. BitcodeWrapper wrapper(bitcode, bitcodeSize);
  161. mCompilerVersion = wrapper.getCompilerVersion();
  162. mOptimizationLevel = wrapper.getOptimizationLevel();
  163. }
  164. MetadataExtractor::MetadataExtractor(const llvm::Module *module)
  165. : mModule(module), mBitcode(nullptr), mBitcodeSize(0),
  166. mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
  167. mExportReduceCount(0), mExportVarNameList(nullptr),
  168. mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
  169. mExportForEachSignatureList(nullptr),
  170. mExportForEachInputCountList(nullptr),
  171. mExportReduceList(nullptr),
  172. mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
  173. mObjectSlotCount(0), mObjectSlotList(nullptr),
  174. mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
  175. mBuildChecksum(nullptr) {
  176. const llvm::NamedMDNode *const wrapperMDNode = module->getNamedMetadata(kWrapperMetadataName);
  177. bccAssert((wrapperMDNode != nullptr) && (wrapperMDNode->getNumOperands() == 1));
  178. const llvm::MDNode *const wrapperMDTuple = wrapperMDNode->getOperand(0);
  179. bool success = true;
  180. success &= extractUIntFromMetadataString(&mCompilerVersion, wrapperMDTuple->getOperand(0));
  181. success &= extractUIntFromMetadataString(&mOptimizationLevel, wrapperMDTuple->getOperand(1));
  182. bccAssert(success);
  183. }
  184. MetadataExtractor::~MetadataExtractor() {
  185. if (mExportVarNameList) {
  186. for (size_t i = 0; i < mExportVarCount; i++) {
  187. delete [] mExportVarNameList[i];
  188. mExportVarNameList[i] = nullptr;
  189. }
  190. }
  191. delete [] mExportVarNameList;
  192. mExportVarNameList = nullptr;
  193. if (mExportFuncNameList) {
  194. for (size_t i = 0; i < mExportFuncCount; i++) {
  195. delete [] mExportFuncNameList[i];
  196. mExportFuncNameList[i] = nullptr;
  197. }
  198. }
  199. delete [] mExportFuncNameList;
  200. mExportFuncNameList = nullptr;
  201. if (mExportForEachNameList) {
  202. for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
  203. delete [] mExportForEachNameList[i];
  204. mExportForEachNameList[i] = nullptr;
  205. }
  206. }
  207. delete [] mExportForEachNameList;
  208. mExportForEachNameList = nullptr;
  209. delete [] mExportForEachSignatureList;
  210. mExportForEachSignatureList = nullptr;
  211. delete [] mExportForEachInputCountList;
  212. mExportForEachInputCountList = nullptr;
  213. delete [] mExportReduceList;
  214. mExportReduceList = nullptr;
  215. for (size_t i = 0; i < mPragmaCount; i++) {
  216. if (mPragmaKeyList) {
  217. delete [] mPragmaKeyList[i];
  218. mPragmaKeyList[i] = nullptr;
  219. }
  220. if (mPragmaValueList) {
  221. delete [] mPragmaValueList[i];
  222. mPragmaValueList[i] = nullptr;
  223. }
  224. }
  225. delete [] mPragmaKeyList;
  226. mPragmaKeyList = nullptr;
  227. delete [] mPragmaValueList;
  228. mPragmaValueList = nullptr;
  229. delete [] mObjectSlotList;
  230. mObjectSlotList = nullptr;
  231. delete [] mBuildChecksum;
  232. return;
  233. }
  234. bool MetadataExtractor::populateObjectSlotMetadata(
  235. const llvm::NamedMDNode *ObjectSlotMetadata) {
  236. if (!ObjectSlotMetadata) {
  237. return true;
  238. }
  239. mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
  240. if (!mObjectSlotCount) {
  241. return true;
  242. }
  243. std::unique_ptr<uint32_t[]> TmpSlotList(new uint32_t[mObjectSlotCount]());
  244. for (size_t i = 0; i < mObjectSlotCount; i++) {
  245. llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
  246. if (ObjectSlot != nullptr && ObjectSlot->getNumOperands() == 1) {
  247. if (!extractUIntFromMetadataString(&TmpSlotList[i], ObjectSlot->getOperand(0))) {
  248. ALOGE("Non-integer object slot value");
  249. return false;
  250. }
  251. } else {
  252. ALOGE("Corrupt object slot information");
  253. return false;
  254. }
  255. }
  256. delete [] mObjectSlotList;
  257. mObjectSlotList = TmpSlotList.release();
  258. return true;
  259. }
  260. void MetadataExtractor::populatePragmaMetadata(
  261. const llvm::NamedMDNode *PragmaMetadata) {
  262. if (!PragmaMetadata) {
  263. return;
  264. }
  265. mPragmaCount = PragmaMetadata->getNumOperands();
  266. if (!mPragmaCount) {
  267. return;
  268. }
  269. const char **TmpKeyList = new const char*[mPragmaCount];
  270. const char **TmpValueList = new const char*[mPragmaCount];
  271. for (size_t i = 0; i < mPragmaCount; i++) {
  272. llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
  273. if (Pragma != nullptr && Pragma->getNumOperands() == 2) {
  274. llvm::Metadata *PragmaKeyMDS = Pragma->getOperand(0);
  275. TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
  276. llvm::Metadata *PragmaValueMDS = Pragma->getOperand(1);
  277. TmpValueList[i] = createStringFromValue(PragmaValueMDS);
  278. }
  279. }
  280. mPragmaKeyList = TmpKeyList;
  281. mPragmaValueList = TmpValueList;
  282. // Check to see if we have any FP precision-related pragmas.
  283. std::string Relaxed("rs_fp_relaxed");
  284. std::string Imprecise("rs_fp_imprecise");
  285. std::string Full("rs_fp_full");
  286. bool RelaxedPragmaSeen = false;
  287. bool FullPragmaSeen = false;
  288. for (size_t i = 0; i < mPragmaCount; i++) {
  289. if (!Relaxed.compare(mPragmaKeyList[i])) {
  290. RelaxedPragmaSeen = true;
  291. } else if (!Imprecise.compare(mPragmaKeyList[i])) {
  292. ALOGW("rs_fp_imprecise is deprecated. Assuming rs_fp_relaxed instead.");
  293. RelaxedPragmaSeen = true;
  294. } else if (!Full.compare(mPragmaKeyList[i])) {
  295. FullPragmaSeen = true;
  296. }
  297. }
  298. if (RelaxedPragmaSeen && FullPragmaSeen) {
  299. ALOGE("Full and relaxed precision specified at the same time!");
  300. }
  301. mRSFloatPrecision = RelaxedPragmaSeen ? RS_FP_Relaxed : RS_FP_Full;
  302. #ifdef __ANDROID__
  303. // Provide an override for precsiion via adb shell setprop
  304. // adb shell setprop debug.rs.precision rs_fp_full
  305. // adb shell setprop debug.rs.precision rs_fp_relaxed
  306. // adb shell setprop debug.rs.precision rs_fp_imprecise
  307. char PrecisionPropBuf[PROP_VALUE_MAX];
  308. const std::string PrecisionPropName("debug.rs.precision");
  309. property_get("debug.rs.precision", PrecisionPropBuf, "");
  310. if (PrecisionPropBuf[0]) {
  311. if (!Relaxed.compare(PrecisionPropBuf)) {
  312. ALOGI("Switching to RS FP relaxed mode via setprop");
  313. mRSFloatPrecision = RS_FP_Relaxed;
  314. } else if (!Imprecise.compare(PrecisionPropBuf)) {
  315. ALOGW("Switching to RS FP relaxed mode via setprop. rs_fp_imprecise was "
  316. "specified but is deprecated ");
  317. mRSFloatPrecision = RS_FP_Relaxed;
  318. } else if (!Full.compare(PrecisionPropBuf)) {
  319. ALOGI("Switching to RS FP full mode via setprop");
  320. mRSFloatPrecision = RS_FP_Full;
  321. } else {
  322. ALOGE("Unrecognized debug.rs.precision %s", PrecisionPropBuf);
  323. }
  324. }
  325. #endif
  326. }
  327. uint32_t MetadataExtractor::calculateNumInputs(const llvm::Function *Function,
  328. uint32_t Signature) {
  329. if (hasForEachSignatureIn(Signature)) {
  330. uint32_t OtherCount = 0;
  331. OtherCount += hasForEachSignatureUsrData(Signature);
  332. OtherCount += hasForEachSignatureX(Signature);
  333. OtherCount += hasForEachSignatureY(Signature);
  334. OtherCount += hasForEachSignatureZ(Signature);
  335. OtherCount += hasForEachSignatureCtxt(Signature);
  336. OtherCount += hasForEachSignatureOut(Signature) &&
  337. Function->getReturnType()->isVoidTy();
  338. return Function->arg_size() - OtherCount;
  339. } else {
  340. return 0;
  341. }
  342. }
  343. bool MetadataExtractor::populateForEachMetadata(
  344. const llvm::NamedMDNode *Names,
  345. const llvm::NamedMDNode *Signatures) {
  346. if (!Names && !Signatures && mCompilerVersion == 0) {
  347. // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
  348. // section for ForEach. We generate a full signature for a "root" function
  349. // which means that we need to set the bottom 5 bits in the mask.
  350. mExportForEachSignatureCount = 1;
  351. char **TmpNameList = new char*[mExportForEachSignatureCount];
  352. size_t RootLen = strlen(kRoot) + 1;
  353. TmpNameList[0] = new char[RootLen];
  354. strncpy(TmpNameList[0], kRoot, RootLen);
  355. uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
  356. TmpSigList[0] = 0x1f;
  357. mExportForEachNameList = (const char**)TmpNameList;
  358. mExportForEachSignatureList = TmpSigList;
  359. return true;
  360. }
  361. if (Signatures) {
  362. mExportForEachSignatureCount = Signatures->getNumOperands();
  363. if (!mExportForEachSignatureCount) {
  364. return true;
  365. }
  366. } else {
  367. mExportForEachSignatureCount = 0;
  368. mExportForEachSignatureList = nullptr;
  369. return true;
  370. }
  371. std::unique_ptr<uint32_t[]> TmpSigList(new uint32_t[mExportForEachSignatureCount]);
  372. std::unique_ptr<const char *[]> TmpNameList(new const char*[mExportForEachSignatureCount]);
  373. std::unique_ptr<uint32_t[]> TmpInputCountList(new uint32_t[mExportForEachSignatureCount]);
  374. for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
  375. llvm::MDNode *SigNode = Signatures->getOperand(i);
  376. if (SigNode != nullptr && SigNode->getNumOperands() == 1) {
  377. if (!extractUIntFromMetadataString(&TmpSigList[i], SigNode->getOperand(0))) {
  378. ALOGE("Non-integer signature value");
  379. return false;
  380. }
  381. } else {
  382. ALOGE("Corrupt signature information");
  383. return false;
  384. }
  385. }
  386. if (Names) {
  387. for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
  388. llvm::MDNode *Name = Names->getOperand(i);
  389. if (Name != nullptr && Name->getNumOperands() == 1) {
  390. TmpNameList[i] = createStringFromValue(Name->getOperand(0));
  391. // Note that looking up the function by name can fail: One of
  392. // the uses of MetadataExtractor is as part of the
  393. // RSEmbedInfoPass, which bcc_compat runs sufficiently late in
  394. // the phase order that RSKernelExpandPass has already run and
  395. // the original (UNexpanded) kernel function (TmpNameList[i])
  396. // may have been deleted as having no references (if it has
  397. // been inlined into the expanded kernel function and is
  398. // otherwise unreferenced).
  399. llvm::Function *Func =
  400. mModule->getFunction(llvm::StringRef(TmpNameList[i]));
  401. TmpInputCountList[i] = (Func != nullptr) ?
  402. calculateNumInputs(Func, TmpSigList[i]) : 0;
  403. }
  404. }
  405. } else {
  406. if (mExportForEachSignatureCount != 1) {
  407. ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
  408. mExportForEachSignatureCount);
  409. }
  410. char *RootName = new char[5];
  411. strncpy(RootName, "root", 5);
  412. TmpNameList[0] = RootName;
  413. }
  414. delete [] mExportForEachNameList;
  415. mExportForEachNameList = TmpNameList.release();
  416. delete [] mExportForEachSignatureList;
  417. mExportForEachSignatureList = TmpSigList.release();
  418. delete [] mExportForEachInputCountList;
  419. mExportForEachInputCountList = TmpInputCountList.release();
  420. return true;
  421. }
  422. bool MetadataExtractor::populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata) {
  423. mExportReduceCount = 0;
  424. mExportReduceList = nullptr;
  425. if (!ReduceMetadata || !(mExportReduceCount = ReduceMetadata->getNumOperands()))
  426. return true;
  427. std::unique_ptr<Reduce[]> TmpReduceList(new Reduce[mExportReduceCount]);
  428. for (size_t i = 0; i < mExportReduceCount; i++) {
  429. llvm::MDNode *Node = ReduceMetadata->getOperand(i);
  430. if (!Node || Node->getNumOperands() < 3) {
  431. ALOGE("Missing reduce metadata");
  432. return false;
  433. }
  434. TmpReduceList[i].mReduceName = createStringFromValue(Node->getOperand(0));
  435. if (!extractUIntFromMetadataString(&TmpReduceList[i].mAccumulatorDataSize,
  436. Node->getOperand(1))) {
  437. ALOGE("Non-integer accumulator data size value in reduce metadata");
  438. return false;
  439. }
  440. llvm::MDNode *AccumulatorNode = llvm::dyn_cast<llvm::MDNode>(Node->getOperand(2));
  441. if (!AccumulatorNode || AccumulatorNode->getNumOperands() != 2) {
  442. ALOGE("Malformed accumulator node in reduce metadata");
  443. return false;
  444. }
  445. TmpReduceList[i].mAccumulatorName = createStringFromValue(AccumulatorNode->getOperand(0));
  446. if (!extractUIntFromMetadataString(&TmpReduceList[i].mSignature,
  447. AccumulatorNode->getOperand(1))) {
  448. ALOGE("Non-integer signature value in reduce metadata");
  449. return false;
  450. }
  451. // Note that looking up the function by name can fail: One of the
  452. // uses of MetadataExtractor is as part of the RSEmbedInfoPass,
  453. // which bcc_compat runs sufficiently late in the phase order that
  454. // RSKernelExpandPass has already run and the original
  455. // (UNexpanded) accumulator function (mAccumulatorName) may have
  456. // been deleted as having no references (if it has been inlined
  457. // into the expanded accumulator function and is otherwise
  458. // unreferenced).
  459. llvm::Function *Func =
  460. mModule->getFunction(llvm::StringRef(TmpReduceList[i].mAccumulatorName));
  461. // Why calculateNumInputs() - 1? The "-1" is because we don't
  462. // want to treat the accumulator argument as an input.
  463. TmpReduceList[i].mInputCount = (Func ? calculateNumInputs(Func, TmpReduceList[i].mSignature) - 1 : 0);
  464. TmpReduceList[i].mInitializerName = createStringFromOptionalValue(Node, 3);
  465. TmpReduceList[i].mCombinerName = createStringFromOptionalValue(Node, 4);
  466. TmpReduceList[i].mOutConverterName = createStringFromOptionalValue(Node, 5);
  467. TmpReduceList[i].mHalterName = createStringFromOptionalValue(Node, 6);
  468. }
  469. mExportReduceList = TmpReduceList.release();
  470. return true;
  471. }
  472. void MetadataExtractor::readThreadableFlag(
  473. const llvm::NamedMDNode *ThreadableMetadata) {
  474. // Scripts are threadable by default. If we read a valid metadata value for
  475. // 'ThreadableMetadataName' and it is set to 'no', we mark script as non
  476. // threadable. All other exception paths retain the default value.
  477. mIsThreadable = true;
  478. if (ThreadableMetadata == nullptr)
  479. return;
  480. llvm::MDNode *mdNode = ThreadableMetadata->getOperand(0);
  481. if (mdNode == nullptr)
  482. return;
  483. llvm::Metadata *mdValue = mdNode->getOperand(0);
  484. if (mdValue == nullptr)
  485. return;
  486. if (getStringOperand(mdValue) == "no")
  487. mIsThreadable = false;
  488. }
  489. void MetadataExtractor::readBuildChecksumMetadata(
  490. const llvm::NamedMDNode *ChecksumMetadata) {
  491. if (ChecksumMetadata == nullptr)
  492. return;
  493. llvm::MDNode *mdNode = ChecksumMetadata->getOperand(0);
  494. if (mdNode == nullptr)
  495. return;
  496. llvm::Metadata *mdValue = mdNode->getOperand(0);
  497. if (mdValue == nullptr)
  498. return;
  499. mBuildChecksum = createStringFromValue(mdValue);
  500. }
  501. bool MetadataExtractor::extract() {
  502. if (!(mBitcode && mBitcodeSize) && !mModule) {
  503. ALOGE("Invalid/empty bitcode/module");
  504. return false;
  505. }
  506. std::unique_ptr<llvm::LLVMContext> mContext;
  507. bool shouldNullModule = false;
  508. if (!mModule) {
  509. mContext.reset(new llvm::LLVMContext());
  510. std::unique_ptr<llvm::MemoryBuffer> MEM(
  511. llvm::MemoryBuffer::getMemBuffer(
  512. llvm::StringRef(mBitcode, mBitcodeSize), "", false));
  513. std::string error;
  514. llvm::ErrorOr<std::unique_ptr<llvm::Module> > errval =
  515. llvm::parseBitcodeFile(MEM.get()->getMemBufferRef(), *mContext);
  516. if (std::error_code ec = errval.getError()) {
  517. ALOGE("Could not parse bitcode file");
  518. ALOGE("%s", ec.message().c_str());
  519. return false;
  520. }
  521. mModule = errval.get().release();
  522. shouldNullModule = true;
  523. }
  524. const llvm::NamedMDNode *ExportVarMetadata =
  525. mModule->getNamedMetadata(ExportVarMetadataName);
  526. const llvm::NamedMDNode *ExportFuncMetadata =
  527. mModule->getNamedMetadata(ExportFuncMetadataName);
  528. const llvm::NamedMDNode *ExportForEachNameMetadata =
  529. mModule->getNamedMetadata(ExportForEachNameMetadataName);
  530. const llvm::NamedMDNode *ExportForEachMetadata =
  531. mModule->getNamedMetadata(ExportForEachMetadataName);
  532. const llvm::NamedMDNode *ExportReduceMetadata =
  533. mModule->getNamedMetadata(ExportReduceMetadataName);
  534. const llvm::NamedMDNode *PragmaMetadata =
  535. mModule->getNamedMetadata(PragmaMetadataName);
  536. const llvm::NamedMDNode *ObjectSlotMetadata =
  537. mModule->getNamedMetadata(ObjectSlotMetadataName);
  538. const llvm::NamedMDNode *ThreadableMetadata =
  539. mModule->getNamedMetadata(ThreadableMetadataName);
  540. const llvm::NamedMDNode *ChecksumMetadata =
  541. mModule->getNamedMetadata(ChecksumMetadataName);
  542. const llvm::NamedMDNode *DebugInfoMetadata =
  543. mModule->getNamedMetadata(DebugInfoMetadataName);
  544. if (!populateNameMetadata(ExportVarMetadata, mExportVarNameList,
  545. mExportVarCount)) {
  546. ALOGE("Could not populate export variable metadata");
  547. goto err;
  548. }
  549. if (!populateNameMetadata(ExportFuncMetadata, mExportFuncNameList,
  550. mExportFuncCount)) {
  551. ALOGE("Could not populate export function metadata");
  552. goto err;
  553. }
  554. if (!populateForEachMetadata(ExportForEachNameMetadata,
  555. ExportForEachMetadata)) {
  556. ALOGE("Could not populate ForEach signature metadata");
  557. goto err;
  558. }
  559. if (!populateReduceMetadata(ExportReduceMetadata)) {
  560. ALOGE("Could not populate export general reduction metadata");
  561. goto err;
  562. }
  563. populatePragmaMetadata(PragmaMetadata);
  564. if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
  565. ALOGE("Could not populate object slot metadata");
  566. goto err;
  567. }
  568. readThreadableFlag(ThreadableMetadata);
  569. readBuildChecksumMetadata(ChecksumMetadata);
  570. mHasDebugInfo = DebugInfoMetadata != nullptr;
  571. if (shouldNullModule) {
  572. mModule = nullptr;
  573. }
  574. return true;
  575. err:
  576. if (shouldNullModule) {
  577. mModule = nullptr;
  578. }
  579. return false;
  580. }
  581. } // namespace bcinfo