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