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 placeholder 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 RSExportForEach(RSContext * Context,const llvm::StringRef & Name,clang::SourceLocation Loc)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 getName()106 inline const std::string &getName() const { 107 return mName; 108 } 109 getOrdinal()110 inline unsigned getOrdinal() const { 111 slangAssert(!mDummyRoot); 112 return mOrdinal; 113 } 114 getNumParameters()115 inline size_t getNumParameters() const { 116 return numParams; 117 } 118 hasIns()119 inline bool hasIns() const { 120 return (!mIns.empty()); 121 } 122 hasOut()123 inline bool hasOut() const { 124 return (mOut != nullptr); 125 } 126 hasUsrData()127 inline bool hasUsrData() const { 128 return (mUsrData != nullptr); 129 } 130 hasReturn()131 inline bool hasReturn() const { 132 return mHasReturnType; 133 } 134 getIns()135 inline const InVec& getIns() const { 136 return mIns; 137 } 138 getInTypes()139 inline const InTypeVec& getInTypes() const { 140 return mInTypes; 141 } 142 getOutType()143 inline const RSExportType *getOutType() const { 144 return mOutType; 145 } 146 getParamPacketType()147 inline const RSExportRecordType *getParamPacketType() const { 148 return mParamPacketType; 149 } 150 getSignatureMetadata()151 inline unsigned int getSignatureMetadata() const { 152 return mSignatureMetadata; 153 } 154 isDummyRoot()155 inline bool isDummyRoot() const { 156 return mDummyRoot; 157 } 158 159 // is this a pass-by-value kernel? isKernelStyle()160 inline bool isKernelStyle() const { 161 return mIsKernelStyle; 162 } 163 164 typedef RSExportRecordType::const_field_iterator const_param_iterator; 165 params_begin()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 params_end()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 } params_count()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