blob: 2537fdd03fc3efb53c4d9a20c4eabaf404b18ed8 [file] [log] [blame]
Stephen Hines932bc6e2011-07-27 16:26:26 -07001/*
Stephen Hinescc366e52012-02-21 17:22:04 -08002 * Copyright 2011-2012, The Android Open Source Project
Stephen Hines932bc6e2011-07-27 16:26:26 -07003 *
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#include "bcinfo/MetadataExtractor.h"
18
Stephen Hinesb67c9e72012-03-22 11:02:48 -070019#include "bcinfo/BitcodeWrapper.h"
20
Stephen Hines932bc6e2011-07-27 16:26:26 -070021#define LOG_TAG "bcinfo"
22#include <cutils/log.h>
23
24#include "llvm/ADT/OwningPtr.h"
25#include "llvm/Bitcode/ReaderWriter.h"
Daniel Malea094881f2011-12-14 17:39:16 -050026#include "llvm/Constants.h"
Stephen Hines932bc6e2011-07-27 16:26:26 -070027#include "llvm/LLVMContext.h"
28#include "llvm/Module.h"
29#include "llvm/Support/MemoryBuffer.h"
30
31#include <cstdlib>
32
33namespace bcinfo {
34
35// Name of metadata node where pragma info resides (should be synced with
36// slang.cpp)
37static const llvm::StringRef PragmaMetadataName = "#pragma";
38
39// Name of metadata node where exported variable names reside (should be
40// synced with slang_rs_metadata.h)
41static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
42
43// Name of metadata node where exported function names reside (should be
44// synced with slang_rs_metadata.h)
45static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
46
Stephen Hinescc366e52012-02-21 17:22:04 -080047// Name of metadata node where exported ForEach name information resides
48// (should be synced with slang_rs_metadata.h)
49static const llvm::StringRef ExportForEachNameMetadataName =
50 "#rs_export_foreach_name";
51
Stephen Hines33f8fe22011-08-17 12:56:22 -070052// Name of metadata node where exported ForEach signature information resides
53// (should be synced with slang_rs_metadata.h)
54static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
55
Stephen Hines932bc6e2011-07-27 16:26:26 -070056// Name of metadata node where RS object slot info resides (should be
57// synced with slang_rs_metadata.h)
58static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
59
60
61MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
Stephen Hines569986d2012-03-09 19:58:45 -080062 : mModule(NULL), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
63 mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
64 mExportVarNameList(NULL), mExportFuncNameList(NULL),
65 mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
66 mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
Stephen Hinesa7e5c8f2012-03-28 12:58:24 -070067 mObjectSlotCount(0), mObjectSlotList(NULL),
Stephen Hinese1fd8042012-03-27 11:03:46 -070068 mRSFloatPrecision(RS_FP_Full) {
Stephen Hinesb67c9e72012-03-22 11:02:48 -070069 BitcodeWrapper wrapper(bitcode, bitcodeSize);
70 mCompilerVersion = wrapper.getCompilerVersion();
71 mOptimizationLevel = wrapper.getOptimizationLevel();
Stephen Hines569986d2012-03-09 19:58:45 -080072}
73
74
75MetadataExtractor::MetadataExtractor(const llvm::Module *module)
76 : mModule(module), mBitcode(NULL), mBitcodeSize(0), mExportVarCount(0),
Stephen Hines33f8fe22011-08-17 12:56:22 -070077 mExportFuncCount(0), mExportForEachSignatureCount(0),
Stephen Hines569986d2012-03-09 19:58:45 -080078 mExportVarNameList(NULL), mExportFuncNameList(NULL),
Stephen Hinescc366e52012-02-21 17:22:04 -080079 mExportForEachNameList(NULL), mExportForEachSignatureList(NULL),
80 mPragmaCount(0), mPragmaKeyList(NULL), mPragmaValueList(NULL),
Stephen Hines98abb2d2012-04-06 16:52:51 -070081 mObjectSlotCount(0), mObjectSlotList(NULL),
82 mRSFloatPrecision(RS_FP_Full) {
Stephen Hinesa7e5c8f2012-03-28 12:58:24 -070083 mCompilerVersion = 0;
84 mOptimizationLevel = 3;
Stephen Hines932bc6e2011-07-27 16:26:26 -070085}
86
87
88MetadataExtractor::~MetadataExtractor() {
Stephen Hines569986d2012-03-09 19:58:45 -080089 if (mExportVarNameList) {
90 for (size_t i = 0; i < mExportVarCount; i++) {
91 delete [] mExportVarNameList[i];
92 mExportVarNameList[i] = NULL;
93 }
94 }
95 delete [] mExportVarNameList;
96 mExportVarNameList = NULL;
97
98 if (mExportFuncNameList) {
99 for (size_t i = 0; i < mExportFuncCount; i++) {
100 delete [] mExportFuncNameList[i];
101 mExportFuncNameList[i] = NULL;
102 }
103 }
104 delete [] mExportFuncNameList;
105 mExportFuncNameList = NULL;
106
Stephen Hinescc366e52012-02-21 17:22:04 -0800107 if (mExportForEachNameList) {
108 for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
109 delete [] mExportForEachNameList[i];
110 mExportForEachNameList[i] = NULL;
111 }
112 }
113 delete [] mExportForEachNameList;
114 mExportForEachNameList = NULL;
115
Stephen Hines33f8fe22011-08-17 12:56:22 -0700116 delete [] mExportForEachSignatureList;
117 mExportForEachSignatureList = NULL;
118
Stephen Hinescc366e52012-02-21 17:22:04 -0800119 for (size_t i = 0; i < mPragmaCount; i++) {
120 if (mPragmaKeyList) {
121 delete [] mPragmaKeyList[i];
122 mPragmaKeyList[i] = NULL;
123 }
124 if (mPragmaValueList) {
125 delete [] mPragmaValueList[i];
126 mPragmaValueList[i] = NULL;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700127 }
128 }
129 delete [] mPragmaKeyList;
130 mPragmaKeyList = NULL;
131 delete [] mPragmaValueList;
132 mPragmaValueList = NULL;
133
134 delete [] mObjectSlotList;
135 mObjectSlotList = NULL;
136
137 return;
138}
139
140
141bool MetadataExtractor::populateObjectSlotMetadata(
142 const llvm::NamedMDNode *ObjectSlotMetadata) {
143 if (!ObjectSlotMetadata) {
144 return true;
145 }
146
147 mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
148
149 if (!mObjectSlotCount) {
150 return true;
151 }
152
153 uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
154 memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
155
156 for (size_t i = 0; i < mObjectSlotCount; i++) {
157 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
158 if (ObjectSlot != NULL && ObjectSlot->getNumOperands() == 1) {
159 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
160 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
161 llvm::StringRef Slot =
162 static_cast<llvm::MDString*>(SlotMDS)->getString();
163 uint32_t USlot = 0;
164 if (Slot.getAsInteger(10, USlot)) {
Steve Block10c14122012-01-08 10:15:06 +0000165 ALOGE("Non-integer object slot value '%s'", Slot.str().c_str());
Stephen Hines932bc6e2011-07-27 16:26:26 -0700166 return false;
167 }
168 TmpSlotList[i] = USlot;
169 }
170 }
171 }
172
173 mObjectSlotList = TmpSlotList;
174
175 return true;
176}
177
178
179static const char *createStringFromValue(llvm::Value *v) {
180 if (v->getValueID() != llvm::Value::MDStringVal) {
181 return NULL;
182 }
183
184 llvm::StringRef ref = static_cast<llvm::MDString*>(v)->getString();
185
186 char *c = new char[ref.size() + 1];
187 memcpy(c, ref.data(), ref.size());
188 c[ref.size()] = '\0';
189
190 return c;
191}
192
193
194void MetadataExtractor::populatePragmaMetadata(
195 const llvm::NamedMDNode *PragmaMetadata) {
196 if (!PragmaMetadata) {
197 return;
198 }
199
200 mPragmaCount = PragmaMetadata->getNumOperands();
201 if (!mPragmaCount) {
202 return;
203 }
204
Stephen Hines569986d2012-03-09 19:58:45 -0800205 const char **TmpKeyList = new const char*[mPragmaCount];
206 const char **TmpValueList = new const char*[mPragmaCount];
Stephen Hines932bc6e2011-07-27 16:26:26 -0700207
208 for (size_t i = 0; i < mPragmaCount; i++) {
209 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
210 if (Pragma != NULL && Pragma->getNumOperands() == 2) {
211 llvm::Value *PragmaKeyMDS = Pragma->getOperand(0);
Stephen Hines569986d2012-03-09 19:58:45 -0800212 TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700213 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
Stephen Hines569986d2012-03-09 19:58:45 -0800214 TmpValueList[i] = createStringFromValue(PragmaValueMDS);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700215 }
216 }
217
Stephen Hines569986d2012-03-09 19:58:45 -0800218 mPragmaKeyList = TmpKeyList;
219 mPragmaValueList = TmpValueList;
220
Stephen Hinese1fd8042012-03-27 11:03:46 -0700221 // Check to see if we have any FP precision-related pragmas.
222 std::string Relaxed("rs_fp_relaxed");
223 std::string Imprecise("rs_fp_imprecise");
224 bool RelaxedPragmaSeen = false;
225 bool ImprecisePragmaSeen = false;
226
227 for (size_t i = 0; i < mPragmaCount; i++) {
228 if (!Relaxed.compare(mPragmaKeyList[i])) {
229 if (RelaxedPragmaSeen || ImprecisePragmaSeen) {
230 ALOGE("Multiple float precision pragmas specified!");
231 }
232 RelaxedPragmaSeen = true;
233 } else if (!Imprecise.compare(mPragmaKeyList[i])) {
234 if (RelaxedPragmaSeen || ImprecisePragmaSeen) {
235 ALOGE("Multiple float precision pragmas specified!");
236 }
237 ImprecisePragmaSeen = true;
238 }
239 }
240
241 // Imprecise is selected over Relaxed precision.
242 // In the absence of both, we stick to the default Full precision.
243 if (ImprecisePragmaSeen) {
244 mRSFloatPrecision = RS_FP_Imprecise;
245 } else if (RelaxedPragmaSeen) {
246 mRSFloatPrecision = RS_FP_Relaxed;
247 }
248
Stephen Hines932bc6e2011-07-27 16:26:26 -0700249 return;
250}
251
252
Stephen Hines569986d2012-03-09 19:58:45 -0800253bool MetadataExtractor::populateVarNameMetadata(
254 const llvm::NamedMDNode *VarNameMetadata) {
255 if (!VarNameMetadata) {
256 return true;
257 }
258
259 mExportVarCount = VarNameMetadata->getNumOperands();
260 if (!mExportVarCount) {
261 return true;
262 }
263
264 const char **TmpNameList = new const char *[mExportVarCount];
265
266 for (size_t i = 0; i < mExportVarCount; i++) {
267 llvm::MDNode *Name = VarNameMetadata->getOperand(i);
268 if (Name != NULL && Name->getNumOperands() > 1) {
269 TmpNameList[i] = createStringFromValue(Name->getOperand(0));
270 }
271 }
272
273 mExportVarNameList = TmpNameList;
274
275 return true;
276}
277
278
279bool MetadataExtractor::populateFuncNameMetadata(
280 const llvm::NamedMDNode *FuncNameMetadata) {
281 if (!FuncNameMetadata) {
282 return true;
283 }
284
285 mExportFuncCount = FuncNameMetadata->getNumOperands();
286 if (!mExportFuncCount) {
287 return true;
288 }
289
290 const char **TmpNameList = new const char*[mExportFuncCount];
291
292 for (size_t i = 0; i < mExportFuncCount; i++) {
293 llvm::MDNode *Name = FuncNameMetadata->getOperand(i);
294 if (Name != NULL && Name->getNumOperands() == 1) {
295 TmpNameList[i] = createStringFromValue(Name->getOperand(0));
296 }
297 }
298
299 mExportFuncNameList = TmpNameList;
300
301 return true;
302}
303
304
Stephen Hines33f8fe22011-08-17 12:56:22 -0700305bool MetadataExtractor::populateForEachMetadata(
Stephen Hinescc366e52012-02-21 17:22:04 -0800306 const llvm::NamedMDNode *Names,
307 const llvm::NamedMDNode *Signatures) {
Stephen Hines6649e6b2012-06-06 16:01:59 -0700308 if (!Names && !Signatures) {
Stephen Hines0231bb02011-10-10 15:30:25 -0700309 // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
310 // section for ForEach. We generate a full signature for a "root" function
311 // which means that we need to set the bottom 5 bits in the mask.
312 mExportForEachSignatureCount = 1;
Stephen Hinescc366e52012-02-21 17:22:04 -0800313 char **TmpNameList = new char*[mExportForEachSignatureCount];
314 TmpNameList[0] = new char[5];
315 strncpy(TmpNameList[0], "root", 5);
316
Stephen Hines0231bb02011-10-10 15:30:25 -0700317 uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
318 TmpSigList[0] = 0x1f;
Stephen Hines569986d2012-03-09 19:58:45 -0800319
Stephen Hinescc366e52012-02-21 17:22:04 -0800320 mExportForEachNameList = (const char**)TmpNameList;
Stephen Hines0231bb02011-10-10 15:30:25 -0700321 mExportForEachSignatureList = TmpSigList;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700322 return true;
323 }
324
Stephen Hines6649e6b2012-06-06 16:01:59 -0700325 if (Signatures) {
326 mExportForEachSignatureCount = Signatures->getNumOperands();
327 if (!mExportForEachSignatureCount) {
328 return true;
329 }
330 } else {
331 mExportForEachSignatureCount = 0;
332 mExportForEachSignatureList = NULL;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700333 return true;
334 }
335
336 uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
Stephen Hines569986d2012-03-09 19:58:45 -0800337 const char **TmpNameList = new const char*[mExportForEachSignatureCount];
Stephen Hines33f8fe22011-08-17 12:56:22 -0700338
339 for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
Stephen Hinescc366e52012-02-21 17:22:04 -0800340 llvm::MDNode *SigNode = Signatures->getOperand(i);
Stephen Hines33f8fe22011-08-17 12:56:22 -0700341 if (SigNode != NULL && SigNode->getNumOperands() == 1) {
342 llvm::Value *SigVal = SigNode->getOperand(0);
343 if (SigVal->getValueID() == llvm::Value::MDStringVal) {
344 llvm::StringRef SigString =
345 static_cast<llvm::MDString*>(SigVal)->getString();
346 uint32_t Signature = 0;
347 if (SigString.getAsInteger(10, Signature)) {
Steve Block10c14122012-01-08 10:15:06 +0000348 ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
Stephen Hines33f8fe22011-08-17 12:56:22 -0700349 return false;
350 }
351 TmpSigList[i] = Signature;
352 }
353 }
354 }
355
Stephen Hines6649e6b2012-06-06 16:01:59 -0700356 if (Names) {
357 for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
358 llvm::MDNode *Name = Names->getOperand(i);
359 if (Name != NULL && Name->getNumOperands() == 1) {
360 TmpNameList[i] = createStringFromValue(Name->getOperand(0));
361 }
Stephen Hinescc366e52012-02-21 17:22:04 -0800362 }
Stephen Hines6649e6b2012-06-06 16:01:59 -0700363 } else {
364 if (mExportForEachSignatureCount != 1) {
365 ALOGE("mExportForEachSignatureCount = %u, but should be 1",
366 mExportForEachSignatureCount);
367 }
368 char *RootName = new char[5];
369 strncpy(RootName, "root", 5);
370 TmpNameList[0] = RootName;
Stephen Hinescc366e52012-02-21 17:22:04 -0800371 }
372
Stephen Hines569986d2012-03-09 19:58:45 -0800373 mExportForEachNameList = TmpNameList;
374 mExportForEachSignatureList = TmpSigList;
375
Stephen Hines33f8fe22011-08-17 12:56:22 -0700376 return true;
377}
378
379
Stephen Hines932bc6e2011-07-27 16:26:26 -0700380bool MetadataExtractor::extract() {
Stephen Hines569986d2012-03-09 19:58:45 -0800381 if (!(mBitcode && mBitcodeSize) && !mModule) {
382 ALOGE("Invalid/empty bitcode/module");
Stephen Hines932bc6e2011-07-27 16:26:26 -0700383 return false;
384 }
385
Stephen Hines569986d2012-03-09 19:58:45 -0800386 llvm::OwningPtr<llvm::LLVMContext> mContext;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700387
Stephen Hines569986d2012-03-09 19:58:45 -0800388 if (!mModule) {
389 mContext.reset(new llvm::LLVMContext());
390 llvm::OwningPtr<llvm::MemoryBuffer> MEM(
391 llvm::MemoryBuffer::getMemBuffer(
Stephen Hinese708ffe2012-05-03 15:18:49 -0700392 llvm::StringRef(mBitcode, mBitcodeSize), "", false));
Stephen Hines569986d2012-03-09 19:58:45 -0800393 std::string error;
394
395 // Module ownership is handled by the context, so we don't need to free it.
396 mModule = llvm::ParseBitcodeFile(MEM.get(), *mContext, &error);
397 if (!mModule) {
398 ALOGE("Could not parse bitcode file");
399 ALOGE("%s", error.c_str());
400 return false;
401 }
Stephen Hines932bc6e2011-07-27 16:26:26 -0700402 }
403
404 const llvm::NamedMDNode *ExportVarMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800405 mModule->getNamedMetadata(ExportVarMetadataName);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700406 const llvm::NamedMDNode *ExportFuncMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800407 mModule->getNamedMetadata(ExportFuncMetadataName);
Stephen Hinescc366e52012-02-21 17:22:04 -0800408 const llvm::NamedMDNode *ExportForEachNameMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800409 mModule->getNamedMetadata(ExportForEachNameMetadataName);
Stephen Hines33f8fe22011-08-17 12:56:22 -0700410 const llvm::NamedMDNode *ExportForEachMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800411 mModule->getNamedMetadata(ExportForEachMetadataName);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700412 const llvm::NamedMDNode *PragmaMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800413 mModule->getNamedMetadata(PragmaMetadataName);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700414 const llvm::NamedMDNode *ObjectSlotMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800415 mModule->getNamedMetadata(ObjectSlotMetadataName);
Daniel Malea094881f2011-12-14 17:39:16 -0500416
Stephen Hines932bc6e2011-07-27 16:26:26 -0700417
Stephen Hines569986d2012-03-09 19:58:45 -0800418 if (!populateVarNameMetadata(ExportVarMetadata)) {
419 ALOGE("Could not populate export variable metadata");
420 return false;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700421 }
422
Stephen Hines569986d2012-03-09 19:58:45 -0800423 if (!populateFuncNameMetadata(ExportFuncMetadata)) {
424 ALOGE("Could not populate export function metadata");
425 return false;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700426 }
427
Stephen Hinescc366e52012-02-21 17:22:04 -0800428 if (!populateForEachMetadata(ExportForEachNameMetadata,
429 ExportForEachMetadata)) {
Steve Block10c14122012-01-08 10:15:06 +0000430 ALOGE("Could not populate ForEach signature metadata");
Stephen Hines33f8fe22011-08-17 12:56:22 -0700431 return false;
432 }
433
Stephen Hines932bc6e2011-07-27 16:26:26 -0700434 populatePragmaMetadata(PragmaMetadata);
435
436 if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
Steve Block10c14122012-01-08 10:15:06 +0000437 ALOGE("Could not populate object slot metadata");
Stephen Hines932bc6e2011-07-27 16:26:26 -0700438 return false;
439 }
440
Stephen Hines932bc6e2011-07-27 16:26:26 -0700441 return true;
442}
443
444} // namespace bcinfo
445