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 
27 namespace clang {
28   class FunctionDecl;
29 }  // namespace clang
30 
31 namespace slang {
32 
33 // Base class for reflecting control-side reduce
34 class 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 
RSExportReduce(RSContext * Context,const clang::SourceLocation Location,const llvm::StringRef & NameReduce,const llvm::StringRef & NameInitializer,const llvm::StringRef & NameAccumulator,const llvm::StringRef & NameCombiner,const llvm::StringRef & NameOutConverter,const llvm::StringRef & NameHalter)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, Location),
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 
getLocation()142   const clang::SourceLocation &getLocation() const { return mLocation; }
143 
getNameReduce()144   const std::string &getNameReduce() const { return mNameReduce; }
getNameInitializer()145   const std::string &getNameInitializer() const { return mNameInitializer; }
getNameAccumulator()146   const std::string &getNameAccumulator() const { return mNameAccumulator; }
getNameCombiner()147   const std::string &getNameCombiner() const { return mNameCombiner; }
getNameOutConverter()148   const std::string &getNameOutConverter() const { return mNameOutConverter; }
getNameHalter()149   const std::string &getNameHalter() const { return mNameHalter; }
150 
getAccumulatorSignatureMetadata()151   unsigned int getAccumulatorSignatureMetadata() const { return mAccumulatorSignatureMetadata; }
152 
getAccumulatorTypeSize()153   unsigned int getAccumulatorTypeSize() const { return mAccumulatorTypeSize; }
154 
getAccumulatorIns()155   const InVec &getAccumulatorIns() const { return mAccumulatorIns; }
getAccumulatorInTypes()156   const InTypeVec &getAccumulatorInTypes() const { return mAccumulatorInTypes; }
157 
getResultType()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