15baf6324a97430016026419deaef246ad75430fcStephen Hines/* 29999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines * Copyright 2011-2012, The Android Open Source Project 35baf6324a97430016026419deaef246ad75430fcStephen Hines * 45baf6324a97430016026419deaef246ad75430fcStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 55baf6324a97430016026419deaef246ad75430fcStephen Hines * you may not use this file except in compliance with the License. 65baf6324a97430016026419deaef246ad75430fcStephen Hines * You may obtain a copy of the License at 75baf6324a97430016026419deaef246ad75430fcStephen Hines * 85baf6324a97430016026419deaef246ad75430fcStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 95baf6324a97430016026419deaef246ad75430fcStephen Hines * 105baf6324a97430016026419deaef246ad75430fcStephen Hines * Unless required by applicable law or agreed to in writing, software 115baf6324a97430016026419deaef246ad75430fcStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 125baf6324a97430016026419deaef246ad75430fcStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135baf6324a97430016026419deaef246ad75430fcStephen Hines * See the License for the specific language governing permissions and 145baf6324a97430016026419deaef246ad75430fcStephen Hines * limitations under the License. 155baf6324a97430016026419deaef246ad75430fcStephen Hines */ 165baf6324a97430016026419deaef246ad75430fcStephen Hines 17593a894650e81be54173106ec266f0311cebebd3Stephen Hines#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_ // NOLINT 18593a894650e81be54173106ec266f0311cebebd3Stephen Hines#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_ 195baf6324a97430016026419deaef246ad75430fcStephen Hines 205baf6324a97430016026419deaef246ad75430fcStephen Hines#include "llvm/ADT/StringRef.h" 21c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes#include "llvm/ADT/SmallVector.h" 225baf6324a97430016026419deaef246ad75430fcStephen Hines#include "llvm/Support/raw_ostream.h" 235baf6324a97430016026419deaef246ad75430fcStephen Hines 245baf6324a97430016026419deaef246ad75430fcStephen Hines#include "clang/AST/Decl.h" 255baf6324a97430016026419deaef246ad75430fcStephen Hines 265baf6324a97430016026419deaef246ad75430fcStephen Hines#include "slang_assert.h" 275baf6324a97430016026419deaef246ad75430fcStephen Hines#include "slang_rs_context.h" 28593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_exportable.h" 29593a894650e81be54173106ec266f0311cebebd3Stephen Hines#include "slang_rs_export_type.h" 305baf6324a97430016026419deaef246ad75430fcStephen Hines 315baf6324a97430016026419deaef246ad75430fcStephen Hinesnamespace clang { 325baf6324a97430016026419deaef246ad75430fcStephen Hines class FunctionDecl; 335baf6324a97430016026419deaef246ad75430fcStephen Hines} // namespace clang 345baf6324a97430016026419deaef246ad75430fcStephen Hines 355baf6324a97430016026419deaef246ad75430fcStephen Hinesnamespace slang { 365baf6324a97430016026419deaef246ad75430fcStephen Hines 37593a894650e81be54173106ec266f0311cebebd3Stephen Hines// Base class for reflecting control-side forEach (currently for root() 38593a894650e81be54173106ec266f0311cebebd3Stephen Hines// functions that fit appropriate criteria) 39593a894650e81be54173106ec266f0311cebebd3Stephen Hinesclass RSExportForEach : public RSExportable { 40c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes public: 41c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes 42c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes typedef llvm::SmallVectorImpl<const clang::ParmVarDecl*> InVec; 43c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes typedef llvm::SmallVectorImpl<const RSExportType*> InTypeVec; 44c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes 45c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes typedef InVec::const_iterator InIter; 46c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes typedef InTypeVec::const_iterator InTypeIter; 47c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes 485baf6324a97430016026419deaef246ad75430fcStephen Hines private: 495baf6324a97430016026419deaef246ad75430fcStephen Hines std::string mName; 50593a894650e81be54173106ec266f0311cebebd3Stephen Hines RSExportRecordType *mParamPacketType; 51c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes llvm::SmallVector<const RSExportType*, 16> mInTypes; 52b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines RSExportType *mOutType; 53593a894650e81be54173106ec266f0311cebebd3Stephen Hines size_t numParams; 545baf6324a97430016026419deaef246ad75430fcStephen Hines 557b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines unsigned int mSignatureMetadata; 564ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 57c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes llvm::SmallVector<const clang::ParmVarDecl*, 16> mIns; 58b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::ParmVarDecl *mOut; 59b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::ParmVarDecl *mUsrData; 60b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::ParmVarDecl *mX; 61b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::ParmVarDecl *mY; 62b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 639ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines clang::QualType mResultType; // return type (if present). 640f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet bool mHasReturnType; // does this kernel have a return type? 650f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet bool mIsKernelStyle; // is this a pass-by-value kernel? 669ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines 67c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines bool mDummyRoot; 68c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 69b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines // TODO(all): Add support for LOD/face when we have them 70c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines RSExportForEach(RSContext *Context, const llvm::StringRef &Name) 71593a894650e81be54173106ec266f0311cebebd3Stephen Hines : RSExportable(Context, RSExportable::EX_FOREACH), 72c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes mName(Name.data(), Name.size()), mParamPacketType(NULL), 737b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines mOutType(NULL), numParams(0), mSignatureMetadata(0), 74c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes mOut(NULL), mUsrData(NULL), mX(NULL), mY(NULL), 7550cab07b24f9d85899e697cac88a05cb8347fe74Narayan Kamath mResultType(clang::QualType()), mHasReturnType(false), 760f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet mIsKernelStyle(false), mDummyRoot(false) { 775baf6324a97430016026419deaef246ad75430fcStephen Hines } 785baf6324a97430016026419deaef246ad75430fcStephen Hines 79b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines bool validateAndConstructParams(RSContext *Context, 80b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines const clang::FunctionDecl *FD); 81b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 820f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet bool validateAndConstructOldStyleParams(RSContext *Context, 8342f81b2b44205f421c6bd4727ce8c25b0effcb55Jean-Luc Brouillet const clang::FunctionDecl *FD); 840f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet 859ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines bool validateAndConstructKernelParams(RSContext *Context, 869ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines const clang::FunctionDecl *FD); 879ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines 8842f81b2b44205f421c6bd4727ce8c25b0effcb55Jean-Luc Brouillet bool validateIterationParameters(RSContext *Context, 8942f81b2b44205f421c6bd4727ce8c25b0effcb55Jean-Luc Brouillet const clang::FunctionDecl *FD, 9042f81b2b44205f421c6bd4727ce8c25b0effcb55Jean-Luc Brouillet size_t *IndexOfFirstIterator); 9142f81b2b44205f421c6bd4727ce8c25b0effcb55Jean-Luc Brouillet 920f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet bool setSignatureMetadata(RSContext *Context, 930f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet const clang::FunctionDecl *FD); 945baf6324a97430016026419deaef246ad75430fcStephen Hines public: 95593a894650e81be54173106ec266f0311cebebd3Stephen Hines static RSExportForEach *Create(RSContext *Context, 96593a894650e81be54173106ec266f0311cebebd3Stephen Hines const clang::FunctionDecl *FD); 97593a894650e81be54173106ec266f0311cebebd3Stephen Hines 98c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines static RSExportForEach *CreateDummyRoot(RSContext *Context); 99c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 100593a894650e81be54173106ec266f0311cebebd3Stephen Hines inline const std::string &getName() const { 101593a894650e81be54173106ec266f0311cebebd3Stephen Hines return mName; 102593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 103593a894650e81be54173106ec266f0311cebebd3Stephen Hines 104593a894650e81be54173106ec266f0311cebebd3Stephen Hines inline size_t getNumParameters() const { 105593a894650e81be54173106ec266f0311cebebd3Stephen Hines return numParams; 106593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 107593a894650e81be54173106ec266f0311cebebd3Stephen Hines 108c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes inline bool hasIns() const { 109c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes return (!mIns.empty()); 110b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 111b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 112b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines inline bool hasOut() const { 113b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return (mOut != NULL); 114b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 115b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 116b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines inline bool hasUsrData() const { 117b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return (mUsrData != NULL); 118b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 119b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 1209ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines inline bool hasReturn() const { 1210f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet return mHasReturnType; 1229ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines } 1239ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines 124c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes inline const InVec& getIns() const { 125c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes return mIns; 126c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes } 127c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes 128c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes inline const InTypeVec& getInTypes() const { 129c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes return mInTypes; 130b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 131b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 132b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines inline const RSExportType *getOutType() const { 133b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return mOutType; 134b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 135b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 136b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines inline const RSExportRecordType *getParamPacketType() const { 137b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines return mParamPacketType; 138b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines } 139593a894650e81be54173106ec266f0311cebebd3Stephen Hines 1407b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines inline unsigned int getSignatureMetadata() const { 1417b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines return mSignatureMetadata; 1424ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines } 1434ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines 144c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines inline bool isDummyRoot() const { 145c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines return mDummyRoot; 146c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines } 147c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines 148593a894650e81be54173106ec266f0311cebebd3Stephen Hines typedef RSExportRecordType::const_field_iterator const_param_iterator; 1495baf6324a97430016026419deaef246ad75430fcStephen Hines 150593a894650e81be54173106ec266f0311cebebd3Stephen Hines inline const_param_iterator params_begin() const { 151593a894650e81be54173106ec266f0311cebebd3Stephen Hines slangAssert((mParamPacketType != NULL) && 152593a894650e81be54173106ec266f0311cebebd3Stephen Hines "Get parameter from export foreach having no parameter!"); 153593a894650e81be54173106ec266f0311cebebd3Stephen Hines return mParamPacketType->fields_begin(); 154593a894650e81be54173106ec266f0311cebebd3Stephen Hines } 155b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines 156593a894650e81be54173106ec266f0311cebebd3Stephen Hines inline const_param_iterator params_end() const { 157593a894650e81be54173106ec266f0311cebebd3Stephen Hines slangAssert((mParamPacketType != NULL) && 158593a894650e81be54173106ec266f0311cebebd3Stephen Hines "Get parameter from export foreach having no parameter!"); 159593a894650e81be54173106ec266f0311cebebd3Stephen Hines return mParamPacketType->fields_end(); 1605baf6324a97430016026419deaef246ad75430fcStephen Hines } 1615baf6324a97430016026419deaef246ad75430fcStephen Hines 1625baf6324a97430016026419deaef246ad75430fcStephen Hines inline static bool isInitRSFunc(const clang::FunctionDecl *FD) { 1635baf6324a97430016026419deaef246ad75430fcStephen Hines if (!FD) { 1645baf6324a97430016026419deaef246ad75430fcStephen Hines return false; 1655baf6324a97430016026419deaef246ad75430fcStephen Hines } 1665baf6324a97430016026419deaef246ad75430fcStephen Hines const llvm::StringRef Name = FD->getName(); 1675baf6324a97430016026419deaef246ad75430fcStephen Hines static llvm::StringRef FuncInit("init"); 1685baf6324a97430016026419deaef246ad75430fcStephen Hines return Name.equals(FuncInit); 1695baf6324a97430016026419deaef246ad75430fcStephen Hines } 1705baf6324a97430016026419deaef246ad75430fcStephen Hines 1715baf6324a97430016026419deaef246ad75430fcStephen Hines inline static bool isRootRSFunc(const clang::FunctionDecl *FD) { 1725baf6324a97430016026419deaef246ad75430fcStephen Hines if (!FD) { 1735baf6324a97430016026419deaef246ad75430fcStephen Hines return false; 1745baf6324a97430016026419deaef246ad75430fcStephen Hines } 1755baf6324a97430016026419deaef246ad75430fcStephen Hines const llvm::StringRef Name = FD->getName(); 1765baf6324a97430016026419deaef246ad75430fcStephen Hines static llvm::StringRef FuncRoot("root"); 1775baf6324a97430016026419deaef246ad75430fcStephen Hines return Name.equals(FuncRoot); 1785baf6324a97430016026419deaef246ad75430fcStephen Hines } 1795baf6324a97430016026419deaef246ad75430fcStephen Hines 180688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines inline static bool isDtorRSFunc(const clang::FunctionDecl *FD) { 181688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (!FD) { 182688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines return false; 183688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 184688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines const llvm::StringRef Name = FD->getName(); 185688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines static llvm::StringRef FuncDtor(".rs.dtor"); 186688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines return Name.equals(FuncDtor); 187688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 188688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 189c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes static bool isGraphicsRootRSFunc(unsigned int targetAPI, 1909999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines const clang::FunctionDecl *FD); 1919999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines 192c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes static bool isRSForEachFunc(unsigned int targetAPI, slang::RSContext *Context, 193089cde338148fbb75825aea4539ccdae8211ffefStephen Hines const clang::FunctionDecl *FD); 194593a894650e81be54173106ec266f0311cebebd3Stephen Hines 195c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes inline static bool isSpecialRSFunc(unsigned int targetAPI, 1969999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines const clang::FunctionDecl *FD) { 1979999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines return isGraphicsRootRSFunc(targetAPI, FD) || isInitRSFunc(FD) || 1989999ec3aa0c4d7a6befd3a300dc07f0cea91cb6cStephen Hines isDtorRSFunc(FD); 1995baf6324a97430016026419deaef246ad75430fcStephen Hines } 2005baf6324a97430016026419deaef246ad75430fcStephen Hines 201c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes static bool validateSpecialFuncDecl(unsigned int targetAPI, 202d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet slang::RSContext *Context, 2035baf6324a97430016026419deaef246ad75430fcStephen Hines const clang::FunctionDecl *FD); 204593a894650e81be54173106ec266f0311cebebd3Stephen Hines}; // RSExportForEach 2055baf6324a97430016026419deaef246ad75430fcStephen Hines 2065baf6324a97430016026419deaef246ad75430fcStephen Hines} // namespace slang 2075baf6324a97430016026419deaef246ad75430fcStephen Hines 208593a894650e81be54173106ec266f0311cebebd3Stephen Hines#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_ NOLINT 209