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