Skip to content

Commit

Permalink
[Arc] Make arc.model have an SSACFG region (#7701)
Browse files Browse the repository at this point in the history
Remove the `RegionKindInterface` from `arc.model` such that its body
region becomes an SSACFG region. The current implementation of the
LowerState pass already creates models which honor SSA dominance, and
future improvements to the Arc dialect will benefit from models
enforcing dominance.
  • Loading branch information
fabianschuiki authored Oct 14, 2024
1 parent 2452233 commit 629abef
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 44 deletions.
5 changes: 1 addition & 4 deletions include/circt/Dialect/Arc/ArcOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ def TapOp : ArcOp<"tap"> {
}

def ModelOp : ArcOp<"model", [
RegionKindInterface, IsolatedFromAbove, NoTerminator, Symbol,
IsolatedFromAbove, NoTerminator, Symbol,
DeclareOpInterfaceMethods<SymbolUserOpInterface>
]> {
let summary = "A model with stratified clocks";
Expand All @@ -691,9 +691,6 @@ def ModelOp : ArcOp<"model", [
}];

let extraClassDeclaration = [{
static mlir::RegionKind getRegionKind(unsigned index) {
return mlir::RegionKind::Graph;
}
mlir::Block &getBodyBlock() { return getBody().front(); }
}];

Expand Down
60 changes: 30 additions & 30 deletions test/Dialect/Arc/group-resets-and-enables.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ arc.model @BasicResetGrouping io !hw.modty<input clock : i1, input i0 : i4, inpu
%in_i1 = arc.root_input "i1", %arg0 : (!arc.storage) -> !arc.state<i4>
%in_reset0 = arc.root_input "reset0", %arg0 : (!arc.storage) -> !arc.state<i1>
%in_reset1 = arc.root_input "reset1", %arg0 : (!arc.storage) -> !arc.state<i1>
// CHECK: [[FOO_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK: [[BAR_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%0 = arc.state_read %in_clock : <i1>
// Group resets:
arc.clock_tree %0 {
// CHECK: [[IN_RESET0:%.+]] = arc.state_read %in_reset0
%3 = arc.state_read %in_reset0 : <i1>
// CHECK-NEXT: scf.if [[IN_RESET0]] {
scf.if %3 {
// CHECK-NEXT: arc.state_write [[FOO_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[FOO_ALLOC]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC]] = %c0_i4
arc.state_write %1 = %c0_i4 : <i4>
// CHECK-NEXT: } else {
} else {
Expand Down Expand Up @@ -131,8 +135,8 @@ arc.model @BasicResetGrouping io !hw.modty<input clock : i1, input i0 : i4, inpu
%15 = arc.state_read %in_reset0 : <i1>
// CHECK-NEXT: scf.if [[IN_RESET0]] {
scf.if %15 {
// CHECK-NEXT: arc.state_write [[FOO_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[FOO_ALLOC]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC]] = %c0_i4
arc.state_write %1 = %c0_i4 : <i4>
// CHECK-NEXT: } else {
} else {
Expand All @@ -147,10 +151,6 @@ arc.model @BasicResetGrouping io !hw.modty<input clock : i1, input i0 : i4, inpu
}
// CHECK-NEXT: }
}
// CHECK-NEXT: [[FOO_ALLOC]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK-NEXT: [[BAR_ALLOC]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
}

// CHECK-LABEL: arc.model @BasicEnableGrouping
Expand All @@ -162,13 +162,17 @@ arc.model @BasicEnableGrouping io !hw.modty<input clock : i1, input i0 : i4, inp
%in_i1 = arc.root_input "i1", %arg0 : (!arc.storage) -> !arc.state<i4>
%in_en0 = arc.root_input "en0", %arg0 : (!arc.storage) -> !arc.state<i1>
%in_en1 = arc.root_input "en1", %arg0 : (!arc.storage) -> !arc.state<i1>
// CHECK: [[FOO_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK: [[BAR_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%0 = arc.state_read %in_clock : <i1>
// Group enables:
arc.clock_tree %0 {
// CHECK: [[IN_EN0:%.+]] = arc.state_read %in_en0
%3 = arc.state_read %in_en0 : <i1>
// CHECK-NEXT: arc.state_write [[FOO_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[FOO_ALLOC]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC]] = %c0_i4
arc.state_write %1 = %c0_i4 : <i4>
arc.state_write %2 = %c0_i4 : <i4>
// CHECK-NEXT: scf.if [[IN_EN0]] {
Expand Down Expand Up @@ -204,10 +208,6 @@ arc.model @BasicEnableGrouping io !hw.modty<input clock : i1, input i0 : i4, inp
arc.state_write %2 = %9 if %7 : <i4>
// CHECK-NEXT: }
}
// CHECK-NEXT: [[FOO_ALLOC]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK-NEXT: [[BAR_ALLOC]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
}

// CHECK-LABEL: arc.model @GroupAssignmentsInIfTesting
Expand All @@ -218,6 +218,10 @@ arc.model @GroupAssignmentsInIfTesting io !hw.modty<input clock : i1, input i1 :
%in_i2 = arc.root_input "i2", %arg0 : (!arc.storage) -> !arc.state<i4>
%in_cond0 = arc.root_input "cond0", %arg0 : (!arc.storage) -> !arc.state<i1>
%in_cond1 = arc.root_input "cond1", %arg0 : (!arc.storage) -> !arc.state<i1>
// CHECK: [[FOO_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK: [[BAR_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%0 = arc.state_read %in_clock : <i1>
// Do pull value in (1st and 2nd layer)
arc.clock_tree %0 {
Expand All @@ -228,14 +232,14 @@ arc.model @GroupAssignmentsInIfTesting io !hw.modty<input clock : i1, input i1 :
// CHECK-NEXT: scf.if [[IN_COND0]] {
scf.if %3 {
// CHECK-NEXT: [[IN_I1:%.+]] = arc.state_read %in_i1
// CHECK-NEXT: arc.state_write [[FOO_ALLOC:%.+]] = [[IN_I1]]
// CHECK-NEXT: arc.state_write [[FOO_ALLOC]] = [[IN_I1]]
arc.state_write %1 = %4 : <i4>
// CHECK: [[IN_COND1:%.+]] = arc.state_read %in_cond1
%6 = arc.state_read %in_cond1 : <i1>
// CHECK-NEXT: scf.if [[IN_COND1]] {
scf.if %6 {
// CHECK-NEXT: [[IN_I2:%.+]] = arc.state_read %in_i2
// CHECK-NEXT: arc.state_write [[BAR_ALLOC:%.+]] = [[IN_I2]]
// CHECK-NEXT: arc.state_write [[BAR_ALLOC]] = [[IN_I2]]
arc.state_write %2 = %5 : <i4>
// CHECK-NEXT: }
}
Expand All @@ -251,11 +255,11 @@ arc.model @GroupAssignmentsInIfTesting io !hw.modty<input clock : i1, input i1 :
%6 = arc.state_read %in_i1 : <i4>
// CHECK-NEXT: scf.if [[IN_COND0]] {
scf.if %5 {
// CHECK-NEXT: arc.state_write [[FOO_ALLOC:%.+]] = [[IN_I1]]
// CHECK-NEXT: arc.state_write [[FOO_ALLOC]] = [[IN_I1]]
arc.state_write %1 = %6 : <i4>
// CHECK-NEXT: }
}
// CHECK-NEXT: arc.state_write [[BAR_ALLOC:%.+]] = [[IN_I1]]
// CHECK-NEXT: arc.state_write [[BAR_ALLOC]] = [[IN_I1]]
arc.state_write %2 = %6 : <i4>
// CHECK-NEXT: }
}
Expand All @@ -268,23 +272,19 @@ arc.model @GroupAssignmentsInIfTesting io !hw.modty<input clock : i1, input i1 :
// CHECK-NEXT: scf.if [[IN_COND0]] {
scf.if %5 {
// CHECK-NEXT: [[IN_I1:%.+]] = arc.state_read %in_i1
// CHECK-NEXT: arc.state_write [[FOO_ALLOC:%.+]] = [[IN_I1]]
// CHECK-NEXT: arc.state_write [[FOO_ALLOC]] = [[IN_I1]]
arc.state_write %1 = %7 : <i4>
// CHECK-NEXT: [[IN_COND1:%.+]] = arc.state_read %in_cond1
// CHECK-NEXT: scf.if [[IN_COND1]] {
scf.if %6 {
// CHECK-NEXT: arc.state_write [[BAR_ALLOC:%.+]] = [[IN_I1]]
// CHECK-NEXT: arc.state_write [[BAR_ALLOC]] = [[IN_I1]]
arc.state_write %2 = %7 : <i4>
// CHECK-NEXT: }
}
// CHECK-NEXT: }
}
// CHECK-NEXT: }
}
// CHECK-NEXT: [[FOO_ALLOC]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK-NEXT: [[BAR_ALLOC]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
}

// CHECK-LABEL: arc.model @ResetAndEnableGrouping
Expand All @@ -297,15 +297,19 @@ arc.model @ResetAndEnableGrouping io !hw.modty<input clock : i1, input i0 : i4,
%in_reset = arc.root_input "reset", %arg0 : (!arc.storage) -> !arc.state<i1>
%in_en0 = arc.root_input "en0", %arg0 : (!arc.storage) -> !arc.state<i1>
%in_en1 = arc.root_input "en1", %arg0 : (!arc.storage) -> !arc.state<i1>
// CHECK: [[FOO_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK: [[BAR_ALLOC:%.+]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%0 = arc.state_read %in_clock : <i1>
// Group enables inside resets (and pull in reads):
arc.clock_tree %0 {
// CHECK: [[IN_RESET:%.+]] = arc.state_read %in_reset
%3 = arc.state_read %in_reset : <i1>
// CHECK-NEXT: scf.if [[IN_RESET]] {
scf.if %3 {
// CHECK-NEXT: arc.state_write [[FOO_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC:%.+]] = %c0_i4
// CHECK-NEXT: arc.state_write [[FOO_ALLOC]] = %c0_i4
// CHECK-NEXT: arc.state_write [[BAR_ALLOC]] = %c0_i4
arc.state_write %1 = %c0_i4 : <i4>
arc.state_write %2 = %c0_i4 : <i4>
// CHECK-NEXT: } else {
Expand Down Expand Up @@ -389,8 +393,4 @@ arc.model @ResetAndEnableGrouping io !hw.modty<input clock : i1, input i0 : i4,
}
// CHECK-NEXT: }
}
// CHECK-NEXT: [[FOO_ALLOC]] = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
// CHECK-NEXT: [[BAR_ALLOC]] = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
%1 = arc.alloc_state %arg0 {name = "foo"} : (!arc.storage) -> !arc.state<i4>
%2 = arc.alloc_state %arg0 {name = "bar"} : (!arc.storage) -> !arc.state<i4>
}
6 changes: 3 additions & 3 deletions test/Dialect/Arc/legalize-state-update-error.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
arc.model @Memory io !hw.modty<> {
^bb0(%arg0: !arc.storage):
%false = hw.constant false
%mem1 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%mem2 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%s1 = arc.alloc_state %arg0 : (!arc.storage) -> !arc.state<i32>
arc.clock_tree %false attributes {ct4} {
%r1 = arc.state_read %s1 : <i32>
scf.if %false {
Expand All @@ -16,7 +19,4 @@ arc.model @Memory io !hw.modty<> {
%mr1 = arc.memory_read %mem2[%false] : <2 x i32, i1>
}
}
%mem1 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%mem2 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%s1 = arc.alloc_state %arg0 : (!arc.storage) -> !arc.state<i32>
}
14 changes: 7 additions & 7 deletions test/Dialect/Arc/legalize-state-update.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,17 @@ arc.model @DontLeakThroughClockTreeOrPassthrough io !hw.modty<input a : i1, outp
arc.model @Memory io !hw.modty<> {
^bb0(%arg0: !arc.storage):
%false = hw.constant false
// CHECK: [[MEM1:%.+]] = arc.alloc_memory %arg0 :
// CHECK: [[MEM2:%.+]] = arc.alloc_memory %arg0 :
%mem1 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%mem2 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%s1 = arc.alloc_state %arg0 : (!arc.storage) -> !arc.state<i32>
// CHECK: arc.clock_tree %false attributes {ct1}
arc.clock_tree %false attributes {ct1} {
// CHECK-NEXT: arc.state_read
// CHECK-NEXT: arc.memory_read [[MEM1:%.+]][%false]
// CHECK-NEXT: arc.memory_read [[MEM1]][%false]
// CHECK-NEXT: arc.memory_write [[MEM1]]
// CHECK-NEXT: arc.memory_read [[MEM2:%.+]][%false]
// CHECK-NEXT: arc.memory_read [[MEM2]][%false]
// CHECK-NEXT: arc.memory_write [[MEM2]]
%r1 = arc.state_read %s1 : <i32>
arc.memory_write %mem2[%false], %r1 : <2 x i32, i1>
Expand Down Expand Up @@ -245,9 +250,4 @@ arc.model @Memory io !hw.modty<> {
%mr2 = arc.memory_read %mem2[%false] : <2 x i32, i1>
// CHECK-NEXT: }
}
// CHECK: [[MEM1]] = arc.alloc_memory %arg0 :
// CHECK: [[MEM2]] = arc.alloc_memory %arg0 :
%mem1 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%mem2 = arc.alloc_memory %arg0 : (!arc.storage) -> !arc.memory<2 x i32, i1>
%s1 = arc.alloc_state %arg0 : (!arc.storage) -> !arc.state<i32>
}

0 comments on commit 629abef

Please sign in to comment.