RSInfoExtractor.cpp revision 6f3138bbc93b7105ddb49a803c15c3f98077f533
11e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang/* 21e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Copyright 2012, The Android Open Source Project 31e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * 41e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 51e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * you may not use this file except in compliance with the License. 61e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * You may obtain a copy of the License at 71e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * 81e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 91e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * 101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * Unless required by applicable law or agreed to in writing, software 111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * See the License for the specific language governing permissions and 141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * limitations under the License. 151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang */ 161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang//===----------------------------------------------------------------------===// 181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// This file implements RSInfo::ExtractFromSource() 191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang//===----------------------------------------------------------------------===// 20e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines#include "bcc/Renderscript/RSInfo.h" 211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#include <llvm/Constants.h> 231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#include <llvm/Metadata.h> 241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#include <llvm/Module.h> 251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 26c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Source.h" 27ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h" 281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changusing namespace bcc; 301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changnamespace { 321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Name of metadata node where pragma info resides (should be synced with 341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// slang.cpp) 351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst llvm::StringRef pragma_metadata_name("#pragma"); 361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang/* 381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * The following names should be synced with the one appeared in 391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang * slang_rs_metadata.h. 401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang */ 411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Name of metadata node where exported variable names reside 421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst llvm::StringRef export_var_metadata_name("#rs_export_var"); 431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Name of metadata node where exported function names reside 451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst llvm::StringRef export_func_metadata_name("#rs_export_func"); 461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Name of metadata node where exported ForEach name information resides 481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst llvm::StringRef export_foreach_name_metadata_name("#rs_export_foreach_name"); 491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Name of metadata node where exported ForEach signature information resides 511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst llvm::StringRef export_foreach_metadata_name("#rs_export_foreach"); 521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Name of metadata node where RS object slot info resides (should be 541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst llvm::StringRef object_slot_metadata_name("#rs_object_slots"); 551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changinline llvm::StringRef getStringFromOperand(const llvm::Value *pString) { 571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if ((pString != NULL) && (pString->getValueID() == llvm::Value::MDStringVal)) { 581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return static_cast<const llvm::MDString *>(pString)->getString(); 591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return llvm::StringRef(); 611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} 621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changtemplate<size_t NumOperands> 641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changinline size_t getMetadataStringLength(const llvm::NamedMDNode *pMetadata) { 651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (pMetadata == NULL) { 661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return 0; 671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang size_t string_size = 0; 701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang for (unsigned i = 0, e = pMetadata->getNumOperands(); i < e; i++) { 711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::MDNode *node = pMetadata->getOperand(i); 721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if ((node != NULL) && (node->getNumOperands() >= NumOperands)) { 731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Compiler try its best to unroll this loop since NumOperands is a 741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // template parameter (therefore the number of iteration can be determined 751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // at compile-time and it's usually small.) 761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang for (unsigned j = 0; j < NumOperands; j++) { 771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::StringRef s = getStringFromOperand(node->getOperand(j)); 781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (s.size() > 0) { 791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // +1 is for the null-terminator at the end of string. 801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang string_size += (s.size() + 1); 811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return string_size; 871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} 881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Write a string pString to the string pool pStringPool at offset pWriteStart. 901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang// Return the pointer the pString resides within the string pool. 911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changconst char *writeString(const llvm::StringRef &pString, char *pStringPool, 921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang off_t *pWriteStart) { 931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (pString.empty()) { 941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return pStringPool; 951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang char *pStringWriteStart = pStringPool + *pWriteStart; 981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Copy the string. 991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ::memcpy(pStringWriteStart, pString.data(), pString.size()); 1001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Write null-terminator at the end of the string. 1011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang pStringWriteStart[ pString.size() ] = '\0'; 1021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Update pWriteStart. 1031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang *pWriteStart += (pString.size() + 1); 1041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return pStringWriteStart; 1061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} 1071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changbool writeDependency(const std::string &pSourceName, const uint8_t *pSHA1, 1091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang char *pStringPool, off_t *pWriteStart, 1101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang RSInfo::DependencyTableTy &pDepTable) { 1111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const char *source_name = writeString(pSourceName, pStringPool, pWriteStart); 1121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang uint8_t *sha1 = reinterpret_cast<uint8_t *>(pStringPool + *pWriteStart); 1141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 115f290793bc65b8483332ac8b568962395c4a63927Zonr Chang // SHA-1 is special. It's size of SHA1_DIGEST_LENGTH (=20) bytes long without 116f290793bc65b8483332ac8b568962395c4a63927Zonr Chang // null-terminator. 117f290793bc65b8483332ac8b568962395c4a63927Zonr Chang ::memcpy(sha1, pSHA1, SHA1_DIGEST_LENGTH); 1181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Record in the result RSInfo object. 1191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang pDepTable.push(std::make_pair(source_name, sha1)); 1201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Update the string pool pointer. 121f290793bc65b8483332ac8b568962395c4a63927Zonr Chang *pWriteStart += SHA1_DIGEST_LENGTH; 1221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return true; 1241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} 1251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} // end anonymous namespace 1271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1281e2adce6df4414d827149ec563c9c89f21ea7426Zonr ChangRSInfo *RSInfo::ExtractFromSource(const Source &pSource, 1297bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao const DependencyTableTy &pDeps) 1301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang{ 1311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const llvm::Module &module = pSource.getModule(); 1321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const char *module_name = module.getModuleIdentifier().c_str(); 1331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const llvm::NamedMDNode *pragma = 1351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getNamedMetadata(pragma_metadata_name); 1361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const llvm::NamedMDNode *export_var = 1371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getNamedMetadata(export_var_metadata_name); 1381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const llvm::NamedMDNode *export_func = 1391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getNamedMetadata(export_func_metadata_name); 1401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const llvm::NamedMDNode *export_foreach_name = 1411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getNamedMetadata(export_foreach_name_metadata_name); 1421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const llvm::NamedMDNode *export_foreach_signature = 1431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getNamedMetadata(export_foreach_metadata_name); 1441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang const llvm::NamedMDNode *object_slots = 1451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getNamedMetadata(object_slot_metadata_name); 1461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Always write a byte 0x0 at the beginning of the string pool. 1481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang size_t string_pool_size = 1; 1491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang off_t cur_string_pool_offset = 0; 1501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang RSInfo *result = NULL; 1521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata 1541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // section for ForEach. We generate a full signature for a "root" function. 1551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if ((export_foreach_name == NULL) || (export_foreach_signature == NULL)) { 1561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang export_foreach_name = NULL; 1571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang export_foreach_signature = NULL; 1581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang string_pool_size += 5; // insert "root\0" for #rs_export_foreach_name 1591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 1601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang string_pool_size += getMetadataStringLength<2>(pragma); 1621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang string_pool_size += getMetadataStringLength<1>(export_var); 1631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang string_pool_size += getMetadataStringLength<1>(export_func); 1641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang string_pool_size += getMetadataStringLength<1>(export_foreach_name); 1651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Don't forget to reserve the space for the dependency informationin string 1671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // pool. 168f290793bc65b8483332ac8b568962395c4a63927Zonr Chang string_pool_size += ::strlen(LibBCCPath) + 1 + SHA1_DIGEST_LENGTH; 169f290793bc65b8483332ac8b568962395c4a63927Zonr Chang string_pool_size += ::strlen(LibRSPath) + 1 + SHA1_DIGEST_LENGTH; 1702665c2f94ed14c1d15925d83b47aa519a11dafe5Shih-wei Liao string_pool_size += ::strlen(LibCLCorePath) + 1 + SHA1_DIGEST_LENGTH; 171b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao#if defined(ARCH_ARM_HAVE_NEON) 172b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao string_pool_size += ::strlen(LibCLCoreNEONPath) + 1 + SHA1_DIGEST_LENGTH; 173b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao#endif 1741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang for (unsigned i = 0, e = pDeps.size(); i != e; i++) { 1757bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao // +1 for null-terminator 1767bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao string_pool_size += ::strlen(/* name */pDeps[i].first) + 1; 1777bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao // +SHA1_DIGEST_LENGTH for SHA-1 checksum 1787bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao string_pool_size += SHA1_DIGEST_LENGTH; 1791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 1801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Allocate result object 1821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result = new (std::nothrow) RSInfo(string_pool_size); 1831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (result == NULL) { 1841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGE("Out of memory when create RSInfo object for %s!", module_name); 1851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 1861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 1871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Check string pool. 1891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (result->mStringPool == NULL) { 1901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGE("Out of memory when allocate string pool in RSInfo object for %s!", 1911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module_name); 1921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 1931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 1941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // First byte of string pool should be an empty string 1961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mStringPool[ cur_string_pool_offset++ ] = '\0'; 1971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 1981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Populate all the strings and data. 1991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#define FOR_EACH_NODE_IN(_metadata, _node) \ 2001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang for (unsigned i = 0, e = (_metadata)->getNumOperands(); i != e; i++) \ 2011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (((_node) = (_metadata)->getOperand(i)) != NULL) 2021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #pragma 2041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Pragma is actually a key-value pair. The value can be an empty string while 2061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // the key cannot. 2071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (pragma != NULL) { 2081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::MDNode *node; 2091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang FOR_EACH_NODE_IN(pragma, node) { 2101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::StringRef key = getStringFromOperand(node->getOperand(0)); 2111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::StringRef val = getStringFromOperand(node->getOperand(1)); 2121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (key.empty()) { 2131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGW("%s contains pragma metadata with empty key (skip)!", 2141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module_name); 2151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } else { 2161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mPragmas.push(std::make_pair( 2171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang writeString(key, result->mStringPool, &cur_string_pool_offset), 2181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang writeString(val, result->mStringPool, &cur_string_pool_offset))); 2191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } // key.empty() 2201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } // FOR_EACH_NODE_IN 2211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } // pragma != NULL 2221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 2231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #rs_export_var 2251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (export_var != NULL) { 2271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::MDNode *node; 2281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang FOR_EACH_NODE_IN(export_var, node) { 2291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::StringRef name = getStringFromOperand(node->getOperand(0)); 2301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (name.empty()) { 2311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGW("%s contains empty entry in #rs_export_var metadata (skip)!", 2321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module_name); 2331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } else { 2341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mExportVarNames.push( 2351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang writeString(name, result->mStringPool, &cur_string_pool_offset)); 2361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 2401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2411e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #rs_export_func 2421e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2431e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (export_func != NULL) { 2441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::MDNode *node; 2451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang FOR_EACH_NODE_IN(export_func, node) { 2461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::StringRef name = getStringFromOperand(node->getOperand(0)); 2471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (name.empty()) { 2481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGW("%s contains empty entry in #rs_export_func metadata (skip)!", 2491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module_name); 2501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } else { 2511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mExportFuncNames.push( 2521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang writeString(name, result->mStringPool, &cur_string_pool_offset)); 2531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2551e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2561e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 2571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #rs_export_foreach and #rs_export_foreach_name 2591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 2601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // It's a little bit complicated to deal with #rs_export_foreach (the 2611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // signature of foreach-able function) and #rs_export_foreach_name (the name 2621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // of function which is foreach-able). We have to maintain a legacy case: 2631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // 2641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // In pre-ICS bitcode, forEach feature only supports non-graphic root() 2651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // function and only one signature corresponded to that non-graphic root() 2661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // was written to the #rs_export_foreach metadata section. There's no 2671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #rs_export_foreach_name metadata section. 2681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // 2691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Currently, not only non-graphic root() is supported but also other 2701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // functions that are exportable. Therefore, a new metadata section 2711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #rs_export_foreach_name is added to specify which functions are 2721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // for-eachable. In this case, #rs_export_foreach (the function name) and 2731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #rs_export_foreach metadata (the signature) is one-to-one mapping among 2741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // their entries. 2751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if ((export_foreach_name != NULL) && (export_foreach_signature != NULL)) { 2761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang unsigned num_foreach_function; 2771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 2781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Should be one-to-one mapping. 2791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (export_foreach_name->getNumOperands() != 2801e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang export_foreach_signature->getNumOperands()) { 2811e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGE("Mismatch number of foreach-able function names (%u) in " 2821e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang "#rs_export_foreach_name and number of signatures (%u) " 2831e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang "in %s!", export_foreach_name->getNumOperands(), 2841e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang export_foreach_signature->getNumOperands(), module_name); 2851e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 2861e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2871e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 2881e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang num_foreach_function = export_foreach_name->getNumOperands(); 2891e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang for (unsigned i = 0; i < num_foreach_function; i++) { 2901e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::MDNode *name_node = export_foreach_name->getOperand(i); 2911e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::MDNode *signature_node = export_foreach_signature->getOperand(i); 2921e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 2931e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::StringRef name, signature_string; 2941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (name_node != NULL) { 2951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang name = getStringFromOperand(name_node->getOperand(0)); 2961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 2971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (signature_node != NULL) { 2981e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang signature_string = getStringFromOperand(signature_node->getOperand(0)); 2991e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3001e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 3011e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (!name.empty() && !signature_string.empty()) { 3021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Both name_node and signature_node are not NULL nodes. 3031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang uint32_t signature; 3041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (signature_string.getAsInteger(10, signature)) { 3051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGE("Non-integer signature value '%s' for function %s found in %s!", 3061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang signature_string.str().c_str(), name.str().c_str(), module_name); 3071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 3081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mExportForeachFuncs.push(std::make_pair( 3101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang writeString(name, result->mStringPool, &cur_string_pool_offset), 3111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang signature)); 3121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } else { 3131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // One or both of the name and signature value are empty. It's safe only 3141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // if both of them are empty. 3151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (name.empty() && signature_string.empty()) { 3161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGW("Entries #%u at #rs_export_foreach_name and #rs_export_foreach" 3171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang " are both NULL in %s! (skip)", i, module_name); 3181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang continue; 3191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } else { 3201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGE("Entries #%u at %s is NULL in %s! (skip)", i, 3211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang (name.empty() ? "#rs_export_foreach_name" : 3221e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang "#rs_export_foreach"), module_name); 3231e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 3241e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3251e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3261e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } // end for 3271e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } else { 3281e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // To handle the legacy case, we generate a full signature for a "root" 3291e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // function which means that we need to set the bottom 5 bits (0x1f) in the 3301e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // mask. 3311e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mExportForeachFuncs.push(std::make_pair( 3321e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang writeString(llvm::StringRef("root"), result->mStringPool, 3331e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang &cur_string_pool_offset), 0x1f)); 3341e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3351e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 3361e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 3371e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // #rs_object_slots 3381e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 3391e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (object_slots != NULL) { 3401e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::MDNode *node; 3416f3138bbc93b7105ddb49a803c15c3f98077f533Stephen Hines for (unsigned int i = 0; i <= export_var->getNumOperands(); i++) { 3426f3138bbc93b7105ddb49a803c15c3f98077f533Stephen Hines result->mObjectSlots.push(0); 3436f3138bbc93b7105ddb49a803c15c3f98077f533Stephen Hines } 3441e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang FOR_EACH_NODE_IN(object_slots, node) { 3451e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang llvm::StringRef val = getStringFromOperand(node->getOperand(0)); 3461e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (val.empty()) { 3471e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGW("%s contains empty entry in #rs_object_slots (skip)!", 3481e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getModuleIdentifier().c_str()); 3491e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } else { 3501e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang uint32_t slot; 3511e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (val.getAsInteger(10, slot)) { 3521e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang ALOGE("Non-integer object slot value '%s' in %s!", val.str().c_str(), 3531e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang module.getModuleIdentifier().c_str()); 3541e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 3556f3138bbc93b7105ddb49a803c15c3f98077f533Stephen Hines } else { 3566f3138bbc93b7105ddb49a803c15c3f98077f533Stephen Hines result->mObjectSlots.editItemAt(slot) = 1; 3571e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3581e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3591e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3601e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3611e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang#undef FOR_EACH_NODE_IN 3621e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 3631e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 3641e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Record built-in dependency information. 3651e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 3661e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang LoadBuiltInSHA1Information(); 3671e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 3681e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (!writeDependency(LibBCCPath, LibBCCSHA1, 3691e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mStringPool, &cur_string_pool_offset, 3701e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mDependencyTable)) { 3711e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 3721e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3731e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 3741e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang if (!writeDependency(LibRSPath, LibRSSHA1, 3751e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mStringPool, &cur_string_pool_offset, 3761e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mDependencyTable)) { 3771e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang goto bail; 3781e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 3791e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 3802665c2f94ed14c1d15925d83b47aa519a11dafe5Shih-wei Liao if (!writeDependency(LibCLCorePath, LibCLCoreSHA1, 3812665c2f94ed14c1d15925d83b47aa519a11dafe5Shih-wei Liao result->mStringPool, &cur_string_pool_offset, 3822665c2f94ed14c1d15925d83b47aa519a11dafe5Shih-wei Liao result->mDependencyTable)) { 3832665c2f94ed14c1d15925d83b47aa519a11dafe5Shih-wei Liao goto bail; 3842665c2f94ed14c1d15925d83b47aa519a11dafe5Shih-wei Liao } 3852665c2f94ed14c1d15925d83b47aa519a11dafe5Shih-wei Liao 386b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao#if defined(ARCH_ARM_HAVE_NEON) 387b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao if (!writeDependency(LibCLCoreNEONPath, LibCLCoreNEONSHA1, 388b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao result->mStringPool, &cur_string_pool_offset, 389b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao result->mDependencyTable)) { 390b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao goto bail; 391b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao } 392b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao#endif 393b1cc74f2fc38ea115b69f65302bc62478fe59a4aShih-wei Liao 3941e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 3951e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Record dependency information. 3961e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 3971e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang for (unsigned i = 0, e = pDeps.size(); i != e; i++) { 3987bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao if (!writeDependency(/* name */pDeps[i].first, /* SHA-1 */pDeps[i].second, 3997bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao result->mStringPool, &cur_string_pool_offset, 4007bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao result->mDependencyTable)) { 4017bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao goto bail; 4021e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 4031e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang } 4041e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 4051e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 4061e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // Determine whether the bitcode contains debug information 4071e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang //===--------------------------------------------------------------------===// 4081e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // The root context of the debug information in the bitcode is put under 4091e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang // the metadata named "llvm.dbg.cu". 4101e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang result->mHeader.hasDebugInformation = 4111e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang static_cast<uint8_t>(module.getNamedMetadata("llvm.dbg.cu") != NULL); 4121e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 4131e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang assert((cur_string_pool_offset == string_pool_size) && 4141e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang "Unexpected string pool size!"); 4151e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 4161e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return result; 4171e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang 4181e2adce6df4414d827149ec563c9c89f21ea7426Zonr Changbail: 4191e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang delete result; 4201e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang return NULL; 4211e2adce6df4414d827149ec563c9c89f21ea7426Zonr Chang} 422