1c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala/*
2c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * Copyright 2015, The Android Open Source Project
3c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala *
4c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * Licensed under the Apache License, Version 2.0 (the "License");
5c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * you may not use this file except in compliance with the License.
6c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * You may obtain a copy of the License at
7c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala *
8c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala *     http://www.apache.org/licenses/LICENSE-2.0
9c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala *
10c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * Unless required by applicable law or agreed to in writing, software
11c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * distributed under the License is distributed on an "AS IS" BASIS,
12c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * See the License for the specific language governing permissions and
14c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala * limitations under the License.
15c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala */
16c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
17c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_REDUCE_H_  // NOLINT
18c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_REDUCE_H_
19c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
20c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "llvm/ADT/StringRef.h"
21c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "llvm/ADT/SmallVector.h"
22c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
23c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_context.h"
24c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_exportable.h"
25c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_export_type.h"
26c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
27c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Walanamespace clang {
28c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  class FunctionDecl;
29c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala}  // namespace clang
30c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
31c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Walanamespace slang {
32c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
33c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala// Base class for reflecting control-side reduce
34c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Walaclass RSExportReduce : public RSExportable {
35c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala public:
36c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  typedef llvm::SmallVectorImpl<const clang::ParmVarDecl*> InVec;
37277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  typedef llvm::SmallVectorImpl<const RSExportType*> InTypeVec;
38277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
39277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  typedef InVec::const_iterator InIter;
40277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross  typedef InTypeVec::const_iterator InTypeIter;
41277fd5e6545c8ba1272027ee6e6bc55a96316dc0David Gross
4215e44e66adc350adb4fe0533a442092c64333ab5David Gross private:
4315e44e66adc350adb4fe0533a442092c64333ab5David Gross  // pragma location (for error reporting)
4415e44e66adc350adb4fe0533a442092c64333ab5David Gross  clang::SourceLocation mLocation;
4515e44e66adc350adb4fe0533a442092c64333ab5David Gross
4615e44e66adc350adb4fe0533a442092c64333ab5David Gross  // reduction kernel name
4715e44e66adc350adb4fe0533a442092c64333ab5David Gross  std::string mNameReduce;
4815e44e66adc350adb4fe0533a442092c64333ab5David Gross
4915e44e66adc350adb4fe0533a442092c64333ab5David Gross  // constituent function names
5015e44e66adc350adb4fe0533a442092c64333ab5David Gross  std::string mNameInitializer;
5115e44e66adc350adb4fe0533a442092c64333ab5David Gross  std::string mNameAccumulator;
5215e44e66adc350adb4fe0533a442092c64333ab5David Gross  std::string mNameCombiner;
5315e44e66adc350adb4fe0533a442092c64333ab5David Gross  std::string mNameOutConverter;
5415e44e66adc350adb4fe0533a442092c64333ab5David Gross  std::string mNameHalter;
5515e44e66adc350adb4fe0533a442092c64333ab5David Gross
5665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  // constituent function identity
5765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  enum FnIdent {
5865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    FN_IDENT_INITIALIZER,
5965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    FN_IDENT_ACCUMULATOR,
6065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    FN_IDENT_COMBINER,
6165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    FN_IDENT_OUT_CONVERTER,
6265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    FN_IDENT_HALTER
6365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  };
6465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const char *getKey(FnIdent Kind);
6565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
6665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  // signature information for accumulator function
6765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  unsigned int mAccumulatorSignatureMetadata;
6865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
6965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  // size of accumulator data type (compType), in bytes
7065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  unsigned int mAccumulatorTypeSize;
7165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
7265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  // input information for accumulator function
7365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const int kAccumulatorInsSmallSize = 4;
7465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  llvm::SmallVector<const clang::ParmVarDecl*, kAccumulatorInsSmallSize> mAccumulatorIns;
7565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  llvm::SmallVector<const RSExportType*, kAccumulatorInsSmallSize> mAccumulatorInTypes;
7665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
7765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  // result information
7865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  RSExportType *mResultType;
7965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
808ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  RSExportReduce(RSContext *Context,
818ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                 const clang::SourceLocation Location,
828ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                 const llvm::StringRef &NameReduce,
838ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                 const llvm::StringRef &NameInitializer,
848ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                 const llvm::StringRef &NameAccumulator,
858ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                 const llvm::StringRef &NameCombiner,
868ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                 const llvm::StringRef &NameOutConverter,
878ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                 const llvm::StringRef &NameHalter)
888ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    : RSExportable(Context, RSExportable::EX_REDUCE),
8915e44e66adc350adb4fe0533a442092c64333ab5David Gross      mLocation(Location),
9015e44e66adc350adb4fe0533a442092c64333ab5David Gross      mNameReduce(NameReduce),
9115e44e66adc350adb4fe0533a442092c64333ab5David Gross      mNameInitializer(NameInitializer),
9215e44e66adc350adb4fe0533a442092c64333ab5David Gross      mNameAccumulator(NameAccumulator),
9315e44e66adc350adb4fe0533a442092c64333ab5David Gross      mNameCombiner(NameCombiner),
9415e44e66adc350adb4fe0533a442092c64333ab5David Gross      mNameOutConverter(NameOutConverter),
9565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross      mNameHalter(NameHalter),
9665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross      mAccumulatorSignatureMetadata(0),
9765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross      mAccumulatorTypeSize(0),
9865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross      mResultType(nullptr) {
9915e44e66adc350adb4fe0533a442092c64333ab5David Gross  }
10015e44e66adc350adb4fe0533a442092c64333ab5David Gross
1018ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  RSExportReduce(const RSExportReduce &) = delete;
1028ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  void operator=(const RSExportReduce &) = delete;
10315e44e66adc350adb4fe0533a442092c64333ab5David Gross
10465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  struct StateOfAnalyzeTranslationUnit;
10565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
10665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static void notOk(StateOfAnalyzeTranslationUnit &S, FnIdent Kind);
10765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
10865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static void checkPointeeConstQualified(StateOfAnalyzeTranslationUnit &S,
10965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                                         FnIdent Kind, const llvm::StringRef &Name,
11065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                                         const clang::ParmVarDecl *Param, bool ExpectedQualification);
11165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
11265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static void checkVoidReturn(StateOfAnalyzeTranslationUnit &S, FnIdent Kind, clang::FunctionDecl *Fn);
11365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
11465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  clang::FunctionDecl *lookupFunction(StateOfAnalyzeTranslationUnit &S,
11565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                                      const char *Kind, const llvm::StringRef &Name);
11665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
11765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  void analyzeInitializer(StateOfAnalyzeTranslationUnit &S);
11865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  void analyzeAccumulator(StateOfAnalyzeTranslationUnit &S);
11965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  void analyzeCombiner(StateOfAnalyzeTranslationUnit &S);
12065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  void analyzeOutConverter(StateOfAnalyzeTranslationUnit &S);
12165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  void analyzeHalter(StateOfAnalyzeTranslationUnit &S);
12265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  void analyzeResultType(StateOfAnalyzeTranslationUnit &S);
12365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
12415e44e66adc350adb4fe0533a442092c64333ab5David Gross public:
12565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
12665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const char KeyReduce[];
12765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const char KeyInitializer[];
12865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const char KeyAccumulator[];
12965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const char KeyCombiner[];
13065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const char KeyOutConverter[];
13165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  static const char KeyHalter[];
13265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
1338ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  static RSExportReduce *Create(RSContext *Context,
1348ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                                const clang::SourceLocation Location,
1358ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                                const llvm::StringRef &NameReduce,
1368ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                                const llvm::StringRef &NameInitializer,
1378ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                                const llvm::StringRef &NameAccumulator,
1388ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                                const llvm::StringRef &NameCombiner,
1398ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                                const llvm::StringRef &NameOutConverter,
1408ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross                                const llvm::StringRef &NameHalter);
14115e44e66adc350adb4fe0533a442092c64333ab5David Gross
14215e44e66adc350adb4fe0533a442092c64333ab5David Gross  const clang::SourceLocation &getLocation() const { return mLocation; }
14315e44e66adc350adb4fe0533a442092c64333ab5David Gross
14415e44e66adc350adb4fe0533a442092c64333ab5David Gross  const std::string &getNameReduce() const { return mNameReduce; }
14515e44e66adc350adb4fe0533a442092c64333ab5David Gross  const std::string &getNameInitializer() const { return mNameInitializer; }
14615e44e66adc350adb4fe0533a442092c64333ab5David Gross  const std::string &getNameAccumulator() const { return mNameAccumulator; }
14715e44e66adc350adb4fe0533a442092c64333ab5David Gross  const std::string &getNameCombiner() const { return mNameCombiner; }
14815e44e66adc350adb4fe0533a442092c64333ab5David Gross  const std::string &getNameOutConverter() const { return mNameOutConverter; }
14915e44e66adc350adb4fe0533a442092c64333ab5David Gross  const std::string &getNameHalter() const { return mNameHalter; }
15065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
15165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  unsigned int getAccumulatorSignatureMetadata() const { return mAccumulatorSignatureMetadata; }
15265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
15365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  unsigned int getAccumulatorTypeSize() const { return mAccumulatorTypeSize; }
15465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
15565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  const InVec &getAccumulatorIns() const { return mAccumulatorIns; }
15665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  const InTypeVec &getAccumulatorInTypes() const { return mAccumulatorInTypes; }
15765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
15865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  const RSExportType *getResultType() const { return mResultType; }
15965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
16065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  // Does one of this reduction's constituent function names match Candidate?
16165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  bool matchName(const llvm::StringRef &Candidate) const;
16265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
16365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  bool analyzeTranslationUnit();
1648ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross};  // RSExportReduce
16515e44e66adc350adb4fe0533a442092c64333ab5David Gross
166c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala}  // namespace slang
167c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
168c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_EXPORT_REDUCE_H_  NOLINT
169