Skip to content

Commit 7337dfe

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

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
@@ -1796,6 +1796,52 @@ mlir::ValueRange P4HIR::ParserSelectCaseOp::getSelectKeys() {
17961796
return yield.getArgs();
17971797
}
17981798

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

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)