slang_rs_context.cpp revision 8f093e05e28046b6fc74175b66a06152f72e0c66
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 29999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen 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_context.h" 186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 2041ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h" 22fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni#include "clang/AST/Attr.h" 239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h" 249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclBase.h" 25be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/AST/Mangle.h" 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/Type.h" 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/Linkage.h" 29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h" 3041ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang 3123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h" 3223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DataLayout.h" 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang.h" 356e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 365e306b944425a952fe744f59d828538137a59375David Gross#include "slang_backend.h" 37593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_foreach.h" 386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_func.h" 39c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_export_reduce.h" 406315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_export_var.h" 42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_exportable.h" 436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_pragma_handler.h" 44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "slang_rs_reflection.h" 45eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala#include "slang_rs_special_func.h" 469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 47e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 499e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen HinesRSContext::RSContext(clang::Preprocessor &PP, 509e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines clang::ASTContext &Ctx, 513fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines const clang::TargetInfo &Target, 524cc67fce91f43215d61b2695746eab102a3db516Stephen Hines PragmaList *Pragmas, 53fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines unsigned int TargetAPI, 54fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines bool Verbose) 556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr : mPP(PP), 566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mCtx(Ctx), 573fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines mPragmas(Pragmas), 584a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines mTargetAPI(TargetAPI), 59fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines mVerbose(Verbose), 605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes mDataLayout(nullptr), 616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mLLVMContext(llvm::getGlobalContext()), 625abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes mLicenseNote(nullptr), 630a813a3ef2a82f19d7eab9e23ae8493197143803Stephen Hines mRSPackageName("android.renderscript"), 643fa286b4c2f110c6be2bbfac9c715bb1ec880338Shih-wei Liao version(0), 659ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines mMangleCtx(Ctx.createMangleContext()), 66fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni mIs64Bit(Target.getPointerWidth(0) == 64), 67fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni mNextSlot(1) { 684cc67fce91f43215d61b2695746eab102a3db516Stephen Hines 69109e90a854ac8d8f4df24ef27db636a641ba9913Jean-Luc Brouillet AddPragmaHandlers(PP, this); 7096ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Prepare target data 728f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar mDataLayout = new llvm::DataLayout(Target.getDataLayoutString()); 73fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni 74fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni // Reserve slot 0 for the root kernel. 75fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni mExportForEach.push_back(nullptr); 76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportVar(const clang::VarDecl *VD) { 796e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(!VD->getName().empty() && "Variable name should not be empty"); 80537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = RSExportType::CreateFromDecl(this, VD); 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!ET) 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVar *EV = new RSExportVar(this, VD, ET); 865abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (EV == nullptr) 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportVars.push_back(EV); 90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 94fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Niint RSContext::getForEachSlotNumber(const clang::FunctionDecl* FD) { 95fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni const clang::StringRef& funcName = FD->getName(); 96fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni return getForEachSlotNumber(funcName); 97fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni} 98fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni 99fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Niint RSContext::getForEachSlotNumber(const clang::StringRef& funcName) { 100fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni auto it = mExportForEachMap.find(funcName); 101fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni if (it == mExportForEachMap.end()) { 102fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni return -1; 103fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 104fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni return it->second; 105fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni} 106fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni 1076315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrbool RSContext::processExportFunc(const clang::FunctionDecl *FD) { 1086e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(!FD->getName().empty() && "Function name should not be empty"); 109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1103fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines if (!FD->isThisDeclarationADefinition()) { 1113fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines return true; 1123fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines } 113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross slangAssert(FD->getStorageClass() == clang::SC_None); 115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 116c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala // Specialized function 117eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala if (RSSpecialFunc::isSpecialRSFunc(mTargetAPI, FD)) { 1189999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines // Do not reflect specialized functions like init, dtor, or graphics root. 119eae0b7ad0195360b0afc37d51553f2917f1aa365Matt Wala return RSSpecialFunc::validateSpecialFuncDecl(mTargetAPI, this, FD); 120c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala } 121c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala 122c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala // Foreach kernel 123c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala if (RSExportForEach::isRSForEachFunc(mTargetAPI, FD)) { 124fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni RSExportForEach *EFE = RSExportForEach::Create(this, FD); 125fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni if (EFE == nullptr) { 126fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni return false; 127fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 128fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni const llvm::StringRef& funcName = FD->getName(); 129fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni if (funcName.equals("root")) { 130fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni mExportForEach[0] = EFE; 131fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } else { 1325d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines mExportForEach.push_back(EFE); 1335d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines } 134fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni return true; 1353fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines } 1363fbe68a4ec20fec25f8a40191437bbc02d00f591Stephen Hines 137c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala // Reduce kernel 138c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala if (RSExportReduce::isRSReduceFunc(mTargetAPI, FD)) { 139c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala if (auto *ER = RSExportReduce::Create(this, FD)) { 140c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala mExportReduce.push_back(ER); 141c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala return true; 142c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala } 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 144c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala } 145c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala 146c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala // Invokable 147c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala if (auto *EF = RSExportFunc::Create(this, FD)) { 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportFuncs.push_back(EF); 149c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala return true; 150c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala } 151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 152c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala return false; 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 155fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Nibool RSContext::addForEach(const clang::FunctionDecl* FD) { 156fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni const llvm::StringRef& funcName = FD->getName(); 157fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni 158fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni if (funcName.equals("root")) { 159fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni // The root kernel should always be in slot 0. 160fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni mExportForEachMap.insert(std::make_pair(funcName, 0)); 161fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } else { 162fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni mExportForEachMap.insert(std::make_pair(funcName, mNextSlot++)); 163fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 164fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni 165fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni return true; 166fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni} 167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::processExportType(const llvm::StringRef &Name) { 1699e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl(); 170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1715abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(TUDecl != nullptr && "Translation unit declaration (top-level " 1725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes "declaration) is null object"); 173f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao 1749e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines const clang::IdentifierInfo *II = mPP.getIdentifierInfo(Name); 1755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (II == nullptr) 1766315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): alert identifier @Name mark as an exportable type cannot be 1776315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // found 1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 179f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao 180c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines clang::DeclContext::lookup_result R = TUDecl->lookup(II); 1815abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSExportType *ET = nullptr; 182f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao 183c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines for (clang::DeclContext::lookup_iterator I = R.begin(), E = R.end(); 1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I != E; 1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao I++) { 1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::NamedDecl *const ND = *I; 1875abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes const clang::Type *T = nullptr; 188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (ND->getKind()) { 1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Decl::Typedef: { 1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = static_cast<const clang::TypedefDecl*>( 1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ND)->getCanonicalDecl()->getUnderlyingType().getTypePtr(); 1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Decl::Record: { 1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = static_cast<const clang::RecordDecl*>(ND)->getTypeForDecl(); 1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // unsupported, skip 2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 202ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao } 203ac91815eb4918b9307ec876f34f2b60adf28c78bShih-wei Liao } 204537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 2055abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (T != nullptr) 20613fad85b3c99a37c17d8acfec72f46b8ee64e912Stephen Hines ET = RSExportType::Create(this, T, NotLegacyKernelArgument); 2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 208462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2095abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return (ET != nullptr); 210462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 21288f21e16250d2e52a75607b7f0c396e1c2a34201Yang Nivoid RSContext::setAllocationType(const clang::TypeDecl* TD) { 21388f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni mAllocationType = mCtx.getTypeDeclType(TD); 21488f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni} 21588f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni 2162615f383dfc1542a05f19aee23b03a09bd018f4eYang Nivoid RSContext::setScriptCallType(const clang::TypeDecl* TD) { 2172615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni mScriptCallType = mCtx.getTypeDeclType(TD); 2182615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni} 2192615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni 220fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Nibool RSContext::processExports() { 221b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines bool valid = true; 222593a894650e81be54173106ec266f0311cebebd3Stephen Hines 223593a894650e81be54173106ec266f0311cebebd3Stephen Hines if (getDiagnostics()->hasErrorOccurred()) { 224593a894650e81be54173106ec266f0311cebebd3Stephen Hines return false; 225593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 226593a894650e81be54173106ec266f0311cebebd3Stephen Hines 2275d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl(); 228fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni for (auto I = TUDecl->decls_begin(), E = TUDecl->decls_end(); I != E; I++) { 229fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni clang::Decl* D = *I; 230fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni switch (D->getKind()) { 231fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni case clang::Decl::Var: { 232fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni clang::VarDecl* VD = llvm::dyn_cast<clang::VarDecl>(D); 233a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines bool ShouldExportVariable = true; 2345d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines if (VD->getFormalLinkage() == clang::ExternalLinkage) { 235a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines clang::QualType QT = VD->getTypeSourceInfo()->getType(); 236a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines if (QT.isConstQualified() && !VD->hasInit()) { 237a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines if (Slang::IsLocInRSHeaderFile(VD->getLocation(), 238a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines *getSourceManager())) { 239a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines // We don't export variables internal to the runtime's 240a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines // implementation. 241a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines ShouldExportVariable = false; 242a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines } else { 243a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines clang::DiagnosticsEngine *DiagEngine = getDiagnostics(); 244a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines DiagEngine->Report(VD->getLocation(), DiagEngine->getCustomDiagID( 245a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines clang::DiagnosticsEngine::Error, 246a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines "invalid declaration of uninitialized constant variable '%0'")) 247a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines << VD->getName(); 248a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines valid = false; 249a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines } 250a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines } 2515e306b944425a952fe744f59d828538137a59375David Gross if (valid && ShouldExportVariable && isSyntheticName(VD->getName())) 2525e306b944425a952fe744f59d828538137a59375David Gross ShouldExportVariable = false; 253a5d846df579f3d60457f664a284afe2cc2b9f8dbStephen Hines if (valid && ShouldExportVariable && !processExportVar(VD)) { 2545d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines valid = false; 2555d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines } 2565d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines } 257fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni break; 258fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 259fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni case clang::Decl::Function: { 260fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni clang::FunctionDecl* FD = llvm::dyn_cast<clang::FunctionDecl>(D); 2615d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines if (FD->getFormalLinkage() == clang::ExternalLinkage) { 2625d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines if (!processExportFunc(FD)) { 2635d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines valid = false; 2645d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines } 2655d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines } 266fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni break; 267fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni } 268fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni default: 269fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni break; 2705d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines } 2715d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines } 2725d9263d3a3a7457b9e5fe6e518c0d822dcdfcda6Stephen Hines 27315410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni // Create a dummy root in slot 0 if a root kernel is not seen 27415410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni // and there exists a non-root kernel. 275fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni if (valid && mExportForEach[0] == nullptr) { 27615410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni const size_t numExportedForEach = mExportForEach.size(); 27715410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni if (numExportedForEach > 1) { 27815410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni mExportForEach[0] = RSExportForEach::CreateDummyRoot(this); 27915410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni } else { 28015410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni slangAssert(numExportedForEach == 1); 28115410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni mExportForEach.pop_back(); 28215410146cdc2a354ade80ceb3cd134f8a792d92aYang Ni } 283c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } 284c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Finally, export type forcely set to be exported by user 2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (NeedExportTypeSet::const_iterator EI = mNeedExportTypes.begin(), 2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EE = mNeedExportTypes.end(); 2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI != EE; 2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI++) { 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!processExportType(EI->getKey())) { 291b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines valid = false; 2923f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 295b6809edd6ee8b90982425fb8ad24e867708b46fcStephen Hines return valid; 2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 297537446c9542fdda458920876ed8a020a97ddf7a4Shih-wei Liao 2985e306b944425a952fe744f59d828538137a59375David Grossbool RSContext::processReducePragmas(Backend *BE) { 2995e306b944425a952fe744f59d828538137a59375David Gross // This is needed to ensure that the dummy variable is emitted into 3005e306b944425a952fe744f59d828538137a59375David Gross // the bitcode -- which in turn forces the function to be emitted 3015e306b944425a952fe744f59d828538137a59375David Gross // into the bitcode. We couldn't do this at 3025e306b944425a952fe744f59d828538137a59375David Gross // markUsedByReducePragma() time because we had to wait until the 3035e306b944425a952fe744f59d828538137a59375David Gross // Backend is available. 3045e306b944425a952fe744f59d828538137a59375David Gross for (auto DummyVar : mUsedByReducePragmaDummyVars) 3055e306b944425a952fe744f59d828538137a59375David Gross BE->HandleTopLevelDecl(clang::DeclGroupRef(DummyVar)); 3065e306b944425a952fe744f59d828538137a59375David Gross 30765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross bool valid = true; 30865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross for (auto I = export_reduce_new_begin(), E = export_reduce_new_end(); I != E; ++I) { 30965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (! (*I)->analyzeTranslationUnit()) 31065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross valid = false; 31165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } 31265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross return valid; 31365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross} 31465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 3155e306b944425a952fe744f59d828538137a59375David Grossvoid RSContext::markUsedByReducePragma(clang::FunctionDecl *FD, CheckName Check) { 3165e306b944425a952fe744f59d828538137a59375David Gross if (mUsedByReducePragmaFns.find(FD) != mUsedByReducePragmaFns.end()) 3175e306b944425a952fe744f59d828538137a59375David Gross return; // already marked used 3185e306b944425a952fe744f59d828538137a59375David Gross 3195e306b944425a952fe744f59d828538137a59375David Gross if (Check == CheckNameYes) { 3205e306b944425a952fe744f59d828538137a59375David Gross // This is an inefficient linear search. If this turns out to be a 3215e306b944425a952fe744f59d828538137a59375David Gross // problem in practice, then processReducePragmas() could build a 3225e306b944425a952fe744f59d828538137a59375David Gross // set or hash table or something similar containing all function 3235e306b944425a952fe744f59d828538137a59375David Gross // names mentioned in a reduce pragma and searchable in O(c) or 3245e306b944425a952fe744f59d828538137a59375David Gross // O(log(n)) time rather than the currently-implemented O(n) search. 3255e306b944425a952fe744f59d828538137a59375David Gross auto NameMatches = [this, FD]() { 3265e306b944425a952fe744f59d828538137a59375David Gross for (auto I = export_reduce_new_begin(), E = export_reduce_new_end(); I != E; ++I) { 3275e306b944425a952fe744f59d828538137a59375David Gross if ((*I)->matchName(FD->getName())) 3285e306b944425a952fe744f59d828538137a59375David Gross return true; 3295e306b944425a952fe744f59d828538137a59375David Gross } 3305e306b944425a952fe744f59d828538137a59375David Gross return false; 3315e306b944425a952fe744f59d828538137a59375David Gross }; 3325e306b944425a952fe744f59d828538137a59375David Gross if (!NameMatches()) 3335e306b944425a952fe744f59d828538137a59375David Gross return; 33465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } 3355e306b944425a952fe744f59d828538137a59375David Gross 3365e306b944425a952fe744f59d828538137a59375David Gross mUsedByReducePragmaFns.insert(FD); 3375e306b944425a952fe744f59d828538137a59375David Gross 3385e306b944425a952fe744f59d828538137a59375David Gross // This is needed to prevent clang from warning that the function is 3395e306b944425a952fe744f59d828538137a59375David Gross // unused (in the case where it is only referenced by #pragma rs 3405e306b944425a952fe744f59d828538137a59375David Gross // reduce). 3415e306b944425a952fe744f59d828538137a59375David Gross FD->setIsUsed(); 3425e306b944425a952fe744f59d828538137a59375David Gross 3435e306b944425a952fe744f59d828538137a59375David Gross // Each constituent function "f" of a reduction kernel gets a dummy variable generated for it: 3445e306b944425a952fe744f59d828538137a59375David Gross // void *.rs.reduce_fn.f = (void*)&f; 3455e306b944425a952fe744f59d828538137a59375David Gross // This is a trick to ensure that clang will not delete "f" as unused. 3465e306b944425a952fe744f59d828538137a59375David Gross 3475e306b944425a952fe744f59d828538137a59375David Gross // `-VarDecl 0x87cb558 <line:3:1, col:30> col:7 var 'void *' cinit 3485e306b944425a952fe744f59d828538137a59375David Gross // `-CStyleCastExpr 0x87cb630 <col:19, col:26> 'void *' <BitCast> 3495e306b944425a952fe744f59d828538137a59375David Gross // `-ImplicitCastExpr 0x87cb618 <col:26> 'void (*)(int *, float, double)' <FunctionToPointerDecay> 3505e306b944425a952fe744f59d828538137a59375David Gross // `-DeclRefExpr 0x87cb5b8 <col:26> 'void (int *, float, double)' Function 0x8784e10 'foo' 'void (int *, float, double) 3515e306b944425a952fe744f59d828538137a59375David Gross 3525e306b944425a952fe744f59d828538137a59375David Gross const clang::QualType VoidPtrType = mCtx.getPointerType(mCtx.VoidTy); 3535e306b944425a952fe744f59d828538137a59375David Gross 3545e306b944425a952fe744f59d828538137a59375David Gross clang::DeclContext *const DC = FD->getDeclContext(); 3555e306b944425a952fe744f59d828538137a59375David Gross const clang::SourceLocation Loc = FD->getLocation(); 3565e306b944425a952fe744f59d828538137a59375David Gross 3575e306b944425a952fe744f59d828538137a59375David Gross clang::VarDecl *const VD = clang::VarDecl::Create( 3585e306b944425a952fe744f59d828538137a59375David Gross mCtx, DC, Loc, Loc, 3595e306b944425a952fe744f59d828538137a59375David Gross &mCtx.Idents.get(std::string(".rs.reduce_fn.") + FD->getNameAsString()), 3605e306b944425a952fe744f59d828538137a59375David Gross VoidPtrType, 3615e306b944425a952fe744f59d828538137a59375David Gross mCtx.getTrivialTypeSourceInfo(VoidPtrType), 3625e306b944425a952fe744f59d828538137a59375David Gross clang::SC_None); 3635e306b944425a952fe744f59d828538137a59375David Gross VD->setLexicalDeclContext(DC); 3645e306b944425a952fe744f59d828538137a59375David Gross DC->addDecl(VD); 3655e306b944425a952fe744f59d828538137a59375David Gross 3665e306b944425a952fe744f59d828538137a59375David Gross clang::DeclRefExpr *const DRE = clang::DeclRefExpr::Create(mCtx, 3675e306b944425a952fe744f59d828538137a59375David Gross clang::NestedNameSpecifierLoc(), 3685e306b944425a952fe744f59d828538137a59375David Gross Loc, 3695e306b944425a952fe744f59d828538137a59375David Gross FD, false, Loc, FD->getType(), 3705e306b944425a952fe744f59d828538137a59375David Gross clang::VK_RValue); 3715e306b944425a952fe744f59d828538137a59375David Gross clang::ImplicitCastExpr *const ICE = clang::ImplicitCastExpr::Create(mCtx, mCtx.getPointerType(FD->getType()), 3725e306b944425a952fe744f59d828538137a59375David Gross clang::CK_FunctionToPointerDecay, DRE, 3735e306b944425a952fe744f59d828538137a59375David Gross nullptr, clang::VK_RValue); 3745e306b944425a952fe744f59d828538137a59375David Gross clang::CStyleCastExpr *const CSCE = clang::CStyleCastExpr::Create(mCtx, VoidPtrType, clang::VK_RValue, clang::CK_BitCast, 3755e306b944425a952fe744f59d828538137a59375David Gross ICE, nullptr, nullptr, 3765e306b944425a952fe744f59d828538137a59375David Gross Loc, Loc); 3775e306b944425a952fe744f59d828538137a59375David Gross VD->setInit(CSCE); 3785e306b944425a952fe744f59d828538137a59375David Gross 3795e306b944425a952fe744f59d828538137a59375David Gross mUsedByReducePragmaDummyVars.push_back(VD); 38065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross} 38165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSContext::insertExportType(const llvm::StringRef &TypeName, 3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET) { 3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ExportTypeMap::value_type *NewItem = 3852eb9a3f7c48fe54eb4e813d80e3363bc79553a1eStephen Hines ExportTypeMap::value_type::Create(TypeName, 3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mExportTypes.getAllocator(), 3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET); 3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 3899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (mExportTypes.insert(NewItem)) { 3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 3923f45a25c23fa0f2cca4070f4d8713dc1a83f5ff7Matt Wala NewItem->Destroy(mExportTypes.getAllocator()); 3939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 3949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 395462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 396462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 397462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSContext::~RSContext() { 3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete mLicenseNote; 39923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines delete mDataLayout; 400a41ce1d98094da84643995d40d71c529905123fcZonr Chang for (ExportableList::iterator I = mExportables.begin(), 401a41ce1d98094da84643995d40d71c529905123fcZonr Chang E = mExportables.end(); 402a41ce1d98094da84643995d40d71c529905123fcZonr Chang I != E; 403a41ce1d98094da84643995d40d71c529905123fcZonr Chang I++) { 404641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*I)->isKeep()) 405641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang delete *I; 406a41ce1d98094da84643995d40d71c529905123fcZonr Chang } 407462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 408e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 409e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 410