Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2011-2012, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  // NOLINT
     18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_
     19 
     20 #include "llvm/ADT/StringRef.h"
     21 #include "llvm/ADT/SmallVector.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 
     24 #include "clang/AST/Decl.h"
     25 
     26 #include "slang_assert.h"
     27 #include "slang_rs_context.h"
     28 #include "slang_rs_exportable.h"
     29 #include "slang_rs_export_type.h"
     30 
     31 namespace clang {
     32   class FunctionDecl;
     33 }  // namespace clang
     34 
     35 namespace slang {
     36 
     37 // Base class for reflecting control-side forEach
     38 class RSExportForEach : public RSExportable {
     39  public:
     40 
     41   typedef llvm::SmallVectorImpl<const clang::ParmVarDecl*> InVec;
     42   typedef llvm::SmallVectorImpl<const RSExportType*> InTypeVec;
     43 
     44   typedef InVec::const_iterator InIter;
     45   typedef InTypeVec::const_iterator InTypeIter;
     46 
     47  private:
     48   std::string mName;
     49 
     50   // For diagnostic purposes, we record the order in which we parse
     51   // foreach kernels.  Does not apply to a dummy root.
     52   unsigned mOrdinal;
     53 
     54   RSExportRecordType *mParamPacketType;
     55   llvm::SmallVector<const RSExportType*, 16> mInTypes;
     56   RSExportType *mOutType;
     57   size_t numParams;
     58 
     59   unsigned int mSignatureMetadata;
     60 
     61   llvm::SmallVector<const clang::ParmVarDecl*, 16> mIns;
     62   const clang::ParmVarDecl *mOut;
     63   const clang::ParmVarDecl *mUsrData;
     64 
     65   // Accumulator for metadata bits corresponding to special parameters.
     66   unsigned int mSpecialParameterSignatureMetadata;
     67 
     68   clang::QualType mResultType;  // return type (if present).
     69   bool mHasReturnType;  // does this kernel have a return type?
     70   bool mIsKernelStyle;  // is this a pass-by-value kernel?
     71 
     72   bool mDummyRoot;
     73 
     74   // TODO(all): Add support for LOD/face when we have them
     75   RSExportForEach(RSContext *Context, const llvm::StringRef &Name, clang::SourceLocation Loc)
     76     : RSExportable(Context, RSExportable::EX_FOREACH, Loc),
     77       mName(Name.data(), Name.size()), mOrdinal(~unsigned(0)),
     78       mParamPacketType(nullptr),
     79       mOutType(nullptr), numParams(0), mSignatureMetadata(0),
     80       mOut(nullptr), mUsrData(nullptr), mSpecialParameterSignatureMetadata(0),
     81       mResultType(clang::QualType()), mHasReturnType(false),
     82       mIsKernelStyle(false), mDummyRoot(false) {
     83   }
     84 
     85   bool validateAndConstructParams(RSContext *Context,
     86                                   const clang::FunctionDecl *FD);
     87 
     88   bool validateAndConstructOldStyleParams(RSContext *Context,
     89                                           const clang::FunctionDecl *FD);
     90 
     91   bool validateAndConstructKernelParams(RSContext *Context,
     92                                         const clang::FunctionDecl *FD);
     93 
     94   bool processSpecialParameters(RSContext *Context,
     95                                 const clang::FunctionDecl *FD,
     96                                 size_t *IndexOfFirstSpecialParameter);
     97 
     98   bool setSignatureMetadata(RSContext *Context,
     99                             const clang::FunctionDecl *FD);
    100  public:
    101   static RSExportForEach *Create(RSContext *Context,
    102                                  const clang::FunctionDecl *FD);
    103 
    104   static RSExportForEach *CreateDummyRoot(RSContext *Context);
    105 
    106   inline const std::string &getName() const {
    107     return mName;
    108   }
    109 
    110   inline unsigned getOrdinal() const {
    111     slangAssert(!mDummyRoot);
    112     return mOrdinal;
    113   }
    114 
    115   inline size_t getNumParameters() const {
    116     return numParams;
    117   }
    118 
    119   inline bool hasIns() const {
    120     return (!mIns.empty());
    121   }
    122 
    123   inline bool hasOut() const {
    124     return (mOut != nullptr);
    125   }
    126 
    127   inline bool hasUsrData() const {
    128     return (mUsrData != nullptr);
    129   }
    130 
    131   inline bool hasReturn() const {
    132     return mHasReturnType;
    133   }
    134 
    135   inline const InVec& getIns() const {
    136     return mIns;
    137   }
    138 
    139   inline const InTypeVec& getInTypes() const {
    140     return mInTypes;
    141   }
    142 
    143   inline const RSExportType *getOutType() const {
    144     return mOutType;
    145   }
    146 
    147   inline const RSExportRecordType *getParamPacketType() const {
    148     return mParamPacketType;
    149   }
    150 
    151   inline unsigned int getSignatureMetadata() const {
    152     return mSignatureMetadata;
    153   }
    154 
    155   inline bool isDummyRoot() const {
    156     return mDummyRoot;
    157   }
    158 
    159   // is this a pass-by-value kernel?
    160   inline bool isKernelStyle() const {
    161     return mIsKernelStyle;
    162   }
    163 
    164   typedef RSExportRecordType::const_field_iterator const_param_iterator;
    165 
    166   inline const_param_iterator params_begin() const {
    167     slangAssert((mParamPacketType != nullptr) &&
    168                 "Get parameter from export foreach having no parameter!");
    169     return mParamPacketType->fields_begin();
    170   }
    171 
    172   inline const_param_iterator params_end() const {
    173     slangAssert((mParamPacketType != nullptr) &&
    174                 "Get parameter from export foreach having no parameter!");
    175     return mParamPacketType->fields_end();
    176   }
    177   inline size_t params_count() const {
    178     return (mParamPacketType ? mParamPacketType->fields_size() : 0);
    179   }
    180 
    181   static bool isRSForEachFunc(unsigned int targetAPI,
    182                               const clang::FunctionDecl *FD);
    183 
    184   static unsigned getNumInputs(unsigned int targetAPI,
    185                               const clang::FunctionDecl *FD);
    186 };  // RSExportForEach
    187 
    188 }  // namespace slang
    189 
    190 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_  NOLINT
    191