1 //===- Constraint.cpp - Constraint class ----------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // Constraint wrapper to simplify using TableGen Record for constraints.
11 //===----------------------------------------------------------------------===//
13 #include "mlir/TableGen/Constraint.h"
14 #include "llvm/TableGen/Record.h"
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")) {
27 } else if (def
->isSubClassOf("AttrConstraint")) {
29 } else if (def
->isSubClassOf("RegionConstraint")) {
31 } else if (def
->isSubClassOf("SuccessorConstraint")) {
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).
47 const auto *pred
= dyn_cast
<llvm::DefInit
>(val
->getValue());
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"))
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())
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())
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();
87 std::optional
<StringRef
> Constraint::getBaseDefName() const {
88 // Functor used to check a base def in the case where the current def is
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();
100 if (def
->isAnonymous())
101 return checkBaseDefFn("baseAttr");
104 if (def
->isAnonymous())
105 return checkBaseDefFn("baseType");
112 std::optional
<StringRef
> Constraint::getCppFunctionName() const {
113 std::optional
<StringRef
> name
=
114 def
->getValueAsOptionalString("cppFunctionName");
115 if (!name
|| *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
) {
149 if (lhs
== getEmptyKey() || lhs
== getTombstoneKey())
151 if (rhs
== getEmptyKey() || rhs
== getTombstoneKey())
153 return lhs
.getPredicate() == rhs
.getPredicate() &&
154 lhs
.getSummary() == rhs
.getSummary();