From 3c08741164b507573760c720c8cdec830861d3ba Mon Sep 17 00:00:00 2001 From: Fabian Schuiki Date: Wed, 10 Nov 2021 17:26:00 +0100 Subject: [PATCH] [TableGen] Factor common defs out into common `Types.td` (#2120) Create a CIRCT-wide `include/circt/Types.td` file that can collect the common type, attribute, and constraint definitions used throughout the CIRCT project, which may not be specific to one of the given dialects. Things that land here would generally be candidates for upstreaming to MLIR, but it's better to have a common place in CIRCT first where they can incubate. While we're at it, get rid of some of the type definitions which have since appeared in upstream MLIR, and factor some first commonalities out into `Types.td`. There will be quite a few more in the future. --- .../circt/Dialect/FIRRTL/FIRRTLExpressions.td | 8 +--- .../circt/Dialect/FIRRTL/FIRRTLStructure.td | 6 ++- include/circt/Dialect/FIRRTL/FIRRTLTypes.td | 24 ----------- include/circt/Dialect/HW/HWTypes.td | 10 +++++ include/circt/Dialect/SV/SVInOutOps.td | 4 +- include/circt/Dialect/SV/SVTypes.td | 42 ++----------------- include/circt/Types.td | 29 +++++++++++++ 7 files changed, 50 insertions(+), 73 deletions(-) create mode 100644 include/circt/Types.td diff --git a/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td b/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td index 80c0a54bd676..8b93914828fd 100644 --- a/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td +++ b/include/circt/Dialect/FIRRTL/FIRRTLExpressions.td @@ -10,13 +10,7 @@ // //===----------------------------------------------------------------------===// -def APSIntAttr : Attr()">, - "arbitrary integer attribute with sign"> { - let storageType = [{ ::mlir::IntegerAttr }]; - let returnType = [{ ::llvm::APSInt }]; - let constBuilderCall = "IntegerAttr::get($_builder.getContext(), $0)"; - let convertFromStorage = "APSInt($_self.getValue(), !getType().isSigned())"; -} +include "circt/Types.td" def SameOperandsIntTypeKind : NativeOpTrait<"SameOperandsIntTypeKind"> { let cppNamespace = "::circt::firrtl"; diff --git a/include/circt/Dialect/FIRRTL/FIRRTLStructure.td b/include/circt/Dialect/FIRRTL/FIRRTLStructure.td index 8c51c808e892..9172f317a3da 100644 --- a/include/circt/Dialect/FIRRTL/FIRRTLStructure.td +++ b/include/circt/Dialect/FIRRTL/FIRRTLStructure.td @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +include "circt/Types.td" + def CircuitOp : FIRRTLOp<"circuit", [IsolatedFromAbove, SymbolTable, SingleBlock, NoTerminator, NoRegionArguments]> { @@ -139,8 +141,8 @@ def NonLocalAnchor : FIRRTLOp<"nla", annotations to anchor to in the global scope. This lets components of the path point to a common entity. }]; - let arguments = (ins SymbolNameAttr:$sym_name, SymbolArrayAttr:$modpath, - StringArrayAttr:$namepath); + let arguments = (ins SymbolNameAttr:$sym_name, + FlatSymbolRefArrayAttr:$modpath, StrArrayAttr:$namepath); let results = (outs); let assemblyFormat = [{ $sym_name $modpath $namepath attr-dict}]; } diff --git a/include/circt/Dialect/FIRRTL/FIRRTLTypes.td b/include/circt/Dialect/FIRRTL/FIRRTLTypes.td index 9db470a3fb9d..3859dd39487a 100644 --- a/include/circt/Dialect/FIRRTL/FIRRTLTypes.td +++ b/include/circt/Dialect/FIRRTL/FIRRTLTypes.td @@ -212,30 +212,6 @@ def InvalidValueAttr : AttrDef { ]; } -def SymbolArrayAttr: ArrayAttrBase< - And<[ - // Guarantee this is an ArrayAttr first - CPred<"$_self.isa<::mlir::ArrayAttr>()">, - // Guarantee all elements are FlatSymbolRefAttr - CPred<"::llvm::all_of($_self.cast<::mlir::ArrayAttr>(), " - "[&](::mlir::Attribute attr) { return attr.isa<" - "::mlir::FlatSymbolRefAttr>();})">]>, - ""> { - let constBuilderCall = "$_builder.getArrayAttr($0)"; -} - -def StringArrayAttr: ArrayAttrBase< - And<[ - // Guarantee this is an ArrayAttr first - CPred<"$_self.isa<::mlir::ArrayAttr>()">, - // Guarantee all elements are StringAttr - CPred<"::llvm::all_of($_self.cast<::mlir::ArrayAttr>(), " - "[&](::mlir::Attribute attr) { return attr.isa<" - "::mlir::StringAttr>();})">]>, - ""> { - let constBuilderCall = "$_builder.getArrayAttr($0)"; -} - class AugmentedType : AttrDef { let parameters = ( ins "DictionaryAttr":$underlying diff --git a/include/circt/Dialect/HW/HWTypes.td b/include/circt/Dialect/HW/HWTypes.td index 6722432720c8..d99ec46bc0f7 100644 --- a/include/circt/Dialect/HW/HWTypes.td +++ b/include/circt/Dialect/HW/HWTypes.td @@ -57,5 +57,15 @@ def UnionType : DialectType()">, + "name reference attribute">; + +// Like a FlatSymbolRefArrayAttr, but can also refer to names inside modules. +def NameRefArrayAttr : TypedArrayAttrBase { + let constBuilderCall = "$_builder.getArrayAttr($0)"; +} #endif // CIRCT_DIALECT_HW_HWTYPES diff --git a/include/circt/Dialect/SV/SVInOutOps.td b/include/circt/Dialect/SV/SVInOutOps.td index c912e9a7b867..a604bcbd6552 100644 --- a/include/circt/Dialect/SV/SVInOutOps.td +++ b/include/circt/Dialect/SV/SVInOutOps.td @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +include "circt/Types.td" + // Note that net declarations like 'wire' should not appear in an always block. def WireOp : SVOp<"wire", [NonProceduralOp, DeclareOpInterfaceMethods]> { @@ -91,7 +93,7 @@ def XMROp : SVOp<"xmr", []> { generating this op should ensure that any instance or object in the intended path has public visibility so paths are not invalidated. }]; - let arguments = (ins UnitAttr:$isRooted, StringArrayAttr:$path, StrAttr:$terminal); + let arguments = (ins UnitAttr:$isRooted, StrArrayAttr:$path, StrAttr:$terminal); let results = (outs InOutType:$result); let assemblyFormat = "(`isRooted` $isRooted^)? custom($path, $terminal) attr-dict `:` type($result)"; } diff --git a/include/circt/Dialect/SV/SVTypes.td b/include/circt/Dialect/SV/SVTypes.td index bfe0839d6294..4a48eb4865b7 100644 --- a/include/circt/Dialect/SV/SVTypes.td +++ b/include/circt/Dialect/SV/SVTypes.td @@ -15,6 +15,9 @@ include "circt/Dialect/SV/SVDialect.td" +// TODO: The following should go into a `SVTypesImpl.td` if we ever actually +// define any SV-specific types. Doing so will keep this `SVTypes.td` file +// includable for other dialects, without polluting their output with SV types. class SVType : TypeDef { } //===----------------------------------------------------------------------===// @@ -48,43 +51,4 @@ class InOutElementConstraint : TypesMatchWith<"type should be element of inout type", inoutValue, value, "sv::getInOutElementType($_self)">; -// This type is an array of FlatSymbolRefAttr. -// TODO: This should be moved to mlir, it does not depend on HW dialect. -def SymRefArrayAttr: ArrayAttrBase< - And<[ - // Guarantee this is an ArrayAttr first - CPred<"$_self.isa<::mlir::ArrayAttr>()">, - // Guarantee all elements are DictionaryAttr or SubAnnotationAttr - CPred<"::llvm::all_of($_self.cast<::mlir::ArrayAttr>(), " - "[&](::mlir::Attribute attr) { return attr.isa<" - "::mlir::FlatSymbolRefAttr>();})">]>, - ""> { - let constBuilderCall = "$_builder.getArrayAttr($0)"; -} - -// Like a SymRefArrayAttr, but can also refer to names inside modules. -def NameRefArrayAttr: ArrayAttrBase< - And<[ - // Guarantee this is an ArrayAttr first - CPred<"$_self.isa<::mlir::ArrayAttr>()">, - // Guarantee all elements are symbols or name refs - CPred<"::llvm::all_of($_self.cast<::mlir::ArrayAttr>(), " - "[&](::mlir::Attribute attr) { return attr.isa<" - "::mlir::FlatSymbolRefAttr, ::hw::InnerRefAttr>();})">]>, - ""> { - let constBuilderCall = "$_builder.getArrayAttr($0)"; -} - -def StringArrayAttr: ArrayAttrBase< - And<[ - // Guarantee this is an ArrayAttr first - CPred<"$_self.isa<::mlir::ArrayAttr>()">, - // Guarantee all elements are StringAttr - CPred<"::llvm::all_of($_self.cast<::mlir::ArrayAttr>(), " - "[&](::mlir::Attribute attr) { return attr.isa<" - "::mlir::StringAttr>();})">]>, - ""> { - let constBuilderCall = "$_builder.getArrayAttr($0)"; -} - #endif // CIRCT_DIALECT_SV_SVTYPES diff --git a/include/circt/Types.td b/include/circt/Types.td new file mode 100644 index 000000000000..2d57a0fa2566 --- /dev/null +++ b/include/circt/Types.td @@ -0,0 +1,29 @@ +//===- Types.td - Common type predicates and definitions ---*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file collects type predicates and definitions commonly used in the CIRCT +// dialects. +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_TYPES +#define CIRCT_TYPES + +//===----------------------------------------------------------------------===// +// Attributes +//===----------------------------------------------------------------------===// + +def APSIntAttr : Attr()">, + "arbitrary integer attribute with sign"> { + let storageType = [{ ::mlir::IntegerAttr }]; + let returnType = [{ ::llvm::APSInt }]; + let constBuilderCall = "IntegerAttr::get($_builder.getContext(), $0)"; + let convertFromStorage = "APSInt($_self.getValue(), !getType().isSigned())"; +} + +#endif // CIRCT_TYPES