slang_rs_backend.cpp revision c460b37ffb50819a32c2a8967754b6f784b28263
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_backend.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <string>
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector>
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
22c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "clang/Frontend/CodeGenOptions.h"
23c460b37ffb50819a32c2a8967754b6f784b28263mkopec
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/Twine.h"
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/StringExtras.h"
26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constant.h"
289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constants.h"
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/DerivedTypes.h"
30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Function.h"
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Metadata.h"
32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Module.h"
33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
34c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Support/DebugLoc.h"
356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/IRBuilder.h"
366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
376e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
38592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#include "slang_rs.h"
396315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h"
404ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines#include "slang_rs_export_foreach.h"
416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h"
426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h"
45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
46e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
489ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context,
499207a2e495c8363606861e4f034504ec5c153dabLogan Chien                     clang::DiagnosticsEngine *DiagEngine,
509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::CodeGenOptions &CodeGenOpts,
519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     const clang::TargetOptions &TargetOpts,
523fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines                     PragmaList *Pragmas,
539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     llvm::raw_ostream *OS,
543a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang                     Slang::OutputType OT,
559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                     clang::SourceManager &SourceMgr,
564a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines                     bool AllowRSPrefix)
579207a2e495c8363606861e4f034504ec5c153dabLogan Chien  : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT),
589207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mContext(Context),
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mSourceMgr(SourceMgr),
609207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mAllowRSPrefix(AllowRSPrefix),
619207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportVarMetadata(NULL),
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportFuncMetadata(NULL),
639207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportForEachMetadata(NULL),
649207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mExportTypeMetadata(NULL),
659207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRSObjectSlotsMetadata(NULL),
66c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mRSOptimizationMetadata(NULL),
679207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mRefCount(mContext->getASTContext()) {
68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
70cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types
71cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) {
72cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (FD &&
73cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      FD->hasBody() &&
74cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      !SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr)) {
75d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines    mRefCount.Init();
764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    mRefCount.Visit(FD->getBody());
77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
78cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
79cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
80cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Disallow user-defined functions with prefix "rs"
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  if (!mAllowRSPrefix) {
84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    // Iterate all function declarations in the program.
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines         I != E; I++) {
87ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (FD == NULL)
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!FD->getName().startswith("rs"))  // Check prefix
91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        continue;
92cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines      if (!SlangRS::IsFunctionInRSHeaderFile(FD, mSourceMgr))
939207a2e495c8363606861e4f034504ec5c153dabLogan Chien        mDiagEngine.Report(
949207a2e495c8363606861e4f034504ec5c153dabLogan Chien          clang::FullSourceLoc(FD->getLocation(), mSourceMgr),
959207a2e495c8363606861e4f034504ec5c153dabLogan Chien          mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
969207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "invalid function name prefix, "
979207a2e495c8363606861e4f034504ec5c153dabLogan Chien                                      "\"rs\" is reserved: '%0'"))
989207a2e495c8363606861e4f034504ec5c153dabLogan Chien          << FD->getName();
99cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
100cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
101cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
102cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any non-static function declarations
103cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
104ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
105eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    if (FD && FD->isGlobal()) {
106eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      AnnotateFunction(FD);
107eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  }
109cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
110cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  Backend::HandleTopLevelDecl(D);
111cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  return;
112cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines}
113cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
114c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesnamespace {
115c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
11678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateVarDecl(clang::VarDecl *VD) {
11778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!VD) {
11878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    return true;
11978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  }
12078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  clang::ASTContext &C = VD->getASTContext();
122c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  const clang::Type *T = VD->getType().getTypePtr();
12378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  bool valid = true;
12478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
12578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (VD->getLinkage() == clang::ExternalLinkage) {
12678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    llvm::StringRef TypeName;
12778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    if (!RSExportType::NormalizeType(T, TypeName, &C.getDiagnostics(), VD)) {
12878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
12978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    }
130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
13178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  valid &= RSExportType::ValidateVarDecl(VD);
13278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
13378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  return valid;
134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
135c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
13678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateASTContext(clang::ASTContext &C) {
137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  bool valid = true;
138fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
140c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines          DE = TUDecl->decls_end();
141c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI != DE;
142c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines       DI++) {
143ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*DI);
14478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    if (VD && !ValidateVarDecl(VD)) {
14578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines      valid = false;
146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
148c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  return valid;
150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines}
151c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
152e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines}  // namespace
153c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
154c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
155c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
156c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
15778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines  if (!ValidateASTContext(C)) {
158c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
159c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines  }
160fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
16196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  int version = mContext->getVersion();
16296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  if (version == 0) {
16396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines    // Not setting a version is an error
1649207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(mDiagEngine.getCustomDiagID(
1659207a2e495c8363606861e4f034504ec5c153dabLogan Chien      clang::DiagnosticsEngine::Error,
1669207a2e495c8363606861e4f034504ec5c153dabLogan Chien      "Missing pragma for version in source file"));
16796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  } else if (version > 1) {
1689207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(mDiagEngine.getCustomDiagID(
1699207a2e495c8363606861e4f034504ec5c153dabLogan Chien      clang::DiagnosticsEngine::Error,
1709207a2e495c8363606861e4f034504ec5c153dabLogan Chien      "Pragma for version in source file must be set to 1"));
17196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines  }
17296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines
173688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // Create a static global destructor if necessary (to handle RS object
174688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  // runtime cleanup).
175688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
176688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  if (FD) {
177688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    HandleTopLevelDecl(clang::DeclGroupRef(FD));
178688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines  }
179688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
180cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines  // Process any static function declarations
181fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
182fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines          E = TUDecl->decls_end(); I != E; I++) {
183fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    if ((I->getKind() >= clang::Decl::firstFunction) &&
184fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        (I->getKind() <= clang::Decl::lastFunction)) {
185ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
186eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      if (FD && !FD->isGlobal()) {
187eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        AnnotateFunction(FD);
188eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines      }
189fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    }
190fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  }
191fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
192fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines  return;
193fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines}
194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
195fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines///////////////////////////////////////////////////////////////////////////////
19668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) {
197c808a99831115928b4648f4c8b86dc682594217aStephen Hines  if (!mContext->processExport()) {
198c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    return;
199c808a99831115928b4648f4c8b86dc682594217aStephen Hines  }
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
201c460b37ffb50819a32c2a8967754b6f784b28263mkopec  // Write optimization level
202c460b37ffb50819a32c2a8967754b6f784b28263mkopec  llvm::SmallVector<llvm::Value*, 1> OptimizationOption;
203c460b37ffb50819a32c2a8967754b6f784b28263mkopec  OptimizationOption.push_back(llvm::ConstantInt::get(
204c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel)));
205c460b37ffb50819a32c2a8967754b6f784b28263mkopec
206c460b37ffb50819a32c2a8967754b6f784b28263mkopec  if (mRSOptimizationMetadata == NULL)
207c460b37ffb50819a32c2a8967754b6f784b28263mkopec    mRSOptimizationMetadata = M->getOrInsertNamedMetadata(OPTIMIZATION_LEVEL_MN);
208c460b37ffb50819a32c2a8967754b6f784b28263mkopec  mRSOptimizationMetadata->addOperand(
209c460b37ffb50819a32c2a8967754b6f784b28263mkopec    llvm::MDNode::get(mLLVMContext, OptimizationOption));
210c460b37ffb50819a32c2a8967754b6f784b28263mkopec
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export variable info
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportVar()) {
213b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    int slotCount = 0;
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportVarMetadata == NULL)
21568fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang      mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
218b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
219b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // We emit slot information (#rs_object_slots) for any reference counted
220b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    // RS type or pointer (which can also be bound).
2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
2236315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_vars_end();
2246315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I != E;
2256315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr         I++) {
2266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportVar *EV = *I;
2276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportType *ET = EV->getType();
228b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      bool countsAsRSObject = false;
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Variable name
2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.push_back(
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      switch (ET->getClass()) {
236a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPrimitive: {
237b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          const RSExportPrimitiveType *PT =
238b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines              static_cast<const RSExportPrimitiveType*>(ET);
239a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
241b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines                mLLVMContext, llvm::utostr_32(PT->getType())));
242b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          if (PT->isRSObjectType()) {
243b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            countsAsRSObject = true;
244b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines          }
245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassPointer: {
248a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
249a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
251a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  ->getPointeeType()->getName()).c_str()));
252a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
253a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
254a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassMatrix: {
255a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
256a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(
257a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                mLLVMContext, llvm::utostr_32(
258a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  RSExportPrimitiveType::DataTypeRSMatrix2x2 +
259a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                  static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
260a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
261a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
262a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassVector:
263a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassConstantArray:
264a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        case RSExportType::ExportClassRecord: {
265a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          ExportVarInfo.push_back(
266a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang              llvm::MDString::get(mLLVMContext,
267a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang                EV->getType()->getName().c_str()));
268a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang          break;
269a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
270a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      }
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportVarMetadata->addOperand(
273d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportVarInfo));
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportVarInfo.clear();
275b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
276b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (mRSObjectSlotsMetadata == NULL) {
277b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        mRSObjectSlotsMetadata =
278b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines            M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
279b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
280b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
281b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      if (countsAsRSObject) {
282d27a74edb932580d224a7186731aa6be098ad02eStephen Hines        mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
283d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
284b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      }
285b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
286b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines      slotCount++;
287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export function info
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportFunc()) {
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (mExportFuncMetadata == NULL)
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata =
29468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang          M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_func_iterator
2996315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_funcs_begin(),
3006315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_funcs_end();
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
3036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      const RSExportFunc *EF = *I;
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Function name
3066315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!EF->hasParam()) {
3076315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
3086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                                     EF->getName().c_str()));
3096315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      } else {
31068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang        llvm::Function *F = M->getFunction(EF->getName());
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::Function *HelperFunction;
3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const std::string HelperFunctionName(".helper_" + EF->getName());
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3146e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(F && "Function marked as exported disappeared in Bitcode");
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Create helper function
317462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        {
3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::StructType *HelperFunctionParameterTy = NULL;
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!F->getArgumentList().empty()) {
3217c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao            std::vector<llvm::Type*> HelperFunctionParameterTys;
3220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (llvm::Function::arg_iterator AI = F->arg_begin(),
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                 AE = F->arg_end(); AI != AE; AI++)
3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTys.push_back(AI->getType());
3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            HelperFunctionParameterTy =
327a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            fprintf(stderr, "Failed to export function %s: parameter type "
3320da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                            "mismatch during creation of helper function.\n",
3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                    EF->getName().c_str());
3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3350da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            const RSExportRecordType *Expected = EF->getParamPacketType();
3360da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (Expected) {
3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Expected:\n");
3380da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              Expected->getLLVMType()->dump();
3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (HelperFunctionParameterTy) {
3410da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              fprintf(stderr, "Got:\n");
3420da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              HelperFunctionParameterTy->dump();
3430da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            }
3440da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3450da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3467c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao          std::vector<llvm::Type*> Params;
3470da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          if (HelperFunctionParameterTy) {
3480da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            llvm::PointerType *HelperFunctionParameterTyP =
3490da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                llvm::PointerType::getUnqual(HelperFunctionParameterTy);
3500da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            Params.push_back(HelperFunctionParameterTyP);
3510da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          }
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3530da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang          llvm::FunctionType * HelperFunctionType =
3540da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang              llvm::FunctionType::get(F->getReturnType(),
355a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines                                      Params,
3560da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                                      /* IsVarArgs = */false);
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction =
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Function::Create(HelperFunctionType,
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::GlobalValue::ExternalLinkage,
3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     HelperFunctionName,
36268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang                                     M);
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->addFnAttr(llvm::Attribute::NoInline);
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          HelperFunction->setCallingConv(F->getCallingConv());
3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // Create helper function body
3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          {
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Argument *HelperFunctionParameter =
3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                &(*HelperFunction->arg_begin());
3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::BasicBlock *BB =
3729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::SmallVector<llvm::Value*, 6> Params;
3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::Value *Idx[2];
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            Idx[0] =
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // getelementptr and load instruction for all elements in
3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            // parameter .p
3820da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            for (size_t i = 0; i < EF->getNumParameters(); i++) {
3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // getelementptr
3849207a2e495c8363606861e4f034504ec5c153dabLogan Chien              Idx[1] = llvm::ConstantInt::get(
3859207a2e495c8363606861e4f034504ec5c153dabLogan Chien                llvm::Type::getInt32Ty(mLLVMContext), i);
3869207a2e495c8363606861e4f034504ec5c153dabLogan Chien
3879207a2e495c8363606861e4f034504ec5c153dabLogan Chien              llvm::Value *Ptr =
3889207a2e495c8363606861e4f034504ec5c153dabLogan Chien                IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              // load
3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::Value *V = IB->CreateLoad(Ptr);
3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              Params.push_back(V);
3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
394462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
395a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            // Call and pass the all elements as parameter to F
396a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines            llvm::CallInst *CI = IB->CreateCall(F, Params);
3971ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            CI->setCallingConv(F->getCallingConv());
3991ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRetVoid();
4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            else
4039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              IB->CreateRet(CI);
404462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            delete IB;
4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
408462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        ExportFuncInfo.push_back(
4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
4119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
412462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mExportFuncMetadata->addOperand(
414d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
4159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportFuncInfo.clear();
4169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
4179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
4189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4194ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  // Dump export function info
4204ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  if (mContext->hasExportForEach()) {
4214ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    if (mExportForEachMetadata == NULL)
4224ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      mExportForEachMetadata =
4234ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
4244ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4254ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo;
4264ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4274ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    for (RSContext::const_export_foreach_iterator
4284ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            I = mContext->export_foreach_begin(),
4294ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines            E = mContext->export_foreach_end();
4304ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I != E;
4314ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines         I++) {
4324ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      const RSExportForEach *EFE = *I;
4334ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4344ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.push_back(
4354ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDString::get(mLLVMContext,
4364ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines                              llvm::utostr_32(EFE->getMetadataEncoding())));
4374ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4384ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      mExportForEachMetadata->addOperand(
4394ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines          llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
4404ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines      ExportForEachInfo.clear();
4414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines    }
4424ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
4434ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Dump export type info
4459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mContext->hasExportType()) {
4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (RSContext::const_export_type_iterator
4496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            I = mContext->export_types_begin(),
4506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            E = mContext->export_types_end();
4519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // First, dump type name list to export
4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const RSExportType *ET = I->getValue();
4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.clear();
4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Type name
4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ExportTypeInfo.push_back(
4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (ET->getClass() == RSExportType::ExportClassRecord) {
4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        const RSExportRecordType *ERT =
4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            static_cast<const RSExportRecordType*>(ET);
4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (mExportTypeMetadata == NULL)
4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mExportTypeMetadata =
46768fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang              M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mExportTypeMetadata->addOperand(
470d27a74edb932580d224a7186731aa6be098ad02eStephen Hines            llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // Now, export struct field information to %[struct name]
4739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        std::string StructInfoMetadataName("%");
4749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        StructInfoMetadataName.append(ET->getName());
4759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::NamedMDNode *StructInfoMetadata =
47668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang            M->getOrInsertNamedMetadata(StructInfoMetadataName);
4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        llvm::SmallVector<llvm::Value*, 3> FieldInfo;
4789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4796e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
4806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                    "Metadata with same name was created before");
4816315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
4826315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                FE = ERT->fields_end();
4836315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr             FI != FE;
4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             FI++) {
4859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          const RSExportRecordType::Field *F = *FI;
4869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 1. field name
4889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
4899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  F->getName().c_str()));
4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 2. field type name
4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.push_back(
4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              llvm::MDString::get(mLLVMContext,
4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                  F->getType()->getName().c_str()));
4959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          // 3. field kind
4979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          switch (F->getType()->getClass()) {
4989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassPrimitive:
4999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case RSExportType::ExportClassVector: {
5009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              const RSExportPrimitiveType *EPT =
5019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  static_cast<const RSExportPrimitiveType*>(F->getType());
5029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
5039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
5049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(EPT->getKind())));
5059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
506462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
507462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            default: {
5099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              FieldInfo.push_back(
5109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                  llvm::MDString::get(mLLVMContext,
5119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                      llvm::itostr(
5126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                                        RSExportPrimitiveType::DataKindUser)));
5139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              break;
5149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            }
5159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          }
516462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
517d27a74edb932580d224a7186731aa6be098ad02eStephen Hines          StructInfoMetadata->addOperand(
518d27a74edb932580d224a7186731aa6be098ad02eStephen Hines              llvm::MDNode::get(mLLVMContext, FieldInfo));
5199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          FieldInfo.clear();
520462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
5219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }   // ET->getClass() == RSExportType::ExportClassRecord
522462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
5239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
524462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
526462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
527462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
528462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() {
5299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return;
530462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
531e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
532e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
533