Home | History | Annotate | Download | only in Renderscript
      1 /*
      2  * Copyright 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 //===----------------------------------------------------------------------===//
     18 // This file implements RSInfo::ExtractFromSource()
     19 //===----------------------------------------------------------------------===//
     20 #include "bcc/Renderscript/RSInfo.h"
     21 
     22 #include <llvm/IR/Constants.h>
     23 #include <llvm/IR/Metadata.h>
     24 #include <llvm/IR/Module.h>
     25 
     26 #include "bcc/Source.h"
     27 #include "bcc/Support/Log.h"
     28 
     29 using namespace bcc;
     30 
     31 namespace {
     32 
     33 // Name of metadata node where pragma info resides (should be synced with
     34 // slang.cpp)
     35 const llvm::StringRef pragma_metadata_name("#pragma");
     36 
     37 /*
     38  * The following names should be synced with the one appeared in
     39  * slang_rs_metadata.h.
     40  */
     41 // Name of metadata node where exported variable names reside
     42 const llvm::StringRef export_var_metadata_name("#rs_export_var");
     43 
     44 // Name of metadata node where exported function names reside
     45 const llvm::StringRef export_func_metadata_name("#rs_export_func");
     46 
     47 // Name of metadata node where exported ForEach name information resides
     48 const llvm::StringRef export_foreach_name_metadata_name("#rs_export_foreach_name");
     49 
     50 // Name of metadata node where exported ForEach signature information resides
     51 const llvm::StringRef export_foreach_metadata_name("#rs_export_foreach");
     52 
     53 // Name of metadata node where RS object slot info resides (should be
     54 const llvm::StringRef object_slot_metadata_name("#rs_object_slots");
     55 
     56 inline llvm::StringRef getStringFromOperand(const llvm::Value *pString) {
     57   if ((pString != NULL) && (pString->getValueID() == llvm::Value::MDStringVal)) {
     58     return static_cast<const llvm::MDString *>(pString)->getString();
     59   }
     60   return llvm::StringRef();
     61 }
     62 
     63 template<size_t NumOperands>
     64 inline size_t getMetadataStringLength(const llvm::NamedMDNode *pMetadata) {
     65   if (pMetadata == NULL) {
     66     return 0;
     67   }
     68 
     69   size_t string_size = 0;
     70   for (unsigned i = 0, e = pMetadata->getNumOperands(); i < e; i++) {
     71     llvm::MDNode *node = pMetadata->getOperand(i);
     72     if ((node != NULL) && (node->getNumOperands() >= NumOperands)) {
     73       // Compiler try its best to unroll this loop since NumOperands is a
     74       // template parameter (therefore the number of iteration can be determined
     75       // at compile-time and it's usually small.)
     76       for (unsigned j = 0; j < NumOperands; j++) {
     77         llvm::StringRef s = getStringFromOperand(node->getOperand(j));
     78         if (s.size() > 0) {
     79           // +1 is for the null-terminator at the end of string.
     80           string_size += (s.size() + 1);
     81         }
     82       }
     83     }
     84   }
     85 
     86   return string_size;
     87 }
     88 
     89 // Write a string pString to the string pool pStringPool at offset pWriteStart.
     90 // Return the pointer the pString resides within the string pool.
     91 const char *writeString(const llvm::StringRef &pString, char *pStringPool,
     92                         off_t *pWriteStart) {
     93   if (pString.empty()) {
     94     return pStringPool;
     95   }
     96 
     97   char *pStringWriteStart = pStringPool + *pWriteStart;
     98   // Copy the string.
     99   ::memcpy(pStringWriteStart, pString.data(), pString.size());
    100   // Write null-terminator at the end of the string.
    101   pStringWriteStart[ pString.size() ] = '\0';
    102   // Update pWriteStart.
    103   *pWriteStart += (pString.size() + 1);
    104 
    105   return pStringWriteStart;
    106 }
    107 
    108 bool writeDependency(const std::string &pSourceName, const uint8_t *pSHA1,
    109                      char *pStringPool, off_t *pWriteStart,
    110                      RSInfo::DependencyTableTy &pDepTable) {
    111   const char *source_name = writeString(pSourceName, pStringPool, pWriteStart);
    112 
    113   uint8_t *sha1 = reinterpret_cast<uint8_t *>(pStringPool + *pWriteStart);
    114 
    115   // SHA-1 is special. It's size of SHA1_DIGEST_LENGTH (=20) bytes long without
    116   // null-terminator.
    117   ::memcpy(sha1, pSHA1, SHA1_DIGEST_LENGTH);
    118   // Record in the result RSInfo object.
    119   pDepTable.push(std::make_pair(source_name, sha1));
    120   // Update the string pool pointer.
    121   *pWriteStart += SHA1_DIGEST_LENGTH;
    122 
    123   return true;
    124 }
    125 
    126 } // end anonymous namespace
    127 
    128 RSInfo *RSInfo::ExtractFromSource(const Source &pSource,
    129                                   const DependencyTableTy &pDeps)
    130 {
    131   const llvm::Module &module = pSource.getModule();
    132   const char *module_name = module.getModuleIdentifier().c_str();
    133 
    134   const llvm::NamedMDNode *pragma =
    135       module.getNamedMetadata(pragma_metadata_name);
    136   const llvm::NamedMDNode *export_var =
    137       module.getNamedMetadata(export_var_metadata_name);
    138   const llvm::NamedMDNode *export_func =
    139       module.getNamedMetadata(export_func_metadata_name);
    140   const llvm::NamedMDNode *export_foreach_name =
    141       module.getNamedMetadata(export_foreach_name_metadata_name);
    142   const llvm::NamedMDNode *export_foreach_signature =
    143       module.getNamedMetadata(export_foreach_metadata_name);
    144   const llvm::NamedMDNode *object_slots =
    145       module.getNamedMetadata(object_slot_metadata_name);
    146 
    147   // Always write a byte 0x0 at the beginning of the string pool.
    148   size_t string_pool_size = 1;
    149   off_t cur_string_pool_offset = 0;
    150 
    151   RSInfo *result = NULL;
    152 
    153   // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
    154   // section for ForEach. We generate a full signature for a "root" function.
    155   if ((export_foreach_name == NULL) || (export_foreach_signature == NULL)) {
    156     export_foreach_name = NULL;
    157     export_foreach_signature = NULL;
    158     string_pool_size += 5;  // insert "root\0" for #rs_export_foreach_name
    159   }
    160 
    161   string_pool_size += getMetadataStringLength<2>(pragma);
    162   string_pool_size += getMetadataStringLength<1>(export_var);
    163   string_pool_size += getMetadataStringLength<1>(export_func);
    164   string_pool_size += getMetadataStringLength<1>(export_foreach_name);
    165 
    166   // Don't forget to reserve the space for the dependency informationin string
    167   // pool.
    168   string_pool_size += ::strlen(LibBCCPath) + 1 + SHA1_DIGEST_LENGTH;
    169   string_pool_size += ::strlen(LibCompilerRTPath) + 1 + SHA1_DIGEST_LENGTH;
    170   string_pool_size += ::strlen(LibRSPath) + 1 + SHA1_DIGEST_LENGTH;
    171   string_pool_size += ::strlen(LibCLCorePath) + 1 + SHA1_DIGEST_LENGTH;
    172   string_pool_size += ::strlen(LibCLCoreDebugPath) + 1 + SHA1_DIGEST_LENGTH;
    173 #if defined(ARCH_ARM_HAVE_NEON)
    174   string_pool_size += ::strlen(LibCLCoreNEONPath) + 1 + SHA1_DIGEST_LENGTH;
    175 #endif
    176   for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
    177     // +1 for null-terminator
    178     string_pool_size += ::strlen(/* name */pDeps[i].first) + 1;
    179     // +SHA1_DIGEST_LENGTH for SHA-1 checksum
    180     string_pool_size += SHA1_DIGEST_LENGTH;
    181   }
    182 
    183   // Allocate result object
    184   result = new (std::nothrow) RSInfo(string_pool_size);
    185   if (result == NULL) {
    186     ALOGE("Out of memory when create RSInfo object for %s!", module_name);
    187     goto bail;
    188   }
    189 
    190   // Check string pool.
    191   if (result->mStringPool == NULL) {
    192     ALOGE("Out of memory when allocate string pool in RSInfo object for %s!",
    193           module_name);
    194     goto bail;
    195   }
    196 
    197   // First byte of string pool should be an empty string
    198   result->mStringPool[ cur_string_pool_offset++ ] = '\0';
    199 
    200   // Populate all the strings and data.
    201 #define FOR_EACH_NODE_IN(_metadata, _node)  \
    202   for (unsigned i = 0, e = (_metadata)->getNumOperands(); i != e; i++)  \
    203     if (((_node) = (_metadata)->getOperand(i)) != NULL)
    204   //===--------------------------------------------------------------------===//
    205   // #pragma
    206   //===--------------------------------------------------------------------===//
    207   // Pragma is actually a key-value pair. The value can be an empty string while
    208   // the key cannot.
    209   if (pragma != NULL) {
    210     llvm::MDNode *node;
    211     FOR_EACH_NODE_IN(pragma, node) {
    212         llvm::StringRef key = getStringFromOperand(node->getOperand(0));
    213         llvm::StringRef val = getStringFromOperand(node->getOperand(1));
    214         if (key.empty()) {
    215           ALOGW("%s contains pragma metadata with empty key (skip)!",
    216                 module_name);
    217         } else {
    218           result->mPragmas.push(std::make_pair(
    219               writeString(key, result->mStringPool, &cur_string_pool_offset),
    220               writeString(val, result->mStringPool, &cur_string_pool_offset)));
    221         } // key.empty()
    222     } // FOR_EACH_NODE_IN
    223   } // pragma != NULL
    224 
    225   //===--------------------------------------------------------------------===//
    226   // #rs_export_var
    227   //===--------------------------------------------------------------------===//
    228   if (export_var != NULL) {
    229     llvm::MDNode *node;
    230     FOR_EACH_NODE_IN(export_var, node) {
    231       llvm::StringRef name = getStringFromOperand(node->getOperand(0));
    232       if (name.empty()) {
    233         ALOGW("%s contains empty entry in #rs_export_var metadata (skip)!",
    234               module_name);
    235       } else {
    236           result->mExportVarNames.push(
    237               writeString(name, result->mStringPool, &cur_string_pool_offset));
    238       }
    239     }
    240   }
    241 
    242   //===--------------------------------------------------------------------===//
    243   // #rs_export_func
    244   //===--------------------------------------------------------------------===//
    245   if (export_func != NULL) {
    246     llvm::MDNode *node;
    247     FOR_EACH_NODE_IN(export_func, node) {
    248       llvm::StringRef name = getStringFromOperand(node->getOperand(0));
    249       if (name.empty()) {
    250         ALOGW("%s contains empty entry in #rs_export_func metadata (skip)!",
    251               module_name);
    252       } else {
    253         result->mExportFuncNames.push(
    254             writeString(name, result->mStringPool, &cur_string_pool_offset));
    255       }
    256     }
    257   }
    258 
    259   //===--------------------------------------------------------------------===//
    260   // #rs_export_foreach and #rs_export_foreach_name
    261   //===--------------------------------------------------------------------===//
    262   // It's a little bit complicated to deal with #rs_export_foreach (the
    263   // signature of foreach-able function) and #rs_export_foreach_name (the name
    264   // of function which is foreach-able). We have to maintain a legacy case:
    265   //
    266   //  In pre-ICS bitcode, forEach feature only supports non-graphic root()
    267   //  function and only one signature corresponded to that non-graphic root()
    268   //  was written to the #rs_export_foreach metadata section. There's no
    269   //  #rs_export_foreach_name metadata section.
    270   //
    271   // Currently, not only non-graphic root() is supported but also other
    272   // functions that are exportable. Therefore, a new metadata section
    273   // #rs_export_foreach_name is added to specify which functions are
    274   // for-eachable. In this case, #rs_export_foreach (the function name) and
    275   // #rs_export_foreach metadata (the signature) is one-to-one mapping among
    276   // their entries.
    277   if ((export_foreach_name != NULL) && (export_foreach_signature != NULL)) {
    278     unsigned num_foreach_function;
    279 
    280     // Should be one-to-one mapping.
    281     if (export_foreach_name->getNumOperands() !=
    282         export_foreach_signature->getNumOperands()) {
    283       ALOGE("Mismatch number of foreach-able function names (%u) in "
    284             "#rs_export_foreach_name and number of signatures (%u) "
    285             "in %s!", export_foreach_name->getNumOperands(),
    286             export_foreach_signature->getNumOperands(), module_name);
    287       goto bail;
    288     }
    289 
    290     num_foreach_function = export_foreach_name->getNumOperands();
    291     for (unsigned i = 0; i < num_foreach_function; i++) {
    292       llvm::MDNode *name_node = export_foreach_name->getOperand(i);
    293       llvm::MDNode *signature_node = export_foreach_signature->getOperand(i);
    294 
    295       llvm::StringRef name, signature_string;
    296       if (name_node != NULL) {
    297         name = getStringFromOperand(name_node->getOperand(0));
    298       }
    299       if (signature_node != NULL) {
    300         signature_string = getStringFromOperand(signature_node->getOperand(0));
    301       }
    302 
    303       if (!name.empty() && !signature_string.empty()) {
    304         // Both name_node and signature_node are not NULL nodes.
    305         uint32_t signature;
    306         if (signature_string.getAsInteger(10, signature)) {
    307           ALOGE("Non-integer signature value '%s' for function %s found in %s!",
    308                 signature_string.str().c_str(), name.str().c_str(), module_name);
    309           goto bail;
    310         }
    311         result->mExportForeachFuncs.push(std::make_pair(
    312               writeString(name, result->mStringPool, &cur_string_pool_offset),
    313               signature));
    314       } else {
    315         // One or both of the name and signature value are empty. It's safe only
    316         // if both of them are empty.
    317         if (name.empty() && signature_string.empty()) {
    318           ALOGW("Entries #%u at #rs_export_foreach_name and #rs_export_foreach"
    319                 " are both NULL in %s! (skip)", i, module_name);
    320           continue;
    321         } else {
    322           ALOGE("Entries #%u at %s is NULL in %s! (skip)", i,
    323                 (name.empty() ? "#rs_export_foreach_name" :
    324                                 "#rs_export_foreach"), module_name);
    325           goto bail;
    326         }
    327       }
    328     } // end for
    329   } else {
    330     // To handle the legacy case, we generate a full signature for a "root"
    331     // function which means that we need to set the bottom 5 bits (0x1f) in the
    332     // mask.
    333     result->mExportForeachFuncs.push(std::make_pair(
    334           writeString(llvm::StringRef("root"), result->mStringPool,
    335                       &cur_string_pool_offset), 0x1f));
    336   }
    337 
    338   //===--------------------------------------------------------------------===//
    339   // #rs_object_slots
    340   //===--------------------------------------------------------------------===//
    341   if (object_slots != NULL) {
    342     llvm::MDNode *node;
    343     for (unsigned int i = 0; i <= export_var->getNumOperands(); i++) {
    344       result->mObjectSlots.push(0);
    345     }
    346     FOR_EACH_NODE_IN(object_slots, node) {
    347       llvm::StringRef val = getStringFromOperand(node->getOperand(0));
    348       if (val.empty()) {
    349         ALOGW("%s contains empty entry in #rs_object_slots (skip)!",
    350               module.getModuleIdentifier().c_str());
    351       } else {
    352         uint32_t slot;
    353         if (val.getAsInteger(10, slot)) {
    354           ALOGE("Non-integer object slot value '%s' in %s!", val.str().c_str(),
    355                 module.getModuleIdentifier().c_str());
    356           goto bail;
    357         } else {
    358           result->mObjectSlots.editItemAt(slot) = 1;
    359         }
    360       }
    361     }
    362   }
    363 #undef FOR_EACH_NODE_IN
    364 
    365   if (LoadBuiltInSHA1Information()) {
    366     //===------------------------------------------------------------------===//
    367     // Record built-in dependency information.
    368     //===------------------------------------------------------------------===//
    369     if (!writeDependency(LibBCCPath, LibBCCSHA1,
    370                          result->mStringPool, &cur_string_pool_offset,
    371                          result->mDependencyTable)) {
    372       goto bail;
    373     }
    374 
    375     if (!writeDependency(LibCompilerRTPath, LibCompilerRTSHA1,
    376                          result->mStringPool, &cur_string_pool_offset,
    377                          result->mDependencyTable)) {
    378       goto bail;
    379     }
    380 
    381     if (!writeDependency(LibRSPath, LibRSSHA1,
    382                          result->mStringPool, &cur_string_pool_offset,
    383                          result->mDependencyTable)) {
    384       goto bail;
    385     }
    386 
    387     if (!writeDependency(LibCLCorePath, LibCLCoreSHA1,
    388                          result->mStringPool, &cur_string_pool_offset,
    389                          result->mDependencyTable)) {
    390       goto bail;
    391     }
    392 
    393     if (!writeDependency(LibCLCoreDebugPath, LibCLCoreDebugSHA1,
    394                          result->mStringPool, &cur_string_pool_offset,
    395                          result->mDependencyTable)) {
    396       goto bail;
    397     }
    398 
    399 #if defined(ARCH_ARM_HAVE_NEON)
    400     if (!writeDependency(LibCLCoreNEONPath, LibCLCoreNEONSHA1,
    401                          result->mStringPool, &cur_string_pool_offset,
    402                          result->mDependencyTable)) {
    403       goto bail;
    404     }
    405 #endif
    406 
    407     //===------------------------------------------------------------------===//
    408     // Record dependency information.
    409     //===------------------------------------------------------------------===//
    410     for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
    411       if (!writeDependency(/* name */pDeps[i].first, /* SHA-1 */pDeps[i].second,
    412                            result->mStringPool, &cur_string_pool_offset,
    413                            result->mDependencyTable)) {
    414         goto bail;
    415       }
    416     }
    417   }
    418 
    419   //===--------------------------------------------------------------------===//
    420   // Determine whether the bitcode contains debug information
    421   //===--------------------------------------------------------------------===//
    422   // The root context of the debug information in the bitcode is put under
    423   // the metadata named "llvm.dbg.cu".
    424   result->mHeader.hasDebugInformation =
    425       static_cast<uint8_t>(module.getNamedMetadata("llvm.dbg.cu") != NULL);
    426 
    427   assert((cur_string_pool_offset == string_pool_size) &&
    428             "Unexpected string pool size!");
    429 
    430   return result;
    431 
    432 bail:
    433   delete result;
    434   return NULL;
    435 }
    436