MLIR  21.0.0git
Constraint.cpp
Go to the documentation of this file.
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 
14 #include "llvm/TableGen/Record.h"
15 
16 using namespace mlir;
17 using namespace mlir::tblgen;
18 
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");
24 
25  if (def->isSubClassOf("TypeConstraint")) {
26  kind = CK_Type;
27  } else if (def->isSubClassOf("AttrConstraint")) {
28  kind = CK_Attr;
29  } else if (def->isSubClassOf("PropConstraint")) {
30  kind = CK_Prop;
31  } else if (def->isSubClassOf("RegionConstraint")) {
32  kind = CK_Region;
33  } else if (def->isSubClassOf("SuccessorConstraint")) {
34  kind = CK_Successor;
35  } else if (!def->isSubClassOf("Constraint")) {
36  llvm::errs() << "Expected a constraint but got: \n" << *def << "\n";
37  llvm::report_fatal_error("Abort");
38  }
39 }
40 
42  auto *val = def->getValue("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->getValue());
50  return Pred(pred);
51 }
52 
53 std::string Constraint::getConditionTemplate() const {
54  return getPredicate().getCondition();
55 }
56 
57 StringRef Constraint::getSummary() const {
58  if (std::optional<StringRef> summary =
59  def->getValueAsOptionalString("summary"))
60  return *summary;
61  return def->getName();
62 }
63 
64 StringRef Constraint::getDescription() const {
65  return def->getValueAsOptionalString("description").value_or("");
66 }
67 
68 StringRef Constraint::getDefName() const {
69  if (std::optional<StringRef> baseDefName = getBaseDefName())
70  return *baseDefName;
71  return def->getName();
72 }
73 
74 std::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 
89 std::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(baseName)) {
94  if (const auto *defInit = dyn_cast<llvm::DefInit>(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 
114 std::optional<StringRef> Constraint::getCppFunctionName() const {
115  std::optional<StringRef> name =
116  def->getValueAsOptionalString("cppFunctionName");
117  if (!name || *name == "")
118  return std::nullopt;
119  return name;
120 }
121 
123  llvm::StringRef self,
124  std::vector<std::string> &&entities)
125  : constraint(constraint), self(std::string(self)),
126  entities(std::move(entities)) {}
127 
129  return Constraint(RecordDenseMapInfo::getEmptyKey(),
131 }
132 
134  return Constraint(RecordDenseMapInfo::getTombstoneKey(),
136 }
137 
139  if (constraint == getEmptyKey())
140  return RecordDenseMapInfo::getHashValue(RecordDenseMapInfo::getEmptyKey());
141  if (constraint == getTombstoneKey()) {
142  return RecordDenseMapInfo::getHashValue(
143  RecordDenseMapInfo::getTombstoneKey());
144  }
145  return llvm::hash_combine(constraint.getPredicate(), constraint.getSummary());
146 }
147 
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 }
Pred getPredicate() const
Definition: Constraint.cpp:41
StringRef getSummary() const
Definition: Constraint.cpp:57
const llvm::Record * def
Definition: Constraint.h:90
std::string getUniqueDefName() const
Returns a unique name for the TablGen def of this constraint.
Definition: Constraint.cpp:74
StringRef getDescription() const
Definition: Constraint.cpp:64
StringRef getDefName() const
Returns the name of the TablGen def of this constraint.
Definition: Constraint.cpp:68
std::optional< StringRef > getCppFunctionName() const
Returns the name of the C++ function that should be generated for this constraint,...
Definition: Constraint.cpp:114
Constraint(const llvm::Record *record, Kind kind)
Definition: Constraint.h:43
std::string getConditionTemplate() const
Definition: Constraint.cpp:53
std::string getCondition() const
Definition: Predicate.cpp:39
Include the generated interface declarations.
AppliedConstraint(Constraint &&constraint, StringRef self, std::vector< std::string > &&entities)
Definition: Constraint.cpp:122