slang_rs_backend.cpp revision d460f623328e2b4ebd05bb93910edb471e6e91d6
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 27b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines * Copyright 2010-2012, 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 2243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "clang/AST/ASTContext.h" 23c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "clang/Frontend/CodeGenOptions.h" 24c460b37ffb50819a32c2a8967754b6f784b28263mkopec 25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/Twine.h" 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/StringExtras.h" 27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Constant.h" 2923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Constants.h" 3023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DerivedTypes.h" 3123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Function.h" 3223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/IRBuilder.h" 3323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Metadata.h" 3423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Module.h" 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 36c460b37ffb50819a32c2a8967754b6f784b28263mkopec#include "llvm/Support/DebugLoc.h" 376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 386e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 39592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang#include "slang_rs.h" 406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 414ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines#include "slang_rs_export_foreach.h" 426315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h" 436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h" 45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_metadata.h" 46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 47e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 499ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSBackend::RSBackend(RSContext *Context, 509207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::CodeGenOptions &CodeGenOpts, 529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TargetOptions &TargetOpts, 533fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines PragmaList *Pragmas, 549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::raw_ostream *OS, 553a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang Slang::OutputType OT, 569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::SourceManager &SourceMgr, 5711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool AllowRSPrefix, 5811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) 599207a2e495c8363606861e4f034504ec5c153dabLogan Chien : Backend(DiagEngine, CodeGenOpts, TargetOpts, Pragmas, OS, OT), 609207a2e495c8363606861e4f034504ec5c153dabLogan Chien mContext(Context), 619207a2e495c8363606861e4f034504ec5c153dabLogan Chien mSourceMgr(SourceMgr), 629207a2e495c8363606861e4f034504ec5c153dabLogan Chien mAllowRSPrefix(AllowRSPrefix), 6311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mIsFilterscript(IsFilterscript), 649207a2e495c8363606861e4f034504ec5c153dabLogan Chien mExportVarMetadata(NULL), 659207a2e495c8363606861e4f034504ec5c153dabLogan Chien mExportFuncMetadata(NULL), 667b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines mExportForEachNameMetadata(NULL), 677b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines mExportForEachSignatureMetadata(NULL), 689207a2e495c8363606861e4f034504ec5c153dabLogan Chien mExportTypeMetadata(NULL), 699207a2e495c8363606861e4f034504ec5c153dabLogan Chien mRSObjectSlotsMetadata(NULL), 7011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mRefCount(mContext->getASTContext()), 7111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mASTChecker(mContext->getASTContext(), mContext->getTargetAPI(), 7211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines IsFilterscript) { 73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines// 1) Add zero initialization of local RS object types 76cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesvoid RSBackend::AnnotateFunction(clang::FunctionDecl *FD) { 77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines if (FD && 78cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines FD->hasBody() && 7911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines !SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) { 80d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines mRefCount.Init(); 814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mRefCount.Visit(FD->getBody()); 82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines } 83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines return; 84cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines} 85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines 86fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chienbool RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) { 87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines // Disallow user-defined functions with prefix "rs" 88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines if (!mAllowRSPrefix) { 89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines // Iterate all function declarations in the program. 90cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); 91cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines I != E; I++) { 92ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 93cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines if (FD == NULL) 94cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines continue; 95cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines if (!FD->getName().startswith("rs")) // Check prefix 96cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines continue; 9711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!SlangRS::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) 989207a2e495c8363606861e4f034504ec5c153dabLogan Chien mDiagEngine.Report( 999207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(FD->getLocation(), mSourceMgr), 1009207a2e495c8363606861e4f034504ec5c153dabLogan Chien mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, 1019207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid function name prefix, " 1029207a2e495c8363606861e4f034504ec5c153dabLogan Chien "\"rs\" is reserved: '%0'")) 1039207a2e495c8363606861e4f034504ec5c153dabLogan Chien << FD->getName(); 104cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines } 105cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines } 106cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines 107cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines // Process any non-static function declarations 108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) { 109ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 110eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines if (FD && FD->isGlobal()) { 111ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines // Check that we don't have any array parameters being misintrepeted as 112ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines // kernel pointers due to the C type system's array to pointer decay. 113ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines size_t numParams = FD->getNumParams(); 114ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines for (size_t i = 0; i < numParams; i++) { 115ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(i); 116ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines clang::QualType QT = PVD->getOriginalType(); 117ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines if (QT->isArrayType()) { 118ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines mDiagEngine.Report( 119ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines clang::FullSourceLoc(PVD->getTypeSpecStartLoc(), mSourceMgr), 120ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, 121ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines "exported function parameters may " 122ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines "not have array type: %0")) << QT; 123ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines } 124ab5a535b290d898d0c56036f642d823e3472a804Stephen Hines } 125eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines AnnotateFunction(FD); 126eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines } 127cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines } 128cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines 129fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien return Backend::HandleTopLevelDecl(D); 130cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines} 131cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines 132c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesvoid RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) { 134c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 135c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines 13611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // If we have an invalid RS/FS AST, don't check further. 13711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!mASTChecker.Validate()) { 138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines return; 139c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines } 140fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines 14111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (mIsFilterscript) { 14211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines mContext->addPragma("rs_fp_relaxed", ""); 14311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 14411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 14596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines int version = mContext->getVersion(); 14696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines if (version == 0) { 14796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines // Not setting a version is an error 1487aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines mDiagEngine.Report( 1497aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()), 1507aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines mDiagEngine.getCustomDiagID( 1517aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines clang::DiagnosticsEngine::Error, 1527aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines "missing pragma for version in source file")); 1537aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines } else { 1547aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines slangAssert(version == 1); 15596ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines } 15696ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 157cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines if (mContext->getReflectJavaPackageName().empty()) { 158cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines mDiagEngine.Report( 159cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()), 160cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, 161cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines "missing \"#pragma rs " 162cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines "java_package_name(com.foo.bar)\" " 163cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines "in source file")); 164cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines return; 165cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines } 166cf9a73a4140402c0e9e4fbab27477f22cc7d8e3cStephen Hines 167688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Create a static global destructor if necessary (to handle RS object 168688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // runtime cleanup). 169688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor(); 170688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (FD) { 171688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines HandleTopLevelDecl(clang::DeclGroupRef(FD)); 172688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 173688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 174cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines // Process any static function declarations 175fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 176fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 178fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 179ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I); 180eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines if (FD && !FD->isGlobal()) { 181eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines AnnotateFunction(FD); 182eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines } 183fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines } 184fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines } 185fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines 186fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines return; 187fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines} 188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 189fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines/////////////////////////////////////////////////////////////////////////////// 190d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportVarInfo(llvm::Module *M) { 191d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser int slotCount = 0; 192d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mExportVarMetadata == NULL) 193d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN); 194d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 195d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 2> ExportVarInfo; 196d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 197d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // We emit slot information (#rs_object_slots) for any reference counted 198d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // RS type or pointer (which can also be bound). 199d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 200d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(), 201d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser E = mContext->export_vars_end(); 202d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I != E; 203d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I++) { 204d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportVar *EV = *I; 205d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportType *ET = EV->getType(); 206d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser bool countsAsRSObject = false; 207d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 208d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Variable name 209d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportVarInfo.push_back( 210d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, EV->getName().c_str())); 211d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 212d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Type name 213d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser switch (ET->getClass()) { 214d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser case RSExportType::ExportClassPrimitive: { 215d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportPrimitiveType *PT = 216d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser static_cast<const RSExportPrimitiveType*>(ET); 217d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportVarInfo.push_back( 218d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get( 219d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mLLVMContext, llvm::utostr_32(PT->getType()))); 220d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (PT->isRSObjectType()) { 221d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser countsAsRSObject = true; 222a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 223d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser break; 224a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 225d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser case RSExportType::ExportClassPointer: { 226d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportVarInfo.push_back( 227d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get( 228d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET) 229d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ->getPointeeType()->getName()).c_str())); 230d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser break; 231b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines } 232d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser case RSExportType::ExportClassMatrix: { 233d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportVarInfo.push_back( 234d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get( 235d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mLLVMContext, llvm::utostr_32( 236d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser RSExportPrimitiveType::DataTypeRSMatrix2x2 + 237d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser static_cast<const RSExportMatrixType*>(ET)->getDim() - 2))); 238d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser break; 239b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines } 240d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser case RSExportType::ExportClassVector: 241d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser case RSExportType::ExportClassConstantArray: 242d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser case RSExportType::ExportClassRecord: { 243d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportVarInfo.push_back( 244d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, 245d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser EV->getType()->getName().c_str())); 246d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser break; 247d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 248d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 249d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 250d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportVarMetadata->addOperand( 251d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDNode::get(mLLVMContext, ExportVarInfo)); 252d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportVarInfo.clear(); 253b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines 254d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mRSObjectSlotsMetadata == NULL) { 255d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mRSObjectSlotsMetadata = 256d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN); 257462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 259d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (countsAsRSObject) { 260d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext, 261d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount)))); 262d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 2630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 264d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser slotCount++; 265d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 266d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser} 2670da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 268d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportFunctionInfo(llvm::Module *M) { 269d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mExportFuncMetadata == NULL) 270d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportFuncMetadata = 271d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN); 272d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 273d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo; 274d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 275d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser for (RSContext::const_export_func_iterator 276d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I = mContext->export_funcs_begin(), 277d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser E = mContext->export_funcs_end(); 278d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I != E; 279d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I++) { 280d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportFunc *EF = *I; 281d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 282d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Function name 283d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (!EF->hasParam()) { 284d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext, 285d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser EF->getName().c_str())); 286d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } else { 287d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Function *F = M->getFunction(EF->getName()); 288d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Function *HelperFunction; 289d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const std::string HelperFunctionName(".helper_" + EF->getName()); 290d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 291d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser slangAssert(F && "Function marked as exported disappeared in Bitcode"); 292d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 293d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Create helper function 294d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser { 295d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::StructType *HelperFunctionParameterTy = NULL; 296d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 297d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (!F->getArgumentList().empty()) { 298d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser std::vector<llvm::Type*> HelperFunctionParameterTys; 299d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser for (llvm::Function::arg_iterator AI = F->arg_begin(), 300d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser AE = F->arg_end(); AI != AE; AI++) 301d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser HelperFunctionParameterTys.push_back(AI->getType()); 302d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 303d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser HelperFunctionParameterTy = 304d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys); 305d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 3060da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 307d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) { 308d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser fprintf(stderr, "Failed to export function %s: parameter type " 309d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser "mismatch during creation of helper function.\n", 310d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser EF->getName().c_str()); 3110da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 312d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportRecordType *Expected = EF->getParamPacketType(); 313d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (Expected) { 314d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser fprintf(stderr, "Expected:\n"); 315d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser Expected->getLLVMType()->dump(); 316d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (HelperFunctionParameterTy) { 318d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser fprintf(stderr, "Got:\n"); 319d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser HelperFunctionParameterTy->dump(); 3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 321d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 323d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser std::vector<llvm::Type*> Params; 324d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (HelperFunctionParameterTy) { 325d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::PointerType *HelperFunctionParameterTyP = 326d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::PointerType::getUnqual(HelperFunctionParameterTy); 327d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser Params.push_back(HelperFunctionParameterTyP); 3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 329462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 330d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::FunctionType * HelperFunctionType = 331d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::FunctionType::get(F->getReturnType(), 332d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser Params, 333d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser /* IsVarArgs = */false); 334d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 335d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser HelperFunction = 336d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Function::Create(HelperFunctionType, 337d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::GlobalValue::ExternalLinkage, 338d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser HelperFunctionName, 339d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser M); 340d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 341d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser HelperFunction->addFnAttr(llvm::Attribute::NoInline); 342d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser HelperFunction->setCallingConv(F->getCallingConv()); 343d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 344d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Create helper function body 345d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser { 346d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Argument *HelperFunctionParameter = 347d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser &(*HelperFunction->arg_begin()); 348d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::BasicBlock *BB = 349d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction); 350d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB); 351d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 6> Params; 352d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Value *Idx[2]; 353d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 354d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser Idx[0] = 355d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0); 356d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 357d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // getelementptr and load instruction for all elements in 358d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // parameter .p 359d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser for (size_t i = 0; i < EF->getNumParameters(); i++) { 360d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // getelementptr 361d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser Idx[1] = llvm::ConstantInt::get( 362d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Type::getInt32Ty(mLLVMContext), i); 363d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 364d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Value *Ptr = 365d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser IB->CreateInBoundsGEP(HelperFunctionParameter, Idx); 366d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 367d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // load 368d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::Value *V = IB->CreateLoad(Ptr); 369d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser Params.push_back(V); 370d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 371d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 372d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Call and pass the all elements as parameter to F 373d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::CallInst *CI = IB->CreateCall(F, Params); 374d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 375d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser CI->setCallingConv(F->getCallingConv()); 376d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 377d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) 378d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser IB->CreateRetVoid(); 379d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser else 380d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser IB->CreateRet(CI); 381d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 382d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser delete IB; 383d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 385462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 386d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportFuncInfo.push_back( 387d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str())); 3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 389d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 390d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportFuncMetadata->addOperand( 391d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDNode::get(mLLVMContext, ExportFuncInfo)); 392d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportFuncInfo.clear(); 3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 394d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser} 3959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 396d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportForEachInfo(llvm::Module *M) { 397d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mExportForEachNameMetadata == NULL) { 398d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportForEachNameMetadata = 399d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN); 400d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 401d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mExportForEachSignatureMetadata == NULL) { 402d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportForEachSignatureMetadata = 403d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN); 404d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 4054ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 406d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 1> ExportForEachName; 407d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo; 4084ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 409d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser for (RSContext::const_export_foreach_iterator 410d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I = mContext->export_foreach_begin(), 411d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser E = mContext->export_foreach_end(); 412d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I != E; 413d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I++) { 414d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportForEach *EFE = *I; 4154ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 416d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportForEachName.push_back( 417d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, EFE->getName().c_str())); 4187b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines 419d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportForEachNameMetadata->addOperand( 420d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDNode::get(mLLVMContext, ExportForEachName)); 421d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportForEachName.clear(); 4227b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines 423d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportForEachInfo.push_back( 424d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, 425d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::utostr_32(EFE->getSignatureMetadata()))); 4264ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 427d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportForEachSignatureMetadata->addOperand( 428d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDNode::get(mLLVMContext, ExportForEachInfo)); 429d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportForEachInfo.clear(); 4304ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 431d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser} 4324ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 433d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::dumpExportTypeInfo(llvm::Module *M) { 434d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo; 435d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 436d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser for (RSContext::const_export_type_iterator 437d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I = mContext->export_types_begin(), 438d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser E = mContext->export_types_end(); 439d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I != E; 440d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser I++) { 441d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // First, dump type name list to export 442d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportType *ET = I->getValue(); 443d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 444d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportTypeInfo.clear(); 445d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Type name 446d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser ExportTypeInfo.push_back( 447d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, ET->getName().c_str())); 448d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 449d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (ET->getClass() == RSExportType::ExportClassRecord) { 450d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportRecordType *ERT = 451d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser static_cast<const RSExportRecordType*>(ET); 452d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 453d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mExportTypeMetadata == NULL) 454d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportTypeMetadata = 455d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN); 456d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 457d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mExportTypeMetadata->addOperand( 458d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDNode::get(mLLVMContext, ExportTypeInfo)); 459d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 460d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Now, export struct field information to %[struct name] 461d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser std::string StructInfoMetadataName("%"); 462d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser StructInfoMetadataName.append(ET->getName()); 463d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::NamedMDNode *StructInfoMetadata = 464d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser M->getOrInsertNamedMetadata(StructInfoMetadataName); 465d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 3> FieldInfo; 466d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 467d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser slangAssert(StructInfoMetadata->getNumOperands() == 0 && 468d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser "Metadata with same name was created before"); 469d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 470d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser FE = ERT->fields_end(); 471d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser FI != FE; 472d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser FI++) { 473d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser const RSExportRecordType::Field *F = *FI; 474d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 475d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // 1. field name 476d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser FieldInfo.push_back(llvm::MDString::get(mLLVMContext, 477d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser F->getName().c_str())); 478d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 479d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // 2. field type name 480d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser FieldInfo.push_back( 481d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDString::get(mLLVMContext, 482d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser F->getType()->getName().c_str())); 483d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 484d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser StructInfoMetadata->addOperand( 485d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::MDNode::get(mLLVMContext, FieldInfo)); 486d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser FieldInfo.clear(); 487d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 488d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } // ET->getClass() == RSExportType::ExportClassRecord 489d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser } 490d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser} 491d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 492d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosservoid RSBackend::HandleTranslationUnitPost(llvm::Module *M) { 493d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (!mContext->processExport()) { 494d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser return; 4959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 496462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 497d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser // Write optimization level 498d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser llvm::SmallVector<llvm::Value*, 1> OptimizationOption; 499d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser OptimizationOption.push_back(llvm::ConstantInt::get( 500d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel))); 501d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 502d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mContext->hasExportVar()) 503d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser dumpExportVarInfo(M); 504d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 505d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mContext->hasExportFunc()) 506d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser dumpExportFunctionInfo(M); 507d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 508d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mContext->hasExportForEach()) 509d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser dumpExportForEachInfo(M); 510d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 511d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser if (mContext->hasExportType()) 512d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser dumpExportTypeInfo(M); 513d460f623328e2b4ebd05bb93910edb471e6e91d6Tobias Grosser 5149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 515462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 516462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 517462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSBackend::~RSBackend() { 5189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 519462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 520e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 521e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 522