Skip to content

Commit 30dc9dc

Browse files
committed
Add ParserTransitionSelectOp::canonicalize and implement equivalent of SimplifySelectCases
Signed-off-by: Manolis Tsamis <tsamismanolis@gmail.com>
1 parent a554f9a commit 30dc9dc

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

include/p4mlir/Dialect/P4HIR/P4HIR_ParserOps.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ def ParserTransitionSelectOp : P4HIR_Op<"transition_select",
172172
return { StateIterator(selectCases.begin()), StateIterator(selectCases.end()) };
173173
}
174174
}];
175+
let hasCanonicalizeMethod = 1;
175176
}
176177

177178
def ParserSelectCaseOp : P4HIR_Op<"select_case",

lib/Dialect/P4HIR/P4HIR_Ops.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,52 @@ mlir::ValueRange P4HIR::ParserSelectCaseOp::getSelectKeys() {
17851785
return yield.getArgs();
17861786
}
17871787

1788+
//===----------------------------------------------------------------------===//
1789+
// ParserTransitionSelectOp
1790+
//===----------------------------------------------------------------------===//
1791+
1792+
LogicalResult P4HIR::ParserTransitionSelectOp::canonicalize(P4HIR::ParserTransitionSelectOp op,
1793+
PatternRewriter &rewriter) {
1794+
mlir::Block *body = &op.getBody().back();
1795+
auto selectCases = op.selects();
1796+
auto it = llvm::find_if(selectCases, [](auto op) { return op.isDefault(); });
1797+
1798+
// No default case found.
1799+
if (it == selectCases.end()) return mlir::failure();
1800+
1801+
LogicalResult result = mlir::failure();
1802+
1803+
// Remove unreachable cases after last default case.
1804+
if (std::next(it) != selectCases.end()) {
1805+
mlir::Block *unreachableCases = rewriter.splitBlock(body, ++Block::iterator(*it));
1806+
rewriter.eraseBlock(unreachableCases);
1807+
result = mlir::success();
1808+
}
1809+
1810+
// Canonicalize tuple of universal sets to single universal set.
1811+
auto defaultCase = mlir::cast<P4HIR::ParserSelectCaseOp>(body->back());
1812+
auto defaultYield = mlir::cast<P4HIR::YieldOp>(defaultCase.getTerminator());
1813+
if (defaultYield.getArgs().size() > 1) {
1814+
rewriter.modifyOpInPlace(defaultYield, [&]() {
1815+
auto universalSetAttr = P4HIR::UniversalSetAttr::get(rewriter.getContext());
1816+
auto universalSet =
1817+
rewriter.create<P4HIR::ConstOp>(defaultYield.getLoc(), universalSetAttr);
1818+
defaultYield.getArgsMutable().assign(universalSet);
1819+
});
1820+
1821+
result = mlir::success();
1822+
}
1823+
1824+
// Replace select with single default case with direct transition.
1825+
if (body->getOperations().size() == 1) {
1826+
auto firstCase = *op.selects().begin();
1827+
rewriter.replaceOpWithNewOp<P4HIR::ParserTransitionOp>(op, firstCase.getState());
1828+
result = mlir::success();
1829+
}
1830+
1831+
return result;
1832+
}
1833+
17881834
//===----------------------------------------------------------------------===//
17891835
// SetOp
17901836
//===----------------------------------------------------------------------===//

test/Transforms/Folds/select.mlir

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// RUN: p4mlir-opt --canonicalize %s | FileCheck %s
2+
3+
!b8i = !p4hir.bit<8>
4+
#everything = #p4hir.universal_set : !p4hir.set<!p4hir.dontcare>
5+
#false = #p4hir.bool<false> : !p4hir.bool
6+
#true = #p4hir.bool<true> : !p4hir.bool
7+
#int1_b8i = #p4hir.int<1> : !b8i
8+
#int2_b8i = #p4hir.int<2> : !b8i
9+
#int8_b8i = #p4hir.int<8> : !b8i
10+
#set_const_of_false = #p4hir.set<const : [#false]> : !p4hir.set<!p4hir.bool>
11+
#set_const_of_true = #p4hir.set<const : [#true]> : !p4hir.set<!p4hir.bool>
12+
#set_const_of_int1_b8i = #p4hir.set<const : [#int1_b8i]> : !p4hir.set<!b8i>
13+
#set_const_of_int2_b8i = #p4hir.set<const : [#int2_b8i]> : !p4hir.set<!b8i>
14+
#set_const_of_int8_b8i = #p4hir.set<const : [#int8_b8i]> : !p4hir.set<!b8i>
15+
16+
// CHECK-LABEL: module
17+
module {
18+
p4hir.parser @p1(%arg0: !b8i, %arg1: !p4hir.bool)() {
19+
%set = p4hir.const #set_const_of_int8_b8i
20+
%set_0 = p4hir.const #set_const_of_true
21+
%set_1 = p4hir.const #set_const_of_int2_b8i
22+
%set_2 = p4hir.const #set_const_of_false
23+
%set_3 = p4hir.const #set_const_of_int1_b8i
24+
%everything = p4hir.const #everything
25+
26+
// CHECK-LABEL: p4hir.state @start
27+
p4hir.state @start {
28+
// CHECK-COUNT-2: p4hir.select_case
29+
// CHECK-NOT: p4hir.yield %everything, %everything : !p4hir.set<!p4hir.dontcare>, !p4hir.set<!p4hir.dontcare>
30+
// CHECK: p4hir.yield %everything : !p4hir.set<!p4hir.dontcare>
31+
// Remove dead cases; canonicalize default cases.
32+
p4hir.transition_select %arg0, %arg1 : !b8i, !p4hir.bool {
33+
p4hir.select_case {
34+
p4hir.yield %set_3, %set_2 : !p4hir.set<!b8i>, !p4hir.set<!p4hir.bool>
35+
} to @p1::@reject
36+
p4hir.select_case {
37+
p4hir.yield %everything, %everything : !p4hir.set<!p4hir.dontcare>, !p4hir.set<!p4hir.dontcare>
38+
} to @p1::@next
39+
p4hir.select_case {
40+
p4hir.yield %set_1, %set_0 : !p4hir.set<!b8i>, !p4hir.set<!p4hir.bool>
41+
} to @p1::@reject
42+
}
43+
}
44+
45+
// CHECK-LABEL: p4hir.state @next
46+
p4hir.state @next {
47+
// CHECK-NOT: p4hir.select_case
48+
// CHECK: p4hir.transition to @p1::@final
49+
// Replace select with one default case with direct transition.
50+
p4hir.transition_select %arg0, %arg1 : !b8i, !p4hir.bool {
51+
p4hir.select_case {
52+
p4hir.yield %everything, %everything : !p4hir.set<!p4hir.dontcare>, !p4hir.set<!p4hir.dontcare>
53+
} to @p1::@final
54+
p4hir.select_case {
55+
p4hir.yield %everything : !p4hir.set<!p4hir.dontcare>
56+
} to @p1::@reject
57+
p4hir.select_case {
58+
p4hir.yield %set, %set_2 : !p4hir.set<!b8i>, !p4hir.set<!p4hir.bool>
59+
} to @p1::@reject
60+
p4hir.select_case {
61+
p4hir.yield %everything : !p4hir.set<!p4hir.dontcare>
62+
} to @p1::@reject
63+
}
64+
}
65+
66+
p4hir.state @final {
67+
p4hir.transition to @p1::@accept
68+
}
69+
70+
p4hir.state @accept {
71+
p4hir.parser_accept
72+
}
73+
74+
p4hir.state @reject {
75+
p4hir.parser_reject
76+
}
77+
78+
p4hir.transition to @p1::@start
79+
}
80+
}

0 commit comments

Comments
 (0)