forked from OSchip/llvm-project
Add tblgen::Type to wrap around TableGen Type defs
This CL added a tblgen::Type class to wrap around raw TableGen Record getValue*() calls on Type defs, which will provide a nicer API for handling TableGen Record. The PredCNF class is also updated to work together with tblgen::Type. PiperOrigin-RevId: 228429090
This commit is contained in:
parent
2b902f1288
commit
b2cc2c344e
|
@ -25,22 +25,46 @@
|
|||
#include "mlir/Support/LLVM.h"
|
||||
|
||||
namespace llvm {
|
||||
class Init;
|
||||
class ListInit;
|
||||
class Record;
|
||||
} // end namespace llvm
|
||||
|
||||
namespace mlir {
|
||||
|
||||
// Predicate in conjunctive normal form.
|
||||
// Predicate in Conjunctive Normal Form (CNF).
|
||||
//
|
||||
// CNF is an AND of ORs. That means there are two levels of lists: the inner
|
||||
// list contains predicate atoms, which are ORed. Then outer list ANDs its inner
|
||||
// lists.
|
||||
// An empty CNF is defined as always true, thus matching everything.
|
||||
class PredCNF {
|
||||
public:
|
||||
PredCNF(llvm::ListInit *conditions) : conditions(conditions) {}
|
||||
// Constructs an empty predicate CNF.
|
||||
explicit PredCNF() : def(nullptr) {}
|
||||
|
||||
// Return template string to construct matcher corresponding to predicate in
|
||||
// CNF form with '{0}' representing the type.
|
||||
explicit PredCNF(const llvm::Record *def) : def(def) {}
|
||||
|
||||
// Constructs a predicate CNF out of the given TableGen initializer.
|
||||
// The initializer is allowed to be unset initializer (?); then we are
|
||||
// constructing an empty predicate CNF.
|
||||
explicit PredCNF(const llvm::Init *init);
|
||||
|
||||
// Returns true if this is an empty predicate CNF.
|
||||
bool isEmpty() const { return !def; }
|
||||
|
||||
// Returns the conditions inside this predicate CNF. Returns nullptr if
|
||||
// this is an empty predicate CNF.
|
||||
const llvm::ListInit *getConditions() const;
|
||||
|
||||
// Returns the template string to construct the matcher corresponding to this
|
||||
// predicate CNF. The string uses '{0}' to represent the type.
|
||||
std::string createTypeMatcherTemplate() const;
|
||||
|
||||
private:
|
||||
llvm::ListInit *conditions;
|
||||
// The TableGen definition of this predicate CNF. nullptr means an empty
|
||||
// predicate CNF.
|
||||
const llvm::Record *def;
|
||||
};
|
||||
|
||||
} // end namespace mlir
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
//===- Type.h - Type class --------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Copyright 2019 The MLIR Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
//
|
||||
// Type wrapper to simplify using TableGen Record defining a MLIR Type.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef MLIR_TABLEGEN_TYPE_H_
|
||||
#define MLIR_TABLEGEN_TYPE_H_
|
||||
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/TableGen/Predicate.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace llvm {
|
||||
class DefInit;
|
||||
class Record;
|
||||
} // end namespace llvm
|
||||
|
||||
namespace mlir {
|
||||
namespace tblgen {
|
||||
|
||||
// Wrapper class providing helper methods for accessing MLIR Type defined
|
||||
// in TableGen. This class should closely reflect what is defined as
|
||||
// class Type in TableGen.
|
||||
class Type {
|
||||
public:
|
||||
explicit Type(const llvm::Record &def);
|
||||
explicit Type(const llvm::Record *def) : Type(*def) {}
|
||||
explicit Type(const llvm::DefInit *init);
|
||||
|
||||
// Returns the TableGen def name for this type.
|
||||
StringRef getTableGenDefName() const;
|
||||
|
||||
// Returns the method call to invoke upon a MLIR pattern rewriter to
|
||||
// construct this type. Returns an empty StringRef if the method call
|
||||
// is undefined or unset.
|
||||
StringRef getBuilderCall() const;
|
||||
|
||||
// Returns this type's predicate CNF, which is used for checking the
|
||||
// validity of this type.
|
||||
PredCNF getPredicate() const;
|
||||
|
||||
private:
|
||||
// The TableGen definition of this type.
|
||||
const llvm::Record &def;
|
||||
};
|
||||
|
||||
} // end namespace tblgen
|
||||
} // end namespace mlir
|
||||
|
||||
#endif // MLIR_TABLEGEN_TYPE_H_
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "mlir/TableGen/Operator.h"
|
||||
#include "mlir/TableGen/Predicate.h"
|
||||
#include "mlir/TableGen/Type.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/TableGen/Error.h"
|
||||
|
@ -159,13 +160,9 @@ StringRef mlir::Operator::Attribute::getStorageType() const {
|
|||
}
|
||||
|
||||
bool mlir::Operator::Operand::hasMatcher() const {
|
||||
llvm::Init *matcher = defInit->getDef()->getValue("predicate")->getValue();
|
||||
return !isa<llvm::UnsetInit>(matcher);
|
||||
return !tblgen::Type(defInit).getPredicate().isEmpty();
|
||||
}
|
||||
|
||||
std::string mlir::Operator::Operand::createTypeMatcherTemplate() const {
|
||||
auto predicate = defInit->getDef()->getValue("predicate")->getValue();
|
||||
auto predCnf = cast<llvm::DefInit>(predicate);
|
||||
PredCNF pred(predCnf->getDef()->getValueAsListInit("conditions"));
|
||||
return pred.createTypeMatcherTemplate();
|
||||
return tblgen::Type(defInit).getPredicate().createTypeMatcherTemplate();
|
||||
}
|
||||
|
|
|
@ -27,10 +27,28 @@
|
|||
|
||||
using namespace mlir;
|
||||
|
||||
std::string mlir::PredCNF::createTypeMatcherTemplate() const {
|
||||
PredCNF::PredCNF(const llvm::Init *init) : def(nullptr) {
|
||||
if (const auto *defInit = dyn_cast<llvm::DefInit>(init)) {
|
||||
def = defInit->getDef();
|
||||
assert(def->isSubClassOf("PredCNF") &&
|
||||
"must be subclass of TableGen 'PredCNF' class");
|
||||
}
|
||||
}
|
||||
|
||||
const llvm::ListInit *PredCNF::getConditions() const {
|
||||
if (!def)
|
||||
return nullptr;
|
||||
|
||||
return def->getValueAsListInit("conditions");
|
||||
}
|
||||
|
||||
std::string PredCNF::createTypeMatcherTemplate() const {
|
||||
const auto *conjunctiveList = getConditions();
|
||||
if (!conjunctiveList)
|
||||
return "true";
|
||||
|
||||
std::string outString;
|
||||
llvm::raw_string_ostream ss(outString);
|
||||
auto conjunctiveList = conditions;
|
||||
bool firstDisjunctive = true;
|
||||
for (auto disjunctiveInit : *conjunctiveList) {
|
||||
ss << (firstDisjunctive ? "(" : " && (");
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
//===- Type.cpp - Type class ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Copyright 2019 The MLIR Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// =============================================================================
|
||||
//
|
||||
// Type wrapper to simplify using TableGen Record defining a MLIR Type.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "mlir/TableGen/Type.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
using namespace mlir;
|
||||
|
||||
tblgen::Type::Type(const llvm::Record &def) : def(def) {
|
||||
assert(def.isSubClassOf("Type") &&
|
||||
"must be subclass of TableGen 'Type' class");
|
||||
}
|
||||
|
||||
tblgen::Type::Type(const llvm::DefInit *init) : Type(*init->getDef()) {}
|
||||
|
||||
StringRef tblgen::Type::getTableGenDefName() const { return def.getName(); }
|
||||
|
||||
StringRef tblgen::Type::getBuilderCall() const {
|
||||
const auto *val = def.getValue("builderCall");
|
||||
assert(val && "TableGen 'Type' class should have 'builderCall' field");
|
||||
|
||||
if (const auto *builder = dyn_cast<llvm::CodeInit>(val->getValue()))
|
||||
return builder->getValue();
|
||||
return {};
|
||||
}
|
||||
|
||||
PredCNF tblgen::Type::getPredicate() const {
|
||||
auto *val = def.getValue("predicate");
|
||||
assert(val && "TableGen 'Type' class should have 'predicate' field");
|
||||
|
||||
const auto *pred = dyn_cast<llvm::DefInit>(val->getValue());
|
||||
return PredCNF(pred);
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
#include "mlir/TableGen/GenInfo.h"
|
||||
#include "mlir/TableGen/Operator.h"
|
||||
#include "mlir/TableGen/Predicate.h"
|
||||
#include "mlir/TableGen/Type.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
@ -88,7 +89,7 @@ private:
|
|||
void Pattern::emitAttributeValue(Record *constAttr) {
|
||||
Record *attr = constAttr->getValueAsDef("attr");
|
||||
auto value = constAttr->getValue("value");
|
||||
Record *type = attr->getValueAsDef("type");
|
||||
tblgen::Type type(attr->getValueAsDef("type"));
|
||||
auto storageType = attr->getValueAsString("storageType").trim();
|
||||
|
||||
// For attributes stored as strings we do not need to query builder etc.
|
||||
|
@ -98,20 +99,15 @@ void Pattern::emitAttributeValue(Record *constAttr) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Construct the attribute based on storage type and builder.
|
||||
if (auto b = type->getValue("builderCall")) {
|
||||
if (isa<UnsetInit>(b->getValue()))
|
||||
PrintFatalError(pattern->getLoc(),
|
||||
"no builder specified for " + type->getName());
|
||||
CodeInit *builder = cast<CodeInit>(b->getValue());
|
||||
// TODO(jpienaar): Verify the constants here
|
||||
os << formatv("{0}::get(rewriter.{1}, {2})", storageType,
|
||||
builder->getValue(),
|
||||
value->getValue()->getAsUnquotedString());
|
||||
return;
|
||||
}
|
||||
auto builder = type.getBuilderCall();
|
||||
if (builder.empty())
|
||||
PrintFatalError(pattern->getLoc(),
|
||||
"no builder specified for " + type.getTableGenDefName());
|
||||
|
||||
PrintFatalError(pattern->getLoc(), "unable to emit attribute");
|
||||
// Construct the attribute based on storage type and builder.
|
||||
// TODO(jpienaar): Verify the constants here
|
||||
os << formatv("{0}::get(rewriter.{1}, {2})", storageType, builder,
|
||||
value->getValue()->getAsUnquotedString());
|
||||
}
|
||||
|
||||
void Pattern::collectBoundArguments(DagInit *tree) {
|
||||
|
@ -174,12 +170,8 @@ static void matchOp(Record *pattern, DagInit *tree, int depth,
|
|||
PrintFatalError(pattern->getLoc(),
|
||||
"type argument required for operand");
|
||||
|
||||
// TODO(jpienaar): Factor out type class and move these there.
|
||||
auto predicate = defInit->getDef()->getValue("predicate")->getValue();
|
||||
auto predCnf = cast<DefInit>(predicate);
|
||||
auto conjunctiveList =
|
||||
predCnf->getDef()->getValueAsListInit("conditions");
|
||||
PredCNF pred(conjunctiveList);
|
||||
auto pred = tblgen::Type(defInit).getPredicate();
|
||||
|
||||
os.indent(indent)
|
||||
<< "if (!("
|
||||
<< formatv(pred.createTypeMatcherTemplate().c_str(),
|
||||
|
|
Loading…
Reference in New Issue