Skip to content

[mlir][ods] Do not print default-valued properties when the value is equal to the default #87970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion mlir/include/mlir/Dialect/XeGPU/IR/XeGPUOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class XeGPU_Op<string mnemonic, list<Trait> traits = []>:

code extraBaseClassDeclaration = [{
void printProperties(::mlir::MLIRContext *ctx,
::mlir::OpAsmPrinter &p, const Properties &prop) {
::mlir::OpAsmPrinter &p, const Properties &prop,
::mlir::ArrayRef<::llvm::StringRef> elidedProps) {
Attribute propAttr = getPropertiesAsAttr(ctx, prop);
if (propAttr)
p << "<" << propAttr << ">";
Expand Down
31 changes: 19 additions & 12 deletions mlir/include/mlir/IR/OpDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,10 @@ class OpState {
static ParseResult genericParseProperties(OpAsmParser &parser,
Attribute &result);

/// Print the properties as a Attribute.
static void genericPrintProperties(OpAsmPrinter &p, Attribute properties);
/// Print the properties as a Attribute with names not included within
/// 'elidedProps'
static void genericPrintProperties(OpAsmPrinter &p, Attribute properties,
ArrayRef<StringRef> elidedProps = {});

/// Print an operation name, eliding the dialect prefix if necessary.
static void printOpName(Operation *op, OpAsmPrinter &p,
Expand Down Expand Up @@ -1805,10 +1807,13 @@ class Op : public OpState, public Traits<ConcreteType>... {
template <typename T>
using detect_has_print = llvm::is_detected<has_print, T>;

/// Trait to check if printProperties(OpAsmPrinter, T) exist
/// Trait to check if printProperties(OpAsmPrinter, T, ArrayRef<StringRef>)
/// exist
template <typename T, typename... Args>
using has_print_properties = decltype(printProperties(
std::declval<OpAsmPrinter &>(), std::declval<T>()));
using has_print_properties =
decltype(printProperties(std::declval<OpAsmPrinter &>(),
std::declval<T>(),
std::declval<ArrayRef<StringRef>>()));
template <typename T>
using detect_has_print_properties =
llvm::is_detected<has_print_properties, T>;
Expand Down Expand Up @@ -1974,16 +1979,18 @@ class Op : public OpState, public Traits<ConcreteType>... {
static void populateDefaultProperties(OperationName opName,
InferredProperties<T> &properties) {}

/// Print the operation properties. Unless overridden, this method will try to
/// dispatch to a `printProperties` free-function if it exists, and otherwise
/// by converting the properties to an Attribute.
/// Print the operation properties with names not included within
/// 'elidedProps'. Unless overridden, this method will try to dispatch to a
/// `printProperties` free-function if it exists, and otherwise by converting
/// the properties to an Attribute.
template <typename T>
static void printProperties(MLIRContext *ctx, OpAsmPrinter &p,
const T &properties) {
const T &properties,
ArrayRef<StringRef> elidedProps = {}) {
if constexpr (detect_has_print_properties<T>::value)
return printProperties(p, properties);
genericPrintProperties(p,
ConcreteType::getPropertiesAsAttr(ctx, properties));
return printProperties(p, properties, elidedProps);
genericPrintProperties(
p, ConcreteType::getPropertiesAsAttr(ctx, properties), elidedProps);
}

/// Parser the properties. Unless overridden, this method will print by
Expand Down
30 changes: 24 additions & 6 deletions mlir/lib/IR/Operation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,15 +790,33 @@ void OpState::printOpName(Operation *op, OpAsmPrinter &p,
/// Parse properties as a Attribute.
ParseResult OpState::genericParseProperties(OpAsmParser &parser,
Attribute &result) {
if (parser.parseLess() || parser.parseAttribute(result) ||
parser.parseGreater())
return failure();
if (succeeded(parser.parseOptionalLess())) { // The less is optional.
if (parser.parseAttribute(result) || parser.parseGreater())
return failure();
}
return success();
}

/// Print the properties as a Attribute.
void OpState::genericPrintProperties(OpAsmPrinter &p, Attribute properties) {
p << "<" << properties << ">";
/// Print the properties as a Attribute with names not included within
/// 'elidedProps'
void OpState::genericPrintProperties(OpAsmPrinter &p, Attribute properties,
ArrayRef<StringRef> elidedProps) {
auto dictAttr = dyn_cast_or_null<::mlir::DictionaryAttr>(properties);
if (dictAttr && !elidedProps.empty()) {
ArrayRef<NamedAttribute> attrs = dictAttr.getValue();
llvm::SmallDenseSet<StringRef> elidedAttrsSet(elidedProps.begin(),
elidedProps.end());
bool atLeastOneAttr = llvm::any_of(attrs, [&](NamedAttribute attr) {
return !elidedAttrsSet.contains(attr.getName().strref());
});
if (atLeastOneAttr) {
p << "<";
p.printOptionalAttrDict(dictAttr.getValue(), elidedProps);
p << ">";
}
} else {
p << "<" << properties << ">";
}
}

/// Emit an error about fatal conditions with this operation, reporting up to
Expand Down
5 changes: 5 additions & 0 deletions mlir/test/IR/properties.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ test.using_property_in_custom [1, 4, 20]
// GENERIC-SAME: second = 4
// GENERIC-SAME: }>
test.using_property_ref_in_custom 1 + 4 = 5

// CHECK: test.with_default_valued_properties {{$}}
// GENERIC: "test.with_default_valued_properties"()
// GENERIC-SAME: <{a = 0 : i32}>
test.with_default_valued_properties <{a = 0 : i32}>
17 changes: 13 additions & 4 deletions mlir/test/lib/Dialect/Test/TestOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2909,7 +2909,8 @@ def TestOpWithNiceProperties : TEST_Op<"with_nice_properties"> {
);
let extraClassDeclaration = [{
void printProperties(::mlir::MLIRContext *ctx, ::mlir::OpAsmPrinter &p,
const Properties &prop);
const Properties &prop,
::mlir::ArrayRef<::llvm::StringRef> elidedProps);
static ::mlir::ParseResult parseProperties(::mlir::OpAsmParser &parser,
::mlir::OperationState &result);
static ::mlir::LogicalResult readFromMlirBytecode(
Expand Down Expand Up @@ -2938,7 +2939,8 @@ def TestOpWithNiceProperties : TEST_Op<"with_nice_properties"> {
writer.writeVarInt(prop.value);
}
void TestOpWithNiceProperties::printProperties(::mlir::MLIRContext *ctx,
::mlir::OpAsmPrinter &p, const Properties &prop) {
::mlir::OpAsmPrinter &p, const Properties &prop,
::mlir::ArrayRef<::llvm::StringRef> elidedProps) {
customPrintProperties(p, prop.prop);
}
::mlir::ParseResult TestOpWithNiceProperties::parseProperties(
Expand Down Expand Up @@ -2971,7 +2973,8 @@ def TestOpWithVersionedProperties : TEST_Op<"with_versioned_properties"> {
);
let extraClassDeclaration = [{
void printProperties(::mlir::MLIRContext *ctx, ::mlir::OpAsmPrinter &p,
const Properties &prop);
const Properties &prop,
::mlir::ArrayRef<::llvm::StringRef> elidedProps);
static ::mlir::ParseResult parseProperties(::mlir::OpAsmParser &parser,
::mlir::OperationState &result);
static ::mlir::LogicalResult readFromMlirBytecode(
Expand All @@ -2983,7 +2986,8 @@ def TestOpWithVersionedProperties : TEST_Op<"with_versioned_properties"> {
}];
let extraClassDefinition = [{
void TestOpWithVersionedProperties::printProperties(::mlir::MLIRContext *ctx,
::mlir::OpAsmPrinter &p, const Properties &prop) {
::mlir::OpAsmPrinter &p, const Properties &prop,
::mlir::ArrayRef<::llvm::StringRef> elidedProps) {
customPrintProperties(p, prop.prop);
}
::mlir::ParseResult TestOpWithVersionedProperties::parseProperties(
Expand All @@ -2997,6 +3001,11 @@ def TestOpWithVersionedProperties : TEST_Op<"with_versioned_properties"> {
}];
}

def TestOpWithDefaultValuedProperties : TEST_Op<"with_default_valued_properties"> {
let assemblyFormat = "prop-dict attr-dict";
let arguments = (ins DefaultValuedAttr<I32Attr, "0">:$a);
}

//===----------------------------------------------------------------------===//
// Test Dataflow
//===----------------------------------------------------------------------===//
Expand Down
23 changes: 22 additions & 1 deletion mlir/tools/mlir-tblgen/OpFormatGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1775,9 +1775,30 @@ const char *enumAttrBeginPrinterCode = R"(
/// Generate the printer for the 'prop-dict' directive.
static void genPropDictPrinter(OperationFormat &fmt, Operator &op,
MethodBody &body) {
body << " ::llvm::SmallVector<::llvm::StringRef, 2> elidedProps;\n";
// Add code to check attributes for equality with the default value
// for attributes with the elidePrintingDefaultValue bit set.
for (const NamedAttribute &namedAttr : op.getAttributes()) {
const Attribute &attr = namedAttr.attr;
if (!attr.isDerivedAttr() && attr.hasDefaultValue()) {
const StringRef &name = namedAttr.name;
FmtContext fctx;
fctx.withBuilder("odsBuilder");
std::string defaultValue = std::string(
tgfmt(attr.getConstBuilderTemplate(), &fctx, attr.getDefaultValue()));
body << " {\n";
body << " ::mlir::Builder odsBuilder(getContext());\n";
body << " ::mlir::Attribute attr = " << op.getGetterName(name)
<< "Attr();\n";
body << " if(attr && (attr == " << defaultValue << "))\n";
body << " elidedProps.push_back(\"" << name << "\");\n";
body << " }\n";
}
}

body << " _odsPrinter << \" \";\n"
<< " printProperties(this->getContext(), _odsPrinter, "
"getProperties());\n";
"getProperties(), elidedProps);\n";
}

/// Generate the printer for the 'attr-dict' directive.
Expand Down