18f5fa566SLei Zhang //===- Constraint.cpp - Constraint class ----------------------------------===// 28f5fa566SLei Zhang // 330857107SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 456222a06SMehdi Amini // See https://llvm.org/LICENSE.txt for license information. 556222a06SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68f5fa566SLei Zhang // 756222a06SMehdi Amini //===----------------------------------------------------------------------===// 88f5fa566SLei Zhang // 98f5fa566SLei Zhang // Constraint wrapper to simplify using TableGen Record for constraints. 108f5fa566SLei Zhang // 118f5fa566SLei Zhang //===----------------------------------------------------------------------===// 128f5fa566SLei Zhang 138f5fa566SLei Zhang #include "mlir/TableGen/Constraint.h" 148f5fa566SLei Zhang #include "llvm/TableGen/Record.h" 158f5fa566SLei Zhang 1695019de8SRiver Riddle using namespace mlir; 178f5fa566SLei Zhang using namespace mlir::tblgen; 188f5fa566SLei Zhang 198f5fa566SLei Zhang Constraint::Constraint(const llvm::Record *record) 20b8186b31SMogball : Constraint(record, CK_Uncategorized) { 217c59120fSJacques Pienaar // Look through OpVariable's to their constraint. 227c59120fSJacques Pienaar if (def->isSubClassOf("OpVariable")) 237c59120fSJacques Pienaar def = def->getValueAsDef("constraint"); 24b8186b31SMogball 257c59120fSJacques Pienaar if (def->isSubClassOf("TypeConstraint")) { 268f5fa566SLei Zhang kind = CK_Type; 277c59120fSJacques Pienaar } else if (def->isSubClassOf("AttrConstraint")) { 288f5fa566SLei Zhang kind = CK_Attr; 297c59120fSJacques Pienaar } else if (def->isSubClassOf("RegionConstraint")) { 303650df50SLei Zhang kind = CK_Region; 317c59120fSJacques Pienaar } else if (def->isSubClassOf("SuccessorConstraint")) { 32b1de971bSRiver Riddle kind = CK_Successor; 33340d746aSMehdi Amini } else if (!def->isSubClassOf("Constraint")) { 343e4ad66fSMehdi Amini llvm::errs() << "Expected a constraint but got: \n" << *def << "\n"; 35340d746aSMehdi Amini llvm::report_fatal_error("Abort"); 368f5fa566SLei Zhang } 378f5fa566SLei Zhang } 388f5fa566SLei Zhang 398f5fa566SLei Zhang Pred Constraint::getPredicate() const { 408f5fa566SLei Zhang auto *val = def->getValue("predicate"); 418f5fa566SLei Zhang 428f5fa566SLei Zhang // If no predicate is specified, then return the null predicate (which 438f5fa566SLei Zhang // corresponds to true). 448f5fa566SLei Zhang if (!val) 458f5fa566SLei Zhang return Pred(); 468f5fa566SLei Zhang 478f5fa566SLei Zhang const auto *pred = dyn_cast<llvm::DefInit>(val->getValue()); 488f5fa566SLei Zhang return Pred(pred); 498f5fa566SLei Zhang } 508f5fa566SLei Zhang 518f5fa566SLei Zhang std::string Constraint::getConditionTemplate() const { 528f5fa566SLei Zhang return getPredicate().getCondition(); 538f5fa566SLei Zhang } 548f5fa566SLei Zhang 55e0a93e4bSRiver Riddle StringRef Constraint::getSummary() const { 563cfe412eSFangrui Song if (std::optional<StringRef> summary = 573cfe412eSFangrui Song def->getValueAsOptionalString("summary")) 5895019de8SRiver Riddle return *summary; 598f5fa566SLei Zhang return def->getName(); 608f5fa566SLei Zhang } 618f5fa566SLei Zhang 62bf352e0bSRiver Riddle StringRef Constraint::getDescription() const { 6330c67587SKazu Hirata return def->getValueAsOptionalString("description").value_or(""); 64bf352e0bSRiver Riddle } 65bf352e0bSRiver Riddle 6681f2f4dfSRiver Riddle StringRef Constraint::getDefName() const { 673cfe412eSFangrui Song if (std::optional<StringRef> baseDefName = getBaseDefName()) 68b3fc0fa8SRiver Riddle return *baseDefName; 69b3fc0fa8SRiver Riddle return def->getName(); 70b3fc0fa8SRiver Riddle } 71b3fc0fa8SRiver Riddle 72b3fc0fa8SRiver Riddle std::string Constraint::getUniqueDefName() const { 73b3fc0fa8SRiver Riddle std::string defName = def->getName().str(); 74b3fc0fa8SRiver Riddle 75b3fc0fa8SRiver Riddle // Non-anonymous classes already have a unique name from the def. 76b3fc0fa8SRiver Riddle if (!def->isAnonymous()) 77b3fc0fa8SRiver Riddle return defName; 78b3fc0fa8SRiver Riddle 79b3fc0fa8SRiver Riddle // Otherwise, this is an anonymous class. In these cases we still use the def 80b3fc0fa8SRiver Riddle // name, but we also try attach the name of the base def when present to make 81b3fc0fa8SRiver Riddle // the name more obvious. 823cfe412eSFangrui Song if (std::optional<StringRef> baseDefName = getBaseDefName()) 83b3fc0fa8SRiver Riddle return (*baseDefName + "(" + defName + ")").str(); 84b3fc0fa8SRiver Riddle return defName; 85b3fc0fa8SRiver Riddle } 86b3fc0fa8SRiver Riddle 873cfe412eSFangrui Song std::optional<StringRef> Constraint::getBaseDefName() const { 8881f2f4dfSRiver Riddle // Functor used to check a base def in the case where the current def is 8981f2f4dfSRiver Riddle // anonymous. 903cfe412eSFangrui Song auto checkBaseDefFn = [&](StringRef baseName) -> std::optional<StringRef> { 91b3fc0fa8SRiver Riddle if (const auto *defValue = def->getValue(baseName)) { 92b3fc0fa8SRiver Riddle if (const auto *defInit = dyn_cast<llvm::DefInit>(defValue->getValue())) 93b3fc0fa8SRiver Riddle return Constraint(defInit->getDef(), kind).getDefName(); 94b3fc0fa8SRiver Riddle } 951a36588eSKazu Hirata return std::nullopt; 9681f2f4dfSRiver Riddle }; 9781f2f4dfSRiver Riddle 9881f2f4dfSRiver Riddle switch (kind) { 9981f2f4dfSRiver Riddle case CK_Attr: 10081f2f4dfSRiver Riddle if (def->isAnonymous()) 10181f2f4dfSRiver Riddle return checkBaseDefFn("baseAttr"); 1021a36588eSKazu Hirata return std::nullopt; 10381f2f4dfSRiver Riddle case CK_Type: 10481f2f4dfSRiver Riddle if (def->isAnonymous()) 10581f2f4dfSRiver Riddle return checkBaseDefFn("baseType"); 1061a36588eSKazu Hirata return std::nullopt; 10781f2f4dfSRiver Riddle default: 1081a36588eSKazu Hirata return std::nullopt; 10981f2f4dfSRiver Riddle } 110*a3d41879SMatthias Springer } 111*a3d41879SMatthias Springer 112*a3d41879SMatthias Springer std::optional<StringRef> Constraint::getCppFunctionName() const { 113*a3d41879SMatthias Springer std::optional<StringRef> name = 114*a3d41879SMatthias Springer def->getValueAsOptionalString("cppFunctionName"); 115*a3d41879SMatthias Springer if (!name || *name == "") 116*a3d41879SMatthias Springer return std::nullopt; 117*a3d41879SMatthias Springer return name; 11881f2f4dfSRiver Riddle } 11981f2f4dfSRiver Riddle 1207768ea9fSLei Zhang AppliedConstraint::AppliedConstraint(Constraint &&constraint, 1217768ea9fSLei Zhang llvm::StringRef self, 122c72d849eSLei Zhang std::vector<std::string> &&entities) 123adcd0268SBenjamin Kramer : constraint(constraint), self(std::string(self)), 124adcd0268SBenjamin Kramer entities(std::move(entities)) {} 1251bd1edafSRiver Riddle 1261bd1edafSRiver Riddle Constraint DenseMapInfo<Constraint>::getEmptyKey() { 1271bd1edafSRiver Riddle return Constraint(RecordDenseMapInfo::getEmptyKey(), 1281bd1edafSRiver Riddle Constraint::CK_Uncategorized); 1291bd1edafSRiver Riddle } 1301bd1edafSRiver Riddle 1311bd1edafSRiver Riddle Constraint DenseMapInfo<Constraint>::getTombstoneKey() { 1321bd1edafSRiver Riddle return Constraint(RecordDenseMapInfo::getTombstoneKey(), 1331bd1edafSRiver Riddle Constraint::CK_Uncategorized); 1341bd1edafSRiver Riddle } 1351bd1edafSRiver Riddle 1361bd1edafSRiver Riddle unsigned DenseMapInfo<Constraint>::getHashValue(Constraint constraint) { 1371bd1edafSRiver Riddle if (constraint == getEmptyKey()) 1381bd1edafSRiver Riddle return RecordDenseMapInfo::getHashValue(RecordDenseMapInfo::getEmptyKey()); 1391bd1edafSRiver Riddle if (constraint == getTombstoneKey()) { 1401bd1edafSRiver Riddle return RecordDenseMapInfo::getHashValue( 1411bd1edafSRiver Riddle RecordDenseMapInfo::getTombstoneKey()); 1421bd1edafSRiver Riddle } 1431bd1edafSRiver Riddle return llvm::hash_combine(constraint.getPredicate(), constraint.getSummary()); 1441bd1edafSRiver Riddle } 1451bd1edafSRiver Riddle 1461bd1edafSRiver Riddle bool DenseMapInfo<Constraint>::isEqual(Constraint lhs, Constraint rhs) { 1471bd1edafSRiver Riddle if (lhs == rhs) 1481bd1edafSRiver Riddle return true; 1491bd1edafSRiver Riddle if (lhs == getEmptyKey() || lhs == getTombstoneKey()) 1501bd1edafSRiver Riddle return false; 1511bd1edafSRiver Riddle if (rhs == getEmptyKey() || rhs == getTombstoneKey()) 1521bd1edafSRiver Riddle return false; 1531bd1edafSRiver Riddle return lhs.getPredicate() == rhs.getPredicate() && 1541bd1edafSRiver Riddle lhs.getSummary() == rhs.getSummary(); 1551bd1edafSRiver Riddle } 156