RSInfoExtractor.cpp revision f2ac3176c351cd80bce77fe1488f3de2d0789c1b
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
29using namespace bcc;
30
31namespace {
32
33// Name of metadata node where pragma info resides (should be synced with
34// slang.cpp)
35const 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
42const llvm::StringRef export_var_metadata_name("#rs_export_var");
43
44// Name of metadata node where exported function names reside
45const llvm::StringRef export_func_metadata_name("#rs_export_func");
46
47// Name of metadata node where exported ForEach name information resides
48const llvm::StringRef export_foreach_name_metadata_name("#rs_export_foreach_name");
49
50// Name of metadata node where exported ForEach signature information resides
51const llvm::StringRef export_foreach_metadata_name("#rs_export_foreach");
52
53// Name of metadata node where RS object slot info resides (should be
54const llvm::StringRef object_slot_metadata_name("#rs_object_slots");
55
56inline 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
63template<size_t NumOperands>
64inline 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// Updates pWriteStart to the next available spot.
92const char *writeString(const llvm::StringRef &pString, char *pStringPool,
93                        off_t *pWriteStart) {
94  if (pString.empty()) {
95    return pStringPool;
96  }
97
98  char *pStringWriteStart = pStringPool + *pWriteStart;
99  // Copy the string.
100  ::memcpy(pStringWriteStart, pString.data(), pString.size());
101  // Write null-terminator at the end of the string.
102  pStringWriteStart[ pString.size() ] = '\0';
103  // Update pWriteStart.
104  *pWriteStart += (pString.size() + 1);
105
106  return pStringWriteStart;
107}
108
109} // end anonymous namespace
110
111RSInfo* RSInfo::ExtractFromSource(const Source& pSource, const DependencyHashTy& sourceHashToEmbed,
112                                  const char* compileCommandLineToEmbed,
113                                  const char* buildFingerprintToEmbed) {
114  const llvm::Module &module = pSource.getModule();
115  const char *module_name = module.getModuleIdentifier().c_str();
116
117  const llvm::NamedMDNode *pragma =
118      module.getNamedMetadata(pragma_metadata_name);
119  const llvm::NamedMDNode *export_var =
120      module.getNamedMetadata(export_var_metadata_name);
121  const llvm::NamedMDNode *export_func =
122      module.getNamedMetadata(export_func_metadata_name);
123  const llvm::NamedMDNode *export_foreach_name =
124      module.getNamedMetadata(export_foreach_name_metadata_name);
125  const llvm::NamedMDNode *export_foreach_signature =
126      module.getNamedMetadata(export_foreach_metadata_name);
127  const llvm::NamedMDNode *object_slots =
128      module.getNamedMetadata(object_slot_metadata_name);
129
130  // Always write a byte 0x0 at the beginning of the string pool.
131  size_t string_pool_size = 1;
132  off_t cur_string_pool_offset = 0;
133
134  RSInfo *result = NULL;
135
136  // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
137  // section for ForEach. We generate a full signature for a "root" function.
138  if ((export_foreach_name == NULL) || (export_foreach_signature == NULL)) {
139    export_foreach_name = NULL;
140    export_foreach_signature = NULL;
141    string_pool_size += 5;  // insert "root\0" for #rs_export_foreach_name
142  }
143
144  string_pool_size += getMetadataStringLength<2>(pragma);
145  string_pool_size += getMetadataStringLength<1>(export_var);
146  string_pool_size += getMetadataStringLength<1>(export_func);
147  string_pool_size += getMetadataStringLength<1>(export_foreach_name);
148
149  // Reserve the space for the source hash, command line, and fingerprint
150  string_pool_size += SHA1_DIGEST_LENGTH;
151  string_pool_size += strlen(compileCommandLineToEmbed) + 1;
152  string_pool_size += strlen(buildFingerprintToEmbed) + 1;
153
154  // Allocate result object
155  result = new (std::nothrow) RSInfo(string_pool_size);
156  if (result == NULL) {
157    ALOGE("Out of memory when create RSInfo object for %s!", module_name);
158    goto bail;
159  }
160
161  // Check string pool.
162  if (result->mStringPool == NULL) {
163    ALOGE("Out of memory when allocate string pool in RSInfo object for %s!",
164          module_name);
165    goto bail;
166  }
167
168  // First byte of string pool should be an empty string
169  result->mStringPool[ cur_string_pool_offset++ ] = '\0';
170
171  // Populate all the strings and data.
172#define FOR_EACH_NODE_IN(_metadata, _node)  \
173  for (unsigned i = 0, e = (_metadata)->getNumOperands(); i != e; i++)  \
174    if (((_node) = (_metadata)->getOperand(i)) != NULL)
175  //===--------------------------------------------------------------------===//
176  // #pragma
177  //===--------------------------------------------------------------------===//
178  // Pragma is actually a key-value pair. The value can be an empty string while
179  // the key cannot.
180  if (pragma != NULL) {
181    llvm::MDNode *node;
182    FOR_EACH_NODE_IN(pragma, node) {
183        llvm::StringRef key = getStringFromOperand(node->getOperand(0));
184        llvm::StringRef val = getStringFromOperand(node->getOperand(1));
185        if (key.empty()) {
186          ALOGW("%s contains pragma metadata with empty key (skip)!",
187                module_name);
188        } else {
189          result->mPragmas.push(std::make_pair(
190              writeString(key, result->mStringPool, &cur_string_pool_offset),
191              writeString(val, result->mStringPool, &cur_string_pool_offset)));
192        } // key.empty()
193    } // FOR_EACH_NODE_IN
194  } // pragma != NULL
195
196  //===--------------------------------------------------------------------===//
197  // #rs_export_var
198  //===--------------------------------------------------------------------===//
199  if (export_var != NULL) {
200    llvm::MDNode *node;
201    FOR_EACH_NODE_IN(export_var, node) {
202      llvm::StringRef name = getStringFromOperand(node->getOperand(0));
203      if (name.empty()) {
204        ALOGW("%s contains empty entry in #rs_export_var metadata (skip)!",
205              module_name);
206      } else {
207          result->mExportVarNames.push(
208              writeString(name, result->mStringPool, &cur_string_pool_offset));
209      }
210    }
211  }
212
213  //===--------------------------------------------------------------------===//
214  // #rs_export_func
215  //===--------------------------------------------------------------------===//
216  if (export_func != NULL) {
217    llvm::MDNode *node;
218    FOR_EACH_NODE_IN(export_func, node) {
219      llvm::StringRef name = getStringFromOperand(node->getOperand(0));
220      if (name.empty()) {
221        ALOGW("%s contains empty entry in #rs_export_func metadata (skip)!",
222              module_name);
223      } else {
224        result->mExportFuncNames.push(
225            writeString(name, result->mStringPool, &cur_string_pool_offset));
226      }
227    }
228  }
229
230  //===--------------------------------------------------------------------===//
231  // #rs_export_foreach and #rs_export_foreach_name
232  //===--------------------------------------------------------------------===//
233  // It's a little bit complicated to deal with #rs_export_foreach (the
234  // signature of foreach-able function) and #rs_export_foreach_name (the name
235  // of function which is foreach-able). We have to maintain a legacy case:
236  //
237  //  In pre-ICS bitcode, forEach feature only supports non-graphic root()
238  //  function and only one signature corresponded to that non-graphic root()
239  //  was written to the #rs_export_foreach metadata section. There's no
240  //  #rs_export_foreach_name metadata section.
241  //
242  // Currently, not only non-graphic root() is supported but also other
243  // functions that are exportable. Therefore, a new metadata section
244  // #rs_export_foreach_name is added to specify which functions are
245  // for-eachable. In this case, #rs_export_foreach (the function name) and
246  // #rs_export_foreach metadata (the signature) is one-to-one mapping among
247  // their entries.
248  if ((export_foreach_name != NULL) && (export_foreach_signature != NULL)) {
249    unsigned num_foreach_function;
250
251    // Should be one-to-one mapping.
252    if (export_foreach_name->getNumOperands() !=
253        export_foreach_signature->getNumOperands()) {
254      ALOGE("Mismatch number of foreach-able function names (%u) in "
255            "#rs_export_foreach_name and number of signatures (%u) "
256            "in %s!", export_foreach_name->getNumOperands(),
257            export_foreach_signature->getNumOperands(), module_name);
258      goto bail;
259    }
260
261    num_foreach_function = export_foreach_name->getNumOperands();
262    for (unsigned i = 0; i < num_foreach_function; i++) {
263      llvm::MDNode *name_node = export_foreach_name->getOperand(i);
264      llvm::MDNode *signature_node = export_foreach_signature->getOperand(i);
265
266      llvm::StringRef name, signature_string;
267      if (name_node != NULL) {
268        name = getStringFromOperand(name_node->getOperand(0));
269      }
270      if (signature_node != NULL) {
271        signature_string = getStringFromOperand(signature_node->getOperand(0));
272      }
273
274      if (!name.empty() && !signature_string.empty()) {
275        // Both name_node and signature_node are not NULL nodes.
276        uint32_t signature;
277        if (signature_string.getAsInteger(10, signature)) {
278          ALOGE("Non-integer signature value '%s' for function %s found in %s!",
279                signature_string.str().c_str(), name.str().c_str(), module_name);
280          goto bail;
281        }
282        result->mExportForeachFuncs.push(std::make_pair(
283              writeString(name, result->mStringPool, &cur_string_pool_offset),
284              signature));
285      } else {
286        // One or both of the name and signature value are empty. It's safe only
287        // if both of them are empty.
288        if (name.empty() && signature_string.empty()) {
289          ALOGW("Entries #%u at #rs_export_foreach_name and #rs_export_foreach"
290                " are both NULL in %s! (skip)", i, module_name);
291          continue;
292        } else {
293          ALOGE("Entries #%u at %s is NULL in %s! (skip)", i,
294                (name.empty() ? "#rs_export_foreach_name" :
295                                "#rs_export_foreach"), module_name);
296          goto bail;
297        }
298      }
299    } // end for
300  } else {
301    // To handle the legacy case, we generate a full signature for a "root"
302    // function which means that we need to set the bottom 5 bits (0x1f) in the
303    // mask.
304    result->mExportForeachFuncs.push(std::make_pair(
305          writeString(llvm::StringRef("root"), result->mStringPool,
306                      &cur_string_pool_offset), 0x1f));
307  }
308
309  //===--------------------------------------------------------------------===//
310  // #rs_object_slots
311  //===--------------------------------------------------------------------===//
312  if (object_slots != NULL) {
313    llvm::MDNode *node;
314    for (unsigned int i = 0; i <= export_var->getNumOperands(); i++) {
315      result->mObjectSlots.push(0);
316    }
317    FOR_EACH_NODE_IN(object_slots, node) {
318      llvm::StringRef val = getStringFromOperand(node->getOperand(0));
319      if (val.empty()) {
320        ALOGW("%s contains empty entry in #rs_object_slots (skip)!",
321              module.getModuleIdentifier().c_str());
322      } else {
323        uint32_t slot;
324        if (val.getAsInteger(10, slot)) {
325          ALOGE("Non-integer object slot value '%s' in %s!", val.str().c_str(),
326                module.getModuleIdentifier().c_str());
327          goto bail;
328        } else {
329          result->mObjectSlots.editItemAt(slot) = 1;
330        }
331      }
332    }
333  }
334#undef FOR_EACH_NODE_IN
335
336  //===------------------------------------------------------------------===//
337  // Record information used to invalidate the cache
338  //===------------------------------------------------------------------===//
339  {
340      // Store the SHA-1 in the string pool but without a null-terminator.
341      result->mHeader.sourceSha1Idx = cur_string_pool_offset;
342      uint8_t* sha1 = reinterpret_cast<uint8_t*>(result->mStringPool + cur_string_pool_offset);
343      ::memcpy(sha1, sourceHashToEmbed, SHA1_DIGEST_LENGTH);
344      // Update the string pool pointer.
345      cur_string_pool_offset += SHA1_DIGEST_LENGTH;
346      result->mSourceHash = sha1;
347
348      result->mHeader.compileCommandLineIdx = cur_string_pool_offset;
349      result->mCompileCommandLine = writeString(compileCommandLineToEmbed, result->mStringPool,
350                                                &cur_string_pool_offset);
351
352      result->mHeader.buildFingerprintIdx = cur_string_pool_offset;
353      result->mBuildFingerprint = writeString(buildFingerprintToEmbed, result->mStringPool,
354                                              &cur_string_pool_offset);
355  }
356
357  //===--------------------------------------------------------------------===//
358  // Determine whether the bitcode contains debug information
359  //===--------------------------------------------------------------------===//
360  // The root context of the debug information in the bitcode is put under
361  // the metadata named "llvm.dbg.cu".
362  result->mHeader.hasDebugInformation =
363      static_cast<uint8_t>(module.getNamedMetadata("llvm.dbg.cu") != NULL);
364
365  assert((cur_string_pool_offset == string_pool_size) &&
366            "Unexpected string pool size!");
367
368  return result;
369
370bail:
371  delete result;
372  return NULL;
373}
374