slang_rs_export_reduce.h revision 65f23ed862e1a1e16477ba740f295ff4a83ac822
1/*
2 * Copyright 2015, 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_REDUCE_H_  // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_REDUCE_H_
19
20#include "llvm/ADT/StringRef.h"
21#include "llvm/ADT/SmallVector.h"
22
23#include "slang_rs_context.h"
24#include "slang_rs_exportable.h"
25#include "slang_rs_export_type.h"
26
27namespace clang {
28  class FunctionDecl;
29}  // namespace clang
30
31namespace slang {
32
33// Base class for reflecting control-side reduce
34class RSExportReduce : public RSExportable {
35 public:
36  typedef llvm::SmallVectorImpl<const clang::ParmVarDecl*> InVec;
37  typedef InVec::const_iterator InIter;
38
39 private:
40  // Function name
41  std::string mName;
42  // Input and output type
43  RSExportType *mType;
44  // Inputs
45  llvm::SmallVector<const clang::ParmVarDecl *, 2> mIns;
46
47  RSExportReduce(RSContext *Context, const llvm::StringRef &Name)
48    : RSExportable(Context, RSExportable::EX_REDUCE),
49      mName(Name.data(), Name.size()), mType(nullptr), mIns(2) {
50  }
51
52  RSExportReduce(const RSExportReduce &) = delete;
53  RSExportReduce &operator=(const RSExportReduce &) = delete;
54
55  // Given a reduce kernel declaration, validate the parameters to the
56  // reduce kernel.
57  bool validateAndConstructParams(RSContext *Context,
58                                  const clang::FunctionDecl *FD);
59
60 public:
61  static RSExportReduce *Create(RSContext *Context,
62                                const clang::FunctionDecl *FD);
63
64  const std::string &getName() const {
65    return mName;
66  }
67
68  const InVec &getIns() const {
69    return mIns;
70  }
71
72  const RSExportType *getType() const {
73    return mType;
74  }
75
76  static bool isRSReduceFunc(unsigned int targetAPI,
77                             const clang::FunctionDecl *FD);
78
79};  // RSExportReduce
80
81// Base class for reflecting control-side reduce
82class RSExportReduceNew : public RSExportable {
83 private:
84  // pragma location (for error reporting)
85  clang::SourceLocation mLocation;
86
87  // reduction kernel name
88  std::string mNameReduce;
89
90  // constituent function names
91  std::string mNameInitializer;
92  std::string mNameAccumulator;
93  std::string mNameCombiner;
94  std::string mNameOutConverter;
95  std::string mNameHalter;
96
97  // constituent function identity
98  enum FnIdent {
99    FN_IDENT_INITIALIZER,
100    FN_IDENT_ACCUMULATOR,
101    FN_IDENT_COMBINER,
102    FN_IDENT_OUT_CONVERTER,
103    FN_IDENT_HALTER
104  };
105  static const char *getKey(FnIdent Kind);
106
107  // signature information for accumulator function
108  unsigned int mAccumulatorSignatureMetadata;
109
110  // size of accumulator data type (compType), in bytes
111  unsigned int mAccumulatorTypeSize;
112
113  // input information for accumulator function
114  static const int kAccumulatorInsSmallSize = 4;
115  typedef llvm::SmallVectorImpl<const clang::ParmVarDecl*> InVec;
116  llvm::SmallVector<const clang::ParmVarDecl*, kAccumulatorInsSmallSize> mAccumulatorIns;
117  typedef llvm::SmallVectorImpl<const RSExportType*> InTypeVec;
118  llvm::SmallVector<const RSExportType*, kAccumulatorInsSmallSize> mAccumulatorInTypes;
119
120  // result information
121  RSExportType *mResultType;
122
123  RSExportReduceNew(RSContext *Context,
124                    const clang::SourceLocation Location,
125                    const llvm::StringRef &NameReduce,
126                    const llvm::StringRef &NameInitializer,
127                    const llvm::StringRef &NameAccumulator,
128                    const llvm::StringRef &NameCombiner,
129                    const llvm::StringRef &NameOutConverter,
130                    const llvm::StringRef &NameHalter)
131    : RSExportable(Context, RSExportable::EX_REDUCE_NEW),
132      mLocation(Location),
133      mNameReduce(NameReduce),
134      mNameInitializer(NameInitializer),
135      mNameAccumulator(NameAccumulator),
136      mNameCombiner(NameCombiner),
137      mNameOutConverter(NameOutConverter),
138      mNameHalter(NameHalter),
139      mAccumulatorSignatureMetadata(0),
140      mAccumulatorTypeSize(0),
141      mResultType(nullptr) {
142  }
143
144  RSExportReduceNew(const RSExportReduceNew &) = delete;
145  void operator=(const RSExportReduceNew &) = delete;
146
147  struct StateOfAnalyzeTranslationUnit;
148
149  static void notOk(StateOfAnalyzeTranslationUnit &S, FnIdent Kind);
150
151  static void checkPointeeConstQualified(StateOfAnalyzeTranslationUnit &S,
152                                         FnIdent Kind, const llvm::StringRef &Name,
153                                         const clang::ParmVarDecl *Param, bool ExpectedQualification);
154
155  static void checkVoidReturn(StateOfAnalyzeTranslationUnit &S, FnIdent Kind, clang::FunctionDecl *Fn);
156
157  clang::FunctionDecl *lookupFunction(StateOfAnalyzeTranslationUnit &S,
158                                      const char *Kind, const llvm::StringRef &Name);
159
160  void analyzeInitializer(StateOfAnalyzeTranslationUnit &S);
161  void analyzeAccumulator(StateOfAnalyzeTranslationUnit &S);
162  void analyzeCombiner(StateOfAnalyzeTranslationUnit &S);
163  void analyzeOutConverter(StateOfAnalyzeTranslationUnit &S);
164  void analyzeHalter(StateOfAnalyzeTranslationUnit &S);
165  void analyzeResultType(StateOfAnalyzeTranslationUnit &S);
166
167 public:
168
169  static const char KeyReduce[];
170  static const char KeyInitializer[];
171  static const char KeyAccumulator[];
172  static const char KeyCombiner[];
173  static const char KeyOutConverter[];
174  static const char KeyHalter[];
175
176  static RSExportReduceNew *Create(RSContext *Context,
177                                   const clang::SourceLocation Location,
178                                   const llvm::StringRef &NameReduce,
179                                   const llvm::StringRef &NameInitializer,
180                                   const llvm::StringRef &NameAccumulator,
181                                   const llvm::StringRef &NameCombiner,
182                                   const llvm::StringRef &NameOutConverter,
183                                   const llvm::StringRef &NameHalter);
184
185  const clang::SourceLocation &getLocation() const { return mLocation; }
186
187  const std::string &getNameReduce() const { return mNameReduce; }
188  const std::string &getNameInitializer() const { return mNameInitializer; }
189  const std::string &getNameAccumulator() const { return mNameAccumulator; }
190  const std::string &getNameCombiner() const { return mNameCombiner; }
191  const std::string &getNameOutConverter() const { return mNameOutConverter; }
192  const std::string &getNameHalter() const { return mNameHalter; }
193
194  unsigned int getAccumulatorSignatureMetadata() const { return mAccumulatorSignatureMetadata; }
195
196  unsigned int getAccumulatorTypeSize() const { return mAccumulatorTypeSize; }
197
198  const InVec &getAccumulatorIns() const { return mAccumulatorIns; }
199  const InTypeVec &getAccumulatorInTypes() const { return mAccumulatorInTypes; }
200
201  const RSExportType *getResultType() const { return mResultType; }
202
203  // Does one of this reduction's constituent function names match Candidate?
204  bool matchName(const llvm::StringRef &Candidate) const;
205
206  bool analyzeTranslationUnit();
207};  // RSExportReduceNew
208
209}  // namespace slang
210
211#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_REDUCE_H_  NOLINT
212