Skip to content

Commit 3a212ca

Browse files
committed
[RTG] Add immediate type and attribute
This adds an immediate type and attribute that support any bitwidth and will replace the immediate types and attributes in the RTGTest dialect. Also adds a constant operation that can create an SSA value for any typed attribute. I also moved the labels type to form a kind of ISA subdialect with the immediates and made that explicit in the textual IR. We can do the same for relevant ops in the future.
1 parent 32bb0d3 commit 3a212ca

File tree

25 files changed

+488
-92
lines changed

25 files changed

+488
-92
lines changed

frontends/PyRTG/test/basic.py

+23-23
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ def entry0():
2020
return Set.create(Integer(0), Integer(1))
2121

2222

23-
# MLIR-LABEL: rtg.target @Tgt1 : !rtg.dict<entry0: index, entry1: !rtg.label>
23+
# MLIR-LABEL: rtg.target @Tgt1 : !rtg.dict<entry0: index, entry1: !rtg.isa.label>
2424
# MLIR-NEXT: [[C0:%.+]] = index.constant 0
2525
# MLIR-NEXT: [[LBL:%.+]] = rtg.label_decl "l0"
26-
# MLIR-NEXT: rtg.yield [[C0]], [[LBL]] : index, !rtg.label
26+
# MLIR-NEXT: rtg.yield [[C0]], [[LBL]] : index, !rtg.isa.label
2727
# MLIR-NEXT: }
2828

2929

@@ -40,7 +40,7 @@ def entry1():
4040

4141

4242
# MLIR-LABEL: rtg.sequence @seq0
43-
# MLIR-SAME: ([[SET:%.+]]: !rtg.set<!rtg.label>)
43+
# MLIR-SAME: ([[SET:%.+]]: !rtg.set<!rtg.isa.label>)
4444
# MLIR-NEXT: [[LABEL:%.+]] = rtg.set_select_random [[SET]]
4545
# MLIR-NEXT: rtg.label local [[LABEL]]
4646
# MLIR-NEXT: }
@@ -114,37 +114,37 @@ def test_args(set: Set):
114114
# MLIR-NEXT: rtg.label external [[L1]]
115115
# MLIR-NEXT: rtg.label local [[L2]]
116116

117-
# MLIR-NEXT: [[SET0:%.+]] = rtg.set_create [[L0]], [[L1]] : !rtg.label
118-
# MLIR-NEXT: [[SET1:%.+]] = rtg.set_create [[L2]] : !rtg.label
119-
# MLIR-NEXT: [[EMPTY_SET:%.+]] = rtg.set_create : !rtg.label
120-
# MLIR-NEXT: [[SET2_1:%.+]] = rtg.set_union [[SET0]], [[SET1]] : !rtg.set<!rtg.label>
121-
# MLIR-NEXT: [[SET2:%.+]] = rtg.set_union [[SET2_1]], [[EMPTY_SET]] : !rtg.set<!rtg.label>
122-
# MLIR-NEXT: [[RL0:%.+]] = rtg.set_select_random [[SET2]] : !rtg.set<!rtg.label>
117+
# MLIR-NEXT: [[SET0:%.+]] = rtg.set_create [[L0]], [[L1]] : !rtg.isa.label
118+
# MLIR-NEXT: [[SET1:%.+]] = rtg.set_create [[L2]] : !rtg.isa.label
119+
# MLIR-NEXT: [[EMPTY_SET:%.+]] = rtg.set_create : !rtg.isa.label
120+
# MLIR-NEXT: [[SET2_1:%.+]] = rtg.set_union [[SET0]], [[SET1]] : !rtg.set<!rtg.isa.label>
121+
# MLIR-NEXT: [[SET2:%.+]] = rtg.set_union [[SET2_1]], [[EMPTY_SET]] : !rtg.set<!rtg.isa.label>
122+
# MLIR-NEXT: [[RL0:%.+]] = rtg.set_select_random [[SET2]] : !rtg.set<!rtg.isa.label>
123123
# MLIR-NEXT: rtg.label local [[RL0]]
124-
# MLIR-NEXT: [[SET2_MINUS_SET0:%.+]] = rtg.set_difference [[SET2]], [[SET0]] : !rtg.set<!rtg.label>
125-
# MLIR-NEXT: [[RL1:%.+]] = rtg.set_select_random [[SET2_MINUS_SET0]] : !rtg.set<!rtg.label>
124+
# MLIR-NEXT: [[SET2_MINUS_SET0:%.+]] = rtg.set_difference [[SET2]], [[SET0]] : !rtg.set<!rtg.isa.label>
125+
# MLIR-NEXT: [[RL1:%.+]] = rtg.set_select_random [[SET2_MINUS_SET0]] : !rtg.set<!rtg.isa.label>
126126
# MLIR-NEXT: rtg.label local [[RL1]]
127127

128128
# MLIR-NEXT: rtg.label_decl "L_{{[{][{]0[}][}]}}", %idx5
129129
# MLIR-NEXT: rtg.label local
130130
# MLIR-NEXT: rtg.label_decl "L_{{[{][{]0[}][}]}}", %idx3
131131
# MLIR-NEXT: rtg.label local
132132

133-
# MLIR-NEXT: [[BAG0:%.+]] = rtg.bag_create (%idx2 x [[L0:%.+]], %idx1 x [[L1:%.+]]) : !rtg.label
134-
# MLIR-NEXT: [[BAG1:%.+]] = rtg.bag_create (%idx1 x [[L2:%.+]]) : !rtg.label
135-
# MLIR-NEXT: [[EMPTY_BAG:%.+]] = rtg.bag_create : !rtg.label
136-
# MLIR-NEXT: [[BAG2_1:%.+]] = rtg.bag_union [[BAG0]], [[BAG1]] : !rtg.bag<!rtg.label>
137-
# MLIR-NEXT: [[BAG2:%.+]] = rtg.bag_union [[BAG2_1]], [[EMPTY_BAG]] : !rtg.bag<!rtg.label>
138-
# MLIR-NEXT: [[RL2:%.+]] = rtg.bag_select_random [[BAG2]] : !rtg.bag<!rtg.label>
139-
# MLIR-NEXT: [[SUB:%.+]] = rtg.bag_create (%idx1 x [[RL2]]) : !rtg.label
140-
# MLIR-NEXT: [[BAG3:%.+]] = rtg.bag_difference [[BAG2]], [[SUB]] inf : !rtg.bag<!rtg.label>
133+
# MLIR-NEXT: [[BAG0:%.+]] = rtg.bag_create (%idx2 x [[L0:%.+]], %idx1 x [[L1:%.+]]) : !rtg.isa.label
134+
# MLIR-NEXT: [[BAG1:%.+]] = rtg.bag_create (%idx1 x [[L2:%.+]]) : !rtg.isa.label
135+
# MLIR-NEXT: [[EMPTY_BAG:%.+]] = rtg.bag_create : !rtg.isa.label
136+
# MLIR-NEXT: [[BAG2_1:%.+]] = rtg.bag_union [[BAG0]], [[BAG1]] : !rtg.bag<!rtg.isa.label>
137+
# MLIR-NEXT: [[BAG2:%.+]] = rtg.bag_union [[BAG2_1]], [[EMPTY_BAG]] : !rtg.bag<!rtg.isa.label>
138+
# MLIR-NEXT: [[RL2:%.+]] = rtg.bag_select_random [[BAG2]] : !rtg.bag<!rtg.isa.label>
139+
# MLIR-NEXT: [[SUB:%.+]] = rtg.bag_create (%idx1 x [[RL2]]) : !rtg.isa.label
140+
# MLIR-NEXT: [[BAG3:%.+]] = rtg.bag_difference [[BAG2]], [[SUB]] inf : !rtg.bag<!rtg.isa.label>
141141
# MLIR-NEXT: rtg.label local [[RL2]]
142-
# MLIR-NEXT: [[BAG4:%.+]] = rtg.bag_difference [[BAG3]], [[BAG1]] : !rtg.bag<!rtg.label>
143-
# MLIR-NEXT: [[RL3:%.+]] = rtg.bag_select_random [[BAG4]] : !rtg.bag<!rtg.label>
142+
# MLIR-NEXT: [[BAG4:%.+]] = rtg.bag_difference [[BAG3]], [[BAG1]] : !rtg.bag<!rtg.isa.label>
143+
# MLIR-NEXT: [[RL3:%.+]] = rtg.bag_select_random [[BAG4]] : !rtg.bag<!rtg.isa.label>
144144
# MLIR-NEXT: rtg.label local [[RL3]]
145145

146-
# MLIR-NEXT: [[SEQ:%.+]] = rtg.get_sequence @seq0 : !rtg.sequence<!rtg.set<!rtg.label>>
147-
# MLIR-NEXT: [[SUBST:%.+]] = rtg.substitute_sequence [[SEQ]]([[SET0]]) : !rtg.sequence<!rtg.set<!rtg.label>>
146+
# MLIR-NEXT: [[SEQ:%.+]] = rtg.get_sequence @seq0 : !rtg.sequence<!rtg.set<!rtg.isa.label>>
147+
# MLIR-NEXT: [[SUBST:%.+]] = rtg.substitute_sequence [[SEQ]]([[SET0]]) : !rtg.sequence<!rtg.set<!rtg.isa.label>>
148148
# MLIR-NEXT: [[RAND1:%.+]] = rtg.randomize_sequence [[SUBST]]
149149
# MLIR-NEXT: rtg.embed_sequence [[RAND1]]
150150
# MLIR-NEXT: [[RAND2:%.+]] = rtg.randomize_sequence [[SUBST]]

include/circt-c/Dialect/RTG.h

+25
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ MLIR_CAPI_EXPORTED MlirType rtgDictTypeGet(MlirContext ctxt,
7979
MlirAttribute const *entryNames,
8080
MlirType const *entryTypes);
8181

82+
/// If the type is an RTG immediate.
83+
MLIR_CAPI_EXPORTED bool rtgTypeIsAImmediate(MlirType type);
84+
85+
/// Creates an RTG immediate type in the context.
86+
MLIR_CAPI_EXPORTED MlirType rtgImmediateTypeGet(MlirContext ctx,
87+
uint32_t width);
88+
89+
/// Returns the width of the RTG immediate type.
90+
MLIR_CAPI_EXPORTED uint32_t rtgImmediateTypeGetWidth(MlirType type);
91+
8292
//===----------------------------------------------------------------------===//
8393
// Attribute API.
8494
//===----------------------------------------------------------------------===//
@@ -108,6 +118,21 @@ MLIR_CAPI_EXPORTED bool rtgAttrIsADefaultContextAttr(MlirAttribute attr);
108118
MLIR_CAPI_EXPORTED MlirAttribute rtgDefaultContextAttrGet(MlirContext ctxt,
109119
MlirType type);
110120

121+
/// Checks if the attribute is an RTG immediate attribute.
122+
MLIR_CAPI_EXPORTED bool rtgAttrIsAImmediate(MlirAttribute attr);
123+
124+
/// Creates an RTG immediate attribute in the context with the given width and
125+
/// value.
126+
MLIR_CAPI_EXPORTED MlirAttribute rtgImmediateAttrGet(MlirContext ctx,
127+
uint32_t width,
128+
uint64_t value);
129+
130+
/// Returns the width of the RTG immediate attribute.
131+
MLIR_CAPI_EXPORTED uint32_t rtgImmediateAttrGetWidth(MlirAttribute attr);
132+
133+
/// Returns the value of the RTG immediate attribute.
134+
MLIR_CAPI_EXPORTED uint64_t rtgImmediateAttrGetValue(MlirAttribute attr);
135+
111136
#ifdef __cplusplus
112137
}
113138
#endif

include/circt/Dialect/RTG/IR/RTGAttributes.h

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define CIRCT_DIALECT_RTG_IR_RTGATTRIBUTES_H
1111

1212
#include "circt/Dialect/RTG/IR/RTGAttrInterfaces.h"
13+
#include "circt/Dialect/RTG/IR/RTGTypes.h"
1314
#include "mlir/IR/Attributes.h"
1415
#include "mlir/IR/BuiltinAttributes.h"
1516

include/circt/Dialect/RTG/IR/RTGAttributes.td

+21
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,25 @@ def DefaultContextAttr : RTGAttrDef<"DefaultContext", [
7575
let assemblyFormat = "";
7676
}
7777

78+
//===----------------------------------------------------------------------===//
79+
// Attributes for ISA targets
80+
//===----------------------------------------------------------------------===//
81+
82+
class RTGISAAttrDef<string name, list<Trait> traits = []>
83+
: RTGAttrDef<name, traits> { let mnemonic = "isa." # !tolower(name); }
84+
85+
def ImmediateAttr : RTGISAAttrDef<"Immediate", [
86+
DeclareAttrInterfaceMethods<TypedAttrInterface>,
87+
]> {
88+
let summary = "an ISA immediate value";
89+
let description = [{
90+
This represents an ISA immediate of arbitrary but fixed bit-width. The type
91+
of this attribute must always be an `ImmediateType` of matching bit-width.
92+
}];
93+
94+
let parameters = (ins "llvm::APInt":$value);
95+
96+
let hasCustomAssemblyFormat = true;
97+
}
98+
7899
#endif // CIRCT_DIALECT_RTG_IR_RTGATTRIBUTES_TD

include/circt/Dialect/RTG/IR/RTGDialect.td

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ def RTGDialect : Dialect {
2929
let useDefaultTypePrinterParser = 1;
3030
let cppNamespace = "::circt::rtg";
3131

32+
let hasConstantMaterializer = 1;
33+
3234
let extraClassDeclaration = [{
3335
void registerAttributes();
3436
void registerTypes();

include/circt/Dialect/RTG/IR/RTGOps.td

+15
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ include "circt/Dialect/RTG/IR/RTGISAAssemblyInterfaces.td"
2525
class RTGOp<string mnemonic, list<Trait> traits = []> :
2626
Op<RTGDialect, mnemonic, traits>;
2727

28+
29+
def ConstantOp : RTGOp<"constant", [
30+
Pure,
31+
ConstantLike,
32+
DeclareOpInterfaceMethods<InferTypeOpInterface>
33+
]> {
34+
let summary = "create an SSA value from an attribute";
35+
36+
let arguments = (ins TypedAttrInterface:$value);
37+
let results = (outs AnyType:$result);
38+
39+
let assemblyFormat = "$value attr-dict";
40+
let hasFolder = 1;
41+
}
42+
2843
//===- Sequence Handling Operations ---------------------------------------===//
2944

3045
def SequenceOp : RTGOp<"sequence", [

include/circt/Dialect/RTG/IR/RTGTypes.td

+46-12
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
include "circt/Dialect/RTG/IR/RTGDialect.td"
1717
include "mlir/IR/AttrTypeBase.td"
1818

19-
class RTGTypeDef<string name> : TypeDef<RTGDialect, name>;
19+
class RTGTypeDef<string name, list<Trait> traits = []>
20+
: TypeDef<RTGDialect, name, traits>;
21+
22+
//===----------------------------------------------------------------------===//
23+
// Sequence Types
24+
//===----------------------------------------------------------------------===//
2025

2126
def SequenceType : RTGTypeDef<"Sequence"> {
2227
let summary = "handle to a sequence or sequence family";
@@ -51,17 +56,9 @@ def FullySubstitutedSequenceType : DialectType<RTGDialect,
5156
"::circt::rtg::SequenceType::get($_builder.getContext(), " #
5257
"llvm::ArrayRef<::mlir::Type>{})">;
5358

54-
def LabelType : RTGTypeDef<"Label"> {
55-
let summary = "a reference to a label";
56-
let description = [{
57-
This type represents a label. Payload dialects can add operations to cast
58-
from this type to an immediate type they can use as an operand to an
59-
instruction.
60-
}];
61-
62-
let mnemonic = "label";
63-
let assemblyFormat = "";
64-
}
59+
//===----------------------------------------------------------------------===//
60+
// Types for common datastructures
61+
//===----------------------------------------------------------------------===//
6562

6663
def SetType : RTGTypeDef<"Set"> {
6764
let summary = "a set of values";
@@ -123,6 +120,43 @@ def DictType : RTGTypeDef<"Dict"> {
123120
let genVerifyDecl = 1;
124121
}
125122

123+
//===----------------------------------------------------------------------===//
124+
// Types for ISA targets
125+
//===----------------------------------------------------------------------===//
126+
127+
class RTGISATypeDef<string name, list<Trait> traits = []>
128+
: RTGTypeDef<name, traits> { let mnemonic = "isa." # !tolower(name); }
129+
130+
131+
def LabelType : RTGISATypeDef<"Label"> {
132+
let summary = "a reference to a label";
133+
let description = [{
134+
This type represents a label. Payload dialects can add operations to cast
135+
from this type to an immediate type they can use as an operand to an
136+
instruction or allow an operand of this type directly.
137+
}];
138+
139+
let assemblyFormat = "";
140+
}
141+
142+
def ImmediateType : RTGISATypeDef<"Immediate"> {
143+
let summary = "an ISA immediate";
144+
let description = [{
145+
This type represents immediates of arbitrary but fixed bit-width.
146+
The RTG dialect provides this type to avoid duplication in ISA payload
147+
dialects.
148+
}];
149+
150+
let parameters = (ins "uint32_t":$width);
151+
let assemblyFormat = "`<` $width `>`";
152+
}
153+
154+
class ImmediateOfWidth<int width> : Type<
155+
And<[CPred<"llvm::isa<::circt::rtg::ImmediateType>($_self)">,
156+
CPred<"llvm::cast<::circt::rtg::ImmediateType>($_self).getWidth() == " # width>]>,
157+
"a " # width # "-bit immediate">,
158+
BuildableType<"::circt::rtg::ImmediateType::get($_builder.getContext(), " # width # ")">;
159+
126160
class ImmTypeBase<int width> : TypeDef<RTGDialect, "Imm" # width, []> {
127161
let summary = "represents a " # width # "-bit immediate";
128162
let mnemonic = "imm" # width;

include/circt/Dialect/RTG/IR/RTGVisitors.h

+9-4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class RTGOpVisitor {
3232
auto *thisCast = static_cast<ConcreteType *>(this);
3333
return TypeSwitch<Operation *, ResultType>(op)
3434
.template Case<
35+
// Constants
36+
ConstantOp,
3537
// Bags
3638
BagCreateOp, BagSelectRandomOp, BagDifferenceOp, BagUnionOp,
3739
BagUniqueSizeOp,
@@ -82,6 +84,7 @@ class RTGOpVisitor {
8284
return static_cast<ConcreteType *>(this)->visit##OPKIND##Op(op, args...); \
8385
}
8486

87+
HANDLE(ConstantOp, Unhandled);
8588
HANDLE(SequenceOp, Unhandled);
8689
HANDLE(GetSequenceOp, Unhandled);
8790
HANDLE(SubstituteSequenceOp, Unhandled);
@@ -120,10 +123,11 @@ class RTGTypeVisitor {
120123
ResultType dispatchTypeVisitor(Type type, ExtraArgs... args) {
121124
auto *thisCast = static_cast<ConcreteType *>(this);
122125
return TypeSwitch<Type, ResultType>(type)
123-
.template Case<SequenceType, SetType, BagType, DictType, LabelType,
124-
IndexType, IntegerType>([&](auto expr) -> ResultType {
125-
return thisCast->visitType(expr, args...);
126-
})
126+
.template Case<ImmediateType, SequenceType, SetType, BagType, DictType,
127+
LabelType, IndexType, IntegerType>(
128+
[&](auto expr) -> ResultType {
129+
return thisCast->visitType(expr, args...);
130+
})
127131
.template Case<ContextResourceTypeInterface>(
128132
[&](auto expr) -> ResultType {
129133
return thisCast->visitContextResourceType(expr, args...);
@@ -163,6 +167,7 @@ class RTGTypeVisitor {
163167
args...); \
164168
}
165169

170+
HANDLE(ImmediateType, Unhandled);
166171
HANDLE(SequenceType, Unhandled);
167172
HANDLE(SetType, Unhandled);
168173
HANDLE(BagType, Unhandled);

integration_test/Bindings/Python/dialects/rtg.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
# CHECK: index{{$}}
107107
print(bagTy.element_type)
108108

109-
# CHECK: rtg.sequence @seq(%{{.*}}: !rtg.sequence, %{{.*}}: !rtg.label, %{{.*}}: !rtg.set<index>, %{{.*}}: !rtg.bag<index>, %{{.*}}: !rtgtest.ireg, %{{.*}}: !rtg.randomized_sequence)
109+
# CHECK: rtg.sequence @seq(%{{.*}}: !rtg.sequence, %{{.*}}: !rtg.isa.label, %{{.*}}: !rtg.set<index>, %{{.*}}: !rtg.bag<index>, %{{.*}}: !rtgtest.ireg, %{{.*}}: !rtg.randomized_sequence)
110110
print(m)
111111

112112
with Context() as ctx, Location.unknown():
@@ -221,3 +221,17 @@
221221
print(attr.type)
222222
# CHECK: #rtg.default : !rtgtest.cpu
223223
print(attr)
224+
225+
immediate_type = rtg.ImmediateType.get(32)
226+
# CHECK: width=32
227+
print(f"width={immediate_type.width}")
228+
# CHECK: !rtg.isa.immediate<32>
229+
print(immediate_type)
230+
231+
immediate_attr = rtg.ImmediateAttr.get(32, 42)
232+
# CHECK: width=32
233+
print(f"width={immediate_attr.width}")
234+
# CHECK: value=42
235+
print(f"value={immediate_attr.value}")
236+
# CHECK: #rtg.isa.immediate<32, 42>
237+
print(immediate_attr)

0 commit comments

Comments
 (0)