[RTG] Add context resource attribute interface (#8034)

This commit is contained in:
Martin Erhart 2025-01-16 20:47:49 +00:00 committed by GitHub
parent 701b9dff6d
commit e075079fc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 221 additions and 11 deletions

View File

@ -31,6 +31,20 @@ MLIR_CAPI_EXPORTED bool rtgtestTypeIsACPU(MlirType type);
/// Creates an RTGTest CPU type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestCPUTypeGet(MlirContext ctxt);
//===----------------------------------------------------------------------===//
// Attribute API.
//===----------------------------------------------------------------------===//
/// If the type is an RTGTest CPUAttr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsACPU(MlirAttribute attr);
/// Creates an RTGTest CPU attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestCPUAttrGet(MlirContext ctxt,
unsigned id);
/// Returns the core ID represented by the CPU attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestCPUAttrGetId(MlirAttribute attr);
#ifdef __cplusplus
}
#endif

View File

@ -18,6 +18,11 @@ mlir_tablegen(RTGTypeInterfaces.cpp.inc -gen-type-interface-defs)
add_public_tablegen_target(CIRCTRTGTypeInterfacesIncGen)
add_dependencies(circt-headers CIRCTRTGTypeInterfacesIncGen)
mlir_tablegen(RTGAttrInterfaces.h.inc -gen-attr-interface-decls)
mlir_tablegen(RTGAttrInterfaces.cpp.inc -gen-attr-interface-defs)
add_public_tablegen_target(CIRCTRTGAttrInterfacesIncGen)
add_dependencies(circt-headers CIRCTRTGAttrInterfacesIncGen)
set(LLVM_TARGET_DEFINITIONS RTGISAAssemblyInterfaces.td)
mlir_tablegen(RTGISAAssemblyOpInterfaces.h.inc -gen-op-interface-decls)
mlir_tablegen(RTGISAAssemblyOpInterfaces.cpp.inc -gen-op-interface-defs)

View File

@ -0,0 +1,22 @@
//===- RTGAttrInterfaces.h - Declare RTG attr interfaces --------*- 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.
//
//===----------------------------------------------------------------------===//
#ifndef CIRCT_DIALECT_RTG_IR_RTGATTRINTERFACES_H
#define CIRCT_DIALECT_RTG_IR_RTGATTRINTERFACES_H
#include "circt/Support/LLVM.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributeInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h.inc"
#endif // CIRCT_DIALECT_RTG_IR_RTGATTRINTERFACES_H

View File

@ -11,6 +11,7 @@
include "mlir/IR/Interfaces.td"
include "mlir/IR/OpBase.td"
include "mlir/IR/BuiltinAttributeInterfaces.td"
def ContextResourceOpInterface : OpInterface<"ContextResourceOpInterface"> {
let description = [{
@ -50,4 +51,18 @@ def ContextResourceTypeInterface : TypeInterface<
let cppNamespace = "::circt::rtg";
}
def ContextResourceAttrInterface : AttrInterface<
"ContextResourceAttrInterface", [TypedAttrInterface]> {
let description = [{
This interface should be implemented by attributes that represent context
resources.
Any attribute implementing this interface must be of a type implementing
the `ContextResourceTypeInterface`.
TODO: properly verify this; unfortunately, we don't have a 'verify' field
here like the 'OpInterface' has.
}];
let cppNamespace = "::circt::rtg";
}
#endif // CIRCT_DIALECT_RTG_IR_RTGINTERFACES_TD

View File

@ -13,6 +13,7 @@
#ifndef CIRCT_DIALECT_RTG_IR_RTGOPS_H
#define CIRCT_DIALECT_RTG_IR_RTGOPS_H
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGDialect.h"
#include "circt/Dialect/RTG/IR/RTGTypeInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGTypes.h"

View File

@ -8,3 +8,7 @@ set(LLVM_TARGET_DEFINITIONS RTGTestAttributes.td)
mlir_tablegen(RTGTestEnums.h.inc -gen-enum-decls)
mlir_tablegen(RTGTestEnums.cpp.inc -gen-enum-defs)
add_public_tablegen_target(CIRCTRTGTestEnumsIncGen)
mlir_tablegen(RTGTestAttributes.h.inc -gen-attrdef-decls)
mlir_tablegen(RTGTestAttributes.cpp.inc -gen-attrdef-defs)
add_public_tablegen_target(CIRCTRTGTestAttributeIncGen)

View File

@ -22,6 +22,7 @@ include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "circt/Dialect/RTGTest/IR/RTGTestDialect.td"
include "circt/Dialect/RTGTest/IR/RTGTestAttributes.td"
include "circt/Dialect/RTGTest/IR/RTGTestTypes.td"
include "circt/Dialect/RTGTest/IR/RTGTestAttributes.td"
include "circt/Dialect/RTGTest/IR/RTGTestOps.td"
#endif // CIRCT_DIALECT_RTGTEST_IR_RTGTEST_TD

View File

@ -0,0 +1,21 @@
//===- RTGTestAttributes.h - RTG Test dialect attributes --------*- 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
//
//===----------------------------------------------------------------------===//
#ifndef CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_H
#define CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_H
#include "circt/Dialect/RTGTest/IR/RTGTestTypes.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h"
#define GET_ATTRDEF_CLASSES
#include "circt/Dialect/RTGTest/IR/RTGTestAttributes.h.inc"
#endif // CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_H

View File

@ -13,6 +13,8 @@
#ifndef CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD
#define CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD
include "circt/Dialect/RTGTest/IR/RTGTestDialect.td"
include "circt/Dialect/RTG/IR/RTGInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/EnumAttr.td"
@ -57,4 +59,21 @@ def RegisterAttr : I32EnumAttr<
let cppNamespace = "::circt::rtgtest";
}
class RTGTestAttrDef<string name, list<Trait> traits = []>
: AttrDef<RTGTestDialect, name, traits>;
def CPUAttr : RTGTestAttrDef<"CPU", [ContextResourceAttrInterface]> {
let summary = "this attribute represents a CPU referred to by the core ID";
let parameters = (ins "size_t":$id);
let mnemonic = "cpu";
let assemblyFormat = "`<` $id `>`";
let extraClassDeclaration = [{
// TypedAttrInterface
Type getType() const;
}];
}
#endif // CIRCT_DIALECT_RTGTEST_IR_RTGTESTATTRIBUTES_TD

View File

@ -26,9 +26,11 @@ def RTGTestDialect : Dialect {
}];
let useDefaultTypePrinterParser = 1;
let useDefaultAttributePrinterParser = 1;
let cppNamespace = "::circt::rtgtest";
let extraClassDeclaration = [{
void registerAttributes();
void registerTypes();
}];
}

View File

@ -16,6 +16,7 @@
#include "circt/Dialect/RTG/IR/RTGISAAssemblyOpInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGOpInterfaces.h"
#include "circt/Dialect/RTG/IR/RTGOps.h"
#include "circt/Dialect/RTGTest/IR/RTGTestAttributes.h"
#include "circt/Dialect/RTGTest/IR/RTGTestDialect.h"
#include "circt/Dialect/RTGTest/IR/RTGTestTypes.h"
#include "circt/Support/LLVM.h"

View File

@ -22,7 +22,9 @@ class RTGTestOp<string mnemonic, list<Trait> traits = []> :
def CPUDeclOp : RTGTestOp<"cpu_decl", [
Pure,
ConstantLike,
ContextResourceDefining,
FirstAttrDerivedResultType,
]> {
let summary = "declare a CPU";
let description = [{
@ -30,10 +32,11 @@ def CPUDeclOp : RTGTestOp<"cpu_decl", [
taking advantage of it.
}];
let arguments = (ins IndexAttr:$id);
let arguments = (ins CPUAttr:$id);
let results = (outs CPUType:$cpu);
let assemblyFormat = "$id attr-dict";
let hasFolder = 1;
}
def ConstantTestOp : RTGTestOp<"constant_test", [

View File

@ -19,16 +19,17 @@ with Context() as ctx, Location.unknown():
target = rtg.TargetOp('target_name', TypeAttr.get(dictTy))
targetBlock = Block.create_at_start(target.bodyRegion, [])
with InsertionPoint(targetBlock):
cpu0 = rtgtest.CPUDeclOp(0)
cpu1 = rtgtest.CPUDeclOp(1)
cpuAttr = rtgtest.CPUAttr.get(0)
cpu0 = rtgtest.CPUDeclOp(cpuAttr)
cpu1 = rtgtest.CPUDeclOp(rtgtest.CPUAttr.get(cpuAttr.id + 1))
rtg.YieldOp([cpu0, cpu1])
test = rtg.TestOp('test_name', TypeAttr.get(dictTy))
Block.create_at_start(test.bodyRegion, [cpuTy, cpuTy])
# CHECK: rtg.target @target_name : !rtg.dict<cpu0: !rtgtest.cpu, cpu1: !rtgtest.cpu> {
# CHECK: [[V0:%.+]] = rtgtest.cpu_decl 0
# CHECK: [[V1:%.+]] = rtgtest.cpu_decl 1
# CHECK: [[V0:%.+]] = rtgtest.cpu_decl <0>
# CHECK: [[V1:%.+]] = rtgtest.cpu_decl <1>
# CHECK: rtg.yield [[V0]], [[V1]] : !rtgtest.cpu, !rtgtest.cpu
# CHECK: }
# CHECK: rtg.test @test_name : !rtg.dict<cpu0: !rtgtest.cpu, cpu1: !rtgtest.cpu> {

View File

@ -31,4 +31,14 @@ void circt::python::populateDialectRTGTestSubmodule(py::module &m) {
return cls(rtgtestCPUTypeGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);
mlir_attribute_subclass(m, "CPUAttr", rtgtestAttrIsACPU)
.def_classmethod(
"get",
[](py::object cls, unsigned id, MlirContext ctxt) {
return cls(rtgtestCPUAttrGet(ctxt, id));
},
py::arg("self"), py::arg("id"), py::arg("ctxt") = nullptr)
.def_property_readonly(
"id", [](MlirAttribute self) { return rtgtestCPUAttrGetId(self); });
}

View File

@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "circt-c/Dialect/RTGTest.h"
#include "circt/Dialect/RTGTest/IR/RTGTestAttributes.h"
#include "circt/Dialect/RTGTest/IR/RTGTestDialect.h"
#include "circt/Dialect/RTGTest/IR/RTGTestTypes.h"
@ -30,3 +31,19 @@ bool rtgtestTypeIsACPU(MlirType type) { return isa<CPUType>(unwrap(type)); }
MlirType rtgtestCPUTypeGet(MlirContext ctxt) {
return wrap(CPUType::get(unwrap(ctxt)));
}
//===----------------------------------------------------------------------===//
// Attribute API.
//===----------------------------------------------------------------------===//
bool rtgtestAttrIsACPU(MlirAttribute attr) {
return isa<CPUAttr>(unwrap(attr));
}
MlirAttribute rtgtestCPUAttrGet(MlirContext ctxt, unsigned id) {
return wrap(CPUAttr::get(unwrap(ctxt), id));
}
unsigned rtgtestCPUAttrGetId(MlirAttribute attr) {
return cast<CPUAttr>(unwrap(attr)).getId();
}

View File

@ -1,20 +1,22 @@
add_circt_dialect_library(CIRCTRTGDialect
RTGAttrInterfaces.cpp
RTGDialect.cpp
RTGISAAssemblyOpInterfaces.cpp
RTGOpInterfaces.cpp
RTGOps.cpp
RTGTypes.cpp
RTGTypeInterfaces.cpp
RTGTypes.cpp
ADDITIONAL_HEADER_DIRS
${CIRCT_MAIN_INCLUDE_DIR}/circt/Dialect/RTG/IR
DEPENDS
MLIRRTGIncGen
CIRCTRTGAttrInterfacesIncGen
CIRCTRTGEnumsIncGen
CIRCTRTGOpInterfacesIncGen
CIRCTRTGISAAssemblyOpInterfacesIncGen
CIRCTRTGOpInterfacesIncGen
CIRCTRTGTypeInterfacesIncGen
MLIRRTGIncGen
LINK_LIBS PUBLIC
MLIRIR

View File

@ -0,0 +1,19 @@
//===- RTGAttrInterfaces.cpp - Implement the RTG attr interfaces ----------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h"
//===----------------------------------------------------------------------===//
// TableGen generated logic.
//===----------------------------------------------------------------------===//
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.cpp.inc"

View File

@ -1,4 +1,5 @@
add_circt_dialect_library(CIRCTRTGTestDialect
RTGTestAttributes.cpp
RTGTestDialect.cpp
RTGTestOps.cpp
RTGTestTypes.cpp
@ -9,6 +10,7 @@ add_circt_dialect_library(CIRCTRTGTestDialect
DEPENDS
MLIRRTGTestIncGen
CIRCTRTGTestEnumsIncGen
CIRCTRTGTestAttributeIncGen
LINK_LIBS PUBLIC
MLIRIR

View File

@ -0,0 +1,36 @@
//===- RTGTestAttributes.cpp ----------------------------------------------===//
//
// 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/RTGTestAttributes.h"
#include "circt/Dialect/RTGTest/IR/RTGTestDialect.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/DialectImplementation.h"
#include "llvm/ADT/TypeSwitch.h"
using namespace circt;
using namespace rtgtest;
//===----------------------------------------------------------------------===//
// CPUAttr
//===----------------------------------------------------------------------===//
Type CPUAttr::getType() const { return rtgtest::CPUType::get(getContext()); }
//===----------------------------------------------------------------------===//
// TableGen generated logic.
//===----------------------------------------------------------------------===//
void RTGTestDialect::registerAttributes() {
addAttributes<
#define GET_ATTRDEF_LIST
#include "circt/Dialect/RTGTest/IR/RTGTestAttributes.cpp.inc"
>();
}
#define GET_ATTRDEF_CLASSES
#include "circt/Dialect/RTGTest/IR/RTGTestAttributes.cpp.inc"

View File

@ -26,6 +26,7 @@ using namespace rtgtest;
void RTGTestDialect::initialize() {
registerTypes();
registerAttributes();
// Register operations.
addOperations<
#define GET_OP_LIST

View File

@ -21,7 +21,9 @@ using namespace rtgtest;
// CPUDeclOp
//===----------------------------------------------------------------------===//
size_t CPUDeclOp::getIdentifier(size_t idx) { return getId().getZExtValue(); }
size_t CPUDeclOp::getIdentifier(size_t idx) { return getId().getId(); }
mlir::OpFoldResult CPUDeclOp::fold(FoldAdaptor adaptor) { return getId(); }
//===----------------------------------------------------------------------===//
// ConstantTestOp

View File

@ -21,11 +21,23 @@ static void testCPUType(MlirContext ctx) {
mlirTypeDump(cpuTy);
}
static void testCPUAttr(MlirContext ctx) {
MlirAttribute cpuAttr = rtgtestCPUAttrGet(ctx, 3);
// CHECK: is_cpu
fprintf(stderr, rtgtestAttrIsACPU(cpuAttr) ? "is_cpu\n" : "isnot_cpu\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestCPUAttrGetId(cpuAttr));
// CHECK: #rtgtest.cpu<3>
mlirAttributeDump(cpuAttr);
}
int main(int argc, char **argv) {
MlirContext ctx = mlirContextCreate();
mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtgtest__(), ctx);
testCPUType(ctx);
testCPUAttr(ctx);
mlirContextDestroy(ctx);

View File

@ -3,8 +3,8 @@
// CHECK-LABEL: @cpus
// CHECK-SAME: !rtgtest.cpu
rtg.target @cpus : !rtg.dict<cpu: !rtgtest.cpu> {
// CHECK: rtgtest.cpu_decl 0
%0 = rtgtest.cpu_decl 0
// CHECK: rtgtest.cpu_decl <0>
%0 = rtgtest.cpu_decl <0>
rtg.yield %0 : !rtgtest.cpu
}