Skip to content

Commit ddc4642

Browse files
committed
[RTG] Add int_to_immediate op
1 parent 6e25954 commit ddc4642

File tree

7 files changed

+95
-16
lines changed

7 files changed

+95
-16
lines changed

frontends/PyRTG/src/pyrtg/resources.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@
88
from .rtgtest import rtgtest
99
from .core import Value
1010
from .circt import ir
11+
from .integers import Integer
1112

1213
from typing import Union
1314

1415

1516
class Immediate(Value):
1617

17-
def __init__(self, width: int, value: Union[ir.Value, int]) -> Immediate:
18+
def __init__(self, width: int, value: Union[ir.Value, int,
19+
Integer]) -> Immediate:
1820
self._width = width
1921
self._value = value
2022

2123
def _get_ssa_value(self) -> ir.Value:
2224
if isinstance(self._value, int):
2325
self = rtg.ConstantOp(rtg.ImmediateAttr.get(self._width, self._value))
26+
if isinstance(self._value, Integer):
27+
self = rtg.IntToImmediateOp(rtg.ImmediateType.get(self._width),
28+
self._value)
2429
return self._value
2530

2631
def get_type(self) -> ir.Type:

frontends/PyRTG/test/basic.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,32 +77,32 @@ def test0():
7777
pass
7878

7979

80-
# MLIR-LABEL: rtg.test @test_args
80+
# MLIR-LABEL: rtg.test @test1_args
8181
# MLIR-SAME: (entry0 = [[SET:%.+]]: !rtg.set<index>)
8282
# MLIR-NEXT: [[RAND:%.+]] = rtg.set_select_random [[SET]] : !rtg.set<index>
8383
# MLIR-NEXT: rtg.label_decl "L_{{[{][{]0[}][}]}}", [[RAND]]
8484
# MLIR-NEXT: rtg.label local
8585
# MLIR-NEXT: }
8686

87-
# ELABORATED-LABEL: rtg.test @test_args_Tgt0
87+
# ELABORATED-LABEL: rtg.test @test1_args_Tgt0
8888
# CHECK: rtg.label_decl "L_0"
8989
# CHECK-NEXT: rtg.label local
9090
# CHECK-NEXT: }
9191

92-
# ASM-LABEL: Begin of test_args
92+
# ASM-LABEL: Begin of test1_args
9393
# ASM-EMPTY:
9494
# ASM-NEXT: L_0:
9595
# ASM-EMPTY:
96-
# ASM: End of test_args
96+
# ASM: End of test1_args
9797

9898

9999
@test(("entry0", Set.type(Integer.type())))
100-
def test_args(set: Set):
100+
def test1_args(set: Set):
101101
i = set.get_random()
102102
Label.declare(r"L_{{0}}", i).place()
103103

104104

105-
# MLIR-LABEL: rtg.test @test_labels
105+
# MLIR-LABEL: rtg.test @test2_labels
106106
# MLIR-NEXT: index.constant 5
107107
# MLIR-NEXT: index.constant 3
108108
# MLIR-NEXT: index.constant 2
@@ -158,7 +158,7 @@ def test_args(set: Set):
158158

159159
# MLIR-NEXT: }
160160

161-
# ELABORATED-LABEL: rtg.test @test_labels
161+
# ELABORATED-LABEL: rtg.test @test2_labels
162162
# ELABORATED-NEXT: [[L0:%.+]] = rtg.label_decl "l0"
163163
# ELABORATED-NEXT: rtg.label global [[L0]]
164164
# ELABORATED-NEXT: [[L1:%.+]] = rtg.label_decl "l1_0"
@@ -188,7 +188,7 @@ def test_args(set: Set):
188188

189189
# ELABORATED-NEXT: }
190190

191-
# ASM-LABEL: Begin of test_labels
191+
# ASM-LABEL: Begin of test2_labels
192192
# ASM-EMPTY:
193193
# ASM-NEXT: .global l0
194194
# ASM-NEXT: l0:
@@ -211,11 +211,11 @@ def test_args(set: Set):
211211
# ASM-NEXT: s1:
212212

213213
# ASM-EMPTY:
214-
# ASM: End of test_labels
214+
# ASM: End of test2_labels
215215

216216

217217
@test()
218-
def test_labels():
218+
def test2_labels():
219219
l0 = Label.declare("l0")
220220
l1 = Label.declare_unique("l1")
221221
l2 = Label.declare_unique("l1")
@@ -260,7 +260,7 @@ def test_labels():
260260
seq1()
261261

262262

263-
# MLIR-NEXT: rtg.test @test_registers_and_immediates()
263+
# MLIR-LABEL: rtg.test @test3_registers_and_immediates()
264264
# MLIR-NEXT: [[IMM32:%.+]] = rtg.constant #rtg.isa.immediate<32, 32>
265265
# MLIR-NEXT: [[IMM21:%.+]] = rtg.constant #rtg.isa.immediate<21, 16>
266266
# MLIR-NEXT: [[IMM13:%.+]] = rtg.constant #rtg.isa.immediate<13, 9>
@@ -279,11 +279,24 @@ def test_labels():
279279

280280

281281
@test()
282-
def test_registers_and_immediates():
282+
def test3_registers_and_immediates():
283283
vreg = IntegerRegister.virtual()
284284
imm12 = Immediate(12, 8)
285285
rtgtest.ADDI(vreg, IntegerRegister.t0(), imm12)
286286
rtgtest.SLLI(vreg, IntegerRegister.t1(), Immediate(5, 4))
287287
rtgtest.BEQ(vreg, IntegerRegister.t2(), Immediate(13, 9))
288288
rtgtest.JAL(vreg, Immediate(21, 16))
289289
rtgtest.AUIPC(vreg, Immediate(32, 32))
290+
291+
292+
# MLIR-LABEL: rtg.test @test4_integer_to_immediate()
293+
# MLIR-NEXT: [[V0:%.+]] = rtg.fixed_reg
294+
# MLIR-NEXT: [[V1:%.+]] = index.constant 2
295+
# MLIR-NEXT: [[V2:%.+]] = rtg.isa.int_to_immediate [[V1]] : !rtg.isa.immediate<12>
296+
# MLIR-NEXT: rtgtest.rv32i.addi [[V0]], [[V0]], [[V2]]
297+
298+
299+
@test()
300+
def test4_integer_to_immediate():
301+
rtgtest.ADDI(IntegerRegister.t0(), IntegerRegister.t0(),
302+
Immediate(12, Integer(2)))

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,26 @@ def YieldOp : RTGOp<"yield", [Pure, Terminator]> {
588588

589589
let builders = [OpBuilder<(ins), [{ /* nothing to do */ }]>];
590590
}
591+
592+
//===----------------------------------------------------------------------===//
593+
// ISA Target Operations
594+
//===----------------------------------------------------------------------===//
595+
596+
class RTGISAOp<string mnemonic, list<Trait> traits = []> :
597+
Op<RTGDialect, "isa." # mnemonic, traits>;
598+
599+
//===- ISA Immediate Handling Operations ----------------------------------===//
600+
601+
def IntToImmediateOp : RTGISAOp<"int_to_immediate", [Pure]> {
602+
let summary = "construct an immediate from an integer";
603+
let description = [{
604+
Create an immediate of static bit-width from the provided integer. If the
605+
integer does not fit in the specified bit-width, an error shall be emitted
606+
when executing this operation.
607+
}];
608+
609+
let arguments = (ins Index:$input);
610+
let results = (outs ImmediateType:$result);
611+
612+
let assemblyFormat = "$input `:` qualified(type($result)) attr-dict";
613+
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ class RTGOpVisitor {
5252
RandomizeSequenceOp, EmbedSequenceOp, InterleaveSequencesOp,
5353
// Sets
5454
SetCreateOp, SetSelectRandomOp, SetDifferenceOp, SetUnionOp,
55-
SetSizeOp>([&](auto expr) -> ResultType {
55+
SetSizeOp,
56+
// Immediates
57+
IntToImmediateOp>([&](auto expr) -> ResultType {
5658
return thisCast->visitOp(expr, args...);
5759
})
5860
.Default([&](auto expr) -> ResultType {
@@ -112,6 +114,7 @@ class RTGOpVisitor {
112114
HANDLE(YieldOp, Unhandled);
113115
HANDLE(FixedRegisterOp, Unhandled);
114116
HANDLE(VirtualRegisterOp, Unhandled);
117+
HANDLE(IntToImmediateOp, Unhandled);
115118
#undef HANDLE
116119
};
117120

lib/Dialect/RTG/Transforms/ElaborationPass.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,19 @@ class Elaborator : public RTGOpVisitor<Elaborator, FailureOr<DeletionKind>> {
11691169
return DeletionKind::Delete;
11701170
}
11711171

1172+
FailureOr<DeletionKind> visitOp(IntToImmediateOp op) {
1173+
size_t input = get<size_t>(op.getInput());
1174+
auto width = op.getType().getWidth();
1175+
auto emitError = [&]() { return op->emitError(); };
1176+
if (input > APInt::getAllOnes(width).getZExtValue())
1177+
return emitError() << "cannot represent " << input << " with " << width
1178+
<< " bits";
1179+
1180+
state[op.getResult()] =
1181+
ImmediateAttr::get(op.getContext(), APInt(width, input));
1182+
return DeletionKind::Delete;
1183+
}
1184+
11721185
FailureOr<DeletionKind> visitOp(OnContextOp op) {
11731186
ContextResourceAttrInterface from = currentContext,
11741187
to = cast<ContextResourceAttrInterface>(

test/Dialect/RTG/IR/basic.mlir

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
rtg.test @constants() {
55
// CHECK-NEXT: rtg.constant #rtg.isa.immediate<2, -1> : !rtg.isa.immediate<2>
66
%0 = rtg.constant #rtg.isa.immediate<2, -1>
7+
8+
// CHECK-NEXT: [[V0:%.+]] = index.constant 5
9+
// CHECK-NEXT: rtg.isa.int_to_immediate [[V0]] : !rtg.isa.immediate<32>
10+
%1 = index.constant 5
11+
%2 = rtg.isa.int_to_immediate %1 : !rtg.isa.immediate<32>
712
}
813

914
// CHECK-LABEL: rtg.sequence @ranomizedSequenceType

test/Dialect/RTG/Transform/elaboration.mlir

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ func.func @dummy4(%arg0: index, %arg1: index, %arg2: !rtg.bag<index>, %arg3: !rt
77
func.func @dummy5(%arg0: i1) -> () {return}
88
func.func @dummy6(%arg0: !rtg.isa.immediate<2>) -> () {return}
99

10-
// CHECK-LABEL: @constantImmediate
11-
rtg.test @constantImmediate() {
10+
// CHECK-LABEL: @immediates
11+
rtg.test @immediates() {
1212
// CHECK-NEXT: [[V0:%.+]] = rtg.constant #rtg.isa.immediate<2, -1>
1313
// CHECK-NEXT: func.call @dummy6([[V0]]) : (!rtg.isa.immediate<2>) -> ()
1414
%0 = rtg.constant #rtg.isa.immediate<2, -1>
1515
func.call @dummy6(%0) : (!rtg.isa.immediate<2>) -> ()
16+
17+
// CHECK-NEXT: [[V1:%.+]] = rtg.constant #rtg.isa.immediate<2, 1>
18+
// CHECK-NEXT: func.call @dummy6([[V1]]) : (!rtg.isa.immediate<2>) -> ()
19+
%1 = index.constant 1
20+
%2 = rtg.isa.int_to_immediate %1 : !rtg.isa.immediate<2>
21+
func.call @dummy6(%2) : (!rtg.isa.immediate<2>) -> ()
1622
}
1723

1824
// Test the set operations and passing a sequence to another one via argument
@@ -597,3 +603,14 @@ rtg.test @emptyBagSelect() {
597603
%1 = rtg.bag_select_random %0 : !rtg.bag<!rtg.isa.label>
598604
rtg.label local %1
599605
}
606+
607+
// -----
608+
609+
func.func @dummy6(%arg0: !rtg.isa.immediate<2>) -> () {return}
610+
611+
rtg.test @integerTooBig() {
612+
%1 = index.constant 8
613+
// expected-error @below {{cannot represent 8 with 2 bits}}
614+
%2 = rtg.isa.int_to_immediate %1 : !rtg.isa.immediate<2>
615+
func.call @dummy6(%2) : (!rtg.isa.immediate<2>) -> ()
616+
}

0 commit comments

Comments
 (0)