From 2f52c10833f3aed7ae5cc7b2356d930384964ade Mon Sep 17 00:00:00 2001 From: Martin Erhart Date: Mon, 16 Dec 2024 15:29:17 +0100 Subject: [PATCH] [RTGTest] Improved register representation --- include/circt-c/Dialect/RTGTest.h | 195 +++++++++++++ include/circt/Dialect/RTG/IR/CMakeLists.txt | 10 + .../RTG/IR/RTGISAAssemblyAttrInterfaces.h | 24 ++ .../RTG/IR/RTGISAAssemblyInterfaces.td | 43 +-- .../RTG/IR/RTGISAAssemblyTypeInterfaces.h | 22 ++ include/circt/Dialect/RTG/IR/RTGOps.h | 2 + include/circt/Dialect/RTG/IR/RTGOps.td | 39 +++ include/circt/Dialect/RTG/IR/RTGVisitors.h | 30 +- include/circt/Dialect/RTGTest/IR/RTGTest.td | 1 + .../Dialect/RTGTest/IR/RTGTestAttributes.h | 1 + .../Dialect/RTGTest/IR/RTGTestAttributes.td | 96 ++++--- .../circt/Dialect/RTGTest/IR/RTGTestOps.td | 18 -- .../circt/Dialect/RTGTest/IR/RTGTestTypes.h | 1 + .../circt/Dialect/RTGTest/IR/RTGTestTypes.td | 5 +- .../Bindings/Python/dialects/rtg.py | 71 +++++ lib/Bindings/Python/RTGTestModule.cpp | 256 +++++++++++++++++ lib/CAPI/Dialect/RTGTest.cpp | 259 ++++++++++++++++++ lib/Dialect/RTG/IR/CMakeLists.txt | 4 + .../RTG/IR/RTGISAAssemblyAttrInterfaces.cpp | 19 ++ .../RTG/IR/RTGISAAssemblyTypeInterfaces.cpp | 19 ++ lib/Dialect/RTG/IR/RTGOps.cpp | 60 ++++ .../RTG/Transforms/ElaborationPass.cpp | 1 - lib/Dialect/RTGTest/IR/RTGTestOps.cpp | 47 ---- test/CAPI/rtgtest.c | 229 ++++++++++++++++ test/Dialect/RTGTest/IR/basic.mlir | 149 +++++----- unittests/Dialect/CMakeLists.txt | 1 - unittests/Dialect/RTGTest/CMakeLists.txt | 8 - unittests/Dialect/RTGTest/RegisterTest.cpp | 59 ---- 28 files changed, 1384 insertions(+), 285 deletions(-) create mode 100644 include/circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h create mode 100644 include/circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h create mode 100644 lib/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.cpp create mode 100644 lib/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.cpp delete mode 100644 unittests/Dialect/RTGTest/CMakeLists.txt delete mode 100644 unittests/Dialect/RTGTest/RegisterTest.cpp diff --git a/include/circt-c/Dialect/RTGTest.h b/include/circt-c/Dialect/RTGTest.h index 27761bee4a9d..7a7763d06bd9 100644 --- a/include/circt-c/Dialect/RTGTest.h +++ b/include/circt-c/Dialect/RTGTest.h @@ -45,6 +45,201 @@ MLIR_CAPI_EXPORTED MlirAttribute rtgtestCPUAttrGet(MlirContext ctxt, /// Returns the core ID represented by the CPU attribute. MLIR_CAPI_EXPORTED unsigned rtgtestCPUAttrGetId(MlirAttribute attr); +// Registers. +//===----------------------------------------------------------------------===// + +/// If the type is an RTGTest RegZeroAttr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegZero(MlirAttribute attr); + +/// Creates an RTGTest RegZero attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegZeroAttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegRaAttr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegRa(MlirAttribute attr); + +/// Creates an RTGTest RegRa attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegRaAttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegSpAttr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegSp(MlirAttribute attr); + +/// Creates an RTGTest RegSp attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegSpAttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegGpAttr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegGp(MlirAttribute attr); + +/// Creates an RTGTest RegGp attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegGpAttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegTpAttr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegTp(MlirAttribute attr); + +/// Creates an RTGTest RegTp attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegTpAttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegT0Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT0(MlirAttribute attr); + +/// Creates an RTGTest RegT0 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT0AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegT1Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT1(MlirAttribute attr); + +/// Creates an RTGTest RegT1 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT1AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegT2Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT2(MlirAttribute attr); + +/// Creates an RTGTest RegT2 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT2AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS0Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS0(MlirAttribute attr); + +/// Creates an RTGTest RegS0 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS0AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS1Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS1(MlirAttribute attr); + +/// Creates an RTGTest RegS1 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS1AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA0Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA0(MlirAttribute attr); + +/// Creates an RTGTest RegA0 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA0AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA1Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA1(MlirAttribute attr); + +/// Creates an RTGTest RegA1 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA1AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA2Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA2(MlirAttribute attr); + +/// Creates an RTGTest RegA2 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA2AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA3Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA3(MlirAttribute attr); + +/// Creates an RTGTest RegA3 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA3AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA4Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA4(MlirAttribute attr); + +/// Creates an RTGTest RegA4 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA4AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA5Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA5(MlirAttribute attr); + +/// Creates an RTGTest RegA5 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA5AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA6Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA6(MlirAttribute attr); + +/// Creates an RTGTest RegA6 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA6AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegA7Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegA7(MlirAttribute attr); + +/// Creates an RTGTest RegA7 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegA7AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS2Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS2(MlirAttribute attr); + +/// Creates an RTGTest RegS2 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS2AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS3Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS3(MlirAttribute attr); + +/// Creates an RTGTest RegS3 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS3AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS4Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS4(MlirAttribute attr); + +/// Creates an RTGTest RegS4 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS4AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS5Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS5(MlirAttribute attr); + +/// Creates an RTGTest RegS5 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS5AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS6Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS6(MlirAttribute attr); + +/// Creates an RTGTest RegS6 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS6AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS7Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS7(MlirAttribute attr); + +/// Creates an RTGTest RegS7 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS7AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS8Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS8(MlirAttribute attr); + +/// Creates an RTGTest RegS8 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS8AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS9Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS9(MlirAttribute attr); + +/// Creates an RTGTest RegS9 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS9AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS10Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS10(MlirAttribute attr); + +/// Creates an RTGTest RegS10 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS10AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegS11Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegS11(MlirAttribute attr); + +/// Creates an RTGTest RegS11 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegS11AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegT3Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT3(MlirAttribute attr); + +/// Creates an RTGTest RegT3 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT3AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegT4Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT4(MlirAttribute attr); + +/// Creates an RTGTest RegT4 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT4AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegT5Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT5(MlirAttribute attr); + +/// Creates an RTGTest RegT5 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT5AttrGet(MlirContext ctxt); + +/// If the attribute is an RTGTest RegT6Attr. +MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT6(MlirAttribute attr); + +/// Creates an RTGTest RegT6 attribute in the context. +MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt); + #ifdef __cplusplus } #endif diff --git a/include/circt/Dialect/RTG/IR/CMakeLists.txt b/include/circt/Dialect/RTG/IR/CMakeLists.txt index b6d18335226c..2c3e3f0e4978 100644 --- a/include/circt/Dialect/RTG/IR/CMakeLists.txt +++ b/include/circt/Dialect/RTG/IR/CMakeLists.txt @@ -24,6 +24,16 @@ add_public_tablegen_target(CIRCTRTGAttrInterfacesIncGen) add_dependencies(circt-headers CIRCTRTGAttrInterfacesIncGen) set(LLVM_TARGET_DEFINITIONS RTGISAAssemblyInterfaces.td) +mlir_tablegen(RTGISAAssemblyAttrInterfaces.h.inc -gen-attr-interface-decls) +mlir_tablegen(RTGISAAssemblyAttrInterfaces.cpp.inc -gen-attr-interface-defs) +add_public_tablegen_target(CIRCTRTGISAAssemblyAttrInterfacesIncGen) +add_dependencies(circt-headers CIRCTRTGISAAssemblyAttrInterfacesIncGen) + +mlir_tablegen(RTGISAAssemblyTypeInterfaces.h.inc -gen-type-interface-decls) +mlir_tablegen(RTGISAAssemblyTypeInterfaces.cpp.inc -gen-type-interface-defs) +add_public_tablegen_target(CIRCTRTGISAAssemblyTypeInterfacesIncGen) +add_dependencies(circt-headers CIRCTRTGISAAssemblyTypeInterfacesIncGen) + mlir_tablegen(RTGISAAssemblyOpInterfaces.h.inc -gen-op-interface-decls) mlir_tablegen(RTGISAAssemblyOpInterfaces.cpp.inc -gen-op-interface-defs) add_public_tablegen_target(CIRCTRTGISAAssemblyOpInterfacesIncGen) diff --git a/include/circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h b/include/circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h new file mode 100644 index 000000000000..d66ebb05b857 --- /dev/null +++ b/include/circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h @@ -0,0 +1,24 @@ +//===- RTGISAAssemblyAttrInterfaces.h - Interf. for ISA ASM RTG -*- C++ -*-===// +// +// 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 declares attr interfaces for the RTG Dialect that are specific to +// ISA Assembly tests. +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYATTRINTERFACES_H +#define CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYATTRINTERFACES_H + +#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h" +#include "mlir/IR/Attributes.h" +#include "mlir/IR/BuiltinAttributeInterfaces.h" +#include "llvm/ADT/APInt.h" + +#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h.inc" + +#endif // CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYATTRINTERFACES_H diff --git a/include/circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td b/include/circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td index 392f64f4c61a..0bcebc5dacc4 100644 --- a/include/circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td +++ b/include/circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td @@ -10,51 +10,38 @@ #define CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYINTERFACES_TD include "mlir/IR/Interfaces.td" -include "mlir/IR/OpBase.td" +include "mlir/IR/BuiltinAttributeInterfaces.td" -def RegisterOpInterface : OpInterface<"RegisterOpInterface"> { +def RegisterAttrInterface : AttrInterface<"RegisterAttrInterface", [TypedAttrInterface]> { let description = [{ - This interface should be implemented by operations that represent - ISA registers. It is used for register allocation, emission, etc. - - Virtual registers are indicated by a register index of ~0. + This interface should be implemented by attributes that represent + ISA registers. It is used for elaboration, register allocation, emission, + etc. }]; let cppNamespace = "::circt::rtg"; let methods = [ - InterfaceMethod<[{ - Returns the bitvector of the Dialect's canonical register indices for - which this operation allows. - }], - "::llvm::BitVector", "getAllowedRegs">, - InterfaceMethod<[{ - Returns the Dialect's canonical register index of the register if it - selects a specific one, or ~0 if it isn't fixed yet. - }], - "unsigned", "getFixedReg">, - InterfaceMethod<[{ - Sets this operation to use a specific register given by the Dialect's - canonical register index. - }], - "void", "setFixedReg", (ins "unsigned":$reg)>, InterfaceMethod<[{ Returns the class specific index of the register. This translates from the flat internal representation to the architectural representation. }], "unsigned", "getClassIndex">, - InterfaceMethod<[{ - Returns the class specific index of the register. This translates from - the flat internal representation to the architectural representation. - This returns an APInt for the common binary encoding. - }], - "llvm::APInt", "getClassIndexBinary">, InterfaceMethod<[{ Returns a suitable string for use in assembly format. }], - "std::string", "getRegisterAssembly">, + "llvm::StringLiteral", "getRegisterAssembly">, ]; } +def RegisterTypeInterface : TypeInterface<"RegisterTypeInterface"> { + let description = [{ + This interface should be implemented by types that represent + ISA registers. It is used for elaboration, register allocation, emission, + etc. + }]; + let cppNamespace = "::circt::rtg"; +} + def InstructionOpInterface : OpInterface<"InstructionOpInterface"> { let description = [{ This interface should be implemented by operations that represent diff --git a/include/circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h b/include/circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h new file mode 100644 index 000000000000..1e51f30043bb --- /dev/null +++ b/include/circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h @@ -0,0 +1,22 @@ +//===- RTGISAAssemblyTypeInterfaces.h - Interf. for ISA ASM RTG -*- C++ -*-===// +// +// 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 declares type interfaces for the RTG Dialect that are specific to +// ISA Assembly tests. +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYTYPEINTERFACES_H +#define CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYTYPEINTERFACES_H + +#include "circt/Support/LLVM.h" +#include "mlir/IR/Types.h" + +#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h.inc" + +#endif // CIRCT_DIALECT_RTG_IR_RTGISAASSEMBLYTYPEINTERFACES_H diff --git a/include/circt/Dialect/RTG/IR/RTGOps.h b/include/circt/Dialect/RTG/IR/RTGOps.h index c6e502a3579e..bb55b5c19d5c 100644 --- a/include/circt/Dialect/RTG/IR/RTGOps.h +++ b/include/circt/Dialect/RTG/IR/RTGOps.h @@ -15,6 +15,8 @@ #include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h" #include "circt/Dialect/RTG/IR/RTGDialect.h" +#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h" +#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h" #include "circt/Dialect/RTG/IR/RTGTypeInterfaces.h" #include "circt/Dialect/RTG/IR/RTGTypes.h" #include "circt/Support/LLVM.h" diff --git a/include/circt/Dialect/RTG/IR/RTGOps.td b/include/circt/Dialect/RTG/IR/RTGOps.td index a1077c6a5c7b..c1de7d58149e 100644 --- a/include/circt/Dialect/RTG/IR/RTGOps.td +++ b/include/circt/Dialect/RTG/IR/RTGOps.td @@ -19,6 +19,7 @@ include "mlir/Interfaces/InferTypeOpInterface.td" include "mlir/Interfaces/SideEffectInterfaces.td" include "mlir/Interfaces/InferTypeOpInterface.td" include "circt/Dialect/RTG/IR/RTGInterfaces.td" +include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td" // Base class for the operation in this dialect. class RTGOp traits = []> : @@ -324,6 +325,44 @@ def BagUniqueSizeOp : RTGOp<"bag_unique_size", [Pure]> { }]; } +//===- ISA Register Handling Operations -----------------------------------===// + +def FixedRegisterOp : RTGOp<"fixed_reg", [ + Pure, ConstantLike, + DeclareOpInterfaceMethods, +]> { + let summary = "returns a value representing a fixed register"; + let description = [{ + This operation creates a value representing the register given as the 'reg' + attribute. This is always a concrete ISA register. + The return type always matches the register attribute type. + }]; + + let arguments = (ins RegisterAttrInterface:$reg); + let results = (outs RegisterTypeInterface:$result); + + let assemblyFormat = "$reg attr-dict"; + let hasFolder = 1; +} + +def VirtualRegisterOp : RTGOp<"virtual_reg", [ + DeclareOpInterfaceMethods, +]> { + let summary = "returns a value representing a virtual register"; + let description = [{ + This operation creates a value representing a virtual register. The + 'allowedRegisters' attribute specifies the concrete registers that may be + chosen during register allocation. + }]; + + // ArrayAttr of RegisterAttrInterfaces + let arguments = (ins ArrayAttr:$allowedRegs); + let results = (outs RegisterTypeInterface:$result); + + let assemblyFormat = "$allowedRegs attr-dict"; + let hasVerifier = 1; +} + //===- Test Specification Operations --------------------------------------===// def TestOp : RTGOp<"test", [ diff --git a/include/circt/Dialect/RTG/IR/RTGVisitors.h b/include/circt/Dialect/RTG/IR/RTGVisitors.h index 00a62ec8ca1f..d29377bf752a 100644 --- a/include/circt/Dialect/RTG/IR/RTGVisitors.h +++ b/include/circt/Dialect/RTG/IR/RTGVisitors.h @@ -31,17 +31,23 @@ class RTGOpVisitor { ResultType dispatchOpVisitor(Operation *op, ExtraArgs... args) { auto *thisCast = static_cast(this); return TypeSwitch(op) - .template Case([&](auto expr) -> ResultType { + .template Case< + // Bags + BagCreateOp, BagSelectRandomOp, BagDifferenceOp, BagUnionOp, + BagUniqueSizeOp, + // Labels + LabelDeclOp, LabelUniqueDeclOp, LabelOp, + // Registers + FixedRegisterOp, VirtualRegisterOp, + // RTG tests + TestOp, TargetOp, YieldOp, + // Sequences + SequenceOp, SequenceClosureOp, InvokeSequenceOp, + // Sets + SetCreateOp, SetSelectRandomOp, SetDifferenceOp, SetUnionOp, + SetSizeOp>([&](auto expr) -> ResultType { return thisCast->visitOp(expr, args...); }) - .template Case([&](auto expr) -> ResultType { - return thisCast->visitRegisterOp(expr, args...); - }) .template Case( [&](auto expr) -> ResultType { return thisCast->visitContextResourceOp(expr, args...); @@ -66,10 +72,6 @@ class RTGOpVisitor { /// handled by the concrete visitor. ResultType visitUnhandledOp(Operation *op, ExtraArgs... args); - ResultType visitRegisterOp(RegisterOpInterface op, ExtraArgs... args) { - return static_cast(this)->visitUnhandledOp(op, args...); - } - ResultType visitContextResourceOp(ContextResourceOpInterface op, ExtraArgs... args) { return static_cast(this)->visitUnhandledOp(op, args...); @@ -103,6 +105,8 @@ class RTGOpVisitor { HANDLE(TestOp, Unhandled); HANDLE(TargetOp, Unhandled); HANDLE(YieldOp, Unhandled); + HANDLE(FixedRegisterOp, Unhandled); + HANDLE(VirtualRegisterOp, Unhandled); #undef HANDLE }; diff --git a/include/circt/Dialect/RTGTest/IR/RTGTest.td b/include/circt/Dialect/RTGTest/IR/RTGTest.td index f57332968ad2..b0e5097431dc 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTest.td +++ b/include/circt/Dialect/RTGTest/IR/RTGTest.td @@ -18,6 +18,7 @@ include "mlir/Interfaces/SideEffectInterfaces.td" include "mlir/IR/OpAsmInterface.td" include "circt/Dialect/RTG/IR/RTGInterfaces.td" +include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td" include "circt/Dialect/RTGTest/IR/RTGTestDialect.td" include "circt/Dialect/RTGTest/IR/RTGTestAttributes.td" diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.h b/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.h index 08d734841285..033141adb529 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.h +++ b/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.h @@ -14,6 +14,7 @@ #include "mlir/IR/BuiltinAttributes.h" #include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h" +#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h" #define GET_ATTRDEF_CLASSES #include "circt/Dialect/RTGTest/IR/RTGTestAttributes.h.inc" diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.td b/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.td index 1ce4fdd358cb..3c8c3a812b61 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.td +++ b/include/circt/Dialect/RTGTest/IR/RTGTestAttributes.td @@ -15,49 +15,8 @@ include "circt/Dialect/RTGTest/IR/RTGTestDialect.td" include "circt/Dialect/RTG/IR/RTGInterfaces.td" +include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td" include "mlir/IR/AttrTypeBase.td" -include "mlir/IR/EnumAttr.td" - -// Flat allocation of unique IDs to all registers. The actual ID value does not -// matter. -def RegisterAttr : I32EnumAttr< - "Registers", "Unique IDs for all RTGTest registers", [ - I32EnumAttrCase<"zero", 0>, - I32EnumAttrCase<"ra", 1>, - I32EnumAttrCase<"sp", 2>, - I32EnumAttrCase<"gp", 3>, - I32EnumAttrCase<"tp", 4>, - I32EnumAttrCase<"t0", 5>, - I32EnumAttrCase<"t1", 6>, - I32EnumAttrCase<"t2", 7>, - I32EnumAttrCase<"s0", 8>, - I32EnumAttrCase<"s1", 9>, - I32EnumAttrCase<"a0", 10>, - I32EnumAttrCase<"a1", 11>, - I32EnumAttrCase<"a2", 12>, - I32EnumAttrCase<"a3", 13>, - I32EnumAttrCase<"a4", 14>, - I32EnumAttrCase<"a5", 15>, - I32EnumAttrCase<"a6", 16>, - I32EnumAttrCase<"a7", 17>, - I32EnumAttrCase<"s2", 18>, - I32EnumAttrCase<"s3", 19>, - I32EnumAttrCase<"s4", 20>, - I32EnumAttrCase<"s5", 21>, - I32EnumAttrCase<"s6", 22>, - I32EnumAttrCase<"s7", 23>, - I32EnumAttrCase<"s8", 24>, - I32EnumAttrCase<"s9", 25>, - I32EnumAttrCase<"s10", 26>, - I32EnumAttrCase<"s11", 27>, - I32EnumAttrCase<"t3", 28>, - I32EnumAttrCase<"t4", 29>, - I32EnumAttrCase<"t5", 30>, - I32EnumAttrCase<"t6", 31>, - I32EnumAttrCase<"Virtual", 32> - ]> { - let cppNamespace = "::circt::rtgtest"; -} class RTGTestAttrDef traits = []> : AttrDef; @@ -76,4 +35,57 @@ def CPUAttr : RTGTestAttrDef<"CPU", [ContextResourceAttrInterface]> { }]; } +class IntegerRegisterAttrBase + : RTGTestAttrDef { + + let mnemonic = name; + + let extraClassDeclaration = [{ + unsigned getClassIndex() const { + return }] # classIndex # [{; + } + + llvm::StringLiteral getRegisterAssembly() const { + return "}] # name # [{"; + } + + Type getType() const { + return IntegerRegisterType::get(getContext()); + } + }]; +} + +def RegZeroAttr : IntegerRegisterAttrBase<"RegZero", "zero", 0>; +def RegRaAttr : IntegerRegisterAttrBase<"RegRa", "ra", 1>; +def RegSpAttr : IntegerRegisterAttrBase<"RegSp", "sp", 2>; +def RegGpAttr : IntegerRegisterAttrBase<"RegGp", "gp", 3>; +def RegTpAttr : IntegerRegisterAttrBase<"RegTp", "tp", 4>; +def RegT0Attr : IntegerRegisterAttrBase<"RegT0", "t0", 5>; +def RegT1Attr : IntegerRegisterAttrBase<"RegT1", "t1", 6>; +def RegT2Attr : IntegerRegisterAttrBase<"RegT2", "t2", 7>; +def RegS0Attr : IntegerRegisterAttrBase<"RegS0", "s0", 8>; +def RegS1Attr : IntegerRegisterAttrBase<"RegS1", "s1", 9>; +def RegA0Attr : IntegerRegisterAttrBase<"RegA0", "a0", 10>; +def RegA1Attr : IntegerRegisterAttrBase<"RegA1", "a1", 11>; +def RegA2Attr : IntegerRegisterAttrBase<"RegA2", "a2", 12>; +def RegA3Attr : IntegerRegisterAttrBase<"RegA3", "a3", 13>; +def RegA4Attr : IntegerRegisterAttrBase<"RegA4", "a4", 14>; +def RegA5Attr : IntegerRegisterAttrBase<"RegA5", "a5", 15>; +def RegA6Attr : IntegerRegisterAttrBase<"RegA6", "a6", 16>; +def RegA7Attr : IntegerRegisterAttrBase<"RegA7", "a7", 17>; +def RegS2Attr : IntegerRegisterAttrBase<"RegS2", "s2", 18>; +def RegS3Attr : IntegerRegisterAttrBase<"RegS3", "s3", 19>; +def RegS4Attr : IntegerRegisterAttrBase<"RegS4", "s4", 20>; +def RegS5Attr : IntegerRegisterAttrBase<"RegS5", "s5", 21>; +def RegS6Attr : IntegerRegisterAttrBase<"RegS6", "s6", 22>; +def RegS7Attr : IntegerRegisterAttrBase<"RegS7", "s7", 23>; +def RegS8Attr : IntegerRegisterAttrBase<"RegS8", "s8", 24>; +def RegS9Attr : IntegerRegisterAttrBase<"RegS9", "s9", 25>; +def RegS10Attr : IntegerRegisterAttrBase<"RegS10", "s10", 26>; +def RegS11Attr : IntegerRegisterAttrBase<"RegS11", "s11", 27>; +def RegT3Attr : IntegerRegisterAttrBase<"RegT3", "t3", 28>; +def RegT4Attr : IntegerRegisterAttrBase<"RegT4", "t4", 29>; +def RegT5Attr : IntegerRegisterAttrBase<"RegT5", "t5", 30>; +def RegT6Attr : IntegerRegisterAttrBase<"RegT6", "t6", 31>; + #endif // CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestOps.td b/include/circt/Dialect/RTGTest/IR/RTGTestOps.td index 1f34c6ec45d7..c949d9d51f6d 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestOps.td +++ b/include/circt/Dialect/RTGTest/IR/RTGTestOps.td @@ -48,21 +48,3 @@ def ConstantTestOp : RTGTestOp<"constant_test", [ let assemblyFormat = "type($result) attr-dict"; let hasFolder = 1; } - -def RegisterOp : RTGTestOp<"reg", [ - DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods, -]> { - let summary = "returns a value representing a register"; - let description = [{ - This operation creates a value representing the register given as the 'reg' - attribute. A register can be a concrete register or a virtual register. - Virtual registers will be assigned a concrete register when running register - allocation. - }]; - - let arguments = (ins RegisterAttr:$reg); - let results = (outs RegisterType:$result); - - let assemblyFormat = "$reg attr-dict"; -} diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.h b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.h index 7afa98b81e86..0d57a472874d 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.h +++ b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.h @@ -13,6 +13,7 @@ #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Types.h" +#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h" #include "circt/Dialect/RTG/IR/RTGTypeInterfaces.h" #define GET_TYPEDEF_CLASSES diff --git a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td index fc797603a5c8..67834c808203 100644 --- a/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td +++ b/include/circt/Dialect/RTGTest/IR/RTGTestTypes.td @@ -15,6 +15,7 @@ include "circt/Dialect/RTGTest/IR/RTGTestDialect.td" include "circt/Dialect/RTG/IR/RTGInterfaces.td" +include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td" include "mlir/IR/AttrTypeBase.td" class RTGTestTypeDef traits = []> @@ -32,7 +33,9 @@ def CPUType : RTGTestTypeDef<"CPU", [ContextResourceTypeInterface]> { let assemblyFormat = ""; } -def IntegerRegisterType : TypeDef { +def IntegerRegisterType : TypeDef { let summary = "represents an integer register"; let mnemonic = "ireg"; diff --git a/integration_test/Bindings/Python/dialects/rtg.py b/integration_test/Bindings/Python/dialects/rtg.py index c56d5f9c7127..e146cecc6227 100644 --- a/integration_test/Bindings/Python/dialects/rtg.py +++ b/integration_test/Bindings/Python/dialects/rtg.py @@ -94,3 +94,74 @@ # CHECK: rtg.sequence @seq # CHECK: (%{{.*}}: !rtg.sequence, %{{.*}}: !rtg.label, %{{.*}}: !rtg.set, %{{.*}}: !rtg.bag): print(m) + +with Context() as ctx, Location.unknown(): + circt.register_dialects(ctx) + m = Module.create() + with InsertionPoint(m.body): + # CHECK: rtg.fixed_reg #rtgtest.zero + rtg.FixedRegisterOp(rtgtest.RegZeroAttr.get()) + # CHECK: rtg.fixed_reg #rtgtest.ra + rtg.FixedRegisterOp(rtgtest.RegRaAttr.get()) + # CHECK: rtg.fixed_reg #rtgtest.sp + rtg.FixedRegisterOp(rtgtest.RegSpAttr.get()) + # CHECK: rtg.fixed_reg #rtgtest.gp + rtg.FixedRegisterOp(rtgtest.RegGpAttr.get()) + # CHECK: rtg.fixed_reg #rtgtest.tp + rtg.FixedRegisterOp(rtgtest.RegTpAttr.get()) + # CHECK: rtg.fixed_reg #rtgtest.t0 + rtg.FixedRegisterOp(rtgtest.RegT0Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.t1 + rtg.FixedRegisterOp(rtgtest.RegT1Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.t2 + rtg.FixedRegisterOp(rtgtest.RegT2Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s0 + rtg.FixedRegisterOp(rtgtest.RegS0Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s1 + rtg.FixedRegisterOp(rtgtest.RegS1Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a0 + rtg.FixedRegisterOp(rtgtest.RegA0Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a1 + rtg.FixedRegisterOp(rtgtest.RegA1Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a2 + rtg.FixedRegisterOp(rtgtest.RegA2Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a3 + rtg.FixedRegisterOp(rtgtest.RegA3Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a4 + rtg.FixedRegisterOp(rtgtest.RegA4Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a5 + rtg.FixedRegisterOp(rtgtest.RegA5Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a6 + rtg.FixedRegisterOp(rtgtest.RegA6Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.a7 + rtg.FixedRegisterOp(rtgtest.RegA7Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s2 + rtg.FixedRegisterOp(rtgtest.RegS2Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s3 + rtg.FixedRegisterOp(rtgtest.RegS3Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s4 + rtg.FixedRegisterOp(rtgtest.RegS4Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s5 + rtg.FixedRegisterOp(rtgtest.RegS5Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s6 + rtg.FixedRegisterOp(rtgtest.RegS6Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s7 + rtg.FixedRegisterOp(rtgtest.RegS7Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s8 + rtg.FixedRegisterOp(rtgtest.RegS8Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s9 + rtg.FixedRegisterOp(rtgtest.RegS9Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s10 + rtg.FixedRegisterOp(rtgtest.RegS10Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.s11 + rtg.FixedRegisterOp(rtgtest.RegS11Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.t3 + rtg.FixedRegisterOp(rtgtest.RegT3Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.t4 + rtg.FixedRegisterOp(rtgtest.RegT4Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.t5 + rtg.FixedRegisterOp(rtgtest.RegT5Attr.get()) + # CHECK: rtg.fixed_reg #rtgtest.t6 + rtg.FixedRegisterOp(rtgtest.RegT6Attr.get()) + + print(m) diff --git a/lib/Bindings/Python/RTGTestModule.cpp b/lib/Bindings/Python/RTGTestModule.cpp index 9e69d6ac3491..0dc9b7538a83 100644 --- a/lib/Bindings/Python/RTGTestModule.cpp +++ b/lib/Bindings/Python/RTGTestModule.cpp @@ -41,4 +41,260 @@ void circt::python::populateDialectRTGTestSubmodule(py::module &m) { py::arg("self"), py::arg("id"), py::arg("ctxt") = nullptr) .def_property_readonly( "id", [](MlirAttribute self) { return rtgtestCPUAttrGetId(self); }); + + mlir_attribute_subclass(m, "RegZeroAttr", rtgtestAttrIsARegZero) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegZeroAttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegRaAttr", rtgtestAttrIsARegRa) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegRaAttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegSpAttr", rtgtestAttrIsARegSp) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegSpAttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegGpAttr", rtgtestAttrIsARegGp) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegGpAttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegTpAttr", rtgtestAttrIsARegTp) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegTpAttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegT0Attr", rtgtestAttrIsARegT0) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegT0AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegT1Attr", rtgtestAttrIsARegT1) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegT1AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegT2Attr", rtgtestAttrIsARegT2) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegT2AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS0Attr", rtgtestAttrIsARegS0) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS0AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS1Attr", rtgtestAttrIsARegS1) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS1AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA0Attr", rtgtestAttrIsARegA0) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA0AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA1Attr", rtgtestAttrIsARegA1) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA1AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA2Attr", rtgtestAttrIsARegA2) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA2AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA3Attr", rtgtestAttrIsARegA3) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA3AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA4Attr", rtgtestAttrIsARegA4) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA4AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA5Attr", rtgtestAttrIsARegA5) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA5AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA6Attr", rtgtestAttrIsARegA6) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA6AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegA7Attr", rtgtestAttrIsARegA7) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegA7AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS2Attr", rtgtestAttrIsARegS2) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS2AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS3Attr", rtgtestAttrIsARegS3) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS3AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS4Attr", rtgtestAttrIsARegS4) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS4AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS5Attr", rtgtestAttrIsARegS5) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS5AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS6Attr", rtgtestAttrIsARegS6) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS6AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS7Attr", rtgtestAttrIsARegS7) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS7AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS8Attr", rtgtestAttrIsARegS8) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS8AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS9Attr", rtgtestAttrIsARegS9) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS9AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS10Attr", rtgtestAttrIsARegS10) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS10AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegS11Attr", rtgtestAttrIsARegS11) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegS11AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegT3Attr", rtgtestAttrIsARegT3) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegT3AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegT4Attr", rtgtestAttrIsARegT4) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegT4AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegT5Attr", rtgtestAttrIsARegT5) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegT5AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); + + mlir_attribute_subclass(m, "RegT6Attr", rtgtestAttrIsARegT6) + .def_classmethod( + "get", + [](py::object cls, MlirContext ctxt) { + return cls(rtgtestRegT6AttrGet(ctxt)); + }, + py::arg("self"), py::arg("ctxt") = nullptr); } diff --git a/lib/CAPI/Dialect/RTGTest.cpp b/lib/CAPI/Dialect/RTGTest.cpp index a46996942efc..caefe7111105 100644 --- a/lib/CAPI/Dialect/RTGTest.cpp +++ b/lib/CAPI/Dialect/RTGTest.cpp @@ -47,3 +47,262 @@ MlirAttribute rtgtestCPUAttrGet(MlirContext ctxt, unsigned id) { unsigned rtgtestCPUAttrGetId(MlirAttribute attr) { return cast(unwrap(attr)).getId(); } + +// Registers +//===----------------------------------------------------------------------===// + +bool rtgtestAttrIsARegZero(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegZeroAttrGet(MlirContext ctxt) { + return wrap(RegZeroAttr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegRa(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegRaAttrGet(MlirContext ctxt) { + return wrap(RegRaAttr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegSp(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegSpAttrGet(MlirContext ctxt) { + return wrap(RegSpAttr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegGp(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegGpAttrGet(MlirContext ctxt) { + return wrap(RegGpAttr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegTp(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegTpAttrGet(MlirContext ctxt) { + return wrap(RegTpAttr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegT0(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegT0AttrGet(MlirContext ctxt) { + return wrap(RegT0Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegT1(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegT1AttrGet(MlirContext ctxt) { + return wrap(RegT1Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegT2(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegT2AttrGet(MlirContext ctxt) { + return wrap(RegT2Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS0(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS0AttrGet(MlirContext ctxt) { + return wrap(RegS0Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS1(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS1AttrGet(MlirContext ctxt) { + return wrap(RegS1Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA0(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA0AttrGet(MlirContext ctxt) { + return wrap(RegA0Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA1(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA1AttrGet(MlirContext ctxt) { + return wrap(RegA1Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA2(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA2AttrGet(MlirContext ctxt) { + return wrap(RegA2Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA3(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA3AttrGet(MlirContext ctxt) { + return wrap(RegA3Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA4(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA4AttrGet(MlirContext ctxt) { + return wrap(RegA4Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA5(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA5AttrGet(MlirContext ctxt) { + return wrap(RegA5Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA6(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA6AttrGet(MlirContext ctxt) { + return wrap(RegA6Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegA7(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegA7AttrGet(MlirContext ctxt) { + return wrap(RegA7Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS2(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS2AttrGet(MlirContext ctxt) { + return wrap(RegS2Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS3(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS3AttrGet(MlirContext ctxt) { + return wrap(RegS3Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS4(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS4AttrGet(MlirContext ctxt) { + return wrap(RegS4Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS5(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS5AttrGet(MlirContext ctxt) { + return wrap(RegS5Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS6(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS6AttrGet(MlirContext ctxt) { + return wrap(RegS6Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS7(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS7AttrGet(MlirContext ctxt) { + return wrap(RegS7Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS8(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS8AttrGet(MlirContext ctxt) { + return wrap(RegS8Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS9(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS9AttrGet(MlirContext ctxt) { + return wrap(RegS9Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS10(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS10AttrGet(MlirContext ctxt) { + return wrap(RegS10Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegS11(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegS11AttrGet(MlirContext ctxt) { + return wrap(RegS11Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegT3(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegT3AttrGet(MlirContext ctxt) { + return wrap(RegT3Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegT4(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegT4AttrGet(MlirContext ctxt) { + return wrap(RegT4Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegT5(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegT5AttrGet(MlirContext ctxt) { + return wrap(RegT5Attr::get(unwrap(ctxt))); +} + +bool rtgtestAttrIsARegT6(MlirAttribute attr) { + return isa(unwrap(attr)); +} + +MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt) { + return wrap(RegT6Attr::get(unwrap(ctxt))); +} diff --git a/lib/Dialect/RTG/IR/CMakeLists.txt b/lib/Dialect/RTG/IR/CMakeLists.txt index e5d42615f32c..60805f4cb706 100644 --- a/lib/Dialect/RTG/IR/CMakeLists.txt +++ b/lib/Dialect/RTG/IR/CMakeLists.txt @@ -1,5 +1,7 @@ add_circt_dialect_library(CIRCTRTGDialect RTGDialect.cpp + RTGISAAssemblyAttrInterfaces.cpp + RTGISAAssemblyTypeInterfaces.cpp RTGISAAssemblyOpInterfaces.cpp RTGOpInterfaces.cpp RTGOps.cpp @@ -14,6 +16,8 @@ add_circt_dialect_library(CIRCTRTGDialect MLIRRTGIncGen CIRCTRTGEnumsIncGen CIRCTRTGOpInterfacesIncGen + CIRCTRTGISAAssemblyAttrInterfacesIncGen + CIRCTRTGISAAssemblyTypeInterfacesIncGen CIRCTRTGISAAssemblyOpInterfacesIncGen CIRCTRTGTypeInterfacesIncGen CIRCTRTGAttrInterfacesIncGen diff --git a/lib/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.cpp b/lib/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.cpp new file mode 100644 index 000000000000..fbd5fd29ed1c --- /dev/null +++ b/lib/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.cpp @@ -0,0 +1,19 @@ +//===- RTGISAAssemblyAttrInterfaces.cpp - Interfaces for ISA Assembly RTG -===// +// +// 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 implements the RTG attr interfaces specific to ISA Assembly tests. +// +//===----------------------------------------------------------------------===// + +#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.h" + +//===----------------------------------------------------------------------===// +// TableGen generated logic. +//===----------------------------------------------------------------------===// + +#include "circt/Dialect/RTG/IR/RTGISAAssemblyAttrInterfaces.cpp.inc" diff --git a/lib/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.cpp b/lib/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.cpp new file mode 100644 index 000000000000..bb18aa418199 --- /dev/null +++ b/lib/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.cpp @@ -0,0 +1,19 @@ +//===- RTGISAAssemblyTypeInterfaces.cpp - Interfaces for ISA Assembly RTG -===// +// +// 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 implements the RTG type interfaces specific to ISA Assembly tests. +// +//===----------------------------------------------------------------------===// + +#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.h" + +//===----------------------------------------------------------------------===// +// TableGen generated logic. +//===----------------------------------------------------------------------===// + +#include "circt/Dialect/RTG/IR/RTGISAAssemblyTypeInterfaces.cpp.inc" diff --git a/lib/Dialect/RTG/IR/RTGOps.cpp b/lib/Dialect/RTG/IR/RTGOps.cpp index 2a2fb0035907..2a5347df3bc8 100644 --- a/lib/Dialect/RTG/IR/RTGOps.cpp +++ b/lib/Dialect/RTG/IR/RTGOps.cpp @@ -150,6 +150,66 @@ LogicalResult BagCreateOp::verify() { return success(); } +//===----------------------------------------------------------------------===// +// FixedRegisterOp +//===----------------------------------------------------------------------===// + +LogicalResult FixedRegisterOp::inferReturnTypes( + MLIRContext *context, std::optional loc, ValueRange operands, + DictionaryAttr attributes, OpaqueProperties properties, RegionRange regions, + SmallVectorImpl &inferredReturnTypes) { + inferredReturnTypes.push_back( + properties.as()->getReg().getType()); + return success(); +} + +OpFoldResult FixedRegisterOp::fold(FoldAdaptor adaptor) { return getRegAttr(); } + +//===----------------------------------------------------------------------===// +// VirtualRegisterOp +//===----------------------------------------------------------------------===// + +LogicalResult VirtualRegisterOp::verify() { + if (getAllowedRegs().empty()) + return emitOpError("must have at least one allowed register"); + + if (llvm::any_of(getAllowedRegs(), [](Attribute attr) { + return !isa(attr); + })) + return emitOpError("all elements must be of RegisterAttrInterface"); + + if (!llvm::all_equal( + llvm::map_range(getAllowedRegs().getAsRange(), + [](auto attr) { return attr.getType(); }))) + return emitOpError("all allowed registers must be of the same type"); + + return success(); +} + +LogicalResult VirtualRegisterOp::inferReturnTypes( + MLIRContext *context, std::optional loc, ValueRange operands, + DictionaryAttr attributes, OpaqueProperties properties, RegionRange regions, + SmallVectorImpl &inferredReturnTypes) { + auto allowedRegs = properties.as()->getAllowedRegs(); + if (allowedRegs.empty()) { + if (loc) + return mlir::emitError(*loc, "must have at least one allowed register"); + + return failure(); + } + + auto regAttr = dyn_cast(allowedRegs[0]); + if (!regAttr) { + if (loc) + return mlir::emitError( + *loc, "allowed register attributes must be of RegisterAttrInterface"); + + return failure(); + } + inferredReturnTypes.push_back(regAttr.getType()); + return success(); +} + //===----------------------------------------------------------------------===// // TestOp //===----------------------------------------------------------------------===// diff --git a/lib/Dialect/RTG/Transforms/ElaborationPass.cpp b/lib/Dialect/RTG/Transforms/ElaborationPass.cpp index 9c7316b451eb..1015b74232c0 100644 --- a/lib/Dialect/RTG/Transforms/ElaborationPass.cpp +++ b/lib/Dialect/RTG/Transforms/ElaborationPass.cpp @@ -424,7 +424,6 @@ class Elaborator : public RTGOpVisitor, using RTGBase = RTGOpVisitor, function_ref>; using RTGBase::visitOp; - using RTGBase::visitRegisterOp; Elaborator(SymbolTable &table, std::mt19937 &rng) : rng(rng) {} diff --git a/lib/Dialect/RTGTest/IR/RTGTestOps.cpp b/lib/Dialect/RTGTest/IR/RTGTestOps.cpp index 809cb920bcde..06808b655a3b 100644 --- a/lib/Dialect/RTGTest/IR/RTGTestOps.cpp +++ b/lib/Dialect/RTGTest/IR/RTGTestOps.cpp @@ -33,53 +33,6 @@ mlir::OpFoldResult ConstantTestOp::fold(FoldAdaptor adaptor) { return getValueAttr(); } -//===----------------------------------------------------------------------===// -// RegisterOp -//===----------------------------------------------------------------------===// - -LogicalResult RegisterOp::inferReturnTypes( - MLIRContext *context, std::optional location, ValueRange operands, - DictionaryAttr attributes, OpaqueProperties properties, - mlir::RegionRange regions, SmallVectorImpl &inferredReturnTypes) { - Registers reg = properties.as()->getReg().getValue(); - if (static_cast(reg) >= 32 && reg != Registers::Virtual) { - if (location) - return mlir::emitError(*location) << "unsupported register"; - - return failure(); - } - - inferredReturnTypes.push_back(IntegerRegisterType::get(context)); - return success(); -} - -unsigned RegisterOp::getClassIndex() { return static_cast(getReg()); } - -APInt RegisterOp::getClassIndexBinary() { return APInt(5, getClassIndex()); } - -std::string RegisterOp::getRegisterAssembly() { - return stringifyRegisters(getReg()).str(); -} - -llvm::BitVector RegisterOp::getAllowedRegs() { - llvm::BitVector retval(getMaxEnumValForRegisters(), false); - if (getReg() == Registers::Virtual) - return retval.set(0, 32); - return retval.set(static_cast(getReg())); -} - -unsigned RegisterOp::getFixedReg() { - if (getReg() == Registers::Virtual) - return ~0U; - return static_cast(getReg()); -} - -void RegisterOp::setFixedReg(unsigned reg) { - auto sym = symbolizeRegisters(reg); - assert(sym.has_value() && sym.value() != Registers::Virtual); - setReg(sym.value()); -} - //===----------------------------------------------------------------------===// // TableGen generated logic. //===----------------------------------------------------------------------===// diff --git a/test/CAPI/rtgtest.c b/test/CAPI/rtgtest.c index fdd76426aeb2..57bee6469018 100644 --- a/test/CAPI/rtgtest.c +++ b/test/CAPI/rtgtest.c @@ -32,12 +32,241 @@ static void testCPUAttr(MlirContext ctx) { mlirAttributeDump(cpuAttr); } +static void testRegisters(MlirContext ctx) { + { + MlirAttribute regAttr = rtgtestRegZeroAttrGet(ctx); + // CHECK: is_zero + fprintf(stderr, + rtgtestAttrIsARegZero(regAttr) ? "is_zero\n" : "isnot_zero\n"); + // CHECK: #rtgtest.zero + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegRaAttrGet(ctx); + // CHECK: is_ra + fprintf(stderr, rtgtestAttrIsARegRa(regAttr) ? "is_ra\n" : "isnot_ra\n"); + // CHECK: #rtgtest.ra + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegSpAttrGet(ctx); + // CHECK: is_sp + fprintf(stderr, rtgtestAttrIsARegSp(regAttr) ? "is_sp\n" : "isnot_sp\n"); + // CHECK: #rtgtest.sp + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegGpAttrGet(ctx); + // CHECK: is_gp + fprintf(stderr, rtgtestAttrIsARegGp(regAttr) ? "is_gp\n" : "isnot_gp\n"); + // CHECK: #rtgtest.gp + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegTpAttrGet(ctx); + // CHECK: is_tp + fprintf(stderr, rtgtestAttrIsARegTp(regAttr) ? "is_tp\n" : "isnot_tp\n"); + // CHECK: #rtgtest.tp + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegT0AttrGet(ctx); + // CHECK: is_t0 + fprintf(stderr, rtgtestAttrIsARegT0(regAttr) ? "is_t0\n" : "isnot_t0\n"); + // CHECK: #rtgtest.t0 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegT1AttrGet(ctx); + // CHECK: is_t1 + fprintf(stderr, rtgtestAttrIsARegT1(regAttr) ? "is_t1\n" : "isnot_t1\n"); + // CHECK: #rtgtest.t1 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegT2AttrGet(ctx); + // CHECK: is_t2 + fprintf(stderr, rtgtestAttrIsARegT2(regAttr) ? "is_t2\n" : "isnot_t2\n"); + // CHECK: #rtgtest.t2 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS0AttrGet(ctx); + // CHECK: is_s0 + fprintf(stderr, rtgtestAttrIsARegS0(regAttr) ? "is_s0\n" : "isnot_s0\n"); + // CHECK: #rtgtest.s0 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS1AttrGet(ctx); + // CHECK: is_s1 + fprintf(stderr, rtgtestAttrIsARegS1(regAttr) ? "is_s1\n" : "isnot_s1\n"); + // CHECK: #rtgtest.s1 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA0AttrGet(ctx); + // CHECK: is_a0 + fprintf(stderr, rtgtestAttrIsARegA0(regAttr) ? "is_a0\n" : "isnot_a0\n"); + // CHECK: #rtgtest.a0 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA1AttrGet(ctx); + // CHECK: is_a1 + fprintf(stderr, rtgtestAttrIsARegA1(regAttr) ? "is_a1\n" : "isnot_a1\n"); + // CHECK: #rtgtest.a1 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA2AttrGet(ctx); + // CHECK: is_a2 + fprintf(stderr, rtgtestAttrIsARegA2(regAttr) ? "is_a2\n" : "isnot_a2\n"); + // CHECK: #rtgtest.a2 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA3AttrGet(ctx); + // CHECK: is_a3 + fprintf(stderr, rtgtestAttrIsARegA3(regAttr) ? "is_a3\n" : "isnot_a3\n"); + // CHECK: #rtgtest.a3 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA4AttrGet(ctx); + // CHECK: is_a4 + fprintf(stderr, rtgtestAttrIsARegA4(regAttr) ? "is_a4\n" : "isnot_a4\n"); + // CHECK: #rtgtest.a4 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA5AttrGet(ctx); + // CHECK: is_a5 + fprintf(stderr, rtgtestAttrIsARegA5(regAttr) ? "is_a5\n" : "isnot_a5\n"); + // CHECK: #rtgtest.a5 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA6AttrGet(ctx); + // CHECK: is_a6 + fprintf(stderr, rtgtestAttrIsARegA6(regAttr) ? "is_a6\n" : "isnot_a6\n"); + // CHECK: #rtgtest.a6 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegA7AttrGet(ctx); + // CHECK: is_a7 + fprintf(stderr, rtgtestAttrIsARegA7(regAttr) ? "is_a7\n" : "isnot_a7\n"); + // CHECK: #rtgtest.a7 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS2AttrGet(ctx); + // CHECK: is_s2 + fprintf(stderr, rtgtestAttrIsARegS2(regAttr) ? "is_s2\n" : "isnot_s2\n"); + // CHECK: #rtgtest.s2 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS3AttrGet(ctx); + // CHECK: is_s3 + fprintf(stderr, rtgtestAttrIsARegS3(regAttr) ? "is_s3\n" : "isnot_s3\n"); + // CHECK: #rtgtest.s3 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS4AttrGet(ctx); + // CHECK: is_s4 + fprintf(stderr, rtgtestAttrIsARegS4(regAttr) ? "is_s4\n" : "isnot_s4\n"); + // CHECK: #rtgtest.s4 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS5AttrGet(ctx); + // CHECK: is_s5 + fprintf(stderr, rtgtestAttrIsARegS5(regAttr) ? "is_s5\n" : "isnot_s5\n"); + // CHECK: #rtgtest.s5 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS6AttrGet(ctx); + // CHECK: is_s6 + fprintf(stderr, rtgtestAttrIsARegS6(regAttr) ? "is_s6\n" : "isnot_s6\n"); + // CHECK: #rtgtest.s6 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS7AttrGet(ctx); + // CHECK: is_s7 + fprintf(stderr, rtgtestAttrIsARegS7(regAttr) ? "is_s7\n" : "isnot_s7\n"); + // CHECK: #rtgtest.s7 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS8AttrGet(ctx); + // CHECK: is_s8 + fprintf(stderr, rtgtestAttrIsARegS8(regAttr) ? "is_s8\n" : "isnot_s8\n"); + // CHECK: #rtgtest.s8 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS9AttrGet(ctx); + // CHECK: is_s9 + fprintf(stderr, rtgtestAttrIsARegS9(regAttr) ? "is_s9\n" : "isnot_s9\n"); + // CHECK: #rtgtest.s9 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS10AttrGet(ctx); + // CHECK: is_s10 + fprintf(stderr, rtgtestAttrIsARegS10(regAttr) ? "is_s10\n" : "isnot_s10\n"); + // CHECK: #rtgtest.s10 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegS11AttrGet(ctx); + // CHECK: is_s11 + fprintf(stderr, rtgtestAttrIsARegS11(regAttr) ? "is_s11\n" : "isnot_s11\n"); + // CHECK: #rtgtest.s11 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegT3AttrGet(ctx); + // CHECK: is_t3 + fprintf(stderr, rtgtestAttrIsARegT3(regAttr) ? "is_t3\n" : "isnot_t3\n"); + // CHECK: #rtgtest.t3 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegT4AttrGet(ctx); + // CHECK: is_t4 + fprintf(stderr, rtgtestAttrIsARegT4(regAttr) ? "is_t4\n" : "isnot_t4\n"); + // CHECK: #rtgtest.t4 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegT5AttrGet(ctx); + // CHECK: is_t5 + fprintf(stderr, rtgtestAttrIsARegT5(regAttr) ? "is_t5\n" : "isnot_t5\n"); + // CHECK: #rtgtest.t5 + mlirAttributeDump(regAttr); + } + { + MlirAttribute regAttr = rtgtestRegT6AttrGet(ctx); + // CHECK: is_t6 + fprintf(stderr, rtgtestAttrIsARegT6(regAttr) ? "is_t6\n" : "isnot_t6\n"); + // CHECK: #rtgtest.t6 + mlirAttributeDump(regAttr); + } +} + int main(int argc, char **argv) { MlirContext ctx = mlirContextCreate(); mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtgtest__(), ctx); testCPUType(ctx); testCPUAttr(ctx); + testRegisters(ctx); mlirContextDestroy(ctx); diff --git a/test/Dialect/RTGTest/IR/basic.mlir b/test/Dialect/RTGTest/IR/basic.mlir index 9923bda48e04..049d0f698768 100644 --- a/test/Dialect/RTGTest/IR/basic.mlir +++ b/test/Dialect/RTGTest/IR/basic.mlir @@ -1,4 +1,4 @@ -// RUN: circt-opt %s | FileCheck %s +// RUN: circt-opt %s --split-input-file --verify-diagnostics | FileCheck %s // CHECK-LABEL: @cpus // CHECK-SAME: !rtgtest.cpu @@ -17,70 +17,85 @@ rtg.test @misc : !rtg.dict<> { // CHECK-SAME: !rtgtest.ireg rtg.test @registers : !rtg.dict { ^bb0(%reg: !rtgtest.ireg): - // CHECK: rtgtest.reg zero - // CHECK: rtgtest.reg ra - // CHECK: rtgtest.reg sp - // CHECK: rtgtest.reg gp - // CHECK: rtgtest.reg tp - // CHECK: rtgtest.reg t0 - // CHECK: rtgtest.reg t1 - // CHECK: rtgtest.reg t2 - // CHECK: rtgtest.reg s0 - // CHECK: rtgtest.reg s1 - // CHECK: rtgtest.reg a0 - // CHECK: rtgtest.reg a1 - // CHECK: rtgtest.reg a2 - // CHECK: rtgtest.reg a3 - // CHECK: rtgtest.reg a4 - // CHECK: rtgtest.reg a5 - // CHECK: rtgtest.reg a6 - // CHECK: rtgtest.reg a7 - // CHECK: rtgtest.reg s2 - // CHECK: rtgtest.reg s3 - // CHECK: rtgtest.reg s4 - // CHECK: rtgtest.reg s5 - // CHECK: rtgtest.reg s6 - // CHECK: rtgtest.reg s7 - // CHECK: rtgtest.reg s8 - // CHECK: rtgtest.reg s9 - // CHECK: rtgtest.reg s10 - // CHECK: rtgtest.reg s11 - // CHECK: rtgtest.reg t3 - // CHECK: rtgtest.reg t4 - // CHECK: rtgtest.reg t5 - // CHECK: rtgtest.reg t6 - // CHECK: rtgtest.reg Virtual - %1 = rtgtest.reg zero - %2 = rtgtest.reg ra - %3 = rtgtest.reg sp - %4 = rtgtest.reg gp - %5 = rtgtest.reg tp - %6 = rtgtest.reg t0 - %7 = rtgtest.reg t1 - %8 = rtgtest.reg t2 - %9 = rtgtest.reg s0 - %10 = rtgtest.reg s1 - %11 = rtgtest.reg a0 - %12 = rtgtest.reg a1 - %13 = rtgtest.reg a2 - %14 = rtgtest.reg a3 - %15 = rtgtest.reg a4 - %16 = rtgtest.reg a5 - %17 = rtgtest.reg a6 - %18 = rtgtest.reg a7 - %19 = rtgtest.reg s2 - %20 = rtgtest.reg s3 - %21 = rtgtest.reg s4 - %22 = rtgtest.reg s5 - %23 = rtgtest.reg s6 - %24 = rtgtest.reg s7 - %25 = rtgtest.reg s8 - %26 = rtgtest.reg s9 - %27 = rtgtest.reg s10 - %28 = rtgtest.reg s11 - %29 = rtgtest.reg t3 - %30 = rtgtest.reg t4 - %31 = rtgtest.reg t5 - %32 = rtgtest.reg t6 - %33 = rtgtest.reg Virtual + // CHECK: rtg.fixed_reg #rtgtest.zero : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.ra : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.sp : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.gp : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.tp : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.t0 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.t1 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.t2 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s0 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s1 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a0 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a1 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a2 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a3 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a4 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a5 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a6 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.a7 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s2 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s3 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s4 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s5 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s6 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s7 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s8 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s9 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s10 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.s11 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.t3 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.t4 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.t5 : !rtgtest.ireg + // CHECK: rtg.fixed_reg #rtgtest.t6 : !rtgtest.ireg + rtg.fixed_reg #rtgtest.zero + rtg.fixed_reg #rtgtest.ra + rtg.fixed_reg #rtgtest.sp + rtg.fixed_reg #rtgtest.gp + rtg.fixed_reg #rtgtest.tp + rtg.fixed_reg #rtgtest.t0 + rtg.fixed_reg #rtgtest.t1 + rtg.fixed_reg #rtgtest.t2 + rtg.fixed_reg #rtgtest.s0 + rtg.fixed_reg #rtgtest.s1 + rtg.fixed_reg #rtgtest.a0 + rtg.fixed_reg #rtgtest.a1 + rtg.fixed_reg #rtgtest.a2 + rtg.fixed_reg #rtgtest.a3 + rtg.fixed_reg #rtgtest.a4 + rtg.fixed_reg #rtgtest.a5 + rtg.fixed_reg #rtgtest.a6 + rtg.fixed_reg #rtgtest.a7 + rtg.fixed_reg #rtgtest.s2 + rtg.fixed_reg #rtgtest.s3 + rtg.fixed_reg #rtgtest.s4 + rtg.fixed_reg #rtgtest.s5 + rtg.fixed_reg #rtgtest.s6 + rtg.fixed_reg #rtgtest.s7 + rtg.fixed_reg #rtgtest.s8 + rtg.fixed_reg #rtgtest.s9 + rtg.fixed_reg #rtgtest.s10 + rtg.fixed_reg #rtgtest.s11 + rtg.fixed_reg #rtgtest.t3 + rtg.fixed_reg #rtgtest.t4 + rtg.fixed_reg #rtgtest.t5 + rtg.fixed_reg #rtgtest.t6 + + // CHECK: rtg.virtual_reg [#rtgtest.ra : !rtgtest.ireg, #rtgtest.sp : !rtgtest.ireg] + rtg.virtual_reg [#rtgtest.ra, #rtgtest.sp] +} + +// ----- + +rtg.test @emptyAllowed : !rtg.dict<> { + // expected-error @below {{must have at least one allowed register}} + rtg.virtual_reg [] +} + +// ----- + +rtg.test @invalidAllowedAttr : !rtg.dict<> { + // expected-error @below {{allowed register attributes must be of RegisterAttrInterface}} + rtg.virtual_reg ["invalid"] } diff --git a/unittests/Dialect/CMakeLists.txt b/unittests/Dialect/CMakeLists.txt index 932d4bf03010..e5c67d266fdb 100644 --- a/unittests/Dialect/CMakeLists.txt +++ b/unittests/Dialect/CMakeLists.txt @@ -3,5 +3,4 @@ add_subdirectory(FIRRTL) add_subdirectory(ESI) add_subdirectory(HW) add_subdirectory(OM) -add_subdirectory(RTGTest) add_subdirectory(SMT) diff --git a/unittests/Dialect/RTGTest/CMakeLists.txt b/unittests/Dialect/RTGTest/CMakeLists.txt deleted file mode 100644 index 6eb53f2e0e93..000000000000 --- a/unittests/Dialect/RTGTest/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_circt_unittest(CIRCTRTGTestTests - RegisterTest.cpp -) - -target_link_libraries(CIRCTRTGTestTests - PRIVATE - CIRCTRTGTestDialect -) diff --git a/unittests/Dialect/RTGTest/RegisterTest.cpp b/unittests/Dialect/RTGTest/RegisterTest.cpp deleted file mode 100644 index 25f872b21fde..000000000000 --- a/unittests/Dialect/RTGTest/RegisterTest.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===- RegisterTest.cpp - RTGTest register unit tests ---------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "circt/Dialect/RTGTest/IR/RTGTestOps.h" -#include "gtest/gtest.h" - -using namespace mlir; -using namespace circt; -using namespace rtgtest; - -namespace { - -TEST(RegisterInterfaceTest, IntegerRegisters) { - MLIRContext context; - context.loadDialect(); - Location loc(UnknownLoc::get(&context)); - - SmallVector> regs{ - {Registers::zero, "zero", 0}, {Registers::ra, "ra", 1}, - {Registers::sp, "sp", 2}, {Registers::gp, "gp", 3}, - {Registers::tp, "tp", 4}, {Registers::t0, "t0", 5}, - {Registers::t1, "t1", 6}, {Registers::t2, "t2", 7}, - {Registers::s0, "s0", 8}, {Registers::s1, "s1", 9}, - {Registers::a0, "a0", 10}, {Registers::a1, "a1", 11}, - {Registers::a2, "a2", 12}, {Registers::a3, "a3", 13}, - {Registers::a4, "a4", 14}, {Registers::a5, "a5", 15}, - {Registers::a6, "a6", 16}, {Registers::a7, "a7", 17}, - {Registers::s2, "s2", 18}, {Registers::s3, "s3", 19}, - {Registers::s4, "s4", 20}, {Registers::s5, "s5", 21}, - {Registers::s6, "s6", 22}, {Registers::s7, "s7", 23}, - {Registers::s8, "s8", 24}, {Registers::s9, "s9", 25}, - {Registers::s10, "s10", 26}, {Registers::s11, "s11", 27}, - {Registers::t3, "t3", 28}, {Registers::t4, "t4", 29}, - {Registers::t5, "t5", 30}, {Registers::t6, "t6", 31}}; - - auto moduleOp = ModuleOp::create(loc); - OpBuilder builder = OpBuilder::atBlockBegin(moduleOp.getBody()); - auto regOp = builder.create(loc, Registers::Virtual); - ASSERT_EQ(regOp.getAllowedRegs(), - llvm::BitVector(getMaxEnumValForRegisters(), true)); - ASSERT_EQ(regOp.getFixedReg(), ~0U); - - for (auto [reg, str, idx] : regs) { - regOp.setFixedReg(idx); - ASSERT_EQ(regOp.getClassIndex(), idx); - ASSERT_EQ(regOp.getClassIndexBinary(), APInt(5, idx)); - ASSERT_EQ(regOp.getRegisterAssembly(), str); - ASSERT_EQ(regOp.getAllowedRegs(), - llvm::BitVector(getMaxEnumValForRegisters(), false).set(idx)); - ASSERT_EQ(regOp.getFixedReg(), idx); - } -} - -} // namespace