blob: 6162e644d466d0e7beee3027479ffb21cd946a63 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
2 * Copyright 2010, 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
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
22#include "llvm/ADT/Twine.h"
23#include "llvm/ADT/StringExtras.h"
24
Stephen Hinese639eb52010-11-08 19:27:20 -080025#include "llvm/Constant.h"
26#include "llvm/Constants.h"
27#include "llvm/DerivedTypes.h"
28#include "llvm/Function.h"
29#include "llvm/Metadata.h"
30#include "llvm/Module.h"
31
32#include "llvm/Support/IRBuilder.h"
33
Stephen Hines6e6578a2011-02-07 18:05:48 -080034#include "slang_assert.h"
Zonr Chang592a9542010-10-07 20:03:58 +080035#include "slang_rs.h"
zonr6315f762010-10-05 15:35:14 +080036#include "slang_rs_context.h"
zonr6315f762010-10-05 15:35:14 +080037#include "slang_rs_export_func.h"
38#include "slang_rs_export_type.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080039#include "slang_rs_export_var.h"
40#include "slang_rs_metadata.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070041
Stephen Hinese639eb52010-11-08 19:27:20 -080042namespace slang {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070043
44RSBackend::RSBackend(RSContext *Context,
Stephen Hinese639eb52010-11-08 19:27:20 -080045 clang::Diagnostic *Diags,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070046 const clang::CodeGenOptions &CodeGenOpts,
47 const clang::TargetOptions &TargetOpts,
Stephen Hines3fd0a942011-01-18 12:27:39 -080048 PragmaList *Pragmas,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070049 llvm::raw_ostream *OS,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080050 Slang::OutputType OT,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070051 clang::SourceManager &SourceMgr,
zonr6315f762010-10-05 15:35:14 +080052 bool AllowRSPrefix)
53 : Backend(Diags,
54 CodeGenOpts,
55 TargetOpts,
56 Pragmas,
57 OS,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080058 OT),
zonr6315f762010-10-05 15:35:14 +080059 mContext(Context),
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080060 mSourceMgr(SourceMgr),
61 mAllowRSPrefix(AllowRSPrefix),
zonr6315f762010-10-05 15:35:14 +080062 mExportVarMetadata(NULL),
63 mExportFuncMetadata(NULL),
Stephen Hinesb3a12fe2011-01-26 20:16:38 -080064 mExportTypeMetadata(NULL),
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070065 mRSObjectSlotsMetadata(NULL),
66 mRefCount(mContext->getASTContext()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070067 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070068}
69
Stephen Hinescfae0f32010-11-01 18:57:31 -070070// 1) Add zero initialization of local RS object types
71void RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
72 if (FD &&
73 FD->hasBody() &&
74 !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070075 mRefCount.Init();
Stephen Hines4b32ffd2010-11-05 18:47:11 -070076 mRefCount.Visit(FD->getBody());
Stephen Hinescfae0f32010-11-01 18:57:31 -070077 }
78 return;
79}
80
81void RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
82 // Disallow user-defined functions with prefix "rs"
83 if (!mAllowRSPrefix) {
84 // Iterate all function declarations in the program.
85 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
86 I != E; I++) {
87 clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
88 if (FD == NULL)
89 continue;
90 if (!FD->getName().startswith("rs")) // Check prefix
91 continue;
92 if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
93 mDiags.Report(clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
94 mDiags.getCustomDiagID(clang::Diagnostic::Error,
95 "invalid function name prefix, "
96 "\"rs\" is reserved: '%0'"))
97 << FD->getName();
98 }
99 }
100
101 // Process any non-static function declarations
102 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
Stephen Hineseb2eec92011-01-09 19:13:09 -0800103 clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
104 if (FD && FD->isGlobal()) {
105 AnnotateFunction(FD);
106 }
Stephen Hinescfae0f32010-11-01 18:57:31 -0700107 }
108
109 Backend::HandleTopLevelDecl(D);
110 return;
111}
112
Stephen Hinesc97a3332010-11-30 15:31:08 -0800113namespace {
114
Stephen Hines78e69cb2011-04-22 15:03:19 -0700115static bool ValidateVarDecl(clang::VarDecl *VD) {
116 if (!VD) {
117 return true;
Stephen Hinesc97a3332010-11-30 15:31:08 -0800118 }
Stephen Hines78e69cb2011-04-22 15:03:19 -0700119
120 clang::ASTContext &C = VD->getASTContext();
121 const clang::Type *T = VD->getType().getTypePtr();
122 bool valid = true;
123
124 if (VD->getLinkage() == clang::ExternalLinkage) {
125 llvm::StringRef TypeName;
126 if (!RSExportType::NormalizeType(T, TypeName, &C.getDiagnostics(), VD)) {
127 valid = false;
128 }
129 }
130 valid &= RSExportType::ValidateVarDecl(VD);
131
132 return valid;
Stephen Hinesc97a3332010-11-30 15:31:08 -0800133}
134
Stephen Hines78e69cb2011-04-22 15:03:19 -0700135static bool ValidateASTContext(clang::ASTContext &C) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800136 bool valid = true;
Stephen Hinesfcda2352010-10-19 16:49:32 -0700137 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
Stephen Hinesc97a3332010-11-30 15:31:08 -0800138 for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
139 DE = TUDecl->decls_end();
140 DI != DE;
141 DI++) {
Stephen Hines78e69cb2011-04-22 15:03:19 -0700142 clang::VarDecl *VD = dyn_cast<clang::VarDecl>(*DI);
143 if (VD && !ValidateVarDecl(VD)) {
144 valid = false;
Stephen Hinesc97a3332010-11-30 15:31:08 -0800145 }
146 }
147
148 return valid;
149}
150
Stephen Hinese5e64432010-12-02 18:48:20 -0800151} // namespace
Stephen Hinesc97a3332010-11-30 15:31:08 -0800152
153void RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
154 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
155
Stephen Hines78e69cb2011-04-22 15:03:19 -0700156 if (!ValidateASTContext(C)) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800157 return;
158 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700159
Stephen Hines96ab06c2011-01-05 15:29:26 -0800160 int version = mContext->getVersion();
161 if (version == 0) {
162 // Not setting a version is an error
163 mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
164 "Missing pragma for version in source file"));
165 } else if (version > 1) {
166 mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
167 "Pragma for version in source file must be set to 1"));
168 }
169
Stephen Hinescfae0f32010-11-01 18:57:31 -0700170 // Process any static function declarations
Stephen Hinesfcda2352010-10-19 16:49:32 -0700171 for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
172 E = TUDecl->decls_end(); I != E; I++) {
173 if ((I->getKind() >= clang::Decl::firstFunction) &&
174 (I->getKind() <= clang::Decl::lastFunction)) {
Stephen Hineseb2eec92011-01-09 19:13:09 -0800175 clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I);
176 if (FD && !FD->isGlobal()) {
177 AnnotateFunction(FD);
178 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700179 }
180 }
181
182 return;
183}
184
185///////////////////////////////////////////////////////////////////////////////
Zonr Chang68fc02c2010-10-13 19:09:19 +0800186void RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
Stephen Hinesc808a992010-11-29 17:20:42 -0800187 if (!mContext->processExport()) {
188 mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
189 "elements cannot be exported"));
Stephen Hinesc97a3332010-11-30 15:31:08 -0800190 return;
Stephen Hinesc808a992010-11-29 17:20:42 -0800191 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700192
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700193 // Dump export variable info
194 if (mContext->hasExportVar()) {
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800195 int slotCount = 0;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700196 if (mExportVarMetadata == NULL)
Zonr Chang68fc02c2010-10-13 19:09:19 +0800197 mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700198
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700199 llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800200 llvm::SmallVector<llvm::Value*, 1> SlotVarInfo;
201
202 // We emit slot information (#rs_object_slots) for any reference counted
203 // RS type or pointer (which can also be bound).
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700204
zonr6315f762010-10-05 15:35:14 +0800205 for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
206 E = mContext->export_vars_end();
207 I != E;
208 I++) {
209 const RSExportVar *EV = *I;
210 const RSExportType *ET = EV->getType();
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800211 bool countsAsRSObject = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700212
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700213 // Variable name
214 ExportVarInfo.push_back(
215 llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700216
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700217 // Type name
Zonr Changa65ec162010-10-17 01:53:05 +0800218 switch (ET->getClass()) {
219 case RSExportType::ExportClassPrimitive: {
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800220 const RSExportPrimitiveType *PT =
221 static_cast<const RSExportPrimitiveType*>(ET);
Zonr Changa65ec162010-10-17 01:53:05 +0800222 ExportVarInfo.push_back(
223 llvm::MDString::get(
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800224 mLLVMContext, llvm::utostr_32(PT->getType())));
225 if (PT->isRSObjectType()) {
226 countsAsRSObject = true;
227 }
Zonr Changa65ec162010-10-17 01:53:05 +0800228 break;
229 }
230 case RSExportType::ExportClassPointer: {
231 ExportVarInfo.push_back(
232 llvm::MDString::get(
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700233 mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
Zonr Changa65ec162010-10-17 01:53:05 +0800234 ->getPointeeType()->getName()).c_str()));
235 break;
236 }
237 case RSExportType::ExportClassMatrix: {
238 ExportVarInfo.push_back(
239 llvm::MDString::get(
240 mLLVMContext, llvm::utostr_32(
241 RSExportPrimitiveType::DataTypeRSMatrix2x2 +
242 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
243 break;
244 }
245 case RSExportType::ExportClassVector:
246 case RSExportType::ExportClassConstantArray:
247 case RSExportType::ExportClassRecord: {
248 ExportVarInfo.push_back(
249 llvm::MDString::get(mLLVMContext,
250 EV->getType()->getName().c_str()));
251 break;
252 }
253 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700254
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700255 mExportVarMetadata->addOperand(
256 llvm::MDNode::get(mLLVMContext,
257 ExportVarInfo.data(),
258 ExportVarInfo.size()) );
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700259
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700260 ExportVarInfo.clear();
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800261
262 if (mRSObjectSlotsMetadata == NULL) {
263 mRSObjectSlotsMetadata =
264 M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
265 }
266
267 if (countsAsRSObject) {
268 SlotVarInfo.push_back(
269 llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount)));
270
271 mRSObjectSlotsMetadata->addOperand(
272 llvm::MDNode::get(mLLVMContext,
273 SlotVarInfo.data(),
274 SlotVarInfo.size()));
275 }
276
277 slotCount++;
278 SlotVarInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700279 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700280 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700281
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700282 // Dump export function info
283 if (mContext->hasExportFunc()) {
284 if (mExportFuncMetadata == NULL)
285 mExportFuncMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800286 M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700287
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700288 llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700289
zonr6315f762010-10-05 15:35:14 +0800290 for (RSContext::const_export_func_iterator
291 I = mContext->export_funcs_begin(),
292 E = mContext->export_funcs_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700293 I != E;
294 I++) {
zonr6315f762010-10-05 15:35:14 +0800295 const RSExportFunc *EF = *I;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700296
297 // Function name
zonr6315f762010-10-05 15:35:14 +0800298 if (!EF->hasParam()) {
299 ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
300 EF->getName().c_str()));
301 } else {
Zonr Chang68fc02c2010-10-13 19:09:19 +0800302 llvm::Function *F = M->getFunction(EF->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700303 llvm::Function *HelperFunction;
304 const std::string HelperFunctionName(".helper_" + EF->getName());
305
Stephen Hines6e6578a2011-02-07 18:05:48 -0800306 slangAssert(F && "Function marked as exported disappeared in Bitcode");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700307
308 // Create helper function
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700309 {
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800310 llvm::StructType *HelperFunctionParameterTy = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700311
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800312 if (!F->getArgumentList().empty()) {
313 std::vector<const llvm::Type*> HelperFunctionParameterTys;
314 for (llvm::Function::arg_iterator AI = F->arg_begin(),
315 AE = F->arg_end(); AI != AE; AI++)
316 HelperFunctionParameterTys.push_back(AI->getType());
317
318 HelperFunctionParameterTy =
319 llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
320 }
321
322 if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
323 fprintf(stderr, "Failed to export function %s: parameter type "
324 "mismatch during creation of helper function.\n",
325 EF->getName().c_str());
326
327 const RSExportRecordType *Expected = EF->getParamPacketType();
328 if (Expected) {
329 fprintf(stderr, "Expected:\n");
330 Expected->getLLVMType()->dump();
331 }
332 if (HelperFunctionParameterTy) {
333 fprintf(stderr, "Got:\n");
334 HelperFunctionParameterTy->dump();
335 }
336 }
337
338 std::vector<const llvm::Type*> Params;
339 if (HelperFunctionParameterTy) {
340 llvm::PointerType *HelperFunctionParameterTyP =
341 llvm::PointerType::getUnqual(HelperFunctionParameterTy);
342 Params.push_back(HelperFunctionParameterTyP);
343 }
344
345 llvm::FunctionType * HelperFunctionType =
346 llvm::FunctionType::get(F->getReturnType(),
347 Params,
348 /* IsVarArgs = */false);
Shih-wei Liaocecd11d2010-09-21 08:07:58 -0700349
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700350 HelperFunction =
351 llvm::Function::Create(HelperFunctionType,
352 llvm::GlobalValue::ExternalLinkage,
353 HelperFunctionName,
Zonr Chang68fc02c2010-10-13 19:09:19 +0800354 M);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700355
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700356 HelperFunction->addFnAttr(llvm::Attribute::NoInline);
357 HelperFunction->setCallingConv(F->getCallingConv());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700358
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700359 // Create helper function body
360 {
361 llvm::Argument *HelperFunctionParameter =
362 &(*HelperFunction->arg_begin());
363 llvm::BasicBlock *BB =
364 llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
365 llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
366 llvm::SmallVector<llvm::Value*, 6> Params;
367 llvm::Value *Idx[2];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700368
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700369 Idx[0] =
370 llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700371
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700372 // getelementptr and load instruction for all elements in
373 // parameter .p
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800374 for (size_t i = 0; i < EF->getNumParameters(); i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700375 // getelementptr
376 Idx[1] =
377 llvm::ConstantInt::get(
378 llvm::Type::getInt32Ty(mLLVMContext), i);
379 llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter,
380 Idx,
381 Idx + 2);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700382
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700383 // load
384 llvm::Value *V = IB->CreateLoad(Ptr);
385 Params.push_back(V);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700386 }
387
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700388 // Call and pass the all elements as paramter to F
389 llvm::CallInst *CI = IB->CreateCall(F,
390 Params.data(),
391 Params.data() + Params.size());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700392
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700393 CI->setCallingConv(F->getCallingConv());
394
395 if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
396 IB->CreateRetVoid();
397 else
398 IB->CreateRet(CI);
399
400 delete IB;
401 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700402 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700403
404 ExportFuncInfo.push_back(
405 llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
406 }
407
408 mExportFuncMetadata->addOperand(
409 llvm::MDNode::get(mLLVMContext,
410 ExportFuncInfo.data(),
411 ExportFuncInfo.size()));
412
413 ExportFuncInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700414 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700415 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700416
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700417 // Dump export type info
418 if (mContext->hasExportType()) {
419 llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700420
zonr6315f762010-10-05 15:35:14 +0800421 for (RSContext::const_export_type_iterator
422 I = mContext->export_types_begin(),
423 E = mContext->export_types_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700424 I != E;
425 I++) {
426 // First, dump type name list to export
427 const RSExportType *ET = I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700428
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700429 ExportTypeInfo.clear();
430 // Type name
431 ExportTypeInfo.push_back(
432 llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700433
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700434 if (ET->getClass() == RSExportType::ExportClassRecord) {
435 const RSExportRecordType *ERT =
436 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700437
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700438 if (mExportTypeMetadata == NULL)
439 mExportTypeMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800440 M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700441
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700442 mExportTypeMetadata->addOperand(
443 llvm::MDNode::get(mLLVMContext,
444 ExportTypeInfo.data(),
445 ExportTypeInfo.size()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700446
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700447 // Now, export struct field information to %[struct name]
448 std::string StructInfoMetadataName("%");
449 StructInfoMetadataName.append(ET->getName());
450 llvm::NamedMDNode *StructInfoMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800451 M->getOrInsertNamedMetadata(StructInfoMetadataName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700452 llvm::SmallVector<llvm::Value*, 3> FieldInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700453
Stephen Hines6e6578a2011-02-07 18:05:48 -0800454 slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
455 "Metadata with same name was created before");
zonr6315f762010-10-05 15:35:14 +0800456 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
457 FE = ERT->fields_end();
458 FI != FE;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700459 FI++) {
460 const RSExportRecordType::Field *F = *FI;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700461
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700462 // 1. field name
463 FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
464 F->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700465
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700466 // 2. field type name
467 FieldInfo.push_back(
468 llvm::MDString::get(mLLVMContext,
469 F->getType()->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700470
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700471 // 3. field kind
472 switch (F->getType()->getClass()) {
473 case RSExportType::ExportClassPrimitive:
474 case RSExportType::ExportClassVector: {
475 const RSExportPrimitiveType *EPT =
476 static_cast<const RSExportPrimitiveType*>(F->getType());
477 FieldInfo.push_back(
478 llvm::MDString::get(mLLVMContext,
479 llvm::itostr(EPT->getKind())));
480 break;
481 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700482
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700483 default: {
484 FieldInfo.push_back(
485 llvm::MDString::get(mLLVMContext,
486 llvm::itostr(
zonr6315f762010-10-05 15:35:14 +0800487 RSExportPrimitiveType::DataKindUser)));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700488 break;
489 }
490 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700491
zonr6315f762010-10-05 15:35:14 +0800492 StructInfoMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
493 FieldInfo.data(),
494 FieldInfo.size()));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700495
496 FieldInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700497 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700498 } // ET->getClass() == RSExportType::ExportClassRecord
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700499 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700500 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700501
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700502 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700503}
504
505RSBackend::~RSBackend() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700506 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700507}
Stephen Hinese639eb52010-11-08 19:27:20 -0800508
509} // namespace slang