Use properties for attributes for many dialects

This change enables the use of operation properties for more dialects in
CIRCT. The option to *not* use properties is going to be removed in a
future release of MLIR, but as well we expect this change to bring a
performance improvement.

For all these dialects, the only change required was to properly infer
return types.  Some operations were hardcoded to search through the
attributes, and the attribute was moved to the property storage. By
using the generated adaptor classes, we can abstract over where the
interesting attribute is stored.

For future work, some code may be refactored for further performance
wins now that we are using properties. In particular usages `setAttr`
and `getAttr` may be made faster by using a less generic op
transformation interface.
This commit is contained in:
Andrew Young 2024-10-25 17:51:33 -07:00
parent 542d7e5f37
commit 54aa4e3d05
27 changed files with 31 additions and 91 deletions

View File

@ -22,9 +22,6 @@ def ArcDialect : Dialect {
let hasConstantMaterializer = 1;
let useDefaultTypePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
void registerTypes();
}];

View File

@ -39,9 +39,6 @@ def CalyxDialect : Dialect {
// Depends on the HWDialect to support external primitives using hw.module.extern
let dependentDialects = ["circt::hw::HWDialect"];
let cppNamespace = "::circt::calyx";
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
}
class SameTypeConstraint<string lhs, string rhs>

View File

@ -28,10 +28,6 @@ def CombDialect : Dialect {
}];
let hasConstantMaterializer = 1;
let cppNamespace = "::circt::comb";
// This will be the default after next LLVM bump.
let usePropertiesForAttributes = 1;
}
// Base class for the operation in this dialect.

View File

@ -19,13 +19,8 @@ def DCDialect : Dialect {
handshaking semantics.
}];
let cppNamespace = "circt::dc";
let useDefaultTypePrinterParser = 1;
let dependentDialects = ["circt::esi::ESIDialect"];
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
void registerTypes();
}];

View File

@ -30,9 +30,6 @@ def CHIRRTLDialect : Dialect {
let useDefaultTypePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
/// Register all FIRRTL types.

View File

@ -25,9 +25,6 @@ def FSMDialect : Dialect {
let useDefaultTypePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let dependentDialects = [
"circt::seq::SeqDialect"
];

View File

@ -28,9 +28,6 @@ def HWDialect : Dialect {
let hasConstantMaterializer = 1;
let useDefaultTypePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
/// Register all HW types.
void registerTypes();

View File

@ -16,10 +16,6 @@
def HWArithDialect : Dialect {
let name = "hwarith";
let cppNamespace = "::circt::hwarith";
// This will be the default after next LLVM bump.
let usePropertiesForAttributes = 1;
let summary = "Types and operations for the HWArith dialect";
let description = [{
This dialect defines the `HWArith` dialect, modeling bit-width aware

View File

@ -35,9 +35,6 @@ def Handshake_Dialect : Dialect {
let useDefaultAttributePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let dependentDialects = [
"circt::esi::ESIDialect",
"circt::seq::SeqDialect"

View File

@ -22,10 +22,6 @@ def IbisDialect : Dialect {
}];
let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
void registerTypes();
void registerAttributes();

View File

@ -761,9 +761,9 @@ class PortLikeOp<string mnemonic, list<Trait> traits = []> :
mlir::OpaqueProperties properties,
mlir::RegionRange regions,
SmallVectorImpl<Type> &results) {
results.push_back(PortRefType::get(context,
llvm::cast<TypeAttr>(attrs.get("type")).getValue(),
getPortDirection()));
Adaptor adaptor(operands, attrs, properties, regions);
results.push_back(PortRefType::get(context, adaptor.getType(),
getPortDirection()));
return success();
}

View File

@ -32,9 +32,6 @@ def LLHDDialect : Dialect {
let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
/// Register all LLHD types.
void registerTypes();

View File

@ -18,9 +18,6 @@ def LTLDialect : Dialect {
let cppNamespace = "circt::ltl";
let useDefaultTypePrinterParser = 1;
let dependentDialects = ["hw::HWDialect", "comb::CombDialect"];
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
}
#endif // CIRCT_DIALECT_LTL_LTLDIALECT_TD

View File

@ -16,9 +16,6 @@ def LoopSchedule_Dialect : Dialect {
let name = "loopschedule";
let cppNamespace = "::circt::loopschedule";
let summary = "Representation of scheduled loops";
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
}
include "circt/Dialect/LoopSchedule/LoopScheduleOps.td"

View File

@ -32,9 +32,6 @@ def OMDialect : Dialect {
let useDefaultAttributePrinterParser = 1;
let useDefaultTypePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let dependentDialects = [
"circt::hw::HWDialect"
];

View File

@ -14,10 +14,6 @@ include "mlir/IR/OpBase.td"
def Pipeline_Dialect : Dialect {
let name = "pipeline";
let cppNamespace = "::circt::pipeline";
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let dependentDialects = [
"circt::seq::SeqDialect"
];

View File

@ -32,9 +32,6 @@ def SSPDialect : Dialect {
let useDefaultAttributePrinterParser = true;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
/// Register all SSP attributes.
void registerAttributes();

View File

@ -16,6 +16,7 @@
#include "circt/Dialect/SSP/SSPAttributes.h"
#include "circt/Dialect/SSP/SSPDialect.h"
#include "mlir/Bytecode/BytecodeOpInterface.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/IR/RegionKindInterface.h"
#include "mlir/IR/SymbolTable.h"

View File

@ -28,9 +28,6 @@ def SVDialect : Dialect {
let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
let extraClassDeclaration = [{
/// Register all SV types.
void registerTypes();

View File

@ -25,9 +25,6 @@ def SeqDialect : Dialect {
let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
// This will be the default after next LLVM bump.
let usePropertiesForAttributes = 1;
let cppNamespace = "::circt::seq";
let extraClassDeclaration = [{

View File

@ -35,9 +35,6 @@ def SystemCDialect : Dialect {
}];
let useDefaultTypePrinterParser = 0;
// Opt-out of properties for now, must migrate by LLVM 19. #5273.
let usePropertiesForAttributes = 0;
}
#endif // CIRCT_DIALECT_SYSTEMC_SYSTEMCDIALECT

View File

@ -18,9 +18,6 @@ def VerifDialect : Dialect {
let cppNamespace = "circt::verif";
let hasConstantMaterializer = 1;
// This will be the default after next LLVM bump.
let usePropertiesForAttributes = 1;
let dependentDialects = [
"circt::seq::SeqDialect", "circt::hw::HWDialect"
];

View File

@ -2780,10 +2780,10 @@ LogicalResult UnionExtractOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
Adaptor adaptor(operands, attrs, properties, regions);
auto unionElements =
hw::type_cast<UnionType>((operands[0].getType())).getElements();
unsigned fieldIndex =
attrs.getAs<IntegerAttr>("fieldIndex").getValue().getZExtValue();
hw::type_cast<UnionType>((adaptor.getInput().getType())).getElements();
unsigned fieldIndex = adaptor.getFieldIndexAttr().getValue().getZExtValue();
if (fieldIndex >= unionElements.size()) {
if (loc)
mlir::emitError(*loc, "field index " + Twine(fieldIndex) +

View File

@ -410,7 +410,8 @@ LogicalResult PathOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
auto path = cast<ArrayAttr>(attrs.get("path"));
Adaptor adaptor(operands, attrs, properties, regions);
auto path = adaptor.getPathAttr();
if (path.empty())
return failure();

View File

@ -282,16 +282,16 @@ LogicalResult SigArrayGetOp::ensureOnlySafeAccesses(
// SigStructExtractOp and PtrStructExtractOp
//===----------------------------------------------------------------------===//
template <class SigPtrType>
template <class OpType, class SigPtrType>
static LogicalResult inferReturnTypesOfStructExtractOp(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
typename OpType::Adaptor adaptor(operands, attrs, properties, regions);
Type type =
cast<hw::StructType>(
cast<SigPtrType>(operands[0].getType()).getElementType())
.getFieldType(
cast<StringAttr>(attrs.getNamed("field")->getValue()).getValue());
cast<SigPtrType>(adaptor.getInput().getType()).getElementType())
.getFieldType(adaptor.getField());
if (!type) {
context->getDiagEngine().emit(loc.value_or(UnknownLoc()),
DiagnosticSeverity::Error)
@ -306,7 +306,8 @@ LogicalResult llhd::SigStructExtractOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
return inferReturnTypesOfStructExtractOp<hw::InOutType>(
return inferReturnTypesOfStructExtractOp<llhd::SigStructExtractOp,
hw::InOutType>(
context, loc, operands, attrs, properties, regions, results);
}
@ -314,7 +315,8 @@ LogicalResult llhd::PtrStructExtractOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
return inferReturnTypesOfStructExtractOp<llhd::PtrType>(
return inferReturnTypesOfStructExtractOp<llhd::PtrStructExtractOp,
llhd::PtrType>(
context, loc, operands, attrs, properties, regions, results);
}

View File

@ -510,13 +510,14 @@ LogicalResult TupleCreateOp::inferReturnTypes(
LogicalResult TupleGetOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> location, ValueRange operands,
DictionaryAttr attributes, OpaqueProperties, RegionRange regions,
DictionaryAttr attributes, OpaqueProperties properties, RegionRange regions,
llvm::SmallVectorImpl<Type> &inferredReturnTypes) {
auto idx = attributes.getAs<mlir::IntegerAttr>("index");
Adaptor adaptor(operands, attributes, properties, regions);
auto idx = adaptor.getIndexAttr();
if (operands.empty() || !idx)
return failure();
auto tupleTypes = cast<TupleType>(operands[0].getType()).getTypes();
auto tupleTypes = cast<TupleType>(adaptor.getInput().getType()).getTypes();
if (tupleTypes.size() <= idx.getValue().getLimitedValue()) {
if (location)
mlir::emitError(*location,

View File

@ -1703,13 +1703,13 @@ LogicalResult IndexedPartSelectInOutOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
auto width = attrs.get("width");
Adaptor adaptor(operands, attrs, properties, regions);
auto width = adaptor.getWidthAttr();
if (!width)
return failure();
auto typ =
getElementTypeOfWidth(operands[0].getType(),
cast<IntegerAttr>(width).getValue().getZExtValue());
auto typ = getElementTypeOfWidth(operands[0].getType(),
width.getValue().getZExtValue());
if (!typ)
return failure();
results.push_back(typ);
@ -1756,12 +1756,12 @@ LogicalResult IndexedPartSelectOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
auto width = attrs.get("width");
Adaptor adaptor(operands, attrs, properties, regions);
auto width = adaptor.getWidthAttr();
if (!width)
return failure();
results.push_back(
IntegerType::get(context, cast<IntegerAttr>(width).getInt()));
results.push_back(IntegerType::get(context, width.getInt()));
return success();
}
@ -1786,12 +1786,13 @@ LogicalResult StructFieldInOutOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attrs, mlir::OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &results) {
auto field = attrs.get("field");
Adaptor adaptor(operands, attrs, properties, regions);
auto field = adaptor.getFieldAttr();
if (!field)
return failure();
auto structType =
hw::type_cast<hw::StructType>(getInOutElementType(operands[0].getType()));
auto resultType = structType.getFieldType(cast<StringAttr>(field));
auto resultType = structType.getFieldType(field);
if (!resultType)
return failure();