mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-27 10:18:36 +00:00
[mlir][ods] ODS ops get an extraClassDefinition
Extra definitions are placed in the generated source file for each op class. The substitution `$cppClass` is replaced by the op's C++ class name. This is useful when declaring but not defining methods in TableGen base classes: ``` class BaseOp<string mnemonic> : Op<MyDialect, mnemonic, [DeclareOpInterfaceMethods<SomeInterface>] { let extraClassDeclaration = [{ // ZOp is declared at at the bottom of the file and is incomplete here ZOp getParent(); }]; let extraClassDefinition = [{ int $cppClass::someInterfaceMethod() { return someUtilityFunction(*this); } ZOp $cppClass::getParent() { return dyn_cast<ZOp>(this->getParentOp()); } }]; } ``` Certain things may prevent defining these functions inline, in the declaration. In this example, `ZOp` in the same dialect is incomplete at the function declaration because ops classes are declared in alphabetical order. Alternatively, functions may be too big to be desired as inlined, or they may require dependencies that create cyclic includes, or they may be calling a templated utility function that one may not want to expose in a header. If the functions are not inlined, then inheriting from the base class N times means that each function will need to be defined N times. With `extraClassDefinitions`, they only need to be defined once. Reviewed By: rriddle Differential Revision: https://reviews.llvm.org/D115783
This commit is contained in:
parent
0f5b718030
commit
b0774e5f50
@ -964,6 +964,16 @@ Note that `extraClassDeclaration` is a mechanism intended for long-tail cases by
|
|||||||
power users; for not-yet-implemented widely-applicable cases, improving the
|
power users; for not-yet-implemented widely-applicable cases, improving the
|
||||||
infrastructure is preferable.
|
infrastructure is preferable.
|
||||||
|
|
||||||
|
### Extra definitions
|
||||||
|
|
||||||
|
When defining base op classes in TableGen that are inherited many times by
|
||||||
|
different ops, users may want to provide common definitions of utility and
|
||||||
|
interface functions. However, many of these definitions may not be desirable or
|
||||||
|
possible in `extraClassDeclaration`, which append them to the op's C++ class
|
||||||
|
declaration. In these cases, users can add an `extraClassDefinition` to define
|
||||||
|
code that is added to the generated source file inside the op's C++ namespace.
|
||||||
|
The substitution `$cppClass` is replaced by the op's C++ class name.
|
||||||
|
|
||||||
### Generated C++ code
|
### Generated C++ code
|
||||||
|
|
||||||
[OpDefinitionsGen][OpDefinitionsGen] processes the op definition spec file and
|
[OpDefinitionsGen][OpDefinitionsGen] processes the op definition spec file and
|
||||||
|
@ -2445,6 +2445,11 @@ class Op<Dialect dialect, string mnemonic, list<OpTrait> props = []> {
|
|||||||
// Additional code that will be added to the public part of the generated
|
// Additional code that will be added to the public part of the generated
|
||||||
// C++ code of the op declaration.
|
// C++ code of the op declaration.
|
||||||
code extraClassDeclaration = ?;
|
code extraClassDeclaration = ?;
|
||||||
|
|
||||||
|
// Additional code that will be added to the generated source file. The
|
||||||
|
// generated code is placed inside the op's C++ namespace. `$cppClass` is
|
||||||
|
// replaced by the op's C++ class name.
|
||||||
|
code extraClassDefinition = ?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base class for ops with static/dynamic offset, sizes and strides
|
// Base class for ops with static/dynamic offset, sizes and strides
|
||||||
|
@ -532,22 +532,32 @@ private:
|
|||||||
Visibility visibility;
|
Visibility visibility;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Unstructured extra class declarations, from TableGen definitions. The
|
/// Unstructured extra class declarations and definitions, from TableGen
|
||||||
/// default visibility of extra class declarations is up to the owning class.
|
/// definitions. The default visibility of extra class declarations is up to the
|
||||||
|
/// owning class.
|
||||||
class ExtraClassDeclaration
|
class ExtraClassDeclaration
|
||||||
: public ClassDeclarationBase<ClassDeclaration::ExtraClassDeclaration> {
|
: public ClassDeclarationBase<ClassDeclaration::ExtraClassDeclaration> {
|
||||||
public:
|
public:
|
||||||
/// Create an extra class declaration.
|
/// Create an extra class declaration.
|
||||||
ExtraClassDeclaration(StringRef extraClassDeclaration)
|
ExtraClassDeclaration(StringRef extraClassDeclaration,
|
||||||
: extraClassDeclaration(extraClassDeclaration) {}
|
StringRef extraClassDefinition = "")
|
||||||
|
: extraClassDeclaration(extraClassDeclaration),
|
||||||
|
extraClassDefinition(extraClassDefinition) {}
|
||||||
|
|
||||||
/// Write the extra class declarations.
|
/// Write the extra class declarations.
|
||||||
void writeDeclTo(raw_indented_ostream &os) const override;
|
void writeDeclTo(raw_indented_ostream &os) const override;
|
||||||
|
|
||||||
|
/// Write the extra class definitions.
|
||||||
|
void writeDefTo(raw_indented_ostream &os,
|
||||||
|
StringRef namePrefix) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The string of the extra class declarations. It is re-indented before
|
/// The string of the extra class declarations. It is re-indented before
|
||||||
/// printed.
|
/// printed.
|
||||||
StringRef extraClassDeclaration;
|
StringRef extraClassDeclaration;
|
||||||
|
/// The string of the extra class definitions. It is re-indented before
|
||||||
|
/// printed.
|
||||||
|
StringRef extraClassDefinition;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A class used to emit C++ classes from Tablegen. Contains a list of public
|
/// A class used to emit C++ classes from Tablegen. Contains a list of public
|
||||||
|
@ -235,6 +235,9 @@ public:
|
|||||||
// Returns this op's extra class declaration code.
|
// Returns this op's extra class declaration code.
|
||||||
StringRef getExtraClassDeclaration() const;
|
StringRef getExtraClassDeclaration() const;
|
||||||
|
|
||||||
|
// Returns this op's extra class definition code.
|
||||||
|
StringRef getExtraClassDefinition() const;
|
||||||
|
|
||||||
// Returns the Tablegen definition this operator was constructed from.
|
// Returns the Tablegen definition this operator was constructed from.
|
||||||
// TODO: do not expose the TableGen record, this is a temporary solution to
|
// TODO: do not expose the TableGen record, this is a temporary solution to
|
||||||
// OpEmitter requiring a Record because Operator does not provide enough
|
// OpEmitter requiring a Record because Operator does not provide enough
|
||||||
|
@ -260,6 +260,11 @@ void ExtraClassDeclaration::writeDeclTo(raw_indented_ostream &os) const {
|
|||||||
os.printReindented(extraClassDeclaration);
|
os.printReindented(extraClassDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExtraClassDeclaration::writeDefTo(raw_indented_ostream &os,
|
||||||
|
StringRef namePrefix) const {
|
||||||
|
os.printReindented(extraClassDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Class definitions
|
// Class definitions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -128,6 +128,13 @@ StringRef Operator::getExtraClassDeclaration() const {
|
|||||||
return def.getValueAsString(attr);
|
return def.getValueAsString(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringRef Operator::getExtraClassDefinition() const {
|
||||||
|
constexpr auto attr = "extraClassDefinition";
|
||||||
|
if (def.isValueUnset(attr))
|
||||||
|
return {};
|
||||||
|
return def.getValueAsString(attr);
|
||||||
|
}
|
||||||
|
|
||||||
const llvm::Record &Operator::getDef() const { return def; }
|
const llvm::Record &Operator::getDef() const { return def; }
|
||||||
|
|
||||||
bool Operator::skipDefaultBuilders() const {
|
bool Operator::skipDefaultBuilders() const {
|
||||||
|
@ -382,7 +382,10 @@ def ConversionCallOp : TEST_Op<"conversion_call_op",
|
|||||||
|
|
||||||
let extraClassDeclaration = [{
|
let extraClassDeclaration = [{
|
||||||
/// Return the callee of this operation.
|
/// Return the callee of this operation.
|
||||||
::mlir::CallInterfaceCallable getCallableForCallee() {
|
::mlir::CallInterfaceCallable getCallableForCallee();
|
||||||
|
}];
|
||||||
|
let extraClassDefinition = [{
|
||||||
|
::mlir::CallInterfaceCallable $cppClass::getCallableForCallee() {
|
||||||
return (*this)->getAttrOfType<::mlir::SymbolRefAttr>("callee");
|
return (*this)->getAttrOfType<::mlir::SymbolRefAttr>("callee");
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
@ -15,8 +15,10 @@ using namespace mlir::tblgen;
|
|||||||
// OpClass definitions
|
// OpClass definitions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
OpClass::OpClass(StringRef name, StringRef extraClassDeclaration)
|
OpClass::OpClass(StringRef name, StringRef extraClassDeclaration,
|
||||||
|
std::string extraClassDefinition)
|
||||||
: Class(name.str()), extraClassDeclaration(extraClassDeclaration),
|
: Class(name.str()), extraClassDeclaration(extraClassDeclaration),
|
||||||
|
extraClassDefinition(std::move(extraClassDefinition)),
|
||||||
parent(addParent("::mlir::Op")) {
|
parent(addParent("::mlir::Op")) {
|
||||||
parent.addTemplateParam(getClassName().str());
|
parent.addTemplateParam(getClassName().str());
|
||||||
declare<VisibilityDeclaration>(Visibility::Public);
|
declare<VisibilityDeclaration>(Visibility::Public);
|
||||||
@ -30,5 +32,5 @@ OpClass::OpClass(StringRef name, StringRef extraClassDeclaration)
|
|||||||
void OpClass::finalize() {
|
void OpClass::finalize() {
|
||||||
Class::finalize();
|
Class::finalize();
|
||||||
declare<VisibilityDeclaration>(Visibility::Public);
|
declare<VisibilityDeclaration>(Visibility::Public);
|
||||||
declare<ExtraClassDeclaration>(extraClassDeclaration);
|
declare<ExtraClassDeclaration>(extraClassDeclaration, extraClassDefinition);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,8 @@ public:
|
|||||||
/// - inheritance of `print`
|
/// - inheritance of `print`
|
||||||
/// - a type alias for the associated adaptor class
|
/// - a type alias for the associated adaptor class
|
||||||
///
|
///
|
||||||
OpClass(StringRef name, StringRef extraClassDeclaration);
|
OpClass(StringRef name, StringRef extraClassDeclaration,
|
||||||
|
std::string extraClassDefinition);
|
||||||
|
|
||||||
/// Add an op trait.
|
/// Add an op trait.
|
||||||
void addTrait(Twine trait) { parent.addTemplateParam(trait.str()); }
|
void addTrait(Twine trait) { parent.addTemplateParam(trait.str()); }
|
||||||
@ -39,6 +40,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
/// Hand-written extra class declarations.
|
/// Hand-written extra class declarations.
|
||||||
StringRef extraClassDeclaration;
|
StringRef extraClassDeclaration;
|
||||||
|
/// Hand-written extra class definitions.
|
||||||
|
std::string extraClassDefinition;
|
||||||
/// The parent class, which also contains the traits to be inherited.
|
/// The parent class, which also contains the traits to be inherited.
|
||||||
ParentClass &parent;
|
ParentClass &parent;
|
||||||
};
|
};
|
||||||
|
@ -557,10 +557,18 @@ static void genAttributeVerifier(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Op extra class definitions have a `$cppClass` substitution that is to be
|
||||||
|
/// replaced by the C++ class name.
|
||||||
|
static std::string formatExtraDefinitions(const Operator &op) {
|
||||||
|
FmtContext ctx = FmtContext().addSubst("cppClass", op.getCppClassName());
|
||||||
|
return tgfmt(op.getExtraClassDefinition(), &ctx).str();
|
||||||
|
}
|
||||||
|
|
||||||
OpEmitter::OpEmitter(const Operator &op,
|
OpEmitter::OpEmitter(const Operator &op,
|
||||||
const StaticVerifierFunctionEmitter &staticVerifierEmitter)
|
const StaticVerifierFunctionEmitter &staticVerifierEmitter)
|
||||||
: def(op.getDef()), op(op),
|
: def(op.getDef()), op(op),
|
||||||
opClass(op.getCppClassName(), op.getExtraClassDeclaration()),
|
opClass(op.getCppClassName(), op.getExtraClassDeclaration(),
|
||||||
|
formatExtraDefinitions(op)),
|
||||||
staticVerifierEmitter(staticVerifierEmitter) {
|
staticVerifierEmitter(staticVerifierEmitter) {
|
||||||
verifyCtx.withOp("(*this->getOperation())");
|
verifyCtx.withOp("(*this->getOperation())");
|
||||||
verifyCtx.addSubst("_ctxt", "this->getOperation()->getContext()");
|
verifyCtx.addSubst("_ctxt", "this->getOperation()->getContext()");
|
||||||
|
Loading…
Reference in New Issue
Block a user