brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 92d33bf Raw
158 lines · cpp
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-exception6//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("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 41Pred Constraint::getPredicate() const {42  auto *val = def->getValue("predicate");43 44  // If no predicate is specified, then return the null predicate (which45  // 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 53std::string Constraint::getConditionTemplate() const {54  return getPredicate().getCondition();55}56 57StringRef Constraint::getSummary() const {58  if (std::optional<StringRef> summary =59          def->getValueAsOptionalString("summary"))60    return *summary;61  return def->getName();62}63 64StringRef Constraint::getDescription() const {65  return def->getValueAsOptionalString("description").value_or("");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 def82  // name, but we also try attach the name of the base def when present to make83  // 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 is91  // 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 114std::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 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(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 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