1/*
2 * Copyright 2011-2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef __ANDROID_BCINFO_METADATAEXTRACTOR_H__
18#define __ANDROID_BCINFO_METADATAEXTRACTOR_H__
19
20#include <cstddef>
21#include <stdint.h>
22
23namespace llvm {
24  class Module;
25  class NamedMDNode;
26}
27
28namespace bcinfo {
29
30enum RSFloatPrecision {
31  RS_FP_Full = 0,
32  RS_FP_Relaxed = 1,
33  RS_FP_Imprecise = 2
34};
35
36class MetadataExtractor {
37 private:
38  const llvm::Module *mModule;
39  const char *mBitcode;
40  size_t mBitcodeSize;
41
42  size_t mExportVarCount;
43  size_t mExportFuncCount;
44  size_t mExportForEachSignatureCount;
45  const char **mExportVarNameList;
46  const char **mExportFuncNameList;
47  const char **mExportForEachNameList;
48  const uint32_t *mExportForEachSignatureList;
49
50  size_t mPragmaCount;
51  const char **mPragmaKeyList;
52  const char **mPragmaValueList;
53
54  size_t mObjectSlotCount;
55  const uint32_t *mObjectSlotList;
56
57  uint32_t mCompilerVersion;
58  uint32_t mOptimizationLevel;
59
60  enum RSFloatPrecision mRSFloatPrecision;
61
62  // Helper functions for extraction
63  bool populateVarNameMetadata(const llvm::NamedMDNode *VarNameMetadata);
64  bool populateFuncNameMetadata(const llvm::NamedMDNode *FuncNameMetadata);
65  bool populateForEachMetadata(const llvm::NamedMDNode *Names,
66                               const llvm::NamedMDNode *Signatures);
67  bool populateObjectSlotMetadata(const llvm::NamedMDNode *ObjectSlotMetadata);
68  void populatePragmaMetadata(const llvm::NamedMDNode *PragmaMetadata);
69
70 public:
71  /**
72   * Reads metadata from \p bitcode.
73   *
74   * \param bitcode - input bitcode string.
75   * \param bitcodeSize - length of \p bitcode string (in bytes).
76   */
77  MetadataExtractor(const char *bitcode, size_t bitcodeSize);
78
79  /**
80   * Reads metadata from \p module.
81   *
82   * \param module - input module.
83   */
84  MetadataExtractor(const llvm::Module *module);
85
86  ~MetadataExtractor();
87
88  /**
89   * Extract the actual metadata from the supplied bitcode.
90   *
91   * \return true on success and false if an error occurred.
92   */
93  bool extract();
94
95  /**
96   * \return number of exported global variables (slots) in this script/module.
97   */
98  size_t getExportVarCount() const {
99    return mExportVarCount;
100  }
101
102  /**
103   * \return array of exported variable names.
104   */
105  const char **getExportVarNameList() const {
106    return mExportVarNameList;
107  }
108
109  /**
110   * \return number of exported global functions (slots) in this script/module.
111   */
112  size_t getExportFuncCount() const {
113    return mExportFuncCount;
114  }
115
116  /**
117   * \return array of exported function names.
118   */
119  const char **getExportFuncNameList() const {
120    return mExportFuncNameList;
121  }
122
123  /**
124   * \return number of exported ForEach functions in this script/module.
125   */
126  size_t getExportForEachSignatureCount() const {
127    return mExportForEachSignatureCount;
128  }
129
130  /**
131   * \return array of exported ForEach function signatures.
132   */
133  const uint32_t *getExportForEachSignatureList() const {
134    return mExportForEachSignatureList;
135  }
136
137  /**
138   * \return array of exported ForEach function names.
139   */
140  const char **getExportForEachNameList() const {
141    return mExportForEachNameList;
142  }
143
144  /**
145   * \return number of pragmas contained in pragmaKeyList and pragmaValueList.
146   */
147  size_t getPragmaCount() const {
148    return mPragmaCount;
149  }
150
151  /**
152   * \return pragma keys (the name for the pragma).
153   */
154  const char **getPragmaKeyList() const {
155    return mPragmaKeyList;
156  }
157
158  /**
159   * \return pragma values (contents corresponding to a particular pragma key).
160   */
161  const char **getPragmaValueList() const {
162    return mPragmaValueList;
163  }
164
165  /**
166   * \return number of object slots contained in objectSlotList.
167   */
168  size_t getObjectSlotCount() const {
169    return mObjectSlotCount;
170  }
171
172  /**
173   * \return array of object slot numbers that must be cleaned up by driver
174   *         on script teardown.
175   */
176  const uint32_t *getObjectSlotList() const {
177    return mObjectSlotList;
178  }
179
180  /**
181   * \return compiler version that generated this bitcode.
182   */
183  uint32_t getCompilerVersion() const {
184    return mCompilerVersion;
185  }
186
187  /**
188   * \return compiler optimization level for this bitcode.
189   */
190  uint32_t getOptimizationLevel() const {
191    return mOptimizationLevel;
192  }
193
194  /**
195   * \return minimal floating point precision that the script requires.
196   */
197  enum RSFloatPrecision getRSFloatPrecision() const {
198    return mRSFloatPrecision;
199  }
200
201  /**
202   * \return whether or not this ForEach function signature has an "In"
203   * parameter.
204   *
205   * \param sig - ForEach function signature to check.
206   */
207  static bool hasForEachSignatureIn(uint32_t sig) {
208    return sig & 0x01;
209  }
210
211  /**
212   * \return whether or not this ForEach function signature has an "Out"
213   * parameter.
214   *
215   * \param sig - ForEach function signature to check.
216   */
217  static bool hasForEachSignatureOut(uint32_t sig) {
218    return sig & 0x02;
219  }
220
221  /**
222   * \return whether or not this ForEach function signature has a "UsrData"
223   * parameter.
224   *
225   * \param sig - ForEach function signature to check.
226   */
227  static bool hasForEachSignatureUsrData(uint32_t sig) {
228    return sig & 0x04;
229  }
230
231  /**
232   * \return whether or not this ForEach function signature has an "X"
233   * parameter.
234   *
235   * \param sig - ForEach function signature to check.
236   */
237  static bool hasForEachSignatureX(uint32_t sig) {
238    return sig & 0x08;
239  }
240
241  /**
242   * \return whether or not this ForEach function signature has a "Y"
243   * parameter.
244   *
245   * \param sig - ForEach function signature to check.
246   */
247  static bool hasForEachSignatureY(uint32_t sig) {
248    return sig & 0x10;
249  }
250
251  /**
252   * \return whether or not this ForEach function signature is a
253   * pass-by-value "Kernel".
254   *
255   * \param sig - ForEach function signature to check.
256   */
257  static bool hasForEachSignatureKernel(uint32_t sig) {
258    return sig & 0x20;
259  }
260};
261
262}  // namespace bcinfo
263
264#endif  // __ANDROID_BCINFO_METADATAEXTRACTOR_H__
265