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;
6018c50ebf6e87a6f51de8f21dce6282d1096e50c2David Gross
6118c50ebf6e87a6f51de8f21dce6282d1096e50c2David Gross  // Accumulator for metadata bits corresponding to special parameters.
6218c50ebf6e87a6f51de8f21dce6282d1096e50c2David Gross  unsigned int mSpecialParameterSignatureMetadata;
63b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
649ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  clang::QualType mResultType;  // return type (if present).
650f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool mHasReturnType;  // does this kernel have a return type?
660f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool mIsKernelStyle;  // is this a pass-by-value kernel?
679ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
68c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  bool mDummyRoot;
69c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
70b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  // TODO(all): Add support for LOD/face when we have them
71c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  RSExportForEach(RSContext *Context, const llvm::StringRef &Name)
72593a894650e81be54173106ec266f0311cebebd3Stephen Hines    : RSExportable(Context, RSExportable::EX_FOREACH),
735abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      mName(Name.data(), Name.size()), mParamPacketType(nullptr),
745abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes      mOutType(nullptr), numParams(0), mSignatureMetadata(0),
7518c50ebf6e87a6f51de8f21dce6282d1096e50c2David Gross      mOut(nullptr), mUsrData(nullptr), mSpecialParameterSignatureMetadata(0),
7650cab07b24f9d85899e697cac88a05cb8347fe74Narayan Kamath      mResultType(clang::QualType()), mHasReturnType(false),
770f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet      mIsKernelStyle(false), mDummyRoot(false) {
785baf6324a97430016026419deaef246ad75430fcStephen Hines  }
795baf6324a97430016026419deaef246ad75430fcStephen Hines
80b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  bool validateAndConstructParams(RSContext *Context,
81b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                                  const clang::FunctionDecl *FD);
82b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
830f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool validateAndConstructOldStyleParams(RSContext *Context,
8442f81b2b44205f421c6bd4727ce8c25b0effcb55Jean-Luc Brouillet                                          const clang::FunctionDecl *FD);
850f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet
869ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  bool validateAndConstructKernelParams(RSContext *Context,
879ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                                        const clang::FunctionDecl *FD);
889ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
899764eb3be0f2dcaaefa62fddc9fbedf14784ae38Jean-Luc Brouillet  bool processSpecialParameters(RSContext *Context,
909764eb3be0f2dcaaefa62fddc9fbedf14784ae38Jean-Luc Brouillet                                const clang::FunctionDecl *FD,
919764eb3be0f2dcaaefa62fddc9fbedf14784ae38Jean-Luc Brouillet                                size_t *IndexOfFirstSpecialParameter);
9242f81b2b44205f421c6bd4727ce8c25b0effcb55Jean-Luc Brouillet
930f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet  bool setSignatureMetadata(RSContext *Context,
940f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet                            const clang::FunctionDecl *FD);
955baf6324a97430016026419deaef246ad75430fcStephen Hines public:
96593a894650e81be54173106ec266f0311cebebd3Stephen Hines  static RSExportForEach *Create(RSContext *Context,
97593a894650e81be54173106ec266f0311cebebd3Stephen Hines                                 const clang::FunctionDecl *FD);
98593a894650e81be54173106ec266f0311cebebd3Stephen Hines
99c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  static RSExportForEach *CreateDummyRoot(RSContext *Context);
100c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
101593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline const std::string &getName() const {
102593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return mName;
103593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
104593a894650e81be54173106ec266f0311cebebd3Stephen Hines
105593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline size_t getNumParameters() const {
106593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return numParams;
107593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
108593a894650e81be54173106ec266f0311cebebd3Stephen Hines
109c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  inline bool hasIns() const {
110c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    return (!mIns.empty());
111b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
112b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
113b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline bool hasOut() const {
1145abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    return (mOut != nullptr);
115b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
116b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
117b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline bool hasUsrData() const {
1185abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    return (mUsrData != nullptr);
119b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
120b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
1219ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  inline bool hasReturn() const {
1220f2a2397df53a1bb74609abe3c27719bc7e3c328Jean-Luc Brouillet    return mHasReturnType;
1239ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines  }
1249ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
125c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  inline const InVec& getIns() const {
126c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    return mIns;
127c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  }
128c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
129c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes  inline const InTypeVec& getInTypes() const {
130c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    return mInTypes;
131b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
132b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
133b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline const RSExportType *getOutType() const {
134b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return mOutType;
135b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
136b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
137b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  inline const RSExportRecordType *getParamPacketType() const {
138b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    return mParamPacketType;
139b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines  }
140593a894650e81be54173106ec266f0311cebebd3Stephen Hines
1417b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines  inline unsigned int getSignatureMetadata() const {
1427b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines    return mSignatureMetadata;
1434ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines  }
1444ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines
145c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  inline bool isDummyRoot() const {
146c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    return mDummyRoot;
147c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines  }
148c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
149593a894650e81be54173106ec266f0311cebebd3Stephen Hines  typedef RSExportRecordType::const_field_iterator const_param_iterator;
1505baf6324a97430016026419deaef246ad75430fcStephen Hines
151593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline const_param_iterator params_begin() const {
1525abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    slangAssert((mParamPacketType != nullptr) &&
153593a894650e81be54173106ec266f0311cebebd3Stephen Hines                "Get parameter from export foreach having no parameter!");
154593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return mParamPacketType->fields_begin();
155593a894650e81be54173106ec266f0311cebebd3Stephen Hines  }
156b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
157593a894650e81be54173106ec266f0311cebebd3Stephen Hines  inline const_param_iterator params_end() const {
1585abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    slangAssert((mParamPacketType != nullptr) &&
159593a894650e81be54173106ec266f0311cebebd3Stephen Hines                "Get parameter from export foreach having no parameter!");
160593a894650e81be54173106ec266f0311cebebd3Stephen Hines    return mParamPacketType->fields_end();
1615baf6324a97430016026419deaef246ad75430fcStephen Hines  }
1625baf6324a97430016026419deaef246ad75430fcStephen Hines
163f5b882cc561f656eb650d0fa6db7bac57989ab12Matt Wala  static bool isRSForEachFunc(unsigned int targetAPI,
164089cde338148fbb75825aea4539ccdae8211ffefStephen Hines                              const clang::FunctionDecl *FD);
1651946749cebf4a64341d8210890688fef7d958c22Yang Ni
1661946749cebf4a64341d8210890688fef7d958c22Yang Ni  static unsigned getNumInputs(unsigned int targetAPI,
1671946749cebf4a64341d8210890688fef7d958c22Yang Ni                              const clang::FunctionDecl *FD);
168593a894650e81be54173106ec266f0311cebebd3Stephen Hines};  // RSExportForEach
1695baf6324a97430016026419deaef246ad75430fcStephen Hines
1705baf6324a97430016026419deaef246ad75430fcStephen Hines}  // namespace slang
1715baf6324a97430016026419deaef246ad75430fcStephen Hines
172593a894650e81be54173106ec266f0311cebebd3Stephen Hines#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  NOLINT
173