Skip to content

Commit

Permalink
[RTGTest] Add representation for immediates
Browse files Browse the repository at this point in the history
  • Loading branch information
maerhart committed Jan 21, 2025
1 parent 610f6c0 commit 30f9e93
Show file tree
Hide file tree
Showing 10 changed files with 327 additions and 0 deletions.
54 changes: 54 additions & 0 deletions include/circt-c/Dialect/RTGTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,27 @@ MLIR_CAPI_EXPORTED bool rtgtestTypeIsACPU(MlirType type);
/// Creates an RTGTest CPU type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestCPUTypeGet(MlirContext ctxt);

// Immediates.
//===----------------------------------------------------------------------===//

/// If the type is an RTGTest Imm12Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm12(MlirType type);

/// Creates an RTGTest Imm12 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm12TypeGet(MlirContext ctxt);

/// If the type is an RTGTest Imm21Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm21(MlirType type);

/// Creates an RTGTest Imm21 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm21TypeGet(MlirContext ctxt);

/// If the type is an RTGTest Imm32Type.
MLIR_CAPI_EXPORTED bool rtgtestTypeIsAImm32(MlirType type);

/// Creates an RTGTest Imm32 type in the context.
MLIR_CAPI_EXPORTED MlirType rtgtestImm32TypeGet(MlirContext ctxt);

//===----------------------------------------------------------------------===//
// Attribute API.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -240,6 +261,39 @@ MLIR_CAPI_EXPORTED bool rtgtestAttrIsARegT6(MlirAttribute attr);
/// Creates an RTGTest RegT6 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt);

// Immediates.
//===----------------------------------------------------------------------===//

/// If the attribute is an RTGTest Imm12Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm12(MlirAttribute attr);

/// Creates an RTGTest Imm12 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm12AttrGet(MlirContext ctxt,
unsigned value);

/// Returns the value represented by the Imm12 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm12AttrGetValue(MlirAttribute attr);

/// If the attribute is an RTGTest Imm21Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm21(MlirAttribute attr);

/// Creates an RTGTest Imm21 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm21AttrGet(MlirContext ctxt,
unsigned value);

/// Returns the value represented by the Imm21 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm21AttrGetValue(MlirAttribute attr);

/// If the attribute is an RTGTest Imm32Attr.
MLIR_CAPI_EXPORTED bool rtgtestAttrIsAImm32(MlirAttribute attr);

/// Creates an RTGTest Imm32 attribute in the context.
MLIR_CAPI_EXPORTED MlirAttribute rtgtestImm32AttrGet(MlirContext ctxt,
unsigned value);

/// Returns the value represented by the Imm32 attribute.
MLIR_CAPI_EXPORTED unsigned rtgtestImm32AttrGetValue(MlirAttribute attr);

#ifdef __cplusplus
}
#endif
Expand Down
34 changes: 34 additions & 0 deletions include/circt/Dialect/RTGTest/IR/RTGTestAttributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,40 @@ def CPUAttr : RTGTestAttrDef<"CPU", [ContextResourceAttrInterface]> {
}];
}

class ImmediateAttrBase<int width> : RTGTestAttrDef<"Imm" # width, [
DeclareAttrInterfaceMethods<TypedAttrInterface>,
]> {
let summary = "represents a " # width # "-bit immediate value";

let mnemonic = "imm" # width;
let parameters = (ins "uint32_t":$value);

let assemblyFormat = "`<` $value `>`";

let extraClassDefinition = [{
Type $cppClass::getType() const {
return Imm}] # width # [{Type::get(getContext());
}

LogicalResult $cppClass::verify(
::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError,
uint32_t value) {

if (32 - llvm::countl_zero(value) > }] # width # [{)
return emitError() << "cannot represent " << value << " with }] #
width # [{ bits";

return success();
}
}];

let genVerifyDecl = 1;
}

def Imm12 : ImmediateAttrBase<12>;
def Imm21 : ImmediateAttrBase<21>;
def Imm32 : ImmediateAttrBase<32>;

class IntegerRegisterAttrBase<string cppName, string name, int classIndex>
: RTGTestAttrDef<cppName, [RegisterAttrInterface]> {

Expand Down
15 changes: 15 additions & 0 deletions include/circt/Dialect/RTGTest/IR/RTGTestOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ def CPUDeclOp : RTGTestOp<"cpu_decl", [
let hasFolder = 1;
}

def ImmediateOp : RTGTestOp<"immediate", [
Pure,
ConstantLike,
FirstAttrDerivedResultType,
DeclareOpInterfaceMethods<InferTypeOpInterface>,
]> {
let summary = "declare an immediate value";

let arguments = (ins AnyAttrOf<[Imm12, Imm21, Imm32]>:$imm);
let results = (outs AnyType:$result);

let assemblyFormat = "$imm attr-dict";
let hasFolder = 1;
}

def ConstantTestOp : RTGTestOp<"constant_test", [
Pure, ConstantLike,
]> {
Expand Down
9 changes: 9 additions & 0 deletions include/circt/Dialect/RTGTest/IR/RTGTestTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ def CPUType : RTGTestTypeDef<"CPU", [ContextResourceTypeInterface]> {
let assemblyFormat = "";
}

class ImmTypeBase<int width> : TypeDef<RTGTestDialect, "Imm" # width, []> {
let summary = "represents a " # width # "-bit immediate";
let mnemonic = "imm" # width;
}

def Imm12Type : ImmTypeBase<12>;
def Imm21Type : ImmTypeBase<21>;
def Imm32Type : ImmTypeBase<32>;

def IntegerRegisterType : TypeDef<RTGTestDialect, "IntegerRegister", [
RegisterTypeInterface
]> {
Expand Down
13 changes: 13 additions & 0 deletions integration_test/Bindings/Python/dialects/rtg.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,16 @@
rtg.FixedRegisterOp(rtgtest.RegT6Attr.get())

print(m)

with Context() as ctx, Location.unknown():
circt.register_dialects(ctx)
m = Module.create()
with InsertionPoint(m.body):
# CHECK: rtgtest.immediate #rtgtest.imm12<3> : !rtgtest.imm12
rtgtest.ImmediateOp(rtgtest.Imm12Attr.get(3))
# CHECK: rtgtest.immediate #rtgtest.imm21<3> : !rtgtest.imm21
rtgtest.ImmediateOp(rtgtest.Imm21Attr.get(3))
# CHECK: rtgtest.immediate #rtgtest.imm32<3> : !rtgtest.imm32
rtgtest.ImmediateOp(rtgtest.Imm32Attr.get(3))

print(m)
57 changes: 57 additions & 0 deletions lib/Bindings/Python/RTGTestModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,30 @@ void circt::python::populateDialectRTGTestSubmodule(py::module &m) {
},
py::arg("self"), py::arg("ctxt") = nullptr);

mlir_type_subclass(m, "Imm12Type", rtgtestTypeIsAImm12)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestImm12TypeGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);

mlir_type_subclass(m, "Imm21Type", rtgtestTypeIsAImm21)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestImm21TypeGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);

mlir_type_subclass(m, "Imm32Type", rtgtestTypeIsAImm32)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgtestImm32TypeGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);

mlir_attribute_subclass(m, "CPUAttr", rtgtestAttrIsACPU)
.def_classmethod(
"get",
Expand Down Expand Up @@ -297,4 +321,37 @@ void circt::python::populateDialectRTGTestSubmodule(py::module &m) {
return cls(rtgtestRegT6AttrGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);

mlir_attribute_subclass(m, "Imm12Attr", rtgtestAttrIsAImm12)
.def_classmethod(
"get",
[](py::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm12AttrGet(ctxt, value));
},
py::arg("self"), py::arg("value"), py::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm12AttrGetValue(self);
});

mlir_attribute_subclass(m, "Imm21Attr", rtgtestAttrIsAImm21)
.def_classmethod(
"get",
[](py::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm21AttrGet(ctxt, value));
},
py::arg("self"), py::arg("value"), py::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm21AttrGetValue(self);
});

mlir_attribute_subclass(m, "Imm32Attr", rtgtestAttrIsAImm32)
.def_classmethod(
"get",
[](py::object cls, unsigned value, MlirContext ctxt) {
return cls(rtgtestImm32AttrGet(ctxt, value));
},
py::arg("self"), py::arg("value"), py::arg("ctxt") = nullptr)
.def_property_readonly("value", [](MlirAttribute self) {
return rtgtestImm32AttrGetValue(self);
});
}
60 changes: 60 additions & 0 deletions lib/CAPI/Dialect/RTGTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@ MlirType rtgtestCPUTypeGet(MlirContext ctxt) {
return wrap(CPUType::get(unwrap(ctxt)));
}

// Immediates.
//===----------------------------------------------------------------------===//

bool rtgtestTypeIsAImm12(MlirType type) { return isa<Imm12Type>(unwrap(type)); }

MlirType rtgtestImm12TypeGet(MlirContext ctxt) {
return wrap(Imm12Type::get(unwrap(ctxt)));
}

bool rtgtestTypeIsAImm21(MlirType type) { return isa<Imm21Type>(unwrap(type)); }

MlirType rtgtestImm21TypeGet(MlirContext ctxt) {
return wrap(Imm21Type::get(unwrap(ctxt)));
}

bool rtgtestTypeIsAImm32(MlirType type) { return isa<Imm32Type>(unwrap(type)); }

MlirType rtgtestImm32TypeGet(MlirContext ctxt) {
return wrap(Imm32Type::get(unwrap(ctxt)));
}

//===----------------------------------------------------------------------===//
// Attribute API.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -306,3 +327,42 @@ bool rtgtestAttrIsARegT6(MlirAttribute attr) {
MlirAttribute rtgtestRegT6AttrGet(MlirContext ctxt) {
return wrap(RegT6Attr::get(unwrap(ctxt)));
}

// Immediates.
//===----------------------------------------------------------------------===//

bool rtgtestAttrIsAImm12(MlirAttribute attr) {
return isa<Imm12Attr>(unwrap(attr));
}

MlirAttribute rtgtestImm12AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm12Attr::get(unwrap(ctxt), value));
}

unsigned rtgtestImm12AttrGetValue(MlirAttribute attr) {
return cast<Imm12Attr>(unwrap(attr)).getValue();
}

bool rtgtestAttrIsAImm21(MlirAttribute attr) {
return isa<Imm21Attr>(unwrap(attr));
}

MlirAttribute rtgtestImm21AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm21Attr::get(unwrap(ctxt), value));
}

unsigned rtgtestImm21AttrGetValue(MlirAttribute attr) {
return cast<Imm21Attr>(unwrap(attr)).getValue();
}

bool rtgtestAttrIsAImm32(MlirAttribute attr) {
return isa<Imm32Attr>(unwrap(attr));
}

MlirAttribute rtgtestImm32AttrGet(MlirContext ctxt, unsigned value) {
return wrap(Imm32Attr::get(unwrap(ctxt), value));
}

unsigned rtgtestImm32AttrGetValue(MlirAttribute attr) {
return cast<Imm32Attr>(unwrap(attr)).getValue();
}
17 changes: 17 additions & 0 deletions lib/Dialect/RTGTest/IR/RTGTestOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,23 @@ size_t CPUDeclOp::getIdentifier(size_t idx) { return getId().getId(); }

mlir::OpFoldResult CPUDeclOp::fold(FoldAdaptor adaptor) { return getId(); }

//===----------------------------------------------------------------------===//
// ImmediateOp
//===----------------------------------------------------------------------===//

mlir::OpFoldResult ImmediateOp::fold(FoldAdaptor adaptor) {
return getImmAttr();
}

LogicalResult ImmediateOp::inferReturnTypes(
MLIRContext *context, std::optional<Location> loc, ValueRange operands,
DictionaryAttr attributes, OpaqueProperties properties,
mlir::RegionRange regions, SmallVectorImpl<Type> &inferredReturnTypes) {
inferredReturnTypes.push_back(
cast<TypedAttr>(properties.as<Properties *>()->getImm()).getType());
return success();
}

//===----------------------------------------------------------------------===//
// ConstantTestOp
//===----------------------------------------------------------------------===//
Expand Down
51 changes: 51 additions & 0 deletions test/CAPI/rtgtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,64 @@ static void testRegisters(MlirContext ctx) {
}
}

static void testImmediates(MlirContext ctx) {
MlirType imm12Type = rtgtestImm12TypeGet(ctx);
// CHECK: is_imm12
fprintf(stderr,
rtgtestTypeIsAImm12(imm12Type) ? "is_imm12\n" : "isnot_imm12\n");
// CHECK: !rtgtest.imm12
mlirTypeDump(imm12Type);

MlirType imm21Type = rtgtestImm21TypeGet(ctx);
// CHECK: is_imm21
fprintf(stderr,
rtgtestTypeIsAImm21(imm21Type) ? "is_imm21\n" : "isnot_imm21\n");
// CHECK: !rtgtest.imm21
mlirTypeDump(imm21Type);

MlirType imm32Type = rtgtestImm32TypeGet(ctx);
// CHECK: is_imm32
fprintf(stderr,
rtgtestTypeIsAImm32(imm32Type) ? "is_imm32\n" : "isnot_imm32\n");
// CHECK: !rtgtest.imm32
mlirTypeDump(imm32Type);

MlirAttribute imm12Attr = rtgtestImm12AttrGet(ctx, 3);
// CHECK: is_imm12
fprintf(stderr,
rtgtestAttrIsAImm12(imm12Attr) ? "is_imm12\n" : "isnot_imm12\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestImm12AttrGetValue(imm12Attr));
// CHECK: #rtgtest.imm12<3>
mlirAttributeDump(imm12Attr);

MlirAttribute imm21Attr = rtgtestImm21AttrGet(ctx, 3);
// CHECK: is_imm21
fprintf(stderr,
rtgtestAttrIsAImm21(imm21Attr) ? "is_imm21\n" : "isnot_imm21\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestImm21AttrGetValue(imm21Attr));
// CHECK: #rtgtest.imm21<3>
mlirAttributeDump(imm21Attr);

MlirAttribute imm32Attr = rtgtestImm32AttrGet(ctx, 3);
// CHECK: is_imm32
fprintf(stderr,
rtgtestAttrIsAImm32(imm32Attr) ? "is_imm32\n" : "isnot_imm32\n");
// CHECK: 3
fprintf(stderr, "%u\n", rtgtestImm32AttrGetValue(imm32Attr));
// CHECK: #rtgtest.imm32<3>
mlirAttributeDump(imm32Attr);
}

int main(int argc, char **argv) {
MlirContext ctx = mlirContextCreate();
mlirDialectHandleLoadDialect(mlirGetDialectHandle__rtgtest__(), ctx);

testCPUType(ctx);
testCPUAttr(ctx);
testRegisters(ctx);
testImmediates(ctx);

mlirContextDestroy(ctx);

Expand Down
Loading

0 comments on commit 30f9e93

Please sign in to comment.