Skip to content
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
1 change: 1 addition & 0 deletions include/dynamatic/Dialect/Handshake/HandshakeArithOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ def Handshake_ExtSIOp : Handshake_Arith_IToICastOp<"extsi"> {

def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui"> {
let summary = "Integer signed width extension.";
let hasCanonicalizer = 1;
}

def Handshake_MaximumFOp : Handshake_Arith_FloatBinaryOp<"maximumf", [
Expand Down
2 changes: 1 addition & 1 deletion integration-test/if_convert/buffer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"comment": "To achieve better II"
},
{
"pred": "extsi2",
"pred": "constant11",
"outid": 0,
"slots": 4,
"type": "fifo_break_none",
Expand Down
15 changes: 4 additions & 11 deletions integration-test/loop_path/buffer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
"comment": "To avoid deadlock"
},
{
"pred": "cmpi2",
"pred": "fork1",
"outid": 0,
"slots": 2,
"type": "fifo_break_none",
"comment": "To achieve better II"
},
{
"pred": "fork3",
"outid": 0,
"pred": "fork5",
"outid": 1,
"slots": 2,
"type": "fifo_break_none",
"comment": "To achieve better II"
},
{
"pred": "trunci0",
"pred": "fork11",
"outid": 0,
"slots": 2,
"type": "fifo_break_none",
Expand All @@ -33,12 +33,5 @@
"slots": 2,
"type": "fifo_break_none",
"comment": "Buffer non-spec token to prevent II=2 locking (placed before spec_commit to avoid the effect of non-deterministic naming)"
},
{
"pred": "fork11",
"outid": 0,
"slots": 2,
"type": "fifo_break_none",
"comment": "To absorb latency for spec_commit4 (ctrl)"
}
]
2 changes: 1 addition & 1 deletion integration-test/nested_loop/buffer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"comment": "Buffer non-spec token to prevent II=2 locking"
},
{
"pred": "extsi3",
"pred": "constant18",
"outid": 0,
"slots": 4,
"type": "fifo_break_none",
Expand Down
2 changes: 1 addition & 1 deletion integration-test/single_loop/buffer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"comment": "To absorb latency for spec_commit4 (data)"
},
{
"pred": "extsi1",
"pred": "constant9",
"outid": 0,
"slots": 5,
"type": "fifo_break_none",
Expand Down
10 changes: 10 additions & 0 deletions lib/Dialect/Handshake/HandshakeCanonicalization.td
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ def ExtSIOfExtUI : Pat<
(Handshake_ExtSIOp (Handshake_ExtUIOp $x)), (Handshake_ExtUIOp $x)
>;

def ExtUIOfConst : Pat<
(Handshake_ExtUIOp:$ext (Handshake_ConstantOp $attr, $ctrl)),
(Handshake_ConstantOp (NativeCodeCall<"constantFoldExt($0.getOwner(), $1)"> $ext, $attr), $ctrl)
>;

def ExtSIOfConst : Pat<
(Handshake_ExtSIOp:$ext (Handshake_ConstantOp $attr, $ctrl)),
(Handshake_ConstantOp (NativeCodeCall<"constantFoldExt($0.getOwner(), $1)"> $ext, $attr), $ctrl)
>;

//===----------------------------------------------------------------------===//
// TruncIOp
//===----------------------------------------------------------------------===//
Expand Down
22 changes: 21 additions & 1 deletion lib/Dialect/Handshake/HandshakeOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,21 @@ static unsigned getDataBitWidth(Value val) {
return cast<handshake::ChannelType>(val.getType()).getDataBitWidth();
}

static IntegerAttr constantFoldExt(Operation *op, Attribute attr) {
auto integerAttr = cast<IntegerAttr>(attr);
if (auto extUI = dyn_cast<ExtUIOp>(op))
return IntegerAttr::get(
extUI.getType().getDataType(),
integerAttr.getValue().zext(extUI.getType().getDataBitWidth()));

if (auto extSI = dyn_cast<ExtSIOp>(op))
return IntegerAttr::get(
extSI.getType().getDataType(),
integerAttr.getValue().sext(extSI.getType().getDataBitWidth()));

llvm_unreachable("only expected extui and extsi");
}

namespace {
#include "lib/Dialect/Handshake/HandshakeCanonicalization.inc"
} // namespace
Expand Down Expand Up @@ -1883,7 +1898,7 @@ static OpFoldResult foldExtOp(Op op) {

void ExtSIOp::getCanonicalizationPatterns(RewritePatternSet &results,
MLIRContext *context) {
results.add<ExtSIOfExtUI>(context);
results.add<ExtSIOfExtUI, ExtSIOfConst>(context);
}

OpFoldResult ExtSIOp::fold(FoldAdaptor adaptor) { return foldExtOp(*this); }
Expand Down Expand Up @@ -1912,6 +1927,11 @@ LogicalResult ExtSIOp::verify() { return verifyExtOp(*this); }

OpFoldResult ExtUIOp::fold(FoldAdaptor adaptor) { return foldExtOp(*this); }

void ExtUIOp::getCanonicalizationPatterns(RewritePatternSet &results,
MLIRContext *context) {
results.add<ExtUIOfConst>(context);
}

LogicalResult ExtUIOp::verify() { return verifyExtOp(*this); }

//===----------------------------------------------------------------------===//
Expand Down
31 changes: 14 additions & 17 deletions test/Transforms/HandshakeOptimizeBitwidths/arith-forward.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,10 @@ handshake.func @xoriFW(%arg0: !handshake.channel<i8>, %arg1: !handshake.channel<
// CHECK-LABEL: handshake.func @shliFW(
// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel<i16>,
// CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel<i32> attributes {argNames = ["arg0", "start"], resNames = ["out0"]} {
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i4} : <>, <i4>
// CHECK: %[[VAL_3:.*]] = extsi %[[VAL_0]] : <i16> to <i32>
// CHECK: %[[VAL_4:.*]] = extsi %[[VAL_2]] : <i4> to <i32>
// CHECK: %[[VAL_5:.*]] = shli %[[VAL_3]], %[[VAL_4]] : <i32>
// CHECK: end %[[VAL_5]] : <i32>
// CHECK: %[[VAL_2:.*]] = extsi %[[VAL_0]] : <i16> to <i32>
// CHECK: %[[VAL_3:.*]] = constant %[[VAL_1]] {value = 4 : i32} : <>, <i32>
// CHECK: %[[VAL_4:.*]] = shli %[[VAL_2]], %[[VAL_3]] : <i32>
// CHECK: end %[[VAL_4]] : <i32>
// CHECK: }
handshake.func @shliFW(%arg0: !handshake.channel<i16>, %start: !handshake.control<>) -> !handshake.channel<i32> {
%cst = handshake.constant %start {value = 4 : i4} : <>, <i4>
Expand All @@ -153,12 +152,11 @@ handshake.func @shliFW(%arg0: !handshake.channel<i16>, %start: !handshake.contro
// CHECK-LABEL: handshake.func @shrsiFW(
// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel<i16>,
// CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel<i32> attributes {argNames = ["arg0", "start"], resNames = ["out0"]} {
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i4} : <>, <i4>
// CHECK: %[[VAL_3:.*]] = extui %[[VAL_2]] : <i4> to <i16>
// CHECK: %[[VAL_4:.*]] = shrsi %[[VAL_0]], %[[VAL_3]] : <i16>
// CHECK: %[[VAL_5:.*]] = trunci %[[VAL_4]] : <i16> to <i12>
// CHECK: %[[VAL_6:.*]] = extsi %[[VAL_5]] : <i12> to <i32>
// CHECK: end %[[VAL_6]] : <i32>
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i16} : <>, <i16>
// CHECK: %[[VAL_3:.*]] = shrsi %[[VAL_0]], %[[VAL_2]] : <i16>
// CHECK: %[[VAL_4:.*]] = trunci %[[VAL_3]] : <i16> to <i12>
// CHECK: %[[VAL_5:.*]] = extsi %[[VAL_4]] : <i12> to <i32>
// CHECK: end %[[VAL_5]] : <i32>
// CHECK: }
handshake.func @shrsiFW(%arg0: !handshake.channel<i16>, %start: !handshake.control<>) -> !handshake.channel<i32> {
%cst = handshake.constant %start {value = 4 : i4} : <>, <i4>
Expand All @@ -173,12 +171,11 @@ handshake.func @shrsiFW(%arg0: !handshake.channel<i16>, %start: !handshake.contr
// CHECK-LABEL: handshake.func @shruiFW(
// CHECK-SAME: %[[VAL_0:.*]]: !handshake.channel<i16>,
// CHECK-SAME: %[[VAL_1:.*]]: !handshake.control<>, ...) -> !handshake.channel<i32> attributes {argNames = ["arg0", "start"], resNames = ["out0"]} {
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i4} : <>, <i4>
// CHECK: %[[VAL_3:.*]] = extui %[[VAL_2]] : <i4> to <i16>
// CHECK: %[[VAL_4:.*]] = shrui %[[VAL_0]], %[[VAL_3]] : <i16>
// CHECK: %[[VAL_5:.*]] = trunci %[[VAL_4]] : <i16> to <i12>
// CHECK: %[[VAL_6:.*]] = extsi %[[VAL_5]] : <i12> to <i32>
// CHECK: end %[[VAL_6]] : <i32>
// CHECK: %[[VAL_2:.*]] = constant %[[VAL_1]] {value = 4 : i16} : <>, <i16>
// CHECK: %[[VAL_3:.*]] = shrui %[[VAL_0]], %[[VAL_2]] : <i16>
// CHECK: %[[VAL_4:.*]] = trunci %[[VAL_3]] : <i16> to <i12>
// CHECK: %[[VAL_5:.*]] = extsi %[[VAL_4]] : <i12> to <i32>
// CHECK: end %[[VAL_5]] : <i32>
// CHECK: }
handshake.func @shruiFW(%arg0: !handshake.channel<i16>, %start: !handshake.control<>) -> !handshake.channel<i32> {
%cst = handshake.constant %start {value = 4 : i4} : <>, <i4>
Expand Down
Loading
Loading