blob: 4d1998ec916f1bb6df1bb01f9f275a9f09bd000f [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Stephen Hines7b51b552012-02-16 00:12:38 -08002 * Copyright 2010-2012, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
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
zonr6315f762010-10-05 15:35:14 +080017#include "slang_rs_backend.h"
18
zonr6315f762010-10-05 15:35:14 +080019#include <string>
Stephen Hinese639eb52010-11-08 19:27:20 -080020#include <vector>
zonr6315f762010-10-05 15:35:14 +080021
Shih-wei Liao43730fe2012-08-02 23:06:18 -070022#include "clang/AST/ASTContext.h"
mkopec1c460b372012-01-09 11:21:50 -050023#include "clang/Frontend/CodeGenOptions.h"
24
zonr6315f762010-10-05 15:35:14 +080025#include "llvm/ADT/Twine.h"
26#include "llvm/ADT/StringExtras.h"
27
Stephen Hines23c43582013-01-09 20:02:04 -080028#include "llvm/IR/Constant.h"
29#include "llvm/IR/Constants.h"
30#include "llvm/IR/DerivedTypes.h"
31#include "llvm/IR/Function.h"
32#include "llvm/IR/IRBuilder.h"
33#include "llvm/IR/Metadata.h"
34#include "llvm/IR/Module.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080035
Tim Murrayee4016d2014-04-10 15:49:08 -070036#include "llvm/IR/DebugLoc.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080037
Stephen Hines6e6578a2011-02-07 18:05:48 -080038#include "slang_assert.h"
Zonr Chang592a9542010-10-07 20:03:58 +080039#include "slang_rs.h"
zonr6315f762010-10-05 15:35:14 +080040#include "slang_rs_context.h"
Stephen Hines4ccf75e2011-08-16 18:21:01 -070041#include "slang_rs_export_foreach.h"
zonr6315f762010-10-05 15:35:14 +080042#include "slang_rs_export_func.h"
43#include "slang_rs_export_type.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080044#include "slang_rs_export_var.h"
45#include "slang_rs_metadata.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070046
Stephen Hinese639eb52010-11-08 19:27:20 -080047namespace slang {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070048
49RSBackend::RSBackend(RSContext *Context,
Logan Chien9207a2e2011-10-21 15:39:28 +080050 clang::DiagnosticsEngine *DiagEngine,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070051 const clang::CodeGenOptions &CodeGenOpts,
52 const clang::TargetOptions &TargetOpts,
Stephen Hines3fd0a942011-01-18 12:27:39 -080053 PragmaList *Pragmas,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070054 llvm::raw_ostream *OS,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080055 Slang::OutputType OT,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070056 clang::SourceManager &SourceMgr,
Stephen Hines11274a72012-09-26 19:14:20 -070057 bool AllowRSPrefix,
58 bool IsFilterscript)
Logan Chien9207a2e2011-10-21 15:39:28 +080059 : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
60 mContext(Context),
61 mSourceMgr(SourceMgr),
62 mAllowRSPrefix(AllowRSPrefix),
Stephen Hines11274a72012-09-26 19:14:20 -070063 mIsFilterscript(IsFilterscript),
Chris Wailes5abbe0e2014-08-12 15:58:29 -070064 mExportVarMetadata(nullptr),
65 mExportFuncMetadata(nullptr),
66 mExportForEachNameMetadata(nullptr),
67 mExportForEachSignatureMetadata(nullptr),
68 mExportTypeMetadata(nullptr),
69 mRSObjectSlotsMetadata(nullptr),
Stephen Hines11274a72012-09-26 19:14:20 -070070 mRefCount(mContext->getASTContext()),
Stephen Hines48d893d2013-12-06 18:00:27 -080071 mASTChecker(Context, Context->getTargetAPI(), IsFilterscript) {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070072}
73
Stephen Hinescfae0f32010-11-01 18:57:31 -070074// 1) Add zero initialization of local RS object types
75void RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
76 if (FD &&
77 FD->hasBody() &&
Stephen Hines11274a72012-09-26 19:14:20 -070078 !SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070079 mRefCount.Init();
Stephen Hines4b32ffd2010-11-05 18:47:11 -070080 mRefCount.Visit(FD->getBody());
Stephen Hinescfae0f32010-11-01 18:57:31 -070081 }
Stephen Hinescfae0f32010-11-01 18:57:31 -070082}
83
Logan Chienfa6ef562011-11-25 13:50:02 +080084bool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
Stephen Hinescfae0f32010-11-01 18:57:31 -070085 // Disallow user-defined functions with prefix "rs"
86 if (!mAllowRSPrefix) {
87 // Iterate all function declarations in the program.
88 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
89 I != E; I++) {
Logan Chienab992e52011-07-20 22:06:52 +080090 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Chris Wailes5abbe0e2014-08-12 15:58:29 -070091 if (FD == nullptr)
Stephen Hinescfae0f32010-11-01 18:57:31 -070092 continue;
93 if (!FD->getName().startswith("rs")) // Check prefix
94 continue;
Stephen Hines11274a72012-09-26 19:14:20 -070095 if (!SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
Jean-Luc Brouilletd3f75272014-01-16 18:20:28 -080096 mContext->ReportError(FD->getLocation(),
97 "invalid function name prefix, "
98 "\"rs\" is reserved: '%0'")
99 << FD->getName();
Stephen Hinescfae0f32010-11-01 18:57:31 -0700100 }
101 }
102
103 // Process any non-static function declarations
104 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
Logan Chienab992e52011-07-20 22:06:52 +0800105 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hineseb2eec92011-01-09 19:13:09 -0800106 if (FD && FD->isGlobal()) {
Stephen Hinesab5a5352012-08-04 15:13:40 -0700107 // Check that we don't have any array parameters being misintrepeted as
108 // kernel pointers due to the C type system's array to pointer decay.
109 size_t numParams = FD->getNumParams();
110 for (size_t i = 0; i < numParams; i++) {
111 const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
112 clang::QualType QT = PVD->getOriginalType();
113 if (QT->isArrayType()) {
Jean-Luc Brouilletd3f75272014-01-16 18:20:28 -0800114 mContext->ReportError(
115 PVD->getTypeSpecStartLoc(),
116 "exported function parameters may not have array type: %0")
117 << QT;
Stephen Hinesab5a5352012-08-04 15:13:40 -0700118 }
119 }
Stephen Hineseb2eec92011-01-09 19:13:09 -0800120 AnnotateFunction(FD);
121 }
Stephen Hinescfae0f32010-11-01 18:57:31 -0700122 }
123
Logan Chienfa6ef562011-11-25 13:50:02 +0800124 return Backend::HandleTopLevelDecl(D);
Stephen Hinescfae0f32010-11-01 18:57:31 -0700125}
126
Stephen Hinesc97a3332010-11-30 15:31:08 -0800127
128void RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
129 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
130
Stephen Hines11274a72012-09-26 19:14:20 -0700131 // If we have an invalid RS/FS AST, don't check further.
132 if (!mASTChecker.Validate()) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800133 return;
134 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700135
Stephen Hines11274a72012-09-26 19:14:20 -0700136 if (mIsFilterscript) {
137 mContext->addPragma("rs_fp_relaxed", "");
138 }
139
Stephen Hines96ab06c2011-01-05 15:29:26 -0800140 int version = mContext->getVersion();
141 if (version == 0) {
142 // Not setting a version is an error
Stephen Hines7aff4a02011-12-08 18:34:27 -0800143 mDiagEngine.Report(
144 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
145 mDiagEngine.getCustomDiagID(
146 clang::DiagnosticsEngine::Error,
147 "missing pragma for version in source file"));
148 } else {
149 slangAssert(version == 1);
Stephen Hines96ab06c2011-01-05 15:29:26 -0800150 }
151
Stephen Hinescf9a73a2012-09-20 10:38:02 -0700152 if (mContext->getReflectJavaPackageName().empty()) {
153 mDiagEngine.Report(
154 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
155 mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
156 "missing \"#pragma rs "
157 "java_package_name(com.foo.bar)\" "
158 "in source file"));
159 return;
160 }
161
Stephen Hines688e64b2011-08-23 16:01:25 -0700162 // Create a static global destructor if necessary (to handle RS object
163 // runtime cleanup).
164 clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
165 if (FD) {
166 HandleTopLevelDecl(clang::DeclGroupRef(FD));
167 }
168
Stephen Hinescfae0f32010-11-01 18:57:31 -0700169 // Process any static function declarations
Stephen Hinesfcda2352010-10-19 16:49:32 -0700170 for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
171 E = TUDecl->decls_end(); I != E; I++) {
172 if ((I->getKind() >= clang::Decl::firstFunction) &&
173 (I->getKind() <= clang::Decl::lastFunction)) {
Logan Chienab992e52011-07-20 22:06:52 +0800174 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hineseb2eec92011-01-09 19:13:09 -0800175 if (FD && !FD->isGlobal()) {
176 AnnotateFunction(FD);
177 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700178 }
179 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700180}
181
182///////////////////////////////////////////////////////////////////////////////
Tobias Grosserd460f622013-07-23 10:37:23 -0700183void RSBackend::dumpExportVarInfo(llvm::Module *M) {
184 int slotCount = 0;
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700185 if (mExportVarMetadata == nullptr)
Tobias Grosserd460f622013-07-23 10:37:23 -0700186 mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
187
188 llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
189
190 // We emit slot information (#rs_object_slots) for any reference counted
191 // RS type or pointer (which can also be bound).
192
193 for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
194 E = mContext->export_vars_end();
195 I != E;
196 I++) {
197 const RSExportVar *EV = *I;
198 const RSExportType *ET = EV->getType();
199 bool countsAsRSObject = false;
200
201 // Variable name
202 ExportVarInfo.push_back(
203 llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
204
205 // Type name
206 switch (ET->getClass()) {
207 case RSExportType::ExportClassPrimitive: {
208 const RSExportPrimitiveType *PT =
209 static_cast<const RSExportPrimitiveType*>(ET);
210 ExportVarInfo.push_back(
211 llvm::MDString::get(
212 mLLVMContext, llvm::utostr_32(PT->getType())));
213 if (PT->isRSObjectType()) {
214 countsAsRSObject = true;
215 }
216 break;
217 }
218 case RSExportType::ExportClassPointer: {
219 ExportVarInfo.push_back(
220 llvm::MDString::get(
221 mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
222 ->getPointeeType()->getName()).c_str()));
223 break;
224 }
225 case RSExportType::ExportClassMatrix: {
226 ExportVarInfo.push_back(
227 llvm::MDString::get(
228 mLLVMContext, llvm::utostr_32(
Jean-Luc Brouilleteca05342014-05-15 12:44:21 -0700229 /* TODO Strange value. This pushes just a number, quite
230 * different than the other cases. What is this used for?
231 * These are the metadata values that some partner drivers
232 * want to reference (for TBAA, etc.). We may want to look
233 * at whether these provide any reasonable value (or have
234 * distinct enough values to actually depend on).
235 */
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700236 DataTypeRSMatrix2x2 +
Tobias Grosserd460f622013-07-23 10:37:23 -0700237 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
238 break;
239 }
240 case RSExportType::ExportClassVector:
241 case RSExportType::ExportClassConstantArray:
242 case RSExportType::ExportClassRecord: {
243 ExportVarInfo.push_back(
244 llvm::MDString::get(mLLVMContext,
245 EV->getType()->getName().c_str()));
246 break;
247 }
248 }
249
250 mExportVarMetadata->addOperand(
251 llvm::MDNode::get(mLLVMContext, ExportVarInfo));
252 ExportVarInfo.clear();
253
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700254 if (mRSObjectSlotsMetadata == nullptr) {
Tobias Grosserd460f622013-07-23 10:37:23 -0700255 mRSObjectSlotsMetadata =
256 M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
257 }
258
259 if (countsAsRSObject) {
260 mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
261 llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
262 }
263
264 slotCount++;
265 }
266}
267
268void RSBackend::dumpExportFunctionInfo(llvm::Module *M) {
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700269 if (mExportFuncMetadata == nullptr)
Tobias Grosserd460f622013-07-23 10:37:23 -0700270 mExportFuncMetadata =
271 M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
272
273 llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
274
275 for (RSContext::const_export_func_iterator
276 I = mContext->export_funcs_begin(),
277 E = mContext->export_funcs_end();
278 I != E;
279 I++) {
280 const RSExportFunc *EF = *I;
281
282 // Function name
283 if (!EF->hasParam()) {
284 ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
285 EF->getName().c_str()));
286 } else {
287 llvm::Function *F = M->getFunction(EF->getName());
288 llvm::Function *HelperFunction;
289 const std::string HelperFunctionName(".helper_" + EF->getName());
290
291 slangAssert(F && "Function marked as exported disappeared in Bitcode");
292
293 // Create helper function
294 {
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700295 llvm::StructType *HelperFunctionParameterTy = nullptr;
Tim Murraya6bce2d2014-08-05 13:27:12 -0700296 std::vector<bool> isStructInput;
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700297
Tobias Grosserd460f622013-07-23 10:37:23 -0700298 if (!F->getArgumentList().empty()) {
299 std::vector<llvm::Type*> HelperFunctionParameterTys;
300 for (llvm::Function::arg_iterator AI = F->arg_begin(),
Tim Murraya6bce2d2014-08-05 13:27:12 -0700301 AE = F->arg_end(); AI != AE; AI++) {
302 if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
303 HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
304 isStructInput.push_back(true);
305 } else {
306 HelperFunctionParameterTys.push_back(AI->getType());
307 isStructInput.push_back(false);
308 }
309 }
Tobias Grosserd460f622013-07-23 10:37:23 -0700310 HelperFunctionParameterTy =
311 llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
312 }
313
314 if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
315 fprintf(stderr, "Failed to export function %s: parameter type "
316 "mismatch during creation of helper function.\n",
317 EF->getName().c_str());
318
319 const RSExportRecordType *Expected = EF->getParamPacketType();
320 if (Expected) {
321 fprintf(stderr, "Expected:\n");
322 Expected->getLLVMType()->dump();
323 }
324 if (HelperFunctionParameterTy) {
325 fprintf(stderr, "Got:\n");
326 HelperFunctionParameterTy->dump();
327 }
328 }
329
330 std::vector<llvm::Type*> Params;
331 if (HelperFunctionParameterTy) {
332 llvm::PointerType *HelperFunctionParameterTyP =
333 llvm::PointerType::getUnqual(HelperFunctionParameterTy);
334 Params.push_back(HelperFunctionParameterTyP);
335 }
336
337 llvm::FunctionType * HelperFunctionType =
338 llvm::FunctionType::get(F->getReturnType(),
339 Params,
340 /* IsVarArgs = */false);
341
342 HelperFunction =
343 llvm::Function::Create(HelperFunctionType,
344 llvm::GlobalValue::ExternalLinkage,
345 HelperFunctionName,
346 M);
347
348 HelperFunction->addFnAttr(llvm::Attribute::NoInline);
349 HelperFunction->setCallingConv(F->getCallingConv());
350
351 // Create helper function body
352 {
353 llvm::Argument *HelperFunctionParameter =
354 &(*HelperFunction->arg_begin());
355 llvm::BasicBlock *BB =
356 llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
357 llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
358 llvm::SmallVector<llvm::Value*, 6> Params;
359 llvm::Value *Idx[2];
360
361 Idx[0] =
362 llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
363
364 // getelementptr and load instruction for all elements in
365 // parameter .p
366 for (size_t i = 0; i < EF->getNumParameters(); i++) {
367 // getelementptr
368 Idx[1] = llvm::ConstantInt::get(
369 llvm::Type::getInt32Ty(mLLVMContext), i);
370
Tim Murraya6bce2d2014-08-05 13:27:12 -0700371 llvm::Value *Ptr = NULL;
Tobias Grosserd460f622013-07-23 10:37:23 -0700372
Tim Murraya6bce2d2014-08-05 13:27:12 -0700373 Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
374
375 // Load is only required for non-struct ptrs
376 if (isStructInput[i]) {
377 Params.push_back(Ptr);
378 } else {
379 llvm::Value *V = IB->CreateLoad(Ptr);
380 Params.push_back(V);
381 }
Tobias Grosserd460f622013-07-23 10:37:23 -0700382 }
383
384 // Call and pass the all elements as parameter to F
385 llvm::CallInst *CI = IB->CreateCall(F, Params);
386
387 CI->setCallingConv(F->getCallingConv());
388
389 if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
390 IB->CreateRetVoid();
391 else
392 IB->CreateRet(CI);
393
394 delete IB;
395 }
396 }
397
398 ExportFuncInfo.push_back(
399 llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
400 }
401
402 mExportFuncMetadata->addOperand(
403 llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
404 ExportFuncInfo.clear();
405 }
406}
407
408void RSBackend::dumpExportForEachInfo(llvm::Module *M) {
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700409 if (mExportForEachNameMetadata == nullptr) {
Tobias Grosserd460f622013-07-23 10:37:23 -0700410 mExportForEachNameMetadata =
411 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
412 }
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700413 if (mExportForEachSignatureMetadata == nullptr) {
Tobias Grosserd460f622013-07-23 10:37:23 -0700414 mExportForEachSignatureMetadata =
415 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
416 }
417
418 llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
419 llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
420
421 for (RSContext::const_export_foreach_iterator
422 I = mContext->export_foreach_begin(),
423 E = mContext->export_foreach_end();
424 I != E;
425 I++) {
426 const RSExportForEach *EFE = *I;
427
428 ExportForEachName.push_back(
429 llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
430
431 mExportForEachNameMetadata->addOperand(
432 llvm::MDNode::get(mLLVMContext, ExportForEachName));
433 ExportForEachName.clear();
434
435 ExportForEachInfo.push_back(
436 llvm::MDString::get(mLLVMContext,
437 llvm::utostr_32(EFE->getSignatureMetadata())));
438
439 mExportForEachSignatureMetadata->addOperand(
440 llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
441 ExportForEachInfo.clear();
442 }
443}
444
445void RSBackend::dumpExportTypeInfo(llvm::Module *M) {
446 llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
447
448 for (RSContext::const_export_type_iterator
449 I = mContext->export_types_begin(),
450 E = mContext->export_types_end();
451 I != E;
452 I++) {
453 // First, dump type name list to export
454 const RSExportType *ET = I->getValue();
455
456 ExportTypeInfo.clear();
457 // Type name
458 ExportTypeInfo.push_back(
459 llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
460
461 if (ET->getClass() == RSExportType::ExportClassRecord) {
462 const RSExportRecordType *ERT =
463 static_cast<const RSExportRecordType*>(ET);
464
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700465 if (mExportTypeMetadata == nullptr)
Tobias Grosserd460f622013-07-23 10:37:23 -0700466 mExportTypeMetadata =
467 M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
468
469 mExportTypeMetadata->addOperand(
470 llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
471
472 // Now, export struct field information to %[struct name]
473 std::string StructInfoMetadataName("%");
474 StructInfoMetadataName.append(ET->getName());
475 llvm::NamedMDNode *StructInfoMetadata =
476 M->getOrInsertNamedMetadata(StructInfoMetadataName);
477 llvm::SmallVector<llvm::Value*, 3> FieldInfo;
478
479 slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
480 "Metadata with same name was created before");
481 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
482 FE = ERT->fields_end();
483 FI != FE;
484 FI++) {
485 const RSExportRecordType::Field *F = *FI;
486
487 // 1. field name
488 FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
489 F->getName().c_str()));
490
491 // 2. field type name
492 FieldInfo.push_back(
493 llvm::MDString::get(mLLVMContext,
494 F->getType()->getName().c_str()));
495
496 StructInfoMetadata->addOperand(
497 llvm::MDNode::get(mLLVMContext, FieldInfo));
498 FieldInfo.clear();
499 }
500 } // ET->getClass() == RSExportType::ExportClassRecord
501 }
502}
503
Zonr Chang68fc02c2010-10-13 19:09:19 +0800504void RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
Tim Murray28340a22015-01-20 19:38:15 -0800505
506 if (!mContext->is64Bit()) {
507 M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
508 }
509
Stephen Hinesc808a992010-11-29 17:20:42 -0800510 if (!mContext->processExport()) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800511 return;
Stephen Hinesc808a992010-11-29 17:20:42 -0800512 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700513
Tim Murray28340a22015-01-20 19:38:15 -0800514
515
Tobias Grosserd460f622013-07-23 10:37:23 -0700516 if (mContext->hasExportVar())
517 dumpExportVarInfo(M);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700518
Tobias Grosserd460f622013-07-23 10:37:23 -0700519 if (mContext->hasExportFunc())
520 dumpExportFunctionInfo(M);
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800521
Tobias Grosserd460f622013-07-23 10:37:23 -0700522 if (mContext->hasExportForEach())
523 dumpExportForEachInfo(M);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700524
Tobias Grosserd460f622013-07-23 10:37:23 -0700525 if (mContext->hasExportType())
526 dumpExportTypeInfo(M);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700527}
528
529RSBackend::~RSBackend() {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700530}
Stephen Hinese639eb52010-11-08 19:27:20 -0800531
532} // namespace slang