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