Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Arc] Fix folding of initialized StateOp #7653

Merged
merged 2 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions lib/Dialect/Arc/ArcFolds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,33 @@ static bool isAlways(Value value, bool expected) {

LogicalResult StateOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
if ((isAlways(adaptor.getEnable(), false) ||
isAlways(adaptor.getReset(), true)) &&
!getOperation()->hasAttr("name") && !getOperation()->hasAttr("names")) {
// We can fold to zero here because the states are zero-initialized and
// don't ever change.
for (auto resTy : getResultTypes())
results.push_back(IntegerAttr::get(resTy, 0));
return success();

if (getNumResults() > 0 && !getOperation()->hasAttr("name") &&
!getOperation()->hasAttr("names")) {
bool hasExplicitInitials = !getInitials().empty();
bool allInitialsConstant =
!hasExplicitInitials ||
llvm::all_of(adaptor.getInitials(),
[&](Attribute attr) { return !!attr; });
if (isAlways(adaptor.getEnable(), false) && allInitialsConstant) {
// Fold to the explicit or implicit initial value if
// the state is never enabled and the initial values
// are compile-time constants.
if (hasExplicitInitials)
results.append(adaptor.getInitials().begin(),
adaptor.getInitials().end());
else
for (auto resTy : getResultTypes())
results.push_back(IntegerAttr::get(resTy, 0));
return success();
}
if (!hasExplicitInitials && isAlways(adaptor.getReset(), true)) {
// We assume both the implicit initial value and the
// implicit (synchronous) reset value to be zero.
for (auto resTy : getResultTypes())
results.push_back(IntegerAttr::get(resTy, 0));
return success();
}
}

// Remove operand when input is default value.
Expand Down
20 changes: 17 additions & 3 deletions test/Dialect/Arc/canonicalizers.mlir
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
// RUN: circt-opt --canonicalize %s | FileCheck %s

// CHECK-LABEL: hw.module @stateOpCanonicalizer
hw.module @stateOpCanonicalizer(in %clk: !seq.clock, in %in: i32, in %en: i1, in %rst: i1, out out0: i32, out out1: i32, out out2: i32, out out3: i32, out out4: i32, out out5: i32, out out6: i32, out out7: i32, out out8: i32, out out9: i32, out out10: i32, out out11: i32, out out12: i32, out out13: i32, out out14: i32, out out15: i32) {
hw.module @stateOpCanonicalizer(in %clk: !seq.clock, in %in: i32, in %en: i1, in %rst: i1, out out0: i32, out out1: i32, out out2: i32, out out3: i32, out out4: i32, out out5: i32, out out6: i32, out out7: i32, out out8: i32, out out9: i32, out out10: i32, out out11: i32, out out12: i32, out out13: i32, out out14: i32, out out15: i32, out out16: i32, out out17: i32, out out18: i32, out out19: i32, out out18: i32, out out19: i32) {
// CHECK-NEXT: %c0_i32 = hw.constant 0 : i32
// CHECK-NEXT: %true = hw.constant true
// CHECK-NEXT: %false = hw.constant false
// CHECK-DAG: %c1234_i32 = hw.constant 1234 : i32
// CHECK-DAG: %c4321_i32 = hw.constant 4321 : i32

%true = hw.constant true
%false = hw.constant false
%c1234_i32 = hw.constant 1234 : i32
%c4321_i32 = hw.constant 4321 : i32

arc.state @Foo(%in) clock %clk latency 1 : (i32) -> ()
arc.state @Foo(%in) clock %clk enable %false latency 1 : (i32) -> ()

// CHECK-NEXT: {{%.+}} = arc.state @Bar(%in) clock %clk latency 1 {name = "stateName"} : (i32) -> i32
%1 = arc.state @Bar(%in) clock %clk latency 1 {name = "stateName"} : (i32) -> i32
// CHECK-NEXT: {{%.+}} = arc.state @Bar(%in) clock %clk latency 1 {names = ["stateName"]} : (i32) -> i32
Expand Down Expand Up @@ -39,8 +46,15 @@ hw.module @stateOpCanonicalizer(in %clk: !seq.clock, in %in: i32, in %en: i1, in
// CHECK-NEXT: %{{.+}} = arc.state @Passthrough(%in) clock %clk enable %false reset %true latency 1 {names = ["stateName"]} : (i32) -> i32
%16 = arc.state @Passthrough(%in) clock %clk enable %false reset %true latency 1 {names = ["stateName"]} : (i32) -> i32

// CHECK-NEXT: hw.output %c0_i32, [[V4]], %c0_i32, %c0_i32, %c0_i32, [[V8]], [[V9]], %c0_i32, %c0_i32, %c0_i32, [[V12]]#0, [[V12]]#1, [[V13]]#0, [[V13]]#1, %c0_i32, %c0_i32 : i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32
hw.output %3, %4, %5, %6, %7, %8, %9, %10, %11#0, %11#1, %12#0, %12#1, %13#0, %13#1, %14#0, %14#1 : i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32
%17:2 = arc.state @Passthrough2(%in, %in) clock %clk enable %false reset %true initial (%c1234_i32, %c4321_i32 : i32, i32) latency 1 : (i32, i32) -> (i32, i32)
// CHECK-NEXT: [[V14:%.+]]:2 = arc.state @Passthrough2(%in, %in) clock %clk enable %false reset %true initial (%c1234_i32, %in : i32, i32) latency 1 : (i32, i32) -> (i32, i32)
%18:2 = arc.state @Passthrough2(%in, %in) clock %clk enable %false reset %true initial (%c1234_i32, %in : i32, i32) latency 1 : (i32, i32) -> (i32, i32)

// CHECK-NEXT: [[V15:%.+]]:2 = arc.state @Passthrough2(%in, %in) clock %clk enable %en reset %true initial (%c4321_i32, %c1234_i32 : i32, i32) latency 1 : (i32, i32) -> (i32, i32)
%19:2 = arc.state @Passthrough2(%in, %in) clock %clk enable %en reset %true initial (%c4321_i32, %c1234_i32 : i32, i32) latency 1 : (i32, i32) -> (i32, i32)

// CHECK-NEXT: hw.output %c0_i32, [[V4]], %c0_i32, %c0_i32, %c0_i32, [[V8]], [[V9]], %c0_i32, %c0_i32, %c0_i32, [[V12]]#0, [[V12]]#1, [[V13]]#0, [[V13]]#1, %c0_i32, %c0_i32, %c1234_i32, %c4321_i32, [[V14]]#0, [[V14]]#1, [[V15]]#0, [[V15]]#1 : i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32
hw.output %3, %4, %5, %6, %7, %8, %9, %10, %11#0, %11#1, %12#0, %12#1, %13#0, %13#1, %14#0, %14#1, %17#0, %17#1, %18#0, %18#1, %19#0, %19#1 : i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32
}
arc.define @Foo(%arg0: i32) {
arc.output
Expand Down
Loading