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 
23 namespace llvm {
24   class Function;
25   class Module;
26   class NamedMDNode;
27 }
28 
29 namespace bcinfo {
30 
31 enum RSFloatPrecision {
32   RS_FP_Full = 0,
33   RS_FP_Relaxed = 1,
34 };
35 
36 enum MetadataSignatureBitval {
37   MD_SIG_None        = 0,
38   MD_SIG_In          = 0x000001,
39   MD_SIG_Out         = 0x000002,
40   MD_SIG_Usr         = 0x000004,
41   MD_SIG_X           = 0x000008,
42   MD_SIG_Y           = 0x000010,
43   MD_SIG_Kernel      = 0x000020,
44   MD_SIG_Z           = 0x000040,
45   MD_SIG_Ctxt        = 0x000080,
46 };
47 
48 class MetadataExtractor {
49  private:
50   const llvm::Module *mModule;
51   const char *mBitcode;
52   size_t mBitcodeSize;
53 
54   size_t mExportVarCount;
55   size_t mExportFuncCount;
56   size_t mExportForEachSignatureCount;
57   const char **mExportVarNameList;
58   const char **mExportFuncNameList;
59   const char **mExportForEachNameList;
60   const uint32_t *mExportForEachSignatureList;
61 
62   const uint32_t *mExportForEachInputCountList;
63 
64   size_t mPragmaCount;
65   const char **mPragmaKeyList;
66   const char **mPragmaValueList;
67 
68   size_t mObjectSlotCount;
69   const uint32_t *mObjectSlotList;
70 
71   uint32_t mTargetAPI;
72   uint32_t mCompilerVersion;
73   uint32_t mOptimizationLevel;
74 
75   enum RSFloatPrecision mRSFloatPrecision;
76 
77   // Flag to mark that script is threadable.  True by default.
78   bool mIsThreadable;
79 
80   const char *mBuildChecksum;
81 
82   // Helper functions for extraction
83   bool populateVarNameMetadata(const llvm::NamedMDNode *VarNameMetadata);
84   bool populateFuncNameMetadata(const llvm::NamedMDNode *FuncNameMetadata);
85   bool populateForEachMetadata(const llvm::NamedMDNode *Names,
86                                const llvm::NamedMDNode *Signatures);
87   bool populateObjectSlotMetadata(const llvm::NamedMDNode *ObjectSlotMetadata);
88   void populatePragmaMetadata(const llvm::NamedMDNode *PragmaMetadata);
89   void readThreadableFlag(const llvm::NamedMDNode *ThreadableMetadata);
90   void readBuildChecksumMetadata(const llvm::NamedMDNode *ChecksumMetadata);
91 
92   uint32_t calculateNumInputs(const llvm::Function *Function,
93                               uint32_t Signature);
94 
95  public:
96   /**
97    * Reads metadata from \p bitcode.
98    *
99    * \param bitcode - input bitcode string.
100    * \param bitcodeSize - length of \p bitcode string (in bytes).
101    */
102   MetadataExtractor(const char *bitcode, size_t bitcodeSize);
103 
104   /**
105    * Reads metadata from \p module.
106    *
107    * \param module - input module.
108    */
109   MetadataExtractor(const llvm::Module *module);
110 
111   ~MetadataExtractor();
112 
113   /**
114    * Extract the actual metadata from the supplied bitcode.
115    *
116    * \return true on success and false if an error occurred.
117    */
118   bool extract();
119 
120   /**
121    * \return target API level of this bitcode.
122    *
123    * The target API is used during the SDK compilation to provide proper
124    * visibility of the RenderScript runtime API functions.
125    */
getTargetAPI()126   uint32_t getTargetAPI() const {
127     return mTargetAPI;
128   }
129 
130   /**
131    * \return number of exported global variables (slots) in this script/module.
132    */
getExportVarCount()133   size_t getExportVarCount() const {
134     return mExportVarCount;
135   }
136 
137   /**
138    * \return array of exported variable names.
139    */
getExportVarNameList()140   const char **getExportVarNameList() const {
141     return mExportVarNameList;
142   }
143 
144   /**
145    * \return number of exported global functions (slots) in this script/module.
146    */
getExportFuncCount()147   size_t getExportFuncCount() const {
148     return mExportFuncCount;
149   }
150 
151   /**
152    * \return array of exported function names.
153    */
getExportFuncNameList()154   const char **getExportFuncNameList() const {
155     return mExportFuncNameList;
156   }
157 
158   /**
159    * \return number of exported ForEach functions in this script/module.
160    */
getExportForEachSignatureCount()161   size_t getExportForEachSignatureCount() const {
162     return mExportForEachSignatureCount;
163   }
164 
165   /**
166    * \return array of exported ForEach function signatures.
167    */
getExportForEachSignatureList()168   const uint32_t *getExportForEachSignatureList() const {
169     return mExportForEachSignatureList;
170   }
171 
172   /**
173    * \return array of exported ForEach function names.
174    */
getExportForEachNameList()175   const char **getExportForEachNameList() const {
176     return mExportForEachNameList;
177   }
178 
179   /**
180    * \return array of input parameter counts.
181    */
getExportForEachInputCountList()182   const uint32_t *getExportForEachInputCountList() const {
183     return mExportForEachInputCountList;
184   }
185 
186   /**
187    * \return number of pragmas contained in pragmaKeyList and pragmaValueList.
188    */
getPragmaCount()189   size_t getPragmaCount() const {
190     return mPragmaCount;
191   }
192 
193   /**
194    * \return pragma keys (the name for the pragma).
195    */
getPragmaKeyList()196   const char **getPragmaKeyList() const {
197     return mPragmaKeyList;
198   }
199 
200   /**
201    * \return pragma values (contents corresponding to a particular pragma key).
202    */
getPragmaValueList()203   const char **getPragmaValueList() const {
204     return mPragmaValueList;
205   }
206 
207   /**
208    * \return number of object slots contained in objectSlotList.
209    */
getObjectSlotCount()210   size_t getObjectSlotCount() const {
211     return mObjectSlotCount;
212   }
213 
214   /**
215    * \return array of object slot numbers that must be cleaned up by driver
216    *         on script teardown.
217    */
getObjectSlotList()218   const uint32_t *getObjectSlotList() const {
219     return mObjectSlotList;
220   }
221 
222   /**
223    * \return compiler version that generated this bitcode.
224    */
getCompilerVersion()225   uint32_t getCompilerVersion() const {
226     return mCompilerVersion;
227   }
228 
229   /**
230    * \return compiler optimization level for this bitcode.
231    */
getOptimizationLevel()232   uint32_t getOptimizationLevel() const {
233     return mOptimizationLevel;
234   }
235 
236   /**
237    * \return minimal floating point precision that the script requires.
238    */
getRSFloatPrecision()239   enum RSFloatPrecision getRSFloatPrecision() const {
240     return mRSFloatPrecision;
241   }
242 
243   /**
244    * \return whether or not this ForEach function signature has an "In"
245    * parameter.
246    *
247    * \param sig - ForEach function signature to check.
248    */
hasForEachSignatureIn(uint32_t sig)249   static bool hasForEachSignatureIn(uint32_t sig) {
250     return sig & MD_SIG_In;
251   }
252 
253   /**
254    * \return whether or not this ForEach function signature has an "Out"
255    * parameter.
256    *
257    * \param sig - ForEach function signature to check.
258    */
hasForEachSignatureOut(uint32_t sig)259   static bool hasForEachSignatureOut(uint32_t sig) {
260     return sig & MD_SIG_Out;
261   }
262 
263   /**
264    * \return whether or not this ForEach function signature has a "UsrData"
265    * parameter.
266    *
267    * \param sig - ForEach function signature to check.
268    */
hasForEachSignatureUsrData(uint32_t sig)269   static bool hasForEachSignatureUsrData(uint32_t sig) {
270     return sig & MD_SIG_Usr;
271   }
272 
273   /**
274    * \return whether or not this ForEach function signature has an "X"
275    * parameter.
276    *
277    * \param sig - ForEach function signature to check.
278    */
hasForEachSignatureX(uint32_t sig)279   static bool hasForEachSignatureX(uint32_t sig) {
280     return sig & MD_SIG_X;
281   }
282 
283   /**
284    * \return whether or not this ForEach function signature has a "Y"
285    * parameter.
286    *
287    * \param sig - ForEach function signature to check.
288    */
hasForEachSignatureY(uint32_t sig)289   static bool hasForEachSignatureY(uint32_t sig) {
290     return sig & MD_SIG_Y;
291   }
292 
293   /**
294    * \return whether or not this ForEach function signature is a
295    * pass-by-value "Kernel".
296    *
297    * \param sig - ForEach function signature to check.
298    */
hasForEachSignatureKernel(uint32_t sig)299   static bool hasForEachSignatureKernel(uint32_t sig) {
300     return sig & MD_SIG_Kernel;
301   }
302 
303   /**
304    * \return whether or not this ForEach function signature has a "Z"
305    * parameter.
306    *
307    * \param sig - ForEach function signature to check.
308    */
hasForEachSignatureZ(uint32_t sig)309   static bool hasForEachSignatureZ(uint32_t sig) {
310     return sig & MD_SIG_Z;
311   }
312 
313   /**
314    * \return whether or not this ForEach function signature has a "Ctxt"
315    * parameter.
316    *
317    * \param sig - ForEach function signature to check.
318    */
hasForEachSignatureCtxt(uint32_t sig)319   static bool hasForEachSignatureCtxt(uint32_t sig) {
320     return sig & MD_SIG_Ctxt;
321   }
322 
323   /**
324    * \return whether "Kernels" in this script can be processed
325    * by multiple threads
326    */
327 
isThreadable()328   bool isThreadable() const {
329     return mIsThreadable;
330   }
331 
332   /**
333    * \return the build checksum extracted from the LLVM metadata
334    */
getBuildChecksum()335   const char *getBuildChecksum() const {
336     return mBuildChecksum;
337   }
338 };
339 
340 }  // namespace bcinfo
341 
342 #endif  // __ANDROID_BCINFO_METADATAEXTRACTOR_H__
343