blob: 48a2ecbd37f97e261f4b8bcd5856c24f36eb9c05 [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"
Stephen Hinesfb81ec12015-05-18 20:04:23 -070020#include "rsDefines.h"
Stephen Hinesb67c9e72012-03-22 11:02:48 -070021
Stephen Hines932bc6e2011-07-27 16:26:26 -070022#define LOG_TAG "bcinfo"
23#include <cutils/log.h>
Elliott Hughesfe0de782015-08-12 15:09:33 -070024#ifdef __ANDROID__
Stephen Hines32c56ec2012-06-01 15:26:30 -070025#include <cutils/properties.h>
Nick Kralevich85d95712013-05-22 13:49:01 -070026#endif
Stephen Hines932bc6e2011-07-27 16:26:26 -070027
Stephen Hines932bc6e2011-07-27 16:26:26 -070028#include "llvm/Bitcode/ReaderWriter.h"
Stephen Hinesb730e232013-01-09 15:31:36 -080029#include "llvm/IR/Constants.h"
30#include "llvm/IR/LLVMContext.h"
31#include "llvm/IR/Module.h"
Chris Wailesa6681822014-07-11 15:15:46 -070032#include "llvm/IR/Function.h"
Stephen Hines932bc6e2011-07-27 16:26:26 -070033#include "llvm/Support/MemoryBuffer.h"
34
35#include <cstdlib>
36
37namespace bcinfo {
38
Stephen Hines1bd9f622015-03-18 14:53:10 -070039namespace {
40
Stephen Hinese1c7d292015-04-15 13:20:00 -070041llvm::StringRef getStringOperand(const llvm::Metadata *node) {
42 if (auto *mds = llvm::dyn_cast_or_null<const llvm::MDString>(node)) {
Stephen Hines1bd9f622015-03-18 14:53:10 -070043 return mds->getString();
44 }
45 return llvm::StringRef();
46}
Stephen Hinese1c7d292015-04-15 13:20:00 -070047
48bool extractUIntFromMetadataString(uint32_t *value,
49 const llvm::Metadata *m) {
50 llvm::StringRef SigString = getStringOperand(m);
51 if (SigString != "") {
52 if (!SigString.getAsInteger(10, *value)) {
53 return true;
54 }
55 }
56 return false;
57}
58
Matt Wala1895ac12015-07-16 15:34:29 -070059const char *createStringFromValue(llvm::Metadata *m) {
60 auto ref = getStringOperand(m);
61 char *c = new char[ref.size() + 1];
62 memcpy(c, ref.data(), ref.size());
63 c[ref.size()] = '\0';
64 return c;
Stephen Hines1bd9f622015-03-18 14:53:10 -070065}
66
David Gross79e1a052016-01-11 14:42:51 -080067const char *createStringFromOptionalValue(llvm::MDNode *n, unsigned opndNum) {
68 llvm::Metadata *opnd;
69 if (opndNum >= n->getNumOperands() || !(opnd = n->getOperand(opndNum)))
70 return nullptr;
71 return createStringFromValue(opnd);
72}
73
Matt Wala1895ac12015-07-16 15:34:29 -070074// Collect metadata from NamedMDNodes that contain a list of names
75// (strings).
76//
77// Inputs:
78//
79// NamedMetadata - An LLVM metadata node, each of whose operands have
80// a string as their first entry
81//
82// NameList - A reference that will hold an allocated array of strings
83//
84// Count - A reference that will hold the length of the allocated
85// array of strings
86//
87// Return value:
88//
89// Return true on success, false on error.
90//
91// Upon success, the function sets NameList to an array of strings
92// corresponding the names found in the metadata. The function sets
93// Count to the number of entries in NameList.
94//
95// An error occurs if one of the metadata operands doesn't have a
96// first entry.
97bool populateNameMetadata(const llvm::NamedMDNode *NameMetadata,
98 const char **&NameList, size_t &Count) {
99 if (!NameMetadata) {
100 NameList = nullptr;
101 Count = 0;
102 return true;
103 }
104
105 Count = NameMetadata->getNumOperands();
106 if (!Count) {
107 NameList = nullptr;
108 return true;
109 }
110
111 NameList = new const char *[Count];
112
113 for (size_t i = 0; i < Count; i++) {
114 llvm::MDNode *Name = NameMetadata->getOperand(i);
115 if (Name && Name->getNumOperands() > 0) {
116 NameList[i] = createStringFromValue(Name->getOperand(0));
117 } else {
118 ALOGE("Metadata operand does not contain a name string");
119 for (size_t AllocatedIndex = 0; AllocatedIndex < i; AllocatedIndex++) {
120 delete [] NameList[AllocatedIndex];
121 }
122 delete [] NameList;
123 NameList = nullptr;
124 Count = 0;
125
126 return false;
127 }
128 }
129
130 return true;
131}
132
133} // end anonymous namespace
134
Stephen Hines932bc6e2011-07-27 16:26:26 -0700135// Name of metadata node where pragma info resides (should be synced with
136// slang.cpp)
137static const llvm::StringRef PragmaMetadataName = "#pragma";
138
139// Name of metadata node where exported variable names reside (should be
140// synced with slang_rs_metadata.h)
141static const llvm::StringRef ExportVarMetadataName = "#rs_export_var";
142
143// Name of metadata node where exported function names reside (should be
144// synced with slang_rs_metadata.h)
145static const llvm::StringRef ExportFuncMetadataName = "#rs_export_func";
146
Stephen Hinescc366e52012-02-21 17:22:04 -0800147// Name of metadata node where exported ForEach name information resides
148// (should be synced with slang_rs_metadata.h)
149static const llvm::StringRef ExportForEachNameMetadataName =
150 "#rs_export_foreach_name";
151
Stephen Hines33f8fe22011-08-17 12:56:22 -0700152// Name of metadata node where exported ForEach signature information resides
153// (should be synced with slang_rs_metadata.h)
154static const llvm::StringRef ExportForEachMetadataName = "#rs_export_foreach";
155
David Gross79e1a052016-01-11 14:42:51 -0800156// Name of metadata node where exported general reduce information resides
157// (should be synced with slang_rs_metadata.h)
David Grossa48ea362016-06-02 14:46:55 -0700158static const llvm::StringRef ExportReduceMetadataName = "#rs_export_reduce";
David Gross79e1a052016-01-11 14:42:51 -0800159
Stephen Hines932bc6e2011-07-27 16:26:26 -0700160// Name of metadata node where RS object slot info resides (should be
161// synced with slang_rs_metadata.h)
162static const llvm::StringRef ObjectSlotMetadataName = "#rs_object_slots";
163
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800164static const llvm::StringRef ThreadableMetadataName = "#rs_is_threadable";
Stephen Hines932bc6e2011-07-27 16:26:26 -0700165
Pirama Arumuga Nainar51ee77b2015-02-19 16:33:27 -0800166// Name of metadata node where the checksum for this build is stored. (should
167// be synced with libbcc/lib/Core/Source.cpp)
168static const llvm::StringRef ChecksumMetadataName = "#rs_build_checksum";
169
Dean De Leofff398d2015-11-25 13:00:31 +0000170// Name of metadata node which contains a list of compile units that have debug
171// metadata. If this is null then there is no debug metadata in the compile
172// unit.
173static const llvm::StringRef DebugInfoMetadataName = "llvm.dbg.cu";
174
Stephen Hines932bc6e2011-07-27 16:26:26 -0700175MetadataExtractor::MetadataExtractor(const char *bitcode, size_t bitcodeSize)
Chris Wailes900c6c12014-08-13 15:40:00 -0700176 : mModule(nullptr), mBitcode(bitcode), mBitcodeSize(bitcodeSize),
Stephen Hines569986d2012-03-09 19:58:45 -0800177 mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
David Grossa48ea362016-06-02 14:46:55 -0700178 mExportReduceCount(0), mExportVarNameList(nullptr),
Matt Wala1895ac12015-07-16 15:34:29 -0700179 mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
180 mExportForEachSignatureList(nullptr),
David Grossa48ea362016-06-02 14:46:55 -0700181 mExportForEachInputCountList(nullptr),
182 mExportReduceList(nullptr),
Matt Wala1895ac12015-07-16 15:34:29 -0700183 mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
184 mObjectSlotCount(0), mObjectSlotList(nullptr),
185 mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
Dean De Leofff398d2015-11-25 13:00:31 +0000186 mBuildChecksum(nullptr), mHasDebugInfo(false) {
Stephen Hinesb67c9e72012-03-22 11:02:48 -0700187 BitcodeWrapper wrapper(bitcode, bitcodeSize);
Stephen Hines09479232015-04-02 08:43:41 -0700188 mTargetAPI = wrapper.getTargetAPI();
Stephen Hinesb67c9e72012-03-22 11:02:48 -0700189 mCompilerVersion = wrapper.getCompilerVersion();
190 mOptimizationLevel = wrapper.getOptimizationLevel();
Stephen Hines569986d2012-03-09 19:58:45 -0800191}
192
Stephen Hines569986d2012-03-09 19:58:45 -0800193MetadataExtractor::MetadataExtractor(const llvm::Module *module)
Matt Wala1895ac12015-07-16 15:34:29 -0700194 : mModule(module), mBitcode(nullptr), mBitcodeSize(0),
195 mExportVarCount(0), mExportFuncCount(0), mExportForEachSignatureCount(0),
David Grossa48ea362016-06-02 14:46:55 -0700196 mExportReduceCount(0), mExportVarNameList(nullptr),
Matt Wala1895ac12015-07-16 15:34:29 -0700197 mExportFuncNameList(nullptr), mExportForEachNameList(nullptr),
198 mExportForEachSignatureList(nullptr),
David Grossa48ea362016-06-02 14:46:55 -0700199 mExportForEachInputCountList(nullptr),
200 mExportReduceList(nullptr),
Matt Wala1895ac12015-07-16 15:34:29 -0700201 mPragmaCount(0), mPragmaKeyList(nullptr), mPragmaValueList(nullptr),
202 mObjectSlotCount(0), mObjectSlotList(nullptr),
203 mRSFloatPrecision(RS_FP_Full), mIsThreadable(true),
204 mBuildChecksum(nullptr) {
Stephen Hinese1094342014-05-13 17:55:49 -0700205 mCompilerVersion = RS_VERSION; // Default to the actual current version.
Stephen Hinesa7e5c8f2012-03-28 12:58:24 -0700206 mOptimizationLevel = 3;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700207}
208
209
210MetadataExtractor::~MetadataExtractor() {
Stephen Hines569986d2012-03-09 19:58:45 -0800211 if (mExportVarNameList) {
212 for (size_t i = 0; i < mExportVarCount; i++) {
213 delete [] mExportVarNameList[i];
Chris Wailes900c6c12014-08-13 15:40:00 -0700214 mExportVarNameList[i] = nullptr;
Stephen Hines569986d2012-03-09 19:58:45 -0800215 }
216 }
217 delete [] mExportVarNameList;
Chris Wailes900c6c12014-08-13 15:40:00 -0700218 mExportVarNameList = nullptr;
Stephen Hines569986d2012-03-09 19:58:45 -0800219
220 if (mExportFuncNameList) {
221 for (size_t i = 0; i < mExportFuncCount; i++) {
222 delete [] mExportFuncNameList[i];
Chris Wailes900c6c12014-08-13 15:40:00 -0700223 mExportFuncNameList[i] = nullptr;
Stephen Hines569986d2012-03-09 19:58:45 -0800224 }
225 }
226 delete [] mExportFuncNameList;
Chris Wailes900c6c12014-08-13 15:40:00 -0700227 mExportFuncNameList = nullptr;
Stephen Hines569986d2012-03-09 19:58:45 -0800228
Stephen Hinescc366e52012-02-21 17:22:04 -0800229 if (mExportForEachNameList) {
230 for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
231 delete [] mExportForEachNameList[i];
Chris Wailes900c6c12014-08-13 15:40:00 -0700232 mExportForEachNameList[i] = nullptr;
Stephen Hinescc366e52012-02-21 17:22:04 -0800233 }
234 }
235 delete [] mExportForEachNameList;
Chris Wailes900c6c12014-08-13 15:40:00 -0700236 mExportForEachNameList = nullptr;
Stephen Hinescc366e52012-02-21 17:22:04 -0800237
Stephen Hines33f8fe22011-08-17 12:56:22 -0700238 delete [] mExportForEachSignatureList;
Chris Wailes900c6c12014-08-13 15:40:00 -0700239 mExportForEachSignatureList = nullptr;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700240
David Gross79e1a052016-01-11 14:42:51 -0800241 delete [] mExportForEachInputCountList;
242 mExportForEachInputCountList = nullptr;
243
David Grossa48ea362016-06-02 14:46:55 -0700244 delete [] mExportReduceList;
245 mExportReduceList = nullptr;
David Gross79e1a052016-01-11 14:42:51 -0800246
Stephen Hinescc366e52012-02-21 17:22:04 -0800247 for (size_t i = 0; i < mPragmaCount; i++) {
248 if (mPragmaKeyList) {
249 delete [] mPragmaKeyList[i];
Chris Wailes900c6c12014-08-13 15:40:00 -0700250 mPragmaKeyList[i] = nullptr;
Stephen Hinescc366e52012-02-21 17:22:04 -0800251 }
252 if (mPragmaValueList) {
253 delete [] mPragmaValueList[i];
Chris Wailes900c6c12014-08-13 15:40:00 -0700254 mPragmaValueList[i] = nullptr;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700255 }
256 }
257 delete [] mPragmaKeyList;
Chris Wailes900c6c12014-08-13 15:40:00 -0700258 mPragmaKeyList = nullptr;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700259 delete [] mPragmaValueList;
Chris Wailes900c6c12014-08-13 15:40:00 -0700260 mPragmaValueList = nullptr;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700261
262 delete [] mObjectSlotList;
Chris Wailes900c6c12014-08-13 15:40:00 -0700263 mObjectSlotList = nullptr;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700264
Pirama Arumuga Nainar51ee77b2015-02-19 16:33:27 -0800265 delete [] mBuildChecksum;
266
Stephen Hines932bc6e2011-07-27 16:26:26 -0700267 return;
268}
269
270
271bool MetadataExtractor::populateObjectSlotMetadata(
272 const llvm::NamedMDNode *ObjectSlotMetadata) {
273 if (!ObjectSlotMetadata) {
274 return true;
275 }
276
277 mObjectSlotCount = ObjectSlotMetadata->getNumOperands();
278
279 if (!mObjectSlotCount) {
280 return true;
281 }
282
283 uint32_t *TmpSlotList = new uint32_t[mObjectSlotCount];
284 memset(TmpSlotList, 0, mObjectSlotCount * sizeof(*TmpSlotList));
285
286 for (size_t i = 0; i < mObjectSlotCount; i++) {
287 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
Chris Wailes900c6c12014-08-13 15:40:00 -0700288 if (ObjectSlot != nullptr && ObjectSlot->getNumOperands() == 1) {
Stephen Hinese1c7d292015-04-15 13:20:00 -0700289 if (!extractUIntFromMetadataString(&TmpSlotList[i], ObjectSlot->getOperand(0))) {
290 ALOGE("Non-integer object slot value");
291 return false;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700292 }
Stephen Hinese1c7d292015-04-15 13:20:00 -0700293 } else {
294 ALOGE("Corrupt object slot information");
295 return false;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700296 }
297 }
298
299 mObjectSlotList = TmpSlotList;
300
301 return true;
302}
303
304
Stephen Hines932bc6e2011-07-27 16:26:26 -0700305void MetadataExtractor::populatePragmaMetadata(
306 const llvm::NamedMDNode *PragmaMetadata) {
307 if (!PragmaMetadata) {
308 return;
309 }
310
311 mPragmaCount = PragmaMetadata->getNumOperands();
312 if (!mPragmaCount) {
313 return;
314 }
315
Stephen Hines569986d2012-03-09 19:58:45 -0800316 const char **TmpKeyList = new const char*[mPragmaCount];
317 const char **TmpValueList = new const char*[mPragmaCount];
Stephen Hines932bc6e2011-07-27 16:26:26 -0700318
319 for (size_t i = 0; i < mPragmaCount; i++) {
320 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
Chris Wailes900c6c12014-08-13 15:40:00 -0700321 if (Pragma != nullptr && Pragma->getNumOperands() == 2) {
Stephen Hines1bd9f622015-03-18 14:53:10 -0700322 llvm::Metadata *PragmaKeyMDS = Pragma->getOperand(0);
Stephen Hines569986d2012-03-09 19:58:45 -0800323 TmpKeyList[i] = createStringFromValue(PragmaKeyMDS);
Stephen Hines1bd9f622015-03-18 14:53:10 -0700324 llvm::Metadata *PragmaValueMDS = Pragma->getOperand(1);
Stephen Hines569986d2012-03-09 19:58:45 -0800325 TmpValueList[i] = createStringFromValue(PragmaValueMDS);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700326 }
327 }
328
Stephen Hines569986d2012-03-09 19:58:45 -0800329 mPragmaKeyList = TmpKeyList;
330 mPragmaValueList = TmpValueList;
331
Stephen Hinese1fd8042012-03-27 11:03:46 -0700332 // Check to see if we have any FP precision-related pragmas.
333 std::string Relaxed("rs_fp_relaxed");
334 std::string Imprecise("rs_fp_imprecise");
Stephen Hines32c56ec2012-06-01 15:26:30 -0700335 std::string Full("rs_fp_full");
Stephen Hinese1fd8042012-03-27 11:03:46 -0700336 bool RelaxedPragmaSeen = false;
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700337 bool FullPragmaSeen = false;
Stephen Hinese1fd8042012-03-27 11:03:46 -0700338 for (size_t i = 0; i < mPragmaCount; i++) {
339 if (!Relaxed.compare(mPragmaKeyList[i])) {
Stephen Hinese1fd8042012-03-27 11:03:46 -0700340 RelaxedPragmaSeen = true;
341 } else if (!Imprecise.compare(mPragmaKeyList[i])) {
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700342 ALOGW("rs_fp_imprecise is deprecated. Assuming rs_fp_relaxed instead.");
343 RelaxedPragmaSeen = true;
344 } else if (!Full.compare(mPragmaKeyList[i])) {
345 FullPragmaSeen = true;
Stephen Hinese1fd8042012-03-27 11:03:46 -0700346 }
347 }
348
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700349 if (RelaxedPragmaSeen && FullPragmaSeen) {
350 ALOGE("Full and relaxed precision specified at the same time!");
Stephen Hinese1fd8042012-03-27 11:03:46 -0700351 }
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700352 mRSFloatPrecision = RelaxedPragmaSeen ? RS_FP_Relaxed : RS_FP_Full;
Stephen Hinese1fd8042012-03-27 11:03:46 -0700353
Elliott Hughesfe0de782015-08-12 15:09:33 -0700354#ifdef __ANDROID__
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700355 // Provide an override for precsiion via adb shell setprop
Stephen Hines32c56ec2012-06-01 15:26:30 -0700356 // adb shell setprop debug.rs.precision rs_fp_full
357 // adb shell setprop debug.rs.precision rs_fp_relaxed
358 // adb shell setprop debug.rs.precision rs_fp_imprecise
359 char PrecisionPropBuf[PROPERTY_VALUE_MAX];
360 const std::string PrecisionPropName("debug.rs.precision");
361 property_get("debug.rs.precision", PrecisionPropBuf, "");
362 if (PrecisionPropBuf[0]) {
363 if (!Relaxed.compare(PrecisionPropBuf)) {
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700364 ALOGI("Switching to RS FP relaxed mode via setprop");
Stephen Hines32c56ec2012-06-01 15:26:30 -0700365 mRSFloatPrecision = RS_FP_Relaxed;
366 } else if (!Imprecise.compare(PrecisionPropBuf)) {
Chris Wailes900c6c12014-08-13 15:40:00 -0700367 ALOGW("Switching to RS FP relaxed mode via setprop. rs_fp_imprecise was "
368 "specified but is deprecated ");
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700369 mRSFloatPrecision = RS_FP_Relaxed;
Stephen Hines32c56ec2012-06-01 15:26:30 -0700370 } else if (!Full.compare(PrecisionPropBuf)) {
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700371 ALOGI("Switching to RS FP full mode via setprop");
Stephen Hines32c56ec2012-06-01 15:26:30 -0700372 mRSFloatPrecision = RS_FP_Full;
Jean-Luc Brouillet5f2e6b92014-07-08 11:10:03 -0700373 } else {
374 ALOGE("Unrecognized debug.rs.precision %s", PrecisionPropBuf);
Stephen Hines32c56ec2012-06-01 15:26:30 -0700375 }
376 }
Nick Kralevich85d95712013-05-22 13:49:01 -0700377#endif
Stephen Hines932bc6e2011-07-27 16:26:26 -0700378}
379
Chris Wailesa6681822014-07-11 15:15:46 -0700380uint32_t MetadataExtractor::calculateNumInputs(const llvm::Function *Function,
381 uint32_t Signature) {
382
383 if (hasForEachSignatureIn(Signature)) {
384 uint32_t OtherCount = 0;
385
386 OtherCount += hasForEachSignatureUsrData(Signature);
387 OtherCount += hasForEachSignatureX(Signature);
388 OtherCount += hasForEachSignatureY(Signature);
David Gross33cda5c2015-01-30 11:41:19 -0800389 OtherCount += hasForEachSignatureZ(Signature);
390 OtherCount += hasForEachSignatureCtxt(Signature);
Chris Wailesa6681822014-07-11 15:15:46 -0700391 OtherCount += hasForEachSignatureOut(Signature) &&
392 Function->getReturnType()->isVoidTy();
393
394 return Function->arg_size() - OtherCount;
395
396 } else {
397 return 0;
398 }
399}
400
401
Stephen Hines33f8fe22011-08-17 12:56:22 -0700402bool MetadataExtractor::populateForEachMetadata(
Stephen Hinescc366e52012-02-21 17:22:04 -0800403 const llvm::NamedMDNode *Names,
404 const llvm::NamedMDNode *Signatures) {
Stephen Hines11de13e2013-06-07 11:41:18 -0700405 if (!Names && !Signatures && mCompilerVersion == 0) {
Stephen Hines0231bb02011-10-10 15:30:25 -0700406 // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
407 // section for ForEach. We generate a full signature for a "root" function
408 // which means that we need to set the bottom 5 bits in the mask.
409 mExportForEachSignatureCount = 1;
Stephen Hinescc366e52012-02-21 17:22:04 -0800410 char **TmpNameList = new char*[mExportForEachSignatureCount];
Stephen Hinesfb81ec12015-05-18 20:04:23 -0700411 size_t RootLen = strlen(kRoot) + 1;
412 TmpNameList[0] = new char[RootLen];
413 strncpy(TmpNameList[0], kRoot, RootLen);
Stephen Hinescc366e52012-02-21 17:22:04 -0800414
Stephen Hines0231bb02011-10-10 15:30:25 -0700415 uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
416 TmpSigList[0] = 0x1f;
Stephen Hines569986d2012-03-09 19:58:45 -0800417
Stephen Hinescc366e52012-02-21 17:22:04 -0800418 mExportForEachNameList = (const char**)TmpNameList;
Stephen Hines0231bb02011-10-10 15:30:25 -0700419 mExportForEachSignatureList = TmpSigList;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700420 return true;
421 }
422
Stephen Hines109be672012-06-06 16:01:59 -0700423 if (Signatures) {
424 mExportForEachSignatureCount = Signatures->getNumOperands();
425 if (!mExportForEachSignatureCount) {
426 return true;
427 }
428 } else {
429 mExportForEachSignatureCount = 0;
Chris Wailes900c6c12014-08-13 15:40:00 -0700430 mExportForEachSignatureList = nullptr;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700431 return true;
432 }
433
434 uint32_t *TmpSigList = new uint32_t[mExportForEachSignatureCount];
Stephen Hines569986d2012-03-09 19:58:45 -0800435 const char **TmpNameList = new const char*[mExportForEachSignatureCount];
Chris Wailesa6681822014-07-11 15:15:46 -0700436 uint32_t *TmpInputCountList = new uint32_t[mExportForEachSignatureCount];
Stephen Hines33f8fe22011-08-17 12:56:22 -0700437
438 for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
Stephen Hinescc366e52012-02-21 17:22:04 -0800439 llvm::MDNode *SigNode = Signatures->getOperand(i);
Chris Wailes900c6c12014-08-13 15:40:00 -0700440 if (SigNode != nullptr && SigNode->getNumOperands() == 1) {
Stephen Hinese1c7d292015-04-15 13:20:00 -0700441 if (!extractUIntFromMetadataString(&TmpSigList[i], SigNode->getOperand(0))) {
442 ALOGE("Non-integer signature value");
443 return false;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700444 }
Stephen Hinese1c7d292015-04-15 13:20:00 -0700445 } else {
446 ALOGE("Corrupt signature information");
447 return false;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700448 }
449 }
450
Stephen Hines109be672012-06-06 16:01:59 -0700451 if (Names) {
452 for (size_t i = 0; i < mExportForEachSignatureCount; i++) {
453 llvm::MDNode *Name = Names->getOperand(i);
Chris Wailes900c6c12014-08-13 15:40:00 -0700454 if (Name != nullptr && Name->getNumOperands() == 1) {
Stephen Hines109be672012-06-06 16:01:59 -0700455 TmpNameList[i] = createStringFromValue(Name->getOperand(0));
Chris Wailesa6681822014-07-11 15:15:46 -0700456
David Gross8d7fe842016-02-18 14:00:32 -0800457 // Note that looking up the function by name can fail: One of
458 // the uses of MetadataExtractor is as part of the
459 // RSEmbedInfoPass, which bcc_compat runs sufficiently late in
460 // the phase order that RSKernelExpandPass has already run and
461 // the original (UNexpanded) kernel function (TmpNameList[i])
462 // may have been deleted as having no references (if it has
463 // been inlined into the expanded kernel function and is
464 // otherwise unreferenced).
Chris Wailes900c6c12014-08-13 15:40:00 -0700465 llvm::Function *Func =
466 mModule->getFunction(llvm::StringRef(TmpNameList[i]));
Chris Wailesa6681822014-07-11 15:15:46 -0700467
Chris Wailes900c6c12014-08-13 15:40:00 -0700468 TmpInputCountList[i] = (Func != nullptr) ?
Chris Wailesa6681822014-07-11 15:15:46 -0700469 calculateNumInputs(Func, TmpSigList[i]) : 0;
Stephen Hines109be672012-06-06 16:01:59 -0700470 }
Stephen Hinescc366e52012-02-21 17:22:04 -0800471 }
Stephen Hines109be672012-06-06 16:01:59 -0700472 } else {
473 if (mExportForEachSignatureCount != 1) {
Stephen Hines3e4cac42012-06-07 01:57:15 -0700474 ALOGE("mExportForEachSignatureCount = %zu, but should be 1",
Stephen Hines109be672012-06-06 16:01:59 -0700475 mExportForEachSignatureCount);
476 }
477 char *RootName = new char[5];
478 strncpy(RootName, "root", 5);
479 TmpNameList[0] = RootName;
Stephen Hinescc366e52012-02-21 17:22:04 -0800480 }
481
Stephen Hines569986d2012-03-09 19:58:45 -0800482 mExportForEachNameList = TmpNameList;
483 mExportForEachSignatureList = TmpSigList;
Chris Wailesa6681822014-07-11 15:15:46 -0700484 mExportForEachInputCountList = TmpInputCountList;
Stephen Hines569986d2012-03-09 19:58:45 -0800485
Stephen Hines33f8fe22011-08-17 12:56:22 -0700486 return true;
487}
488
489
David Grossa48ea362016-06-02 14:46:55 -0700490bool MetadataExtractor::populateReduceMetadata(const llvm::NamedMDNode *ReduceMetadata) {
491 mExportReduceCount = 0;
492 mExportReduceList = nullptr;
David Gross79e1a052016-01-11 14:42:51 -0800493
David Grossa48ea362016-06-02 14:46:55 -0700494 if (!ReduceMetadata || !(mExportReduceCount = ReduceMetadata->getNumOperands()))
David Gross79e1a052016-01-11 14:42:51 -0800495 return true;
496
David Grossa48ea362016-06-02 14:46:55 -0700497 Reduce *TmpReduceList = new Reduce[mExportReduceCount];
David Gross79e1a052016-01-11 14:42:51 -0800498
David Grossa48ea362016-06-02 14:46:55 -0700499 for (size_t i = 0; i < mExportReduceCount; i++) {
500 llvm::MDNode *Node = ReduceMetadata->getOperand(i);
David Gross79e1a052016-01-11 14:42:51 -0800501 if (!Node || Node->getNumOperands() < 3) {
502 ALOGE("Missing reduce metadata");
503 return false;
504 }
505
David Grossa48ea362016-06-02 14:46:55 -0700506 TmpReduceList[i].mReduceName = createStringFromValue(Node->getOperand(0));
David Gross79e1a052016-01-11 14:42:51 -0800507
David Grossa48ea362016-06-02 14:46:55 -0700508 if (!extractUIntFromMetadataString(&TmpReduceList[i].mAccumulatorDataSize,
David Gross79e1a052016-01-11 14:42:51 -0800509 Node->getOperand(1))) {
510 ALOGE("Non-integer accumulator data size value in reduce metadata");
511 return false;
512 }
513
514 llvm::MDNode *AccumulatorNode = llvm::dyn_cast<llvm::MDNode>(Node->getOperand(2));
515 if (!AccumulatorNode || AccumulatorNode->getNumOperands() != 2) {
516 ALOGE("Malformed accumulator node in reduce metadata");
517 return false;
518 }
David Grossa48ea362016-06-02 14:46:55 -0700519 TmpReduceList[i].mAccumulatorName = createStringFromValue(AccumulatorNode->getOperand(0));
520 if (!extractUIntFromMetadataString(&TmpReduceList[i].mSignature,
David Gross79e1a052016-01-11 14:42:51 -0800521 AccumulatorNode->getOperand(1))) {
522 ALOGE("Non-integer signature value in reduce metadata");
523 return false;
524 }
David Gross8d7fe842016-02-18 14:00:32 -0800525 // Note that looking up the function by name can fail: One of the
526 // uses of MetadataExtractor is as part of the RSEmbedInfoPass,
527 // which bcc_compat runs sufficiently late in the phase order that
528 // RSKernelExpandPass has already run and the original
529 // (UNexpanded) accumulator function (mAccumulatorName) may have
530 // been deleted as having no references (if it has been inlined
531 // into the expanded accumulator function and is otherwise
532 // unreferenced).
David Gross79e1a052016-01-11 14:42:51 -0800533 llvm::Function *Func =
David Grossa48ea362016-06-02 14:46:55 -0700534 mModule->getFunction(llvm::StringRef(TmpReduceList[i].mAccumulatorName));
David Gross79e1a052016-01-11 14:42:51 -0800535 // Why calculateNumInputs() - 1? The "-1" is because we don't
536 // want to treat the accumulator argument as an input.
David Grossa48ea362016-06-02 14:46:55 -0700537 TmpReduceList[i].mInputCount = (Func ? calculateNumInputs(Func, TmpReduceList[i].mSignature) - 1 : 0);
David Gross79e1a052016-01-11 14:42:51 -0800538
David Grossa48ea362016-06-02 14:46:55 -0700539 TmpReduceList[i].mInitializerName = createStringFromOptionalValue(Node, 3);
540 TmpReduceList[i].mCombinerName = createStringFromOptionalValue(Node, 4);
541 TmpReduceList[i].mOutConverterName = createStringFromOptionalValue(Node, 5);
542 TmpReduceList[i].mHalterName = createStringFromOptionalValue(Node, 6);
David Gross79e1a052016-01-11 14:42:51 -0800543 }
544
David Grossa48ea362016-06-02 14:46:55 -0700545 mExportReduceList = TmpReduceList;
David Gross79e1a052016-01-11 14:42:51 -0800546 return true;
547}
548
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800549void MetadataExtractor::readThreadableFlag(
550 const llvm::NamedMDNode *ThreadableMetadata) {
551
552 // Scripts are threadable by default. If we read a valid metadata value for
553 // 'ThreadableMetadataName' and it is set to 'no', we mark script as non
554 // threadable. All other exception paths retain the default value.
555
556 mIsThreadable = true;
557 if (ThreadableMetadata == nullptr)
558 return;
559
560 llvm::MDNode *mdNode = ThreadableMetadata->getOperand(0);
561 if (mdNode == nullptr)
562 return;
563
Stephen Hines1bd9f622015-03-18 14:53:10 -0700564 llvm::Metadata *mdValue = mdNode->getOperand(0);
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800565 if (mdValue == nullptr)
566 return;
567
Stephen Hinese1c7d292015-04-15 13:20:00 -0700568 if (getStringOperand(mdValue) == "no")
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800569 mIsThreadable = false;
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800570}
571
Pirama Arumuga Nainar51ee77b2015-02-19 16:33:27 -0800572void MetadataExtractor::readBuildChecksumMetadata(
573 const llvm::NamedMDNode *ChecksumMetadata) {
574
575 if (ChecksumMetadata == nullptr)
576 return;
577
Stephen Hines1bd9f622015-03-18 14:53:10 -0700578 llvm::MDNode *mdNode = ChecksumMetadata->getOperand(0);
Pirama Arumuga Nainar51ee77b2015-02-19 16:33:27 -0800579 if (mdNode == nullptr)
580 return;
581
Stephen Hines1bd9f622015-03-18 14:53:10 -0700582 llvm::Metadata *mdValue = mdNode->getOperand(0);
Pirama Arumuga Nainar51ee77b2015-02-19 16:33:27 -0800583 if (mdValue == nullptr)
584 return;
585
586 mBuildChecksum = createStringFromValue(mdValue);
587}
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800588
Stephen Hines932bc6e2011-07-27 16:26:26 -0700589bool MetadataExtractor::extract() {
Stephen Hines569986d2012-03-09 19:58:45 -0800590 if (!(mBitcode && mBitcodeSize) && !mModule) {
591 ALOGE("Invalid/empty bitcode/module");
Stephen Hines932bc6e2011-07-27 16:26:26 -0700592 return false;
593 }
594
Stephen Hinesd0993af2014-07-15 16:49:25 -0700595 std::unique_ptr<llvm::LLVMContext> mContext;
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800596 bool shouldNullModule = false;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700597
Stephen Hines569986d2012-03-09 19:58:45 -0800598 if (!mModule) {
599 mContext.reset(new llvm::LLVMContext());
Stephen Hinesd0993af2014-07-15 16:49:25 -0700600 std::unique_ptr<llvm::MemoryBuffer> MEM(
Stephen Hines569986d2012-03-09 19:58:45 -0800601 llvm::MemoryBuffer::getMemBuffer(
Stephen Hinese708ffe2012-05-03 15:18:49 -0700602 llvm::StringRef(mBitcode, mBitcodeSize), "", false));
Stephen Hines569986d2012-03-09 19:58:45 -0800603 std::string error;
604
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800605 llvm::ErrorOr<std::unique_ptr<llvm::Module> > errval =
606 llvm::parseBitcodeFile(MEM.get()->getMemBufferRef(), *mContext);
Stephen Hinesd0993af2014-07-15 16:49:25 -0700607 if (std::error_code ec = errval.getError()) {
Tim Murrayc2074ca2014-04-08 15:39:08 -0700608 ALOGE("Could not parse bitcode file");
609 ALOGE("%s", ec.message().c_str());
610 return false;
Stephen Hines569986d2012-03-09 19:58:45 -0800611 }
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800612
613 mModule = errval.get().release();
614 shouldNullModule = true;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700615 }
616
617 const llvm::NamedMDNode *ExportVarMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800618 mModule->getNamedMetadata(ExportVarMetadataName);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700619 const llvm::NamedMDNode *ExportFuncMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800620 mModule->getNamedMetadata(ExportFuncMetadataName);
Stephen Hinescc366e52012-02-21 17:22:04 -0800621 const llvm::NamedMDNode *ExportForEachNameMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800622 mModule->getNamedMetadata(ExportForEachNameMetadataName);
Stephen Hines33f8fe22011-08-17 12:56:22 -0700623 const llvm::NamedMDNode *ExportForEachMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800624 mModule->getNamedMetadata(ExportForEachMetadataName);
David Grossa48ea362016-06-02 14:46:55 -0700625 const llvm::NamedMDNode *ExportReduceMetadata =
626 mModule->getNamedMetadata(ExportReduceMetadataName);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700627 const llvm::NamedMDNode *PragmaMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800628 mModule->getNamedMetadata(PragmaMetadataName);
Stephen Hines932bc6e2011-07-27 16:26:26 -0700629 const llvm::NamedMDNode *ObjectSlotMetadata =
Stephen Hines569986d2012-03-09 19:58:45 -0800630 mModule->getNamedMetadata(ObjectSlotMetadataName);
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800631 const llvm::NamedMDNode *ThreadableMetadata =
632 mModule->getNamedMetadata(ThreadableMetadataName);
Pirama Arumuga Nainar51ee77b2015-02-19 16:33:27 -0800633 const llvm::NamedMDNode *ChecksumMetadata =
634 mModule->getNamedMetadata(ChecksumMetadataName);
Dean De Leofff398d2015-11-25 13:00:31 +0000635 const llvm::NamedMDNode *DebugInfoMetadata =
636 mModule->getNamedMetadata(DebugInfoMetadataName);
Daniel Malea094881f2011-12-14 17:39:16 -0500637
Matt Wala1895ac12015-07-16 15:34:29 -0700638 if (!populateNameMetadata(ExportVarMetadata, mExportVarNameList,
639 mExportVarCount)) {
Stephen Hines569986d2012-03-09 19:58:45 -0800640 ALOGE("Could not populate export variable metadata");
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800641 goto err;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700642 }
643
Matt Wala1895ac12015-07-16 15:34:29 -0700644 if (!populateNameMetadata(ExportFuncMetadata, mExportFuncNameList,
645 mExportFuncCount)) {
Stephen Hines569986d2012-03-09 19:58:45 -0800646 ALOGE("Could not populate export function metadata");
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800647 goto err;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700648 }
649
Stephen Hinescc366e52012-02-21 17:22:04 -0800650 if (!populateForEachMetadata(ExportForEachNameMetadata,
651 ExportForEachMetadata)) {
Steve Block10c14122012-01-08 10:15:06 +0000652 ALOGE("Could not populate ForEach signature metadata");
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800653 goto err;
Stephen Hines33f8fe22011-08-17 12:56:22 -0700654 }
655
David Grossa48ea362016-06-02 14:46:55 -0700656 if (!populateReduceMetadata(ExportReduceMetadata)) {
David Gross79e1a052016-01-11 14:42:51 -0800657 ALOGE("Could not populate export general reduction metadata");
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800658 goto err;
David Gross79e1a052016-01-11 14:42:51 -0800659 }
660
Stephen Hines932bc6e2011-07-27 16:26:26 -0700661 populatePragmaMetadata(PragmaMetadata);
662
663 if (!populateObjectSlotMetadata(ObjectSlotMetadata)) {
Steve Block10c14122012-01-08 10:15:06 +0000664 ALOGE("Could not populate object slot metadata");
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800665 goto err;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700666 }
667
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800668 readThreadableFlag(ThreadableMetadata);
Pirama Arumuga Nainar51ee77b2015-02-19 16:33:27 -0800669 readBuildChecksumMetadata(ChecksumMetadata);
Pirama Arumuga Nainar9fe081b2015-01-27 14:09:19 -0800670
Dean De Leofff398d2015-11-25 13:00:31 +0000671 mHasDebugInfo = DebugInfoMetadata != nullptr;
672
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800673 if (shouldNullModule) {
674 mModule = nullptr;
675 }
Stephen Hines932bc6e2011-07-27 16:26:26 -0700676 return true;
Pirama Arumuga Nainar8e908932016-03-06 23:05:45 -0800677
678err:
679 if (shouldNullModule) {
680 mModule = nullptr;
681 }
682 return false;
Stephen Hines932bc6e2011-07-27 16:26:26 -0700683}
684
685} // namespace bcinfo