blob: c6439088994189eba7efe7cd380faa825e3c9216 [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 Hinese639eb52010-11-08 19:27:20 -080028#include "llvm/Constant.h"
29#include "llvm/Constants.h"
30#include "llvm/DerivedTypes.h"
31#include "llvm/Function.h"
Shih-wei Liao43730fe2012-08-02 23:06:18 -070032#include "llvm/IRBuilder.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080033#include "llvm/Metadata.h"
34#include "llvm/Module.h"
35
mkopec1c460b372012-01-09 11:21:50 -050036#include "llvm/Support/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),
Logan Chien9207a2e2011-10-21 15:39:28 +080064 mExportVarMetadata(NULL),
65 mExportFuncMetadata(NULL),
Stephen Hines7b51b552012-02-16 00:12:38 -080066 mExportForEachNameMetadata(NULL),
67 mExportForEachSignatureMetadata(NULL),
Logan Chien9207a2e2011-10-21 15:39:28 +080068 mExportTypeMetadata(NULL),
69 mRSObjectSlotsMetadata(NULL),
Stephen Hines11274a72012-09-26 19:14:20 -070070 mRefCount(mContext->getASTContext()),
71 mASTChecker(mContext->getASTContext(), mContext->getTargetAPI(),
72 IsFilterscript) {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070073}
74
Stephen Hinescfae0f32010-11-01 18:57:31 -070075// 1) Add zero initialization of local RS object types
76void RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
77 if (FD &&
78 FD->hasBody() &&
Stephen Hines11274a72012-09-26 19:14:20 -070079 !SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070080 mRefCount.Init();
Stephen Hines4b32ffd2010-11-05 18:47:11 -070081 mRefCount.Visit(FD->getBody());
Stephen Hinescfae0f32010-11-01 18:57:31 -070082 }
83 return;
84}
85
Logan Chienfa6ef562011-11-25 13:50:02 +080086bool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
Stephen Hinescfae0f32010-11-01 18:57:31 -070087 // Disallow user-defined functions with prefix "rs"
88 if (!mAllowRSPrefix) {
89 // Iterate all function declarations in the program.
90 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
91 I != E; I++) {
Logan Chienab992e52011-07-20 22:06:52 +080092 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hinescfae0f32010-11-01 18:57:31 -070093 if (FD == NULL)
94 continue;
95 if (!FD->getName().startswith("rs")) // Check prefix
96 continue;
Stephen Hines11274a72012-09-26 19:14:20 -070097 if (!SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
Logan Chien9207a2e2011-10-21 15:39:28 +080098 mDiagEngine.Report(
99 clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
100 mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
101 "invalid function name prefix, "
102 "\"rs\" is reserved: '%0'"))
103 << FD->getName();
Stephen Hinescfae0f32010-11-01 18:57:31 -0700104 }
105 }
106
107 // Process any non-static function declarations
108 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
Logan Chienab992e52011-07-20 22:06:52 +0800109 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hineseb2eec92011-01-09 19:13:09 -0800110 if (FD && FD->isGlobal()) {
Stephen Hinesab5a5352012-08-04 15:13:40 -0700111 // Check that we don't have any array parameters being misintrepeted as
112 // kernel pointers due to the C type system's array to pointer decay.
113 size_t numParams = FD->getNumParams();
114 for (size_t i = 0; i < numParams; i++) {
115 const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
116 clang::QualType QT = PVD->getOriginalType();
117 if (QT->isArrayType()) {
118 mDiagEngine.Report(
119 clang::FullSourceLoc(PVD->getTypeSpecStartLoc(), mSourceMgr),
120 mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
121 "exported function parameters may "
122 "not have array type: %0")) << QT;
123 }
124 }
Stephen Hineseb2eec92011-01-09 19:13:09 -0800125 AnnotateFunction(FD);
126 }
Stephen Hinescfae0f32010-11-01 18:57:31 -0700127 }
128
Logan Chienfa6ef562011-11-25 13:50:02 +0800129 return Backend::HandleTopLevelDecl(D);
Stephen Hinescfae0f32010-11-01 18:57:31 -0700130}
131
Stephen Hinesc97a3332010-11-30 15:31:08 -0800132
133void RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
134 clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
135
Stephen Hines11274a72012-09-26 19:14:20 -0700136 // If we have an invalid RS/FS AST, don't check further.
137 if (!mASTChecker.Validate()) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800138 return;
139 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700140
Stephen Hines11274a72012-09-26 19:14:20 -0700141 if (mIsFilterscript) {
142 mContext->addPragma("rs_fp_relaxed", "");
143 }
144
Stephen Hines96ab06c2011-01-05 15:29:26 -0800145 int version = mContext->getVersion();
146 if (version == 0) {
147 // Not setting a version is an error
Stephen Hines7aff4a02011-12-08 18:34:27 -0800148 mDiagEngine.Report(
149 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
150 mDiagEngine.getCustomDiagID(
151 clang::DiagnosticsEngine::Error,
152 "missing pragma for version in source file"));
153 } else {
154 slangAssert(version == 1);
Stephen Hines96ab06c2011-01-05 15:29:26 -0800155 }
156
Stephen Hinescf9a73a2012-09-20 10:38:02 -0700157 if (mContext->getReflectJavaPackageName().empty()) {
158 mDiagEngine.Report(
159 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
160 mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
161 "missing \"#pragma rs "
162 "java_package_name(com.foo.bar)\" "
163 "in source file"));
164 return;
165 }
166
Stephen Hines688e64b2011-08-23 16:01:25 -0700167 // Create a static global destructor if necessary (to handle RS object
168 // runtime cleanup).
169 clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
170 if (FD) {
171 HandleTopLevelDecl(clang::DeclGroupRef(FD));
172 }
173
Stephen Hinescfae0f32010-11-01 18:57:31 -0700174 // Process any static function declarations
Stephen Hinesfcda2352010-10-19 16:49:32 -0700175 for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
176 E = TUDecl->decls_end(); I != E; I++) {
177 if ((I->getKind() >= clang::Decl::firstFunction) &&
178 (I->getKind() <= clang::Decl::lastFunction)) {
Logan Chienab992e52011-07-20 22:06:52 +0800179 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hineseb2eec92011-01-09 19:13:09 -0800180 if (FD && !FD->isGlobal()) {
181 AnnotateFunction(FD);
182 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700183 }
184 }
185
186 return;
187}
188
189///////////////////////////////////////////////////////////////////////////////
Zonr Chang68fc02c2010-10-13 19:09:19 +0800190void RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
Stephen Hinesc808a992010-11-29 17:20:42 -0800191 if (!mContext->processExport()) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800192 return;
Stephen Hinesc808a992010-11-29 17:20:42 -0800193 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700194
mkopec1c460b372012-01-09 11:21:50 -0500195 // Write optimization level
196 llvm::SmallVector<llvm::Value*, 1> OptimizationOption;
197 OptimizationOption.push_back(llvm::ConstantInt::get(
198 mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel)));
199
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700200 // Dump export variable info
201 if (mContext->hasExportVar()) {
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800202 int slotCount = 0;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700203 if (mExportVarMetadata == NULL)
Zonr Chang68fc02c2010-10-13 19:09:19 +0800204 mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700205
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700206 llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800207
208 // We emit slot information (#rs_object_slots) for any reference counted
209 // RS type or pointer (which can also be bound).
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700210
zonr6315f762010-10-05 15:35:14 +0800211 for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
212 E = mContext->export_vars_end();
213 I != E;
214 I++) {
215 const RSExportVar *EV = *I;
216 const RSExportType *ET = EV->getType();
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800217 bool countsAsRSObject = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700218
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700219 // Variable name
220 ExportVarInfo.push_back(
221 llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700222
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700223 // Type name
Zonr Changa65ec162010-10-17 01:53:05 +0800224 switch (ET->getClass()) {
225 case RSExportType::ExportClassPrimitive: {
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800226 const RSExportPrimitiveType *PT =
227 static_cast<const RSExportPrimitiveType*>(ET);
Zonr Changa65ec162010-10-17 01:53:05 +0800228 ExportVarInfo.push_back(
229 llvm::MDString::get(
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800230 mLLVMContext, llvm::utostr_32(PT->getType())));
231 if (PT->isRSObjectType()) {
232 countsAsRSObject = true;
233 }
Zonr Changa65ec162010-10-17 01:53:05 +0800234 break;
235 }
236 case RSExportType::ExportClassPointer: {
237 ExportVarInfo.push_back(
238 llvm::MDString::get(
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700239 mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
Zonr Changa65ec162010-10-17 01:53:05 +0800240 ->getPointeeType()->getName()).c_str()));
241 break;
242 }
243 case RSExportType::ExportClassMatrix: {
244 ExportVarInfo.push_back(
245 llvm::MDString::get(
246 mLLVMContext, llvm::utostr_32(
247 RSExportPrimitiveType::DataTypeRSMatrix2x2 +
248 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
249 break;
250 }
251 case RSExportType::ExportClassVector:
252 case RSExportType::ExportClassConstantArray:
253 case RSExportType::ExportClassRecord: {
254 ExportVarInfo.push_back(
255 llvm::MDString::get(mLLVMContext,
256 EV->getType()->getName().c_str()));
257 break;
258 }
259 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700260
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700261 mExportVarMetadata->addOperand(
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700262 llvm::MDNode::get(mLLVMContext, ExportVarInfo));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700263 ExportVarInfo.clear();
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800264
265 if (mRSObjectSlotsMetadata == NULL) {
266 mRSObjectSlotsMetadata =
267 M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
268 }
269
270 if (countsAsRSObject) {
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700271 mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
272 llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800273 }
274
275 slotCount++;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700276 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700277 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700278
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700279 // Dump export function info
280 if (mContext->hasExportFunc()) {
281 if (mExportFuncMetadata == NULL)
282 mExportFuncMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800283 M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700284
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700285 llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700286
zonr6315f762010-10-05 15:35:14 +0800287 for (RSContext::const_export_func_iterator
288 I = mContext->export_funcs_begin(),
289 E = mContext->export_funcs_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700290 I != E;
291 I++) {
zonr6315f762010-10-05 15:35:14 +0800292 const RSExportFunc *EF = *I;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700293
294 // Function name
zonr6315f762010-10-05 15:35:14 +0800295 if (!EF->hasParam()) {
296 ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
297 EF->getName().c_str()));
298 } else {
Zonr Chang68fc02c2010-10-13 19:09:19 +0800299 llvm::Function *F = M->getFunction(EF->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700300 llvm::Function *HelperFunction;
301 const std::string HelperFunctionName(".helper_" + EF->getName());
302
Stephen Hines6e6578a2011-02-07 18:05:48 -0800303 slangAssert(F && "Function marked as exported disappeared in Bitcode");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700304
305 // Create helper function
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700306 {
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800307 llvm::StructType *HelperFunctionParameterTy = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700308
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800309 if (!F->getArgumentList().empty()) {
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700310 std::vector<llvm::Type*> HelperFunctionParameterTys;
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800311 for (llvm::Function::arg_iterator AI = F->arg_begin(),
312 AE = F->arg_end(); AI != AE; AI++)
313 HelperFunctionParameterTys.push_back(AI->getType());
314
315 HelperFunctionParameterTy =
Stephen Hinesa67e4452011-07-19 15:39:26 -0700316 llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800317 }
318
319 if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
320 fprintf(stderr, "Failed to export function %s: parameter type "
321 "mismatch during creation of helper function.\n",
322 EF->getName().c_str());
323
324 const RSExportRecordType *Expected = EF->getParamPacketType();
325 if (Expected) {
326 fprintf(stderr, "Expected:\n");
327 Expected->getLLVMType()->dump();
328 }
329 if (HelperFunctionParameterTy) {
330 fprintf(stderr, "Got:\n");
331 HelperFunctionParameterTy->dump();
332 }
333 }
334
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700335 std::vector<llvm::Type*> Params;
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800336 if (HelperFunctionParameterTy) {
337 llvm::PointerType *HelperFunctionParameterTyP =
338 llvm::PointerType::getUnqual(HelperFunctionParameterTy);
339 Params.push_back(HelperFunctionParameterTyP);
340 }
341
342 llvm::FunctionType * HelperFunctionType =
343 llvm::FunctionType::get(F->getReturnType(),
Stephen Hinesa67e4452011-07-19 15:39:26 -0700344 Params,
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800345 /* IsVarArgs = */false);
Shih-wei Liaocecd11d2010-09-21 08:07:58 -0700346
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700347 HelperFunction =
348 llvm::Function::Create(HelperFunctionType,
349 llvm::GlobalValue::ExternalLinkage,
350 HelperFunctionName,
Zonr Chang68fc02c2010-10-13 19:09:19 +0800351 M);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700352
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700353 HelperFunction->addFnAttr(llvm::Attribute::NoInline);
354 HelperFunction->setCallingConv(F->getCallingConv());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700355
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700356 // Create helper function body
357 {
358 llvm::Argument *HelperFunctionParameter =
359 &(*HelperFunction->arg_begin());
360 llvm::BasicBlock *BB =
361 llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
362 llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
363 llvm::SmallVector<llvm::Value*, 6> Params;
364 llvm::Value *Idx[2];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700365
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700366 Idx[0] =
367 llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700368
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700369 // getelementptr and load instruction for all elements in
370 // parameter .p
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800371 for (size_t i = 0; i < EF->getNumParameters(); i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700372 // getelementptr
Logan Chien9207a2e2011-10-21 15:39:28 +0800373 Idx[1] = llvm::ConstantInt::get(
374 llvm::Type::getInt32Ty(mLLVMContext), i);
375
376 llvm::Value *Ptr =
377 IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700378
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700379 // load
380 llvm::Value *V = IB->CreateLoad(Ptr);
381 Params.push_back(V);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700382 }
383
Stephen Hinesa67e4452011-07-19 15:39:26 -0700384 // Call and pass the all elements as parameter to F
385 llvm::CallInst *CI = IB->CreateCall(F, Params);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700386
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700387 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 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700396 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700397
398 ExportFuncInfo.push_back(
399 llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
400 }
401
402 mExportFuncMetadata->addOperand(
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700403 llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700404 ExportFuncInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700405 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700406 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700407
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700408 // Dump export function info
409 if (mContext->hasExportForEach()) {
Stephen Hines7b51b552012-02-16 00:12:38 -0800410 if (mExportForEachNameMetadata == NULL) {
411 mExportForEachNameMetadata =
412 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
413 }
414 if (mExportForEachSignatureMetadata == NULL) {
415 mExportForEachSignatureMetadata =
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700416 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
Stephen Hines7b51b552012-02-16 00:12:38 -0800417 }
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700418
Stephen Hines7b51b552012-02-16 00:12:38 -0800419 llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700420 llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
421
422 for (RSContext::const_export_foreach_iterator
423 I = mContext->export_foreach_begin(),
424 E = mContext->export_foreach_end();
425 I != E;
426 I++) {
427 const RSExportForEach *EFE = *I;
428
Stephen Hines7b51b552012-02-16 00:12:38 -0800429 ExportForEachName.push_back(
430 llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
431
432 mExportForEachNameMetadata->addOperand(
433 llvm::MDNode::get(mLLVMContext, ExportForEachName));
434 ExportForEachName.clear();
435
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700436 ExportForEachInfo.push_back(
437 llvm::MDString::get(mLLVMContext,
Stephen Hines7b51b552012-02-16 00:12:38 -0800438 llvm::utostr_32(EFE->getSignatureMetadata())));
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700439
Stephen Hines7b51b552012-02-16 00:12:38 -0800440 mExportForEachSignatureMetadata->addOperand(
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700441 llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
442 ExportForEachInfo.clear();
443 }
444 }
445
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700446 // Dump export type info
447 if (mContext->hasExportType()) {
448 llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700449
zonr6315f762010-10-05 15:35:14 +0800450 for (RSContext::const_export_type_iterator
451 I = mContext->export_types_begin(),
452 E = mContext->export_types_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700453 I != E;
454 I++) {
455 // First, dump type name list to export
456 const RSExportType *ET = I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700457
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700458 ExportTypeInfo.clear();
459 // Type name
460 ExportTypeInfo.push_back(
461 llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700462
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700463 if (ET->getClass() == RSExportType::ExportClassRecord) {
464 const RSExportRecordType *ERT =
465 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700466
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700467 if (mExportTypeMetadata == NULL)
468 mExportTypeMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800469 M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700470
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700471 mExportTypeMetadata->addOperand(
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700472 llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700473
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700474 // Now, export struct field information to %[struct name]
475 std::string StructInfoMetadataName("%");
476 StructInfoMetadataName.append(ET->getName());
477 llvm::NamedMDNode *StructInfoMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800478 M->getOrInsertNamedMetadata(StructInfoMetadataName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700479 llvm::SmallVector<llvm::Value*, 3> FieldInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700480
Stephen Hines6e6578a2011-02-07 18:05:48 -0800481 slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
482 "Metadata with same name was created before");
zonr6315f762010-10-05 15:35:14 +0800483 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
484 FE = ERT->fields_end();
485 FI != FE;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700486 FI++) {
487 const RSExportRecordType::Field *F = *FI;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700488
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700489 // 1. field name
490 FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
491 F->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700492
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700493 // 2. field type name
494 FieldInfo.push_back(
495 llvm::MDString::get(mLLVMContext,
496 F->getType()->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700497
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700498 StructInfoMetadata->addOperand(
499 llvm::MDNode::get(mLLVMContext, FieldInfo));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700500 FieldInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700501 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700502 } // ET->getClass() == RSExportType::ExportClassRecord
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700503 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700504 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700505
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700506 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700507}
508
509RSBackend::~RSBackend() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700510 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700511}
Stephen Hinese639eb52010-11-08 19:27:20 -0800512
513} // namespace slang