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 llvm::SmallVectorImpl<const RSExportType*> InTypeVec;
38
39  typedef InVec::const_iterator InIter;
40  typedef InTypeVec::const_iterator InTypeIter;
41
42 private:
43  // pragma location (for error reporting)
44  clang::SourceLocation mLocation;
45
46  // reduction kernel name
47  std::string mNameReduce;
48
49  // constituent function names
50  std::string mNameInitializer;
51  std::string mNameAccumulator;
52  std::string mNameCombiner;
53  std::string mNameOutConverter;
54  std::string mNameHalter;
55
56  // constituent function identity
57  enum FnIdent {
58    FN_IDENT_INITIALIZER,
59    FN_IDENT_ACCUMULATOR,
60    FN_IDENT_COMBINER,
61    FN_IDENT_OUT_CONVERTER,
62    FN_IDENT_HALTER
63  };
64  static const char *getKey(FnIdent Kind);
65
66  // signature information for accumulator function
67  unsigned int mAccumulatorSignatureMetadata;
68
69  // size of accumulator data type (compType), in bytes
70  unsigned int mAccumulatorTypeSize;
71
72  // input information for accumulator function
73  static const int kAccumulatorInsSmallSize = 4;
74  llvm::SmallVector<const clang::ParmVarDecl*, kAccumulatorInsSmallSize> mAccumulatorIns;
75  llvm::SmallVector<const RSExportType*, kAccumulatorInsSmallSize> mAccumulatorInTypes;
76
77  // result information
78  RSExportType *mResultType;
79
80  RSExportReduce(RSContext *Context,
81                 const clang::SourceLocation Location,
82                 const llvm::StringRef &NameReduce,
83                 const llvm::StringRef &NameInitializer,
84                 const llvm::StringRef &NameAccumulator,
85                 const llvm::StringRef &NameCombiner,
86                 const llvm::StringRef &NameOutConverter,
87                 const llvm::StringRef &NameHalter)
88    : RSExportable(Context, RSExportable::EX_REDUCE),
89      mLocation(Location),
90      mNameReduce(NameReduce),
91      mNameInitializer(NameInitializer),
92      mNameAccumulator(NameAccumulator),
93      mNameCombiner(NameCombiner),
94      mNameOutConverter(NameOutConverter),
95      mNameHalter(NameHalter),
96      mAccumulatorSignatureMetadata(0),
97      mAccumulatorTypeSize(0),
98      mResultType(nullptr) {
99  }
100
101  RSExportReduce(const RSExportReduce &) = delete;
102  void operator=(const RSExportReduce &) = delete;
103
104  struct StateOfAnalyzeTranslationUnit;
105
106  static void notOk(StateOfAnalyzeTranslationUnit &S, FnIdent Kind);
107
108  static void checkPointeeConstQualified(StateOfAnalyzeTranslationUnit &S,
109                                         FnIdent Kind, const llvm::StringRef &Name,
110                                         const clang::ParmVarDecl *Param, bool ExpectedQualification);
111
112  static void checkVoidReturn(StateOfAnalyzeTranslationUnit &S, FnIdent Kind, clang::FunctionDecl *Fn);
113
114  clang::FunctionDecl *lookupFunction(StateOfAnalyzeTranslationUnit &S,
115                                      const char *Kind, const llvm::StringRef &Name);
116
117  void analyzeInitializer(StateOfAnalyzeTranslationUnit &S);
118  void analyzeAccumulator(StateOfAnalyzeTranslationUnit &S);
119  void analyzeCombiner(StateOfAnalyzeTranslationUnit &S);
120  void analyzeOutConverter(StateOfAnalyzeTranslationUnit &S);
121  void analyzeHalter(StateOfAnalyzeTranslationUnit &S);
122  void analyzeResultType(StateOfAnalyzeTranslationUnit &S);
123
124 public:
125
126  static const char KeyReduce[];
127  static const char KeyInitializer[];
128  static const char KeyAccumulator[];
129  static const char KeyCombiner[];
130  static const char KeyOutConverter[];
131  static const char KeyHalter[];
132
133  static RSExportReduce *Create(RSContext *Context,
134                                const clang::SourceLocation Location,
135                                const llvm::StringRef &NameReduce,
136                                const llvm::StringRef &NameInitializer,
137                                const llvm::StringRef &NameAccumulator,
138                                const llvm::StringRef &NameCombiner,
139                                const llvm::StringRef &NameOutConverter,
140                                const llvm::StringRef &NameHalter);
141
142  const clang::SourceLocation &getLocation() const { return mLocation; }
143
144  const std::string &getNameReduce() const { return mNameReduce; }
145  const std::string &getNameInitializer() const { return mNameInitializer; }
146  const std::string &getNameAccumulator() const { return mNameAccumulator; }
147  const std::string &getNameCombiner() const { return mNameCombiner; }
148  const std::string &getNameOutConverter() const { return mNameOutConverter; }
149  const std::string &getNameHalter() const { return mNameHalter; }
150
151  unsigned int getAccumulatorSignatureMetadata() const { return mAccumulatorSignatureMetadata; }
152
153  unsigned int getAccumulatorTypeSize() const { return mAccumulatorTypeSize; }
154
155  const InVec &getAccumulatorIns() const { return mAccumulatorIns; }
156  const InTypeVec &getAccumulatorInTypes() const { return mAccumulatorInTypes; }
157
158  const RSExportType *getResultType() const { return mResultType; }
159
160  // Does one of this reduction's constituent function names match Candidate?
161  bool matchName(const llvm::StringRef &Candidate) const;
162
163  bool analyzeTranslationUnit();
164};  // RSExportReduce
165
166}  // namespace slang
167
168#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_REDUCE_H_  NOLINT
169