blob: 581c3f94792d3dcc5c0ca67d8e51a5ecbbbe9ca5 [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
mkopec1c460b372012-01-09 11:21:50 -050022#include "clang/Frontend/CodeGenOptions.h"
23
zonr6315f762010-10-05 15:35:14 +080024#include "llvm/ADT/Twine.h"
25#include "llvm/ADT/StringExtras.h"
26
Stephen Hinese639eb52010-11-08 19:27:20 -080027#include "llvm/Constant.h"
28#include "llvm/Constants.h"
29#include "llvm/DerivedTypes.h"
30#include "llvm/Function.h"
31#include "llvm/Metadata.h"
32#include "llvm/Module.h"
33
mkopec1c460b372012-01-09 11:21:50 -050034#include "llvm/Support/DebugLoc.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080035#include "llvm/Support/IRBuilder.h"
36
Stephen Hines6e6578a2011-02-07 18:05:48 -080037#include "slang_assert.h"
Zonr Chang592a9542010-10-07 20:03:58 +080038#include "slang_rs.h"
zonr6315f762010-10-05 15:35:14 +080039#include "slang_rs_context.h"
Stephen Hines4ccf75e2011-08-16 18:21:01 -070040#include "slang_rs_export_foreach.h"
zonr6315f762010-10-05 15:35:14 +080041#include "slang_rs_export_func.h"
42#include "slang_rs_export_type.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080043#include "slang_rs_export_var.h"
44#include "slang_rs_metadata.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070045
Stephen Hinese639eb52010-11-08 19:27:20 -080046namespace slang {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070047
48RSBackend::RSBackend(RSContext *Context,
Logan Chien9207a2e2011-10-21 15:39:28 +080049 clang::DiagnosticsEngine *DiagEngine,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070050 const clang::CodeGenOptions &CodeGenOpts,
51 const clang::TargetOptions &TargetOpts,
Stephen Hines3fd0a942011-01-18 12:27:39 -080052 PragmaList *Pragmas,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070053 llvm::raw_ostream *OS,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080054 Slang::OutputType OT,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070055 clang::SourceManager &SourceMgr,
Stephen Hines4a4bf922011-08-18 17:20:33 -070056 bool AllowRSPrefix)
Logan Chien9207a2e2011-10-21 15:39:28 +080057 : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
58 mContext(Context),
59 mSourceMgr(SourceMgr),
60 mAllowRSPrefix(AllowRSPrefix),
61 mExportVarMetadata(NULL),
62 mExportFuncMetadata(NULL),
Stephen Hines7b51b552012-02-16 00:12:38 -080063 mExportForEachNameMetadata(NULL),
64 mExportForEachSignatureMetadata(NULL),
Logan Chien9207a2e2011-10-21 15:39:28 +080065 mExportTypeMetadata(NULL),
66 mRSObjectSlotsMetadata(NULL),
67 mRefCount(mContext->getASTContext()) {
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
Logan Chienfa6ef562011-11-25 13:50:02 +080081bool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
Stephen Hinescfae0f32010-11-01 18:57:31 -070082 // 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++) {
Logan Chienab992e52011-07-20 22:06:52 +080087 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hinescfae0f32010-11-01 18:57:31 -070088 if (FD == NULL)
89 continue;
90 if (!FD->getName().startswith("rs")) // Check prefix
91 continue;
92 if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
Logan Chien9207a2e2011-10-21 15:39:28 +080093 mDiagEngine.Report(
94 clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
95 mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
96 "invalid function name prefix, "
97 "\"rs\" is reserved: '%0'"))
98 << FD->getName();
Stephen Hinescfae0f32010-11-01 18:57:31 -070099 }
100 }
101
102 // Process any non-static function declarations
103 for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
Logan Chienab992e52011-07-20 22:06:52 +0800104 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hineseb2eec92011-01-09 19:13:09 -0800105 if (FD && FD->isGlobal()) {
106 AnnotateFunction(FD);
107 }
Stephen Hinescfae0f32010-11-01 18:57:31 -0700108 }
109
Logan Chienfa6ef562011-11-25 13:50:02 +0800110 return Backend::HandleTopLevelDecl(D);
Stephen Hinescfae0f32010-11-01 18:57:31 -0700111}
112
Stephen Hinesc97a3332010-11-30 15:31:08 -0800113namespace {
114
Stephen Hinesd5a84f62012-04-04 17:44:38 -0700115static bool ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI) {
Stephen Hines78e69cb2011-04-22 15:03:19 -0700116 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;
Stephen Hines5bfec8d2012-04-04 08:18:57 -0700126 if (!RSExportType::NormalizeType(T, TypeName, &C.getDiagnostics(), VD)) {
Stephen Hines78e69cb2011-04-22 15:03:19 -0700127 valid = false;
128 }
129 }
Stephen Hinesd5a84f62012-04-04 17:44:38 -0700130 valid &= RSExportType::ValidateVarDecl(VD, TargetAPI);
Stephen Hines78e69cb2011-04-22 15:03:19 -0700131
132 return valid;
Stephen Hinesc97a3332010-11-30 15:31:08 -0800133}
134
Stephen Hinesd5a84f62012-04-04 17:44:38 -0700135static bool ValidateASTContext(clang::ASTContext &C, unsigned int TargetAPI) {
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++) {
Logan Chienab992e52011-07-20 22:06:52 +0800142 clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI);
Stephen Hinesd5a84f62012-04-04 17:44:38 -0700143 if (VD && !ValidateVarDecl(VD, TargetAPI)) {
Stephen Hines78e69cb2011-04-22 15:03:19 -0700144 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 Hinesd5a84f62012-04-04 17:44:38 -0700156 if (!ValidateASTContext(C, getTargetAPI())) {
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
Stephen Hines7aff4a02011-12-08 18:34:27 -0800163 mDiagEngine.Report(
164 mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
165 mDiagEngine.getCustomDiagID(
166 clang::DiagnosticsEngine::Error,
167 "missing pragma for version in source file"));
168 } else {
169 slangAssert(version == 1);
Stephen Hines96ab06c2011-01-05 15:29:26 -0800170 }
171
Stephen Hines688e64b2011-08-23 16:01:25 -0700172 // Create a static global destructor if necessary (to handle RS object
173 // runtime cleanup).
174 clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
175 if (FD) {
176 HandleTopLevelDecl(clang::DeclGroupRef(FD));
177 }
178
Stephen Hinescfae0f32010-11-01 18:57:31 -0700179 // Process any static function declarations
Stephen Hinesfcda2352010-10-19 16:49:32 -0700180 for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
181 E = TUDecl->decls_end(); I != E; I++) {
182 if ((I->getKind() >= clang::Decl::firstFunction) &&
183 (I->getKind() <= clang::Decl::lastFunction)) {
Logan Chienab992e52011-07-20 22:06:52 +0800184 clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
Stephen Hineseb2eec92011-01-09 19:13:09 -0800185 if (FD && !FD->isGlobal()) {
186 AnnotateFunction(FD);
187 }
Stephen Hinesfcda2352010-10-19 16:49:32 -0700188 }
189 }
190
191 return;
192}
193
194///////////////////////////////////////////////////////////////////////////////
Zonr Chang68fc02c2010-10-13 19:09:19 +0800195void RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
Stephen Hinesc808a992010-11-29 17:20:42 -0800196 if (!mContext->processExport()) {
Stephen Hinesc97a3332010-11-30 15:31:08 -0800197 return;
Stephen Hinesc808a992010-11-29 17:20:42 -0800198 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700199
mkopec1c460b372012-01-09 11:21:50 -0500200 // Write optimization level
201 llvm::SmallVector<llvm::Value*, 1> OptimizationOption;
202 OptimizationOption.push_back(llvm::ConstantInt::get(
203 mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel)));
204
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700205 // Dump export variable info
206 if (mContext->hasExportVar()) {
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800207 int slotCount = 0;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700208 if (mExportVarMetadata == NULL)
Zonr Chang68fc02c2010-10-13 19:09:19 +0800209 mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700210
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700211 llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800212
213 // We emit slot information (#rs_object_slots) for any reference counted
214 // RS type or pointer (which can also be bound).
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700215
zonr6315f762010-10-05 15:35:14 +0800216 for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
217 E = mContext->export_vars_end();
218 I != E;
219 I++) {
220 const RSExportVar *EV = *I;
221 const RSExportType *ET = EV->getType();
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800222 bool countsAsRSObject = false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700223
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700224 // Variable name
225 ExportVarInfo.push_back(
226 llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700227
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700228 // Type name
Zonr Changa65ec162010-10-17 01:53:05 +0800229 switch (ET->getClass()) {
230 case RSExportType::ExportClassPrimitive: {
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800231 const RSExportPrimitiveType *PT =
232 static_cast<const RSExportPrimitiveType*>(ET);
Zonr Changa65ec162010-10-17 01:53:05 +0800233 ExportVarInfo.push_back(
234 llvm::MDString::get(
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800235 mLLVMContext, llvm::utostr_32(PT->getType())));
236 if (PT->isRSObjectType()) {
237 countsAsRSObject = true;
238 }
Zonr Changa65ec162010-10-17 01:53:05 +0800239 break;
240 }
241 case RSExportType::ExportClassPointer: {
242 ExportVarInfo.push_back(
243 llvm::MDString::get(
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700244 mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
Zonr Changa65ec162010-10-17 01:53:05 +0800245 ->getPointeeType()->getName()).c_str()));
246 break;
247 }
248 case RSExportType::ExportClassMatrix: {
249 ExportVarInfo.push_back(
250 llvm::MDString::get(
251 mLLVMContext, llvm::utostr_32(
252 RSExportPrimitiveType::DataTypeRSMatrix2x2 +
253 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
254 break;
255 }
256 case RSExportType::ExportClassVector:
257 case RSExportType::ExportClassConstantArray:
258 case RSExportType::ExportClassRecord: {
259 ExportVarInfo.push_back(
260 llvm::MDString::get(mLLVMContext,
261 EV->getType()->getName().c_str()));
262 break;
263 }
264 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700265
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700266 mExportVarMetadata->addOperand(
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700267 llvm::MDNode::get(mLLVMContext, ExportVarInfo));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700268 ExportVarInfo.clear();
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800269
270 if (mRSObjectSlotsMetadata == NULL) {
271 mRSObjectSlotsMetadata =
272 M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
273 }
274
275 if (countsAsRSObject) {
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700276 mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
277 llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
Stephen Hinesb3a12fe2011-01-26 20:16:38 -0800278 }
279
280 slotCount++;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700281 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700282 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700283
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700284 // Dump export function info
285 if (mContext->hasExportFunc()) {
286 if (mExportFuncMetadata == NULL)
287 mExportFuncMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800288 M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700289
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700290 llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700291
zonr6315f762010-10-05 15:35:14 +0800292 for (RSContext::const_export_func_iterator
293 I = mContext->export_funcs_begin(),
294 E = mContext->export_funcs_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700295 I != E;
296 I++) {
zonr6315f762010-10-05 15:35:14 +0800297 const RSExportFunc *EF = *I;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700298
299 // Function name
zonr6315f762010-10-05 15:35:14 +0800300 if (!EF->hasParam()) {
301 ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
302 EF->getName().c_str()));
303 } else {
Zonr Chang68fc02c2010-10-13 19:09:19 +0800304 llvm::Function *F = M->getFunction(EF->getName());
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700305 llvm::Function *HelperFunction;
306 const std::string HelperFunctionName(".helper_" + EF->getName());
307
Stephen Hines6e6578a2011-02-07 18:05:48 -0800308 slangAssert(F && "Function marked as exported disappeared in Bitcode");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700309
310 // Create helper function
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700311 {
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800312 llvm::StructType *HelperFunctionParameterTy = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700313
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800314 if (!F->getArgumentList().empty()) {
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700315 std::vector<llvm::Type*> HelperFunctionParameterTys;
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800316 for (llvm::Function::arg_iterator AI = F->arg_begin(),
317 AE = F->arg_end(); AI != AE; AI++)
318 HelperFunctionParameterTys.push_back(AI->getType());
319
320 HelperFunctionParameterTy =
Stephen Hinesa67e4452011-07-19 15:39:26 -0700321 llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800322 }
323
324 if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
325 fprintf(stderr, "Failed to export function %s: parameter type "
326 "mismatch during creation of helper function.\n",
327 EF->getName().c_str());
328
329 const RSExportRecordType *Expected = EF->getParamPacketType();
330 if (Expected) {
331 fprintf(stderr, "Expected:\n");
332 Expected->getLLVMType()->dump();
333 }
334 if (HelperFunctionParameterTy) {
335 fprintf(stderr, "Got:\n");
336 HelperFunctionParameterTy->dump();
337 }
338 }
339
Shih-wei Liao7c67e572011-07-19 05:54:53 -0700340 std::vector<llvm::Type*> Params;
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800341 if (HelperFunctionParameterTy) {
342 llvm::PointerType *HelperFunctionParameterTyP =
343 llvm::PointerType::getUnqual(HelperFunctionParameterTy);
344 Params.push_back(HelperFunctionParameterTyP);
345 }
346
347 llvm::FunctionType * HelperFunctionType =
348 llvm::FunctionType::get(F->getReturnType(),
Stephen Hinesa67e4452011-07-19 15:39:26 -0700349 Params,
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800350 /* IsVarArgs = */false);
Shih-wei Liaocecd11d2010-09-21 08:07:58 -0700351
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700352 HelperFunction =
353 llvm::Function::Create(HelperFunctionType,
354 llvm::GlobalValue::ExternalLinkage,
355 HelperFunctionName,
Zonr Chang68fc02c2010-10-13 19:09:19 +0800356 M);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700357
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700358 HelperFunction->addFnAttr(llvm::Attribute::NoInline);
359 HelperFunction->setCallingConv(F->getCallingConv());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700360
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700361 // Create helper function body
362 {
363 llvm::Argument *HelperFunctionParameter =
364 &(*HelperFunction->arg_begin());
365 llvm::BasicBlock *BB =
366 llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
367 llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
368 llvm::SmallVector<llvm::Value*, 6> Params;
369 llvm::Value *Idx[2];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700370
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700371 Idx[0] =
372 llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700373
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700374 // getelementptr and load instruction for all elements in
375 // parameter .p
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800376 for (size_t i = 0; i < EF->getNumParameters(); i++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700377 // getelementptr
Logan Chien9207a2e2011-10-21 15:39:28 +0800378 Idx[1] = llvm::ConstantInt::get(
379 llvm::Type::getInt32Ty(mLLVMContext), i);
380
381 llvm::Value *Ptr =
382 IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700383
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700384 // load
385 llvm::Value *V = IB->CreateLoad(Ptr);
386 Params.push_back(V);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700387 }
388
Stephen Hinesa67e4452011-07-19 15:39:26 -0700389 // Call and pass the all elements as parameter to F
390 llvm::CallInst *CI = IB->CreateCall(F, Params);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700391
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700392 CI->setCallingConv(F->getCallingConv());
393
394 if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
395 IB->CreateRetVoid();
396 else
397 IB->CreateRet(CI);
398
399 delete IB;
400 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700401 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700402
403 ExportFuncInfo.push_back(
404 llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
405 }
406
407 mExportFuncMetadata->addOperand(
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700408 llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700409 ExportFuncInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700410 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700411 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700412
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700413 // Dump export function info
414 if (mContext->hasExportForEach()) {
Stephen Hines7b51b552012-02-16 00:12:38 -0800415 if (mExportForEachNameMetadata == NULL) {
416 mExportForEachNameMetadata =
417 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
418 }
419 if (mExportForEachSignatureMetadata == NULL) {
420 mExportForEachSignatureMetadata =
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700421 M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
Stephen Hines7b51b552012-02-16 00:12:38 -0800422 }
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700423
Stephen Hines7b51b552012-02-16 00:12:38 -0800424 llvm::SmallVector<llvm::Value*, 1> ExportForEachName;
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700425 llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
426
427 for (RSContext::const_export_foreach_iterator
428 I = mContext->export_foreach_begin(),
429 E = mContext->export_foreach_end();
430 I != E;
431 I++) {
432 const RSExportForEach *EFE = *I;
433
Stephen Hines7b51b552012-02-16 00:12:38 -0800434 ExportForEachName.push_back(
435 llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
436
437 mExportForEachNameMetadata->addOperand(
438 llvm::MDNode::get(mLLVMContext, ExportForEachName));
439 ExportForEachName.clear();
440
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700441 ExportForEachInfo.push_back(
442 llvm::MDString::get(mLLVMContext,
Stephen Hines7b51b552012-02-16 00:12:38 -0800443 llvm::utostr_32(EFE->getSignatureMetadata())));
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700444
Stephen Hines7b51b552012-02-16 00:12:38 -0800445 mExportForEachSignatureMetadata->addOperand(
Stephen Hines4ccf75e2011-08-16 18:21:01 -0700446 llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
447 ExportForEachInfo.clear();
448 }
449 }
450
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700451 // Dump export type info
452 if (mContext->hasExportType()) {
453 llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700454
zonr6315f762010-10-05 15:35:14 +0800455 for (RSContext::const_export_type_iterator
456 I = mContext->export_types_begin(),
457 E = mContext->export_types_end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700458 I != E;
459 I++) {
460 // First, dump type name list to export
461 const RSExportType *ET = I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700462
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700463 ExportTypeInfo.clear();
464 // Type name
465 ExportTypeInfo.push_back(
466 llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700467
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700468 if (ET->getClass() == RSExportType::ExportClassRecord) {
469 const RSExportRecordType *ERT =
470 static_cast<const RSExportRecordType*>(ET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700471
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700472 if (mExportTypeMetadata == NULL)
473 mExportTypeMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800474 M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700475
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700476 mExportTypeMetadata->addOperand(
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700477 llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700478
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700479 // Now, export struct field information to %[struct name]
480 std::string StructInfoMetadataName("%");
481 StructInfoMetadataName.append(ET->getName());
482 llvm::NamedMDNode *StructInfoMetadata =
Zonr Chang68fc02c2010-10-13 19:09:19 +0800483 M->getOrInsertNamedMetadata(StructInfoMetadataName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700484 llvm::SmallVector<llvm::Value*, 3> FieldInfo;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700485
Stephen Hines6e6578a2011-02-07 18:05:48 -0800486 slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
487 "Metadata with same name was created before");
zonr6315f762010-10-05 15:35:14 +0800488 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
489 FE = ERT->fields_end();
490 FI != FE;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700491 FI++) {
492 const RSExportRecordType::Field *F = *FI;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700493
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700494 // 1. field name
495 FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
496 F->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700497
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700498 // 2. field type name
499 FieldInfo.push_back(
500 llvm::MDString::get(mLLVMContext,
501 F->getType()->getName().c_str()));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700502
Stephen Hinesd27a74e2011-07-13 20:59:46 -0700503 StructInfoMetadata->addOperand(
504 llvm::MDNode::get(mLLVMContext, FieldInfo));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700505 FieldInfo.clear();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700506 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700507 } // ET->getClass() == RSExportType::ExportClassRecord
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700508 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700509 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700510
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700511 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700512}
513
514RSBackend::~RSBackend() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700515 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700516}
Stephen Hinese639eb52010-11-08 19:27:20 -0800517
518} // namespace slang