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.
10//
11//===----------------------------------------------------------------------===//
12
13#include "mlir/TableGen/Constraint.h"
14#include "llvm/TableGen/Record.h"
15
16using namespace mlir;
17using namespace mlir::tblgen;
18
19Constraint::Constraint(const llvm::Record *record)
20 : Constraint(record, CK_Uncategorized) {
21 // Look through OpVariable's to their constraint.
22 if (def->isSubClassOf(Name: "OpVariable"))
23 def = def->getValueAsDef(FieldName: "constraint");
24
25 if (def->isSubClassOf(Name: "TypeConstraint")) {
26 kind = CK_Type;
27 } else if (def->isSubClassOf(Name: "AttrConstraint")) {
28 kind = CK_Attr;
29 } else if (def->isSubClassOf(Name: "PropConstraint")) {
30 kind = CK_Prop;
31 } else if (def->isSubClassOf(Name: "RegionConstraint")) {
32 kind = CK_Region;
33 } else if (def->isSubClassOf(Name: "SuccessorConstraint")) {
34 kind = CK_Successor;
35 } else if (!def->isSubClassOf(Name: "Constraint")) {
36 llvm::errs() << "Expected a constraint but got: \n" << *def << "\n";
37 llvm::report_fatal_error(reason: "Abort");
38 }
39}
40
41Pred Constraint::getPredicate() const {
42 auto *val = def->getValue(Name: "predicate");
43
44 // If no predicate is specified, then return the null predicate (which
45 // corresponds to true).
46 if (!val)
47 return Pred();
48
49 const auto *pred = dyn_cast<llvm::DefInit>(Val: val->getValue());
50 return Pred(pred);
51}
52
53std::string Constraint::getConditionTemplate() const {
54 return getPredicate().getCondition();
55}
56
57StringRef Constraint::getSummary() const {
58 if (std::optional<StringRef> summary =
59 def->getValueAsOptionalString(FieldName: "summary"))
60 return *summary;
61 return def->getName();
62}
63
64StringRef Constraint::getDescription() const {
65 return def->getValueAsOptionalString(FieldName: "description").value_or(u: "");
66}
67
68StringRef Constraint::getDefName() const {
69 if (std::optional<StringRef> baseDefName = getBaseDefName())
70 return *baseDefName;
71 return def->getName();
72}
73
74std::string Constraint::getUniqueDefName() const {
75 std::string defName = def->getName().str();
76
77 // Non-anonymous classes already have a unique name from the def.
78 if (!def->isAnonymous())
79 return defName;
80
81 // Otherwise, this is an anonymous class. In these cases we still use the def
82 // name, but we also try attach the name of the base def when present to make
83 // the name more obvious.
84 if (std::optional<StringRef> baseDefName = getBaseDefName())
85 return (*baseDefName + "(" + defName + ")").str();
86 return defName;
87}
88
89std::optional<StringRef> Constraint::getBaseDefName() const {
90 // Functor used to check a base def in the case where the current def is
91 // anonymous.
92 auto checkBaseDefFn = [&](StringRef baseName) -> std::optional<StringRef> {
93 if (const auto *defValue = def->getValue(Name: baseName)) {
94 if (const auto *defInit = dyn_cast<llvm::DefInit>(Val: defValue->getValue()))
95 return Constraint(defInit->getDef(), kind).getDefName();
96 }
97 return std::nullopt;
98 };
99
100 switch (kind) {
101 case CK_Attr:
102 if (def->isAnonymous())
103 return checkBaseDefFn("baseAttr");
104 return std::nullopt;
105 case CK_Type:
106 if (def->isAnonymous())
107 return checkBaseDefFn("baseType");
108 return std::nullopt;
109 default:
110 return std::nullopt;
111 }
112}
113
114std::optional<StringRef> Constraint::getCppFunctionName() const {
115 std::optional<StringRef> name =
116 def->getValueAsOptionalString(FieldName: "cppFunctionName");
117 if (!name || *name == "")
118 return std::nullopt;
119 return name;
120}
121
122AppliedConstraint::AppliedConstraint(Constraint &&constraint,
123 llvm::StringRef self,
124 std::vector<std::string> &&entities)
125 : constraint(constraint), self(std::string(self)),
126 entities(std::move(entities)) {}
127
128Constraint DenseMapInfo<Constraint>::getEmptyKey() {
129 return Constraint(RecordDenseMapInfo::getEmptyKey(),
130 Constraint::CK_Uncategorized);
131}
132
133Constraint DenseMapInfo<Constraint>::getTombstoneKey() {
134 return Constraint(RecordDenseMapInfo::getTombstoneKey(),
135 Constraint::CK_Uncategorized);
136}
137
138unsigned DenseMapInfo<Constraint>::getHashValue(Constraint constraint) {
139 if (constraint == getEmptyKey())
140 return RecordDenseMapInfo::getHashValue(PtrVal: RecordDenseMapInfo::getEmptyKey());
141 if (constraint == getTombstoneKey()) {
142 return RecordDenseMapInfo::getHashValue(
143 PtrVal: RecordDenseMapInfo::getTombstoneKey());
144 }
145 return llvm::hash_combine(args: constraint.getPredicate(), args: constraint.getSummary());
146}
147
148bool DenseMapInfo<Constraint>::isEqual(Constraint lhs, Constraint rhs) {
149 if (lhs == rhs)
150 return true;
151 if (lhs == getEmptyKey() || lhs == getTombstoneKey())
152 return false;
153 if (rhs == getEmptyKey() || rhs == getTombstoneKey())
154 return false;
155 return lhs.getPredicate() == rhs.getPredicate() &&
156 lhs.getSummary() == rhs.getSummary();
157}
158

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of mlir/lib/TableGen/Constraint.cpp