xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/Common/GlobalISel/CXXPredicates.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===- CXXPredicates.h ------------------------------------------*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric /// \file Contains utilities related to handling C++ code in MIR patterns for
10*0fca6ea1SDimitry Andric ///   GlobalISel. C++ predicates need to be expanded, and then stored in a
11*0fca6ea1SDimitry Andric ///   static pool until they can be emitted.
12*0fca6ea1SDimitry Andric //
13*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
14*0fca6ea1SDimitry Andric 
15*0fca6ea1SDimitry Andric #ifndef LLVM_UTILS_MIRPATTERNS_CXXPREDICATES_H
16*0fca6ea1SDimitry Andric #define LLVM_UTILS_MIRPATTERNS_CXXPREDICATES_H
17*0fca6ea1SDimitry Andric 
18*0fca6ea1SDimitry Andric #include "llvm/ADT/DenseMap.h"
19*0fca6ea1SDimitry Andric #include "llvm/ADT/Hashing.h"
20*0fca6ea1SDimitry Andric #include "llvm/ADT/StringRef.h"
21*0fca6ea1SDimitry Andric #include <memory>
22*0fca6ea1SDimitry Andric #include <string>
23*0fca6ea1SDimitry Andric #include <vector>
24*0fca6ea1SDimitry Andric 
25*0fca6ea1SDimitry Andric namespace llvm {
26*0fca6ea1SDimitry Andric namespace gi {
27*0fca6ea1SDimitry Andric 
28*0fca6ea1SDimitry Andric /// Entry into the static pool of all CXX Predicate code. This contains
29*0fca6ea1SDimitry Andric /// fully expanded C++ code.
30*0fca6ea1SDimitry Andric ///
31*0fca6ea1SDimitry Andric /// The static pool is hidden inside the object and can be accessed through
32*0fca6ea1SDimitry Andric /// getAllMatchCode/getAllApplyCode
33*0fca6ea1SDimitry Andric ///
34*0fca6ea1SDimitry Andric /// Note that CXXPattern trims C++ code, so the Code is already expected to be
35*0fca6ea1SDimitry Andric /// free of leading/trailing whitespace.
36*0fca6ea1SDimitry Andric class CXXPredicateCode {
37*0fca6ea1SDimitry Andric   using CXXPredicateCodePool =
38*0fca6ea1SDimitry Andric       DenseMap<hash_code, std::unique_ptr<CXXPredicateCode>>;
39*0fca6ea1SDimitry Andric   static CXXPredicateCodePool AllCXXMatchCode;
40*0fca6ea1SDimitry Andric   static CXXPredicateCodePool AllCXXCustomActionCode;
41*0fca6ea1SDimitry Andric 
42*0fca6ea1SDimitry Andric   /// Sorts a `CXXPredicateCodePool` by their IDs and returns it.
43*0fca6ea1SDimitry Andric   static std::vector<const CXXPredicateCode *>
44*0fca6ea1SDimitry Andric   getSorted(const CXXPredicateCodePool &Pool);
45*0fca6ea1SDimitry Andric 
46*0fca6ea1SDimitry Andric   /// Gets an instance of `CXXPredicateCode` for \p Code, or returns an already
47*0fca6ea1SDimitry Andric   /// existing one.
48*0fca6ea1SDimitry Andric   static const CXXPredicateCode &get(CXXPredicateCodePool &Pool,
49*0fca6ea1SDimitry Andric                                      std::string Code);
50*0fca6ea1SDimitry Andric 
51*0fca6ea1SDimitry Andric   CXXPredicateCode(std::string Code, unsigned ID);
52*0fca6ea1SDimitry Andric 
53*0fca6ea1SDimitry Andric public:
54*0fca6ea1SDimitry Andric   static const CXXPredicateCode &getMatchCode(std::string Code) {
55*0fca6ea1SDimitry Andric     return get(AllCXXMatchCode, std::move(Code));
56*0fca6ea1SDimitry Andric   }
57*0fca6ea1SDimitry Andric 
58*0fca6ea1SDimitry Andric   static const CXXPredicateCode &getCustomActionCode(std::string Code) {
59*0fca6ea1SDimitry Andric     return get(AllCXXCustomActionCode, std::move(Code));
60*0fca6ea1SDimitry Andric   }
61*0fca6ea1SDimitry Andric 
62*0fca6ea1SDimitry Andric   static std::vector<const CXXPredicateCode *> getAllMatchCode() {
63*0fca6ea1SDimitry Andric     return getSorted(AllCXXMatchCode);
64*0fca6ea1SDimitry Andric   }
65*0fca6ea1SDimitry Andric 
66*0fca6ea1SDimitry Andric   static std::vector<const CXXPredicateCode *> getAllCustomActionsCode() {
67*0fca6ea1SDimitry Andric     return getSorted(AllCXXCustomActionCode);
68*0fca6ea1SDimitry Andric   }
69*0fca6ea1SDimitry Andric 
70*0fca6ea1SDimitry Andric   const std::string Code;
71*0fca6ea1SDimitry Andric   const unsigned ID;
72*0fca6ea1SDimitry Andric   const std::string BaseEnumName;
73*0fca6ea1SDimitry Andric 
74*0fca6ea1SDimitry Andric   bool needsUnreachable() const {
75*0fca6ea1SDimitry Andric     return !StringRef(Code).starts_with("return");
76*0fca6ea1SDimitry Andric   }
77*0fca6ea1SDimitry Andric 
78*0fca6ea1SDimitry Andric   std::string getEnumNameWithPrefix(StringRef Prefix) const {
79*0fca6ea1SDimitry Andric     return Prefix.str() + BaseEnumName;
80*0fca6ea1SDimitry Andric   }
81*0fca6ea1SDimitry Andric };
82*0fca6ea1SDimitry Andric 
83*0fca6ea1SDimitry Andric } // namespace gi
84*0fca6ea1SDimitry Andric } // end namespace llvm
85*0fca6ea1SDimitry Andric 
86*0fca6ea1SDimitry Andric #endif // ifndef LLVM_UTILS_MIRPATTERNS_CXXPREDICATES_H
87