[RISCV] Rename a lambda to have plural nouns to reflect that it contains a loop. NFC
[llvm-project.git] / mlir / lib / TableGen / Constraint.cpp
blob8cf4ed08a2d54fe4ca873ed2e372b2294e906acd
1 //===- Constraint.cpp - Constraint class ----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Constraint wrapper to simplify using TableGen Record for constraints.
11 //===----------------------------------------------------------------------===//
13 #include "mlir/TableGen/Constraint.h"
14 #include "llvm/TableGen/Record.h"
16 using namespace mlir;
17 using namespace mlir::tblgen;
19 Constraint::Constraint(const llvm::Record *record)
20 : Constraint(record, CK_Uncategorized) {
21 // Look through OpVariable's to their constraint.
22 if (def->isSubClassOf("OpVariable"))
23 def = def->getValueAsDef("constraint");
25 if (def->isSubClassOf("TypeConstraint")) {
26 kind = CK_Type;
27 } else if (def->isSubClassOf("AttrConstraint")) {
28 kind = CK_Attr;
29 } else if (def->isSubClassOf("RegionConstraint")) {
30 kind = CK_Region;
31 } else if (def->isSubClassOf("SuccessorConstraint")) {
32 kind = CK_Successor;
33 } else if (!def->isSubClassOf("Constraint")) {
34 llvm::errs() << "Expected a constraint but got: \n" << *def << "\n";
35 llvm::report_fatal_error("Abort");
39 Pred Constraint::getPredicate() const {
40 auto *val = def->getValue("predicate");
42 // If no predicate is specified, then return the null predicate (which
43 // corresponds to true).
44 if (!val)
45 return Pred();
47 const auto *pred = dyn_cast<llvm::DefInit>(val->getValue());
48 return Pred(pred);
51 std::string Constraint::getConditionTemplate() const {
52 return getPredicate().getCondition();
55 StringRef Constraint::getSummary() const {
56 if (std::optional<StringRef> summary =
57 def->getValueAsOptionalString("summary"))
58 return *summary;
59 return def->getName();
62 StringRef Constraint::getDescription() const {
63 return def->getValueAsOptionalString("description").value_or("");
66 StringRef Constraint::getDefName() const {
67 if (std::optional<StringRef> baseDefName = getBaseDefName())
68 return *baseDefName;
69 return def->getName();
72 std::string Constraint::getUniqueDefName() const {
73 std::string defName = def->getName().str();
75 // Non-anonymous classes already have a unique name from the def.
76 if (!def->isAnonymous())
77 return defName;
79 // Otherwise, this is an anonymous class. In these cases we still use the def
80 // name, but we also try attach the name of the base def when present to make
81 // the name more obvious.
82 if (std::optional<StringRef> baseDefName = getBaseDefName())
83 return (*baseDefName + "(" + defName + ")").str();
84 return defName;
87 std::optional<StringRef> Constraint::getBaseDefName() const {
88 // Functor used to check a base def in the case where the current def is
89 // anonymous.
90 auto checkBaseDefFn = [&](StringRef baseName) -> std::optional<StringRef> {
91 if (const auto *defValue = def->getValue(baseName)) {
92 if (const auto *defInit = dyn_cast<llvm::DefInit>(defValue->getValue()))
93 return Constraint(defInit->getDef(), kind).getDefName();
95 return std::nullopt;
98 switch (kind) {
99 case CK_Attr:
100 if (def->isAnonymous())
101 return checkBaseDefFn("baseAttr");
102 return std::nullopt;
103 case CK_Type:
104 if (def->isAnonymous())
105 return checkBaseDefFn("baseType");
106 return std::nullopt;
107 default:
108 return std::nullopt;
112 std::optional<StringRef> Constraint::getCppFunctionName() const {
113 std::optional<StringRef> name =
114 def->getValueAsOptionalString("cppFunctionName");
115 if (!name || *name == "")
116 return std::nullopt;
117 return name;
120 AppliedConstraint::AppliedConstraint(Constraint &&constraint,
121 llvm::StringRef self,
122 std::vector<std::string> &&entities)
123 : constraint(constraint), self(std::string(self)),
124 entities(std::move(entities)) {}
126 Constraint DenseMapInfo<Constraint>::getEmptyKey() {
127 return Constraint(RecordDenseMapInfo::getEmptyKey(),
128 Constraint::CK_Uncategorized);
131 Constraint DenseMapInfo<Constraint>::getTombstoneKey() {
132 return Constraint(RecordDenseMapInfo::getTombstoneKey(),
133 Constraint::CK_Uncategorized);
136 unsigned DenseMapInfo<Constraint>::getHashValue(Constraint constraint) {
137 if (constraint == getEmptyKey())
138 return RecordDenseMapInfo::getHashValue(RecordDenseMapInfo::getEmptyKey());
139 if (constraint == getTombstoneKey()) {
140 return RecordDenseMapInfo::getHashValue(
141 RecordDenseMapInfo::getTombstoneKey());
143 return llvm::hash_combine(constraint.getPredicate(), constraint.getSummary());
146 bool DenseMapInfo<Constraint>::isEqual(Constraint lhs, Constraint rhs) {
147 if (lhs == rhs)
148 return true;
149 if (lhs == getEmptyKey() || lhs == getTombstoneKey())
150 return false;
151 if (rhs == getEmptyKey() || rhs == getTombstoneKey())
152 return false;
153 return lhs.getPredicate() == rhs.getPredicate() &&
154 lhs.getSummary() == rhs.getSummary();