mirror of https://github.com/llvm/circt.git
[RTGTest] Add representation for immediates (#8053)
This commit is contained in:
parent
c4e458f6d9
commit
a4fa04d143
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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
|
||||
|
|
|
@ -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]> {
|
||||
|
||||
|
|
|
@ -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,
|
||||
]> {
|
||||
|
|
|
@ -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
|
||||
]> {
|
||||
|
|
|
@ -165,3 +165,16 @@ with Context() as ctx, Location.unknown():
|
|||
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)
|
||||
|
|
|
@ -30,6 +30,30 @@ void circt::python::populateDialectRTGTestSubmodule(nb::module_ &m) {
|
|||
},
|
||||
nb::arg("self"), nb::arg("ctxt") = nullptr);
|
||||
|
||||
mlir_type_subclass(m, "Imm12Type", rtgtestTypeIsAImm12)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](nb::object cls, MlirContext ctxt) {
|
||||
return cls(rtgtestImm12TypeGet(ctxt));
|
||||
},
|
||||
nb::arg("self"), nb::arg("ctxt") = nullptr);
|
||||
|
||||
mlir_type_subclass(m, "Imm21Type", rtgtestTypeIsAImm21)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](nb::object cls, MlirContext ctxt) {
|
||||
return cls(rtgtestImm21TypeGet(ctxt));
|
||||
},
|
||||
nb::arg("self"), nb::arg("ctxt") = nullptr);
|
||||
|
||||
mlir_type_subclass(m, "Imm32Type", rtgtestTypeIsAImm32)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](nb::object cls, MlirContext ctxt) {
|
||||
return cls(rtgtestImm32TypeGet(ctxt));
|
||||
},
|
||||
nb::arg("self"), nb::arg("ctxt") = nullptr);
|
||||
|
||||
mlir_attribute_subclass(m, "CPUAttr", rtgtestAttrIsACPU)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
|
@ -295,4 +319,37 @@ void circt::python::populateDialectRTGTestSubmodule(nb::module_ &m) {
|
|||
return cls(rtgtestRegT6AttrGet(ctxt));
|
||||
},
|
||||
nb::arg("self"), nb::arg("ctxt") = nullptr);
|
||||
|
||||
mlir_attribute_subclass(m, "Imm12Attr", rtgtestAttrIsAImm12)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](nb::object cls, unsigned value, MlirContext ctxt) {
|
||||
return cls(rtgtestImm12AttrGet(ctxt, value));
|
||||
},
|
||||
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
|
||||
.def_property_readonly("value", [](MlirAttribute self) {
|
||||
return rtgtestImm12AttrGetValue(self);
|
||||
});
|
||||
|
||||
mlir_attribute_subclass(m, "Imm21Attr", rtgtestAttrIsAImm21)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](nb::object cls, unsigned value, MlirContext ctxt) {
|
||||
return cls(rtgtestImm21AttrGet(ctxt, value));
|
||||
},
|
||||
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
|
||||
.def_property_readonly("value", [](MlirAttribute self) {
|
||||
return rtgtestImm21AttrGetValue(self);
|
||||
});
|
||||
|
||||
mlir_attribute_subclass(m, "Imm32Attr", rtgtestAttrIsAImm32)
|
||||
.def_classmethod(
|
||||
"get",
|
||||
[](nb::object cls, unsigned value, MlirContext ctxt) {
|
||||
return cls(rtgtestImm32AttrGet(ctxt, value));
|
||||
},
|
||||
nb::arg("self"), nb::arg("value"), nb::arg("ctxt") = nullptr)
|
||||
.def_property_readonly("value", [](MlirAttribute self) {
|
||||
return rtgtestImm32AttrGetValue(self);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -260,6 +260,56 @@ 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);
|
||||
|
@ -267,6 +317,7 @@ int main(int argc, char **argv) {
|
|||
testCPUType(ctx);
|
||||
testCPUAttr(ctx);
|
||||
testRegisters(ctx);
|
||||
testImmediates(ctx);
|
||||
|
||||
mlirContextDestroy(ctx);
|
||||
|
||||
|
|
|
@ -86,6 +86,23 @@ rtg.test @registers : !rtg.dict<reg: !rtgtest.ireg> {
|
|||
rtg.virtual_reg [#rtgtest.ra, #rtgtest.sp]
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @immediates
|
||||
rtg.test @immediates : !rtg.dict<> {
|
||||
// CHECK: rtgtest.immediate #rtgtest.imm12<3> : !rtgtest.imm12
|
||||
rtgtest.immediate #rtgtest.imm12<3> : !rtgtest.imm12
|
||||
// CHECK: rtgtest.immediate #rtgtest.imm21<3> : !rtgtest.imm21
|
||||
rtgtest.immediate #rtgtest.imm21<3> : !rtgtest.imm21
|
||||
// CHECK: rtgtest.immediate #rtgtest.imm32<3> : !rtgtest.imm32
|
||||
rtgtest.immediate #rtgtest.imm32<3> : !rtgtest.imm32
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
rtg.test @immediateTooBig : !rtg.dict<> {
|
||||
// expected-error @below {{cannot represent 2000000 with 12 bits}}
|
||||
rtgtest.immediate #rtgtest.imm12<2000000> : !rtgtest.imm12
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
rtg.test @emptyAllowed : !rtg.dict<> {
|
||||
|
|
Loading…
Reference in New Issue