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 (currently for root() 38 // functions that fit appropriate criteria) 39 class RSExportForEach : public RSExportable { 40 public: 41 42 typedef llvm::SmallVectorImpl<const clang::ParmVarDecl*> InVec; 43 typedef llvm::SmallVectorImpl<const RSExportType*> InTypeVec; 44 45 typedef InVec::const_iterator InIter; 46 typedef InTypeVec::const_iterator InTypeIter; 47 48 private: 49 std::string mName; 50 RSExportRecordType *mParamPacketType; 51 llvm::SmallVector<const RSExportType*, 16> mInTypes; 52 RSExportType *mOutType; 53 size_t numParams; 54 55 unsigned int mSignatureMetadata; 56 57 llvm::SmallVector<const clang::ParmVarDecl*, 16> mIns; 58 const clang::ParmVarDecl *mOut; 59 const clang::ParmVarDecl *mUsrData; 60 const clang::ParmVarDecl *mX; 61 const clang::ParmVarDecl *mY; 62 63 clang::QualType mResultType; // return type (if present). 64 bool mHasReturnType; // does this kernel have a return type? 65 bool mIsKernelStyle; // is this a pass-by-value kernel? 66 67 bool mDummyRoot; 68 69 // TODO(all): Add support for LOD/face when we have them RSExportForEach(RSContext * Context,const llvm::StringRef & Name)70 RSExportForEach(RSContext *Context, const llvm::StringRef &Name) 71 : RSExportable(Context, RSExportable::EX_FOREACH), 72 mName(Name.data(), Name.size()), mParamPacketType(NULL), 73 mOutType(NULL), numParams(0), mSignatureMetadata(0), 74 mOut(NULL), mUsrData(NULL), mX(NULL), mY(NULL), 75 mResultType(clang::QualType()), mHasReturnType(false), 76 mIsKernelStyle(false), mDummyRoot(false) { 77 } 78 79 bool validateAndConstructParams(RSContext *Context, 80 const clang::FunctionDecl *FD); 81 82 bool validateAndConstructOldStyleParams(RSContext *Context, 83 const clang::FunctionDecl *FD); 84 85 bool validateAndConstructKernelParams(RSContext *Context, 86 const clang::FunctionDecl *FD); 87 88 bool validateIterationParameters(RSContext *Context, 89 const clang::FunctionDecl *FD, 90 size_t *IndexOfFirstIterator); 91 92 bool setSignatureMetadata(RSContext *Context, 93 const clang::FunctionDecl *FD); 94 public: 95 static RSExportForEach *Create(RSContext *Context, 96 const clang::FunctionDecl *FD); 97 98 static RSExportForEach *CreateDummyRoot(RSContext *Context); 99 getName()100 inline const std::string &getName() const { 101 return mName; 102 } 103 getNumParameters()104 inline size_t getNumParameters() const { 105 return numParams; 106 } 107 hasIns()108 inline bool hasIns() const { 109 return (!mIns.empty()); 110 } 111 hasOut()112 inline bool hasOut() const { 113 return (mOut != NULL); 114 } 115 hasUsrData()116 inline bool hasUsrData() const { 117 return (mUsrData != NULL); 118 } 119 hasReturn()120 inline bool hasReturn() const { 121 return mHasReturnType; 122 } 123 getIns()124 inline const InVec& getIns() const { 125 return mIns; 126 } 127 getInTypes()128 inline const InTypeVec& getInTypes() const { 129 return mInTypes; 130 } 131 getOutType()132 inline const RSExportType *getOutType() const { 133 return mOutType; 134 } 135 getParamPacketType()136 inline const RSExportRecordType *getParamPacketType() const { 137 return mParamPacketType; 138 } 139 getSignatureMetadata()140 inline unsigned int getSignatureMetadata() const { 141 return mSignatureMetadata; 142 } 143 isDummyRoot()144 inline bool isDummyRoot() const { 145 return mDummyRoot; 146 } 147 148 typedef RSExportRecordType::const_field_iterator const_param_iterator; 149 params_begin()150 inline const_param_iterator params_begin() const { 151 slangAssert((mParamPacketType != NULL) && 152 "Get parameter from export foreach having no parameter!"); 153 return mParamPacketType->fields_begin(); 154 } 155 params_end()156 inline const_param_iterator params_end() const { 157 slangAssert((mParamPacketType != NULL) && 158 "Get parameter from export foreach having no parameter!"); 159 return mParamPacketType->fields_end(); 160 } 161 isInitRSFunc(const clang::FunctionDecl * FD)162 inline static bool isInitRSFunc(const clang::FunctionDecl *FD) { 163 if (!FD) { 164 return false; 165 } 166 const llvm::StringRef Name = FD->getName(); 167 static llvm::StringRef FuncInit("init"); 168 return Name.equals(FuncInit); 169 } 170 isRootRSFunc(const clang::FunctionDecl * FD)171 inline static bool isRootRSFunc(const clang::FunctionDecl *FD) { 172 if (!FD) { 173 return false; 174 } 175 const llvm::StringRef Name = FD->getName(); 176 static llvm::StringRef FuncRoot("root"); 177 return Name.equals(FuncRoot); 178 } 179 isDtorRSFunc(const clang::FunctionDecl * FD)180 inline static bool isDtorRSFunc(const clang::FunctionDecl *FD) { 181 if (!FD) { 182 return false; 183 } 184 const llvm::StringRef Name = FD->getName(); 185 static llvm::StringRef FuncDtor(".rs.dtor"); 186 return Name.equals(FuncDtor); 187 } 188 189 static bool isGraphicsRootRSFunc(unsigned int targetAPI, 190 const clang::FunctionDecl *FD); 191 192 static bool isRSForEachFunc(unsigned int targetAPI, slang::RSContext *Context, 193 const clang::FunctionDecl *FD); 194 isSpecialRSFunc(unsigned int targetAPI,const clang::FunctionDecl * FD)195 inline static bool isSpecialRSFunc(unsigned int targetAPI, 196 const clang::FunctionDecl *FD) { 197 return isGraphicsRootRSFunc(targetAPI, FD) || isInitRSFunc(FD) || 198 isDtorRSFunc(FD); 199 } 200 201 static bool validateSpecialFuncDecl(unsigned int targetAPI, 202 slang::RSContext *Context, 203 const clang::FunctionDecl *FD); 204 }; // RSExportForEach 205 206 } // namespace slang 207 208 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_FOREACH_H_ NOLINT 209