slang_rs_backend.cpp revision d0b5edd02be5f09c1d8d211f4a06b031a7b66510
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 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/Twine.h" 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/StringExtras.h" 24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constant.h" 269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Constants.h" 279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/DerivedTypes.h" 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Function.h" 29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Metadata.h" 30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Module.h" 31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "llvm/Support/IRBuilder.h" 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 35592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#include "slang_rs.h" 366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h" 386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h" 40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h" 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 449ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context, 45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::Diagnostic *Diags, 469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::CodeGenOptions &CodeGenOpts, 479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TargetOptions &TargetOpts, 483fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines PragmaList *Pragmas, 499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_ostream *OS, 503a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang Slang::OutputType OT, 519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::SourceManager &SourceMgr, 526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr bool AllowRSPrefix) 536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr : Backend(Diags, 546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr CodeGenOpts, 556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr TargetOpts, 566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Pragmas, 576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr OS, 583a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang OT), 596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mContext(Context), 603a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mSourceMgr(SourceMgr), 613a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang mAllowRSPrefix(AllowRSPrefix), 626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mExportVarMetadata(NULL), 636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mExportFuncMetadata(NULL), 64b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines mExportTypeMetadata(NULL), 65d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines mRSObjectSlotsMetadata(NULL), 66d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines mRefCount(mContext->getASTContext()) { 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 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++) { 87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines clang::FunctionDecl *FD = 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)) 93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines mDiags.Report(clang::FullSourceLoc(FD->getLocation(), mSourceMgr), 94cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines mDiags.getCustomDiagID(clang::Diagnostic::Error, 95cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines "invalid function name prefix, " 96cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines "\"rs\" is reserved: '%0'")) 97cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines << FD->getName(); 98cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines } 99cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines } 100cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines 101cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines // Process any non-static function declarations 102cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) { 103eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I); 104eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines if (FD && FD->isGlobal()) { 105eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines AnnotateFunction(FD); 106eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines } 107cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines } 108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines 109cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines Backend::HandleTopLevelDecl(D); 110cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines return; 111cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines} 112cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines 113c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesnamespace { 114c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 115e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool ValidateVar(clang::VarDecl *VD, clang::Diagnostic *Diags, 116e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::SourceManager *SM) { 117c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines llvm::StringRef TypeName; 118c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines const clang::Type *T = VD->getType().getTypePtr(); 119dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (!RSExportType::NormalizeType(T, TypeName, Diags, SM, VD)) { 120c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines return false; 121c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines } 122c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines return true; 123c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines} 124c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 125c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesbool ValidateASTContext(clang::ASTContext &C, clang::Diagnostic &Diags) { 126c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines bool valid = true; 127fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 128c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(), 129c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines DE = TUDecl->decls_end(); 130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines DI != DE; 131c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines DI++) { 132c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines if (DI->getKind() == clang::Decl::Var) { 133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines clang::VarDecl *VD = (clang::VarDecl*) (*DI); 134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines if (VD->getLinkage() == clang::ExternalLinkage) { 135e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!ValidateVar(VD, &Diags, &C.getSourceManager())) { 136c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines valid = false; 137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines } 138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines } 139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines } 140c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines } 141c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 142c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines return valid; 143c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines} 144c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 145e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) { 148c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines if (!ValidateASTContext(C, mDiags)) { 151c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines return; 152c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines } 153fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines 15496ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines int version = mContext->getVersion(); 15596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (version == 0) { 15696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Not setting a version is an error 15796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error, 15896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines "Missing pragma for version in source file")); 15996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } else if (version > 1) { 16096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error, 16196ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines "Pragma for version in source file must be set to 1")); 16296ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 16396ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 164cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines // Process any static function declarations 165fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 166fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 167fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 168fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 169eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines clang::FunctionDecl *FD = dyn_cast<clang::FunctionDecl>(*I); 170eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines if (FD && !FD->isGlobal()) { 171eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines AnnotateFunction(FD); 172eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines } 173fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines } 174fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines } 175fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines 176fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines return; 177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines} 178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 179fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines/////////////////////////////////////////////////////////////////////////////// 18068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Changvoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) { 181c808a99831115928b4648f4c8b86dc682594217aStephen Hines if (!mContext->processExport()) { 182c808a99831115928b4648f4c8b86dc682594217aStephen Hines mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error, 183c808a99831115928b4648f4c8b86dc682594217aStephen Hines "elements cannot be exported")); 184c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines return; 185c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Dump export variable info 1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mContext->hasExportVar()) { 189b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines int slotCount = 0; 1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mExportVarMetadata == NULL) 19168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN); 1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::SmallVector<llvm::Value*, 2> ExportVarInfo; 194b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines llvm::SmallVector<llvm::Value*, 1> SlotVarInfo; 195b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines 196b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines // We emit slot information (#rs_object_slots) for any reference counted 197b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines // RS type or pointer (which can also be bound). 1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1996315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(), 2006315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr E = mContext->export_vars_end(); 2016315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr I != E; 2026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr I++) { 2036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const RSExportVar *EV = *I; 2046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const RSExportType *ET = EV->getType(); 205b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines bool countsAsRSObject = false; 2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Variable name 2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportVarInfo.push_back( 2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDString::get(mLLVMContext, EV->getName().c_str())); 2109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type name 212a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang switch (ET->getClass()) { 213a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case RSExportType::ExportClassPrimitive: { 214b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines const RSExportPrimitiveType *PT = 215b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines static_cast<const RSExportPrimitiveType*>(ET); 216a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ExportVarInfo.push_back( 217a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang llvm::MDString::get( 218b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines mLLVMContext, llvm::utostr_32(PT->getType()))); 219b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines if (PT->isRSObjectType()) { 220b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines countsAsRSObject = true; 221b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines } 222a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; 223a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 224a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case RSExportType::ExportClassPointer: { 225a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ExportVarInfo.push_back( 226a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang llvm::MDString::get( 2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET) 228a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ->getPointeeType()->getName()).c_str())); 229a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; 230a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case RSExportType::ExportClassMatrix: { 232a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ExportVarInfo.push_back( 233a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang llvm::MDString::get( 234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang mLLVMContext, llvm::utostr_32( 235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang RSExportPrimitiveType::DataTypeRSMatrix2x2 + 236a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang static_cast<const RSExportMatrixType*>(ET)->getDim() - 2))); 237a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; 238a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 239a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case RSExportType::ExportClassVector: 240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case RSExportType::ExportClassConstantArray: 241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case RSExportType::ExportClassRecord: { 242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ExportVarInfo.push_back( 243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang llvm::MDString::get(mLLVMContext, 244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EV->getType()->getName().c_str())); 245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; 246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportVarMetadata->addOperand( 2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDNode::get(mLLVMContext, 2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportVarInfo.data(), 2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportVarInfo.size()) ); 2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportVarInfo.clear(); 255b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines 256b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines if (mRSObjectSlotsMetadata == NULL) { 257b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines mRSObjectSlotsMetadata = 258b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN); 259b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines } 260b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines 261b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines if (countsAsRSObject) { 262b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines SlotVarInfo.push_back( 263b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))); 264b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines 265b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines mRSObjectSlotsMetadata->addOperand( 266b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines llvm::MDNode::get(mLLVMContext, 267b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines SlotVarInfo.data(), 268b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines SlotVarInfo.size())); 269b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines } 270b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines 271b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines slotCount++; 272b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines SlotVarInfo.clear(); 273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Dump export function info 2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mContext->hasExportFunc()) { 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mExportFuncMetadata == NULL) 2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportFuncMetadata = 28068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN); 2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo; 2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2846315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr for (RSContext::const_export_func_iterator 2856315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr I = mContext->export_funcs_begin(), 2866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr E = mContext->export_funcs_end(); 2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) { 2896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const RSExportFunc *EF = *I; 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Function name 2926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (!EF->hasParam()) { 2936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext, 2946315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr EF->getName().c_str())); 2956315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr } else { 29668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang llvm::Function *F = M->getFunction(EF->getName()); 2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Function *HelperFunction; 2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const std::string HelperFunctionName(".helper_" + EF->getName()); 2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3006e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(F && "Function marked as exported disappeared in Bitcode"); 3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create helper function 303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 3040da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang llvm::StructType *HelperFunctionParameterTy = NULL; 3050da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 3060da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!F->getArgumentList().empty()) { 3070da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang std::vector<const llvm::Type*> HelperFunctionParameterTys; 3080da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang for (llvm::Function::arg_iterator AI = F->arg_begin(), 3090da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang AE = F->arg_end(); AI != AE; AI++) 3100da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang HelperFunctionParameterTys.push_back(AI->getType()); 3110da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang HelperFunctionParameterTy = 3130da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys); 3140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 3160da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) { 3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang fprintf(stderr, "Failed to export function %s: parameter type " 3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang "mismatch during creation of helper function.\n", 3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang EF->getName().c_str()); 3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 3210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const RSExportRecordType *Expected = EF->getParamPacketType(); 3220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (Expected) { 3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang fprintf(stderr, "Expected:\n"); 3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Expected->getLLVMType()->dump(); 3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (HelperFunctionParameterTy) { 3270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang fprintf(stderr, "Got:\n"); 3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang HelperFunctionParameterTy->dump(); 3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type*> Params; 3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (HelperFunctionParameterTy) { 3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang llvm::PointerType *HelperFunctionParameterTyP = 3350da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang llvm::PointerType::getUnqual(HelperFunctionParameterTy); 3360da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Params.push_back(HelperFunctionParameterTyP); 3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang llvm::FunctionType * HelperFunctionType = 3400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang llvm::FunctionType::get(F->getReturnType(), 3410da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Params, 3420da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang /* IsVarArgs = */false); 3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao HelperFunction = 3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Function::Create(HelperFunctionType, 3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::GlobalValue::ExternalLinkage, 3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao HelperFunctionName, 34868fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang M); 3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao HelperFunction->addFnAttr(llvm::Attribute::NoInline); 3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao HelperFunction->setCallingConv(F->getCallingConv()); 3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create helper function body 3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao { 3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Argument *HelperFunctionParameter = 3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao &(*HelperFunction->arg_begin()); 3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::BasicBlock *BB = 3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction); 3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB); 3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::SmallVector<llvm::Value*, 6> Params; 3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Value *Idx[2]; 3629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Idx[0] = 3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0); 3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // getelementptr and load instruction for all elements in 3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // parameter .p 3680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang for (size_t i = 0; i < EF->getNumParameters(); i++) { 3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // getelementptr 3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Idx[1] = 3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::ConstantInt::get( 3729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Type::getInt32Ty(mLLVMContext), i); 3739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, 3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Idx, 3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Idx + 2); 3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // load 3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::Value *V = IB->CreateLoad(Ptr); 3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Params.push_back(V); 3809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 381462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Call and pass the all elements as paramter to F 3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::CallInst *CI = IB->CreateCall(F, 3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Params.data(), 3859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Params.data() + Params.size()); 3861ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao 3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao CI->setCallingConv(F->getCallingConv()); 3881ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao 3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) 3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao IB->CreateRetVoid(); 3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 3929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao IB->CreateRet(CI); 393462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete IB; 3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 397462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportFuncInfo.push_back( 3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str())); 4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 401462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportFuncMetadata->addOperand( 4039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDNode::get(mLLVMContext, 4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportFuncInfo.data(), 4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportFuncInfo.size())); 406462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportFuncInfo.clear(); 4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Dump export type info 4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mContext->hasExportType()) { 4139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo; 4149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr for (RSContext::const_export_type_iterator 4166315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr I = mContext->export_types_begin(), 4176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr E = mContext->export_types_end(); 4189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 4199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) { 4209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // First, dump type name list to export 4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *ET = I->getValue(); 4229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportTypeInfo.clear(); 4249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type name 4259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportTypeInfo.push_back( 4269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDString::get(mLLVMContext, ET->getName().c_str())); 4279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) { 4299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportRecordType *ERT = 4309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao static_cast<const RSExportRecordType*>(ET); 4319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mExportTypeMetadata == NULL) 4339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportTypeMetadata = 43468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN); 4359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportTypeMetadata->addOperand( 4379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDNode::get(mLLVMContext, 4389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportTypeInfo.data(), 4399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportTypeInfo.size())); 4409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Now, export struct field information to %[struct name] 4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::string StructInfoMetadataName("%"); 4439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao StructInfoMetadataName.append(ET->getName()); 4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::NamedMDNode *StructInfoMetadata = 44568fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang M->getOrInsertNamedMetadata(StructInfoMetadataName); 4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::SmallVector<llvm::Value*, 3> FieldInfo; 4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4486e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StructInfoMetadata->getNumOperands() == 0 && 4496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Metadata with same name was created before"); 4506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 4516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr FE = ERT->fields_end(); 4526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr FI != FE; 4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportRecordType::Field *F = *FI; 4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 1. field name 4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldInfo.push_back(llvm::MDString::get(mLLVMContext, 4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao F->getName().c_str())); 4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 2. field type name 4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldInfo.push_back( 4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDString::get(mLLVMContext, 4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao F->getType()->getName().c_str())); 4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 3. field kind 4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (F->getType()->getClass()) { 4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportType::ExportClassPrimitive: 4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportType::ExportClassVector: { 4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportPrimitiveType *EPT = 4709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao static_cast<const RSExportPrimitiveType*>(F->getType()); 4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldInfo.push_back( 4729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDString::get(mLLVMContext, 4739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::itostr(EPT->getKind()))); 4749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 475462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 476462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 4789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldInfo.push_back( 4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::MDString::get(mLLVMContext, 4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::itostr( 4816315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportPrimitiveType::DataKindUser))); 4829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 485462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr StructInfoMetadata->addOperand(llvm::MDNode::get(mLLVMContext, 4876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr FieldInfo.data(), 4886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr FieldInfo.size())); 489462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldInfo.clear(); 491462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } // ET->getClass() == RSExportType::ExportClassRecord 493462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 495462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 497462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 498462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 499462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() { 5009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 501462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 502e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 503e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 504