123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- /*
- * Copyright 2011-2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "bcinfo/MetadataExtractor.h"
- #include "bcinfo/BitcodeWrapper.h"
- #include "rsDefines.h"
- #define LOG_TAG "bcinfo"
- #include <log/log.h>
- #include "Assert.h"
- #include "llvm/Bitcode/ReaderWriter.h"
- #include "llvm/IR/Constants.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/Module.h"
- #include "llvm/IR/Function.h"
- #include "llvm/Support/MemoryBuffer.h"
- #ifdef __ANDROID__
- #include "Properties.h"
- #endif
- #include <cstdlib>
- namespace bcinfo {
- namespace {
- llvm::StringRef getStringOperand(const llvm::Metadata *node) {
- if (auto *mds = llvm::dyn_cast_or_null<const llvm::MDString>(node)) {
- return mds->getString();
- }
- return llvm::StringRef();
- }
- bool extractUIntFromMetadataString(uint32_t *value,
- const llvm::Metadata *m) {
- llvm::StringRef SigString = getStringOperand(m);
- if (SigString != "") {
- if (!SigString.getAsInteger(10, *value)) {
- return true;
- }
- }
- return false;
- }
- const char *createStringFromValue(llvm::Metadata *m) {
- auto ref = getStringOperand(m);
- char *c = new char[ref.size() + 1];
- memcpy(c, ref.data(), ref.size());
- c[ref.size()] = '\0';
- return c;
- }
- const char *createStringFromOptionalValue(llvm::MDNode *n, unsigned opndNum) {
- llvm::Metadata *opnd;
- if (opndNum >= n->getNumOperands() || !(opnd = n->getOperand(opndNum)))
- return nullptr;
- return createStringFromValue(opnd);
- }
- // Collect metadata from NamedMDNodes that contain a list of names
- // (strings).
- //
- // Inputs:
- //
- // NamedMetadata - An LLVM metadata node, each of whose operands have
- // a string as their first entry
- //
- // NameList - A reference that will hold an allocated array of strings
- //
- // Count - A reference that will hold the length of the allocated
- // array of strings
- //
- // Return value:
- //
- // Return true on success, false on error.
- //
- // Upon success, the function sets NameList to an array of strings
- // corresponding the names found in the metadata. The function sets
- // Count to the number of entries in NameList.
- //
- // An error occurs if one of the metadata operands doesn't have a
- // first entry.
- bool populateNameMetadata(const llvm::NamedMDNode *NameMetadata,
- const char **&NameList, size_t &Count) {
- if (!NameMetadata) {
- NameList = nullptr;
- Count = 0;
- return true;
- }
- Count = NameMetadata->getNumOperands();
- if (!Count) {
- NameList = nullptr;
- return true;
- }
- NameList = new const char *[Count];
- for (size_t i = 0; i < Count; i++) {
- llvm::MDNode *Name = NameMetadata->getOperand(i);
- if (Name && Name->getNumOperands() > 0) {
- NameList[i] = createStringFromValue(Name->getOperand(0));
- } else {
- ALOGE("Metadata operand does not contain a name string");
- for (size_t AllocatedIndex = 0; AllocatedIndex < i; AllocatedIndex++) {
- delete [] NameList[AllocatedIndex];
- }
- delete [] NameList;
- NameList = nullptr;
- Count = 0;
- return false;
- }
- }
- return true;
- }
- } // end anonymous namespace
- // Name of metadata node where pragma info resides (should be synced with
- // slang.cpp)
- static const llvm::StringRef PragmaMetadataName = "#pragma";
- // Name of metadata node where exported variable names reside (should be
- // synced with slang_rs_metadata.h)
- static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
- // Name of metadata node where exported function names reside (should be
- // synced with slang_rs_metadata.h)
- static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
- // Name of metadata node where exported ForEach name information resides
- // (should be synced with slang_rs_metadata.h)
- static const llvm::StringRef ExportForEachNameMetadataName =
- "#rs_export_foreach_name";
- // Name of metadata node where exported ForEach signature information resides
- // (should be synced with slang_rs_metadata.h)
- static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
- // Name of metadata node where exported general reduce information resides
- // (should be synced with slang_rs_metadata.h)
- static const llvm::StringRef ExportReduceMetadataName = "#rs_export_reduce";
- // Name of metadata node where RS object slot info resides (should be
- // synced with slang_rs_metadata.h)
- static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
- static const llvm::StringRef ThreadableMetadataName = "#rs_is_threadable";
- // Name of metadata node where the checksum for this build is stored. (should
- // be synced with libbcc/lib/Core/Source.cpp)
- static const llvm::StringRef ChecksumMetadataName = "#rs_build_checksum";
- // Name of metadata node which contains a list of compile units that have debug
- // metadata. If this is null then there is no debug metadata in the compile
- // unit.
- static const llvm::StringRef DebugInfoMetadataName = "llvm.dbg.cu";
- const char MetadataExtractor::kWrapperMetadataName[] = "#rs_wrapper";
- MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
- : mModule(nullptr), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
- mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
- mExportReduceCount(0), mExportVarNameList(nullptr),
- mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
- mExportForEachSignatureList(nullptr),
- mExportForEachInputCountList(nullptr),
- mExportReduceList(nullptr),
- mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
- mObjectSlotCount(0), mObjectSlotList(nullptr),
- mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
- mBuildChecksum(nullptr), mHasDebugInfo(false) {
- BitcodeWrapper wrapper(bitcode, bitcodeSize);
- mCompilerVersion = wrapper.getCompilerVersion();
- mOptimizationLevel = wrapper.getOptimizationLevel();
- }
- MetadataExtractor::MetadataExtractor(const llvm::Module *module)
- : mModule(module), mBitcode(nullptr), mBitcodeSize(0),
- mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
- mExportReduceCount(0), mExportVarNameList(nullptr),
- mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
- mExportForEachSignatureList(nullptr),
- mExportForEachInputCountList(nullptr),
- mExportReduceList(nullptr),
- mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
- mObjectSlotCount(0), mObjectSlotList(nullptr),
- mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
- mBuildChecksum(nullptr) {
- const llvm::NamedMDNode *const wrapperMDNode = module->getNamedMetadata(kWrapperMetadataName);
- bccAssert((wrapperMDNode != nullptr) && (wrapperMDNode->getNumOperands() == 1));
- const llvm::MDNode *const wrapperMDTuple = wrapperMDNode->getOperand(0);
- bool success = true;
- success &= extractUIntFromMetadataString(&mCompilerVersion, wrapperMDTuple->getOperand(0));
- success &= extractUIntFromMetadataString(&mOptimizationLevel, wrapperMDTuple->getOperand(1));
- bccAssert(success);
- }
- MetadataExtractor::~MetadataExtractor() {
- if (mExportVarNameList) {
- for (size_t i = 0; i < mExportVarCount; i++) {
- delete [] mExportVarNameList[i];
- mExportVarNameList[i] = nullptr;
- }
- }
- delete [] mExportVarNameList;
- mExportVarNameList = nullptr;
- if (mExportFuncNameList) {
- for (size_t i = 0; i < mExportFuncCount; i++) {
- delete [] mExportFuncNameList[i];
- mExportFuncNameList[i] = nullptr;
- }
- }
- delete [] mExportFuncNameList;
- mExportFuncNameList = nullptr;
- if (mExportForEachNameList) {
- for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
- delete [] mExportForEachNameList[i];
- mExportForEachNameList[i] = nullptr;
- }
- }
- delete [] mExportForEachNameList;
- mExportForEachNameList = nullptr;
- delete [] mExportForEachSignatureList;
- mExportForEachSignatureList = nullptr;
- delete [] mExportForEachInputCountList;
- mExportForEachInputCountList = nullptr;
- delete [] mExportReduceList;
- mExportReduceList = nullptr;
- for (size_t i = 0; i < mPragmaCount; i++) {
- if (mPragmaKeyList) {
- delete [] mPragmaKeyList[i];
- mPragmaKeyList[i] = nullptr;
- }
- if (mPragmaValueList) {
- delete [] mPragmaValueList[i];
- mPragmaValueList[i] = nullptr;
- }
- }
- delete [] mPragmaKeyList;
- mPragmaKeyList = nullptr;
- delete [] mPragmaValueList;
- mPragmaValueList = nullptr;
- delete [] mObjectSlotList;
- mObjectSlotList = nullptr;
- delete [] mBuildChecksum;
- return;
- }
- bool MetadataExtractor::populateObjectSlotMetadata(
- const llvm::NamedMDNode *ObjectSlotMetadata) {
- if (!ObjectSlotMetadata) {
- return true;
- }
- mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
- if (!mObjectSlotCount) {
- return true;
- }
- std::unique_ptr<uint32_t[]> TmpSlotList(new uint32_t[mObjectSlotCount]());
- for (size_t i = 0; i < mObjectSlotCount; i++) {
- llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
- if (ObjectSlot != nullptr && ObjectSlot->getNumOperands() == 1) {
- if (!extractUIntFromMetadataString(&TmpSlotList[i], ObjectSlot->getOperand(0))) {
- ALOGE("Non-integer object slot value");
- return false;
- }
- } else {
- ALOGE("Corrupt object slot information");
- return false;
- }
- }
- delete [] mObjectSlotList;
- mObjectSlotList = TmpSlotList.release();
- return true;
- }
- void MetadataExtractor::populatePragmaMetadata(
- const llvm::NamedMDNode *PragmaMetadata) {
- if (!PragmaMetadata) {
- return;
- }
- mPragmaCount = PragmaMetadata->getNumOperands();
- if (!mPragmaCount) {
- return;
- }
- const char **TmpKeyList = new const char*[mPragmaCount];
- const char **TmpValueList = new const char*[mPragmaCount];
- for (size_t i = 0; i < mPragmaCount; i++) {
- llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
- if (Pragma != nullptr && Pragma->getNumOperands() == 2) {
- llvm::Metadata *PragmaKeyMDS = Pragma->getOperand(0);
- TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
- llvm::Metadata *PragmaValueMDS = Pragma->getOperand(1);
- TmpValueList[i] = createStringFromValue(PragmaValueMDS);
- }
- }
- mPragmaKeyList = TmpKeyList;
- mPragmaValueList = TmpValueList;
- // Check to see if we have any FP precision-related pragmas.
- std::string Relaxed("rs_fp_relaxed");
- std::string Imprecise("rs_fp_imprecise");
- std::string Full("rs_fp_full");
- bool RelaxedPragmaSeen = false;
- bool FullPragmaSeen = false;
- for (size_t i = 0; i < mPragmaCount; i++) {
- if (!Relaxed.compare(mPragmaKeyList[i])) {
- RelaxedPragmaSeen = true;
- } else if (!Imprecise.compare(mPragmaKeyList[i])) {
- ALOGW("rs_fp_imprecise is deprecated. Assuming rs_fp_relaxed instead.");
- RelaxedPragmaSeen = true;
- } else if (!Full.compare(mPragmaKeyList[i])) {
- FullPragmaSeen = true;
- }
- }
- if (RelaxedPragmaSeen && FullPragmaSeen) {
- ALOGE("Full and relaxed precision specified at the same time!");
- }
- mRSFloatPrecision = RelaxedPragmaSeen ? RS_FP_Relaxed : RS_FP_Full;
- #ifdef __ANDROID__
- // Provide an override for precsiion via adb shell setprop
- // adb shell setprop debug.rs.precision rs_fp_full
- // adb shell setprop debug.rs.precision rs_fp_relaxed
- // adb shell setprop debug.rs.precision rs_fp_imprecise
- char PrecisionPropBuf[PROP_VALUE_MAX];
- const std::string PrecisionPropName("debug.rs.precision");
- property_get("debug.rs.precision", PrecisionPropBuf, "");
- if (PrecisionPropBuf[0]) {
- if (!Relaxed.compare(PrecisionPropBuf)) {
- ALOGI("Switching to RS FP relaxed mode via setprop");
- mRSFloatPrecision = RS_FP_Relaxed;
- } else if (!Imprecise.compare(PrecisionPropBuf)) {
- ALOGW("Switching to RS FP relaxed mode via setprop. rs_fp_imprecise was "
- "specified but is deprecated ");
- mRSFloatPrecision = RS_FP_Relaxed;
- } else if (!Full.compare(PrecisionPropBuf)) {
- ALOGI("Switching to RS FP full mode via setprop");
- mRSFloatPrecision = RS_FP_Full;
- } else {
- ALOGE("Unrecognized debug.rs.precision %s", PrecisionPropBuf);
- }
- }
- #endif
- }
- uint32_t MetadataExtractor::calculateNumInputs(const llvm::Function *Function,
- uint32_t Signature) {
- if (hasForEachSignatureIn(Signature)) {
- uint32_t OtherCount = 0;
- OtherCount += hasForEachSignatureUsrData(Signature);
- OtherCount += hasForEachSignatureX(Signature);
- OtherCount += hasForEachSignatureY(Signature);
- OtherCount += hasForEachSignatureZ(Signature);
- OtherCount += hasForEachSignatureCtxt(Signature);
- OtherCount += hasForEachSignatureOut(Signature) &&
- Function->getReturnType()->isVoidTy();
- return Function->arg_size() - OtherCount;
- } else {
- return 0;
- }
- }
- bool MetadataExtractor::populateForEachMetadata(
- const llvm::NamedMDNode *Names,
- const llvm::NamedMDNode *Signatures) {
- if (!Names && !Signatures && mCompilerVersion == 0) {
- // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
- // section for ForEach. We generate a full signature for a "root" function
- // which means that we need to set the bottom 5 bits in the mask.
- mExportForEachSignatureCount = 1;
- char **TmpNameList = new char*[mExportForEachSignatureCount];
- size_t RootLen = strlen(kRoot) + 1;
- TmpNameList[0] = new char[RootLen];
- strncpy(TmpNameList[0], kRoot, RootLen);
- uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
- TmpSigList[0] = 0x1f;
- mExportForEachNameList = (const char**)TmpNameList;
- mExportForEachSignatureList = TmpSigList;
- return true;
- }
- if (Signatures) {
- mExportForEachSignatureCount = Signatures->getNumOperands();
- if (!mExportForEachSignatureCount) {
- return true;
- }
- } else {
- mExportForEachSignatureCount = 0;
- mExportForEachSignatureList = nullptr;
- return true;
- }
- std::unique_ptr<uint32_t[]> TmpSigList(new uint32_t[mExportForEachSignatureCount]);
- std::unique_ptr<const char *[]> TmpNameList(new const char*[mExportForEachSignatureCount]);
- std::unique_ptr<uint32_t[]> TmpInputCountList(new uint32_t[mExportForEachSignatureCount]);
- for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
- llvm::MDNode *SigNode = Signatures->getOperand(i);
- if (SigNode != nullptr && SigNode->getNumOperands() == 1) {
- if (!extractUIntFromMetadataString(&TmpSigList[i], SigNode->getOperand(0))) {
- ALOGE("Non-integer signature value");
- return false;
- }
- } else {
- ALOGE("Corrupt signature information");
- return false;
- }
- }
- if (Names) {
- for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
- llvm::MDNode *Name = Names->getOperand(i);
- if (Name != nullptr && Name->getNumOperands() == 1) {
- TmpNameList[i] = createStringFromValue(Name->getOperand(0));
- // Note that looking up the function by name can fail: One of
- // the uses of MetadataExtractor is as part of the
- // RSEmbedInfoPass, which bcc_compat runs sufficiently late in
- // the phase order that RSKernelExpandPass has already run and
- // the original (UNexpanded) kernel function (TmpNameList[i])
- // may have been deleted as having no references (if it has
- // been inlined into the expanded kernel function and is
- // otherwise unreferenced).
- llvm::Function *Func =
- mModule->getFunction(llvm::StringRef(TmpNameList[i]));
- TmpInputCountList[i] = (Func != nullptr) ?
- calculateNumInputs(Func, TmpSigList[i]) : 0;
- }
- }
- } else {
- if (mExportForEachSignatureCount != 1) {
- ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
- mExportForEachSignatureCount);
- }
- char *RootName = new char[5];
- strncpy(RootName, "root", 5);
- TmpNameList[0] = RootName;
- }
- delete [] mExportForEachNameList;
- mExportForEachNameList = TmpNameList.release();
- delete [] mExportForEachSignatureList;
- mExportForEachSignatureList = TmpSigList.release();
- delete [] mExportForEachInputCountList;
- mExportForEachInputCountList = TmpInputCountList.release();
- return true;
- }
- bool MetadataExtractor::populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata) {
- mExportReduceCount = 0;
- mExportReduceList = nullptr;
- if (!ReduceMetadata || !(mExportReduceCount = ReduceMetadata->getNumOperands()))
- return true;
- std::unique_ptr<Reduce[]> TmpReduceList(new Reduce[mExportReduceCount]);
- for (size_t i = 0; i < mExportReduceCount; i++) {
- llvm::MDNode *Node = ReduceMetadata->getOperand(i);
- if (!Node || Node->getNumOperands() < 3) {
- ALOGE("Missing reduce metadata");
- return false;
- }
- TmpReduceList[i].mReduceName = createStringFromValue(Node->getOperand(0));
- if (!extractUIntFromMetadataString(&TmpReduceList[i].mAccumulatorDataSize,
- Node->getOperand(1))) {
- ALOGE("Non-integer accumulator data size value in reduce metadata");
- return false;
- }
- llvm::MDNode *AccumulatorNode = llvm::dyn_cast<llvm::MDNode>(Node->getOperand(2));
- if (!AccumulatorNode || AccumulatorNode->getNumOperands() != 2) {
- ALOGE("Malformed accumulator node in reduce metadata");
- return false;
- }
- TmpReduceList[i].mAccumulatorName = createStringFromValue(AccumulatorNode->getOperand(0));
- if (!extractUIntFromMetadataString(&TmpReduceList[i].mSignature,
- AccumulatorNode->getOperand(1))) {
- ALOGE("Non-integer signature value in reduce metadata");
- return false;
- }
- // Note that looking up the function by name can fail: One of the
- // uses of MetadataExtractor is as part of the RSEmbedInfoPass,
- // which bcc_compat runs sufficiently late in the phase order that
- // RSKernelExpandPass has already run and the original
- // (UNexpanded) accumulator function (mAccumulatorName) may have
- // been deleted as having no references (if it has been inlined
- // into the expanded accumulator function and is otherwise
- // unreferenced).
- llvm::Function *Func =
- mModule->getFunction(llvm::StringRef(TmpReduceList[i].mAccumulatorName));
- // Why calculateNumInputs() - 1? The "-1" is because we don't
- // want to treat the accumulator argument as an input.
- TmpReduceList[i].mInputCount = (Func ? calculateNumInputs(Func, TmpReduceList[i].mSignature) - 1 : 0);
- TmpReduceList[i].mInitializerName = createStringFromOptionalValue(Node, 3);
- TmpReduceList[i].mCombinerName = createStringFromOptionalValue(Node, 4);
- TmpReduceList[i].mOutConverterName = createStringFromOptionalValue(Node, 5);
- TmpReduceList[i].mHalterName = createStringFromOptionalValue(Node, 6);
- }
- mExportReduceList = TmpReduceList.release();
- return true;
- }
- void MetadataExtractor::readThreadableFlag(
- const llvm::NamedMDNode *ThreadableMetadata) {
- // Scripts are threadable by default. If we read a valid metadata value for
- // 'ThreadableMetadataName' and it is set to 'no', we mark script as non
- // threadable. All other exception paths retain the default value.
- mIsThreadable = true;
- if (ThreadableMetadata == nullptr)
- return;
- llvm::MDNode *mdNode = ThreadableMetadata->getOperand(0);
- if (mdNode == nullptr)
- return;
- llvm::Metadata *mdValue = mdNode->getOperand(0);
- if (mdValue == nullptr)
- return;
- if (getStringOperand(mdValue) == "no")
- mIsThreadable = false;
- }
- void MetadataExtractor::readBuildChecksumMetadata(
- const llvm::NamedMDNode *ChecksumMetadata) {
- if (ChecksumMetadata == nullptr)
- return;
- llvm::MDNode *mdNode = ChecksumMetadata->getOperand(0);
- if (mdNode == nullptr)
- return;
- llvm::Metadata *mdValue = mdNode->getOperand(0);
- if (mdValue == nullptr)
- return;
- mBuildChecksum = createStringFromValue(mdValue);
- }
- bool MetadataExtractor::extract() {
- if (!(mBitcode && mBitcodeSize) && !mModule) {
- ALOGE("Invalid/empty bitcode/module");
- return false;
- }
- std::unique_ptr<llvm::LLVMContext> mContext;
- bool shouldNullModule = false;
- if (!mModule) {
- mContext.reset(new llvm::LLVMContext());
- std::unique_ptr<llvm::MemoryBuffer> MEM(
- llvm::MemoryBuffer::getMemBuffer(
- llvm::StringRef(mBitcode, mBitcodeSize), "", false));
- std::string error;
- llvm::ErrorOr<std::unique_ptr<llvm::Module> > errval =
- llvm::parseBitcodeFile(MEM.get()->getMemBufferRef(), *mContext);
- if (std::error_code ec = errval.getError()) {
- ALOGE("Could not parse bitcode file");
- ALOGE("%s", ec.message().c_str());
- return false;
- }
- mModule = errval.get().release();
- shouldNullModule = true;
- }
- const llvm::NamedMDNode *ExportVarMetadata =
- mModule->getNamedMetadata(ExportVarMetadataName);
- const llvm::NamedMDNode *ExportFuncMetadata =
- mModule->getNamedMetadata(ExportFuncMetadataName);
- const llvm::NamedMDNode *ExportForEachNameMetadata =
- mModule->getNamedMetadata(ExportForEachNameMetadataName);
- const llvm::NamedMDNode *ExportForEachMetadata =
- mModule->getNamedMetadata(ExportForEachMetadataName);
- const llvm::NamedMDNode *ExportReduceMetadata =
- mModule->getNamedMetadata(ExportReduceMetadataName);
- const llvm::NamedMDNode *PragmaMetadata =
- mModule->getNamedMetadata(PragmaMetadataName);
- const llvm::NamedMDNode *ObjectSlotMetadata =
- mModule->getNamedMetadata(ObjectSlotMetadataName);
- const llvm::NamedMDNode *ThreadableMetadata =
- mModule->getNamedMetadata(ThreadableMetadataName);
- const llvm::NamedMDNode *ChecksumMetadata =
- mModule->getNamedMetadata(ChecksumMetadataName);
- const llvm::NamedMDNode *DebugInfoMetadata =
- mModule->getNamedMetadata(DebugInfoMetadataName);
- if (!populateNameMetadata(ExportVarMetadata, mExportVarNameList,
- mExportVarCount)) {
- ALOGE("Could not populate export variable metadata");
- goto err;
- }
- if (!populateNameMetadata(ExportFuncMetadata, mExportFuncNameList,
- mExportFuncCount)) {
- ALOGE("Could not populate export function metadata");
- goto err;
- }
- if (!populateForEachMetadata(ExportForEachNameMetadata,
- ExportForEachMetadata)) {
- ALOGE("Could not populate ForEach signature metadata");
- goto err;
- }
- if (!populateReduceMetadata(ExportReduceMetadata)) {
- ALOGE("Could not populate export general reduction metadata");
- goto err;
- }
- populatePragmaMetadata(PragmaMetadata);
- if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
- ALOGE("Could not populate object slot metadata");
- goto err;
- }
- readThreadableFlag(ThreadableMetadata);
- readBuildChecksumMetadata(ChecksumMetadata);
- mHasDebugInfo = DebugInfoMetadata != nullptr;
- if (shouldNullModule) {
- mModule = nullptr;
- }
- return true;
- err:
- if (shouldNullModule) {
- mModule = nullptr;
- }
- return false;
- }
- } // namespace bcinfo
|