mirror of https://github.com/llvm/circt.git
[ESI] Fix wrap op canonicalizers (#8730)
Fixes the canonicalizers for wrap operations in the ESI dialect by replacing problematic attribute-based folding with proper operation creation and improving pattern matching logic. - Updates `WrapValidReadyOp` and `WrapFIFOOp` fold methods to create `NullSourceOp` operations instead of using attributes - Improves the `WrapFIFOOp` canonicalize method with better error handling and more robust user checking - Delegates constant materialization to the HW dialect for better consistency
This commit is contained in:
parent
0b3976c12e
commit
3e42dbce12
|
@ -41,14 +41,11 @@ void ESIDialect::initialize() {
|
|||
|
||||
Operation *ESIDialect::materializeConstant(OpBuilder &builder, Attribute value,
|
||||
Type type, Location loc) {
|
||||
// Integer constants.
|
||||
if (auto intType = dyn_cast<IntegerType>(type))
|
||||
if (auto attrValue = dyn_cast<IntegerAttr>(value))
|
||||
return builder.create<hw::ConstantOp>(loc, attrValue.getType(),
|
||||
attrValue);
|
||||
if (isa<mlir::UnitAttr>(value))
|
||||
return builder.create<hw::ConstantOp>(loc, builder.getI1Type(), 1);
|
||||
return nullptr;
|
||||
return builder.getContext()
|
||||
->getOrLoadDialect<hw::HWDialect>()
|
||||
->materializeConstant(builder, value, type, loc);
|
||||
}
|
||||
|
||||
// Provide implementations for the enums we use.
|
||||
|
|
|
@ -19,8 +19,10 @@ LogicalResult WrapValidReadyOp::fold(FoldAdaptor,
|
|||
SmallVectorImpl<OpFoldResult> &results) {
|
||||
if (!getChanOutput().getUsers().empty())
|
||||
return failure();
|
||||
results.push_back(NullChannelAttr::get(
|
||||
getContext(), TypeAttr::get(getChanOutput().getType())));
|
||||
OpBuilder builder(getContext());
|
||||
results.push_back(
|
||||
builder.create<NullSourceOp>(getLoc(), getChanOutput().getType())
|
||||
.getOut());
|
||||
results.push_back(IntegerAttr::get(IntegerType::get(getContext(), 1), 1));
|
||||
return success();
|
||||
}
|
||||
|
@ -44,22 +46,30 @@ LogicalResult UnwrapFIFOOp::canonicalize(UnwrapFIFOOp op,
|
|||
|
||||
LogicalResult WrapFIFOOp::fold(FoldAdaptor,
|
||||
SmallVectorImpl<OpFoldResult> &results) {
|
||||
if (getChanOutput().getUsers().empty()) {
|
||||
results.push_back({});
|
||||
results.push_back(IntegerAttr::get(
|
||||
IntegerType::get(getContext(), 1, IntegerType::Signless), 0));
|
||||
return success();
|
||||
}
|
||||
return failure();
|
||||
if (!getChanOutput().getUsers().empty())
|
||||
return failure();
|
||||
|
||||
OpBuilder builder(getContext());
|
||||
results.push_back(
|
||||
builder.create<NullSourceOp>(getLoc(), getChanOutput().getType())
|
||||
.getOut());
|
||||
results.push_back(IntegerAttr::get(
|
||||
IntegerType::get(getContext(), 1, IntegerType::Signless), 0));
|
||||
return success();
|
||||
}
|
||||
|
||||
LogicalResult WrapFIFOOp::canonicalize(WrapFIFOOp op,
|
||||
PatternRewriter &rewriter) {
|
||||
auto unwrap =
|
||||
dyn_cast_or_null<UnwrapFIFOOp>(*op.getChanOutput().getUsers().begin());
|
||||
|
||||
if (!op.getChanOutput().hasOneUse())
|
||||
return rewriter.notifyMatchFailure(
|
||||
op, "channel output doesn't have exactly one use");
|
||||
auto unwrap = dyn_cast_or_null<UnwrapFIFOOp>(
|
||||
op.getChanOutput().getUses().begin()->getOwner());
|
||||
if (succeeded(UnwrapFIFOOp::mergeAndErase(unwrap, op, rewriter)))
|
||||
return success();
|
||||
return failure();
|
||||
return rewriter.notifyMatchFailure(
|
||||
op, "could not find corresponding unwrap for wrap");
|
||||
}
|
||||
|
||||
OpFoldResult WrapWindow::fold(FoldAdaptor) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: circt-opt %s --canonicalize | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: hw.module @TestDanglingFIFO() {
|
||||
// CHECK-NEXT: hw.output
|
||||
hw.module @TestDanglingFIFO() {
|
||||
%c0 = hw.constant 0 : i1
|
||||
%chanOutput, %ready = esi.wrap.fifo %c0, %c0 : !esi.channel<i1, FIFO>
|
||||
}
|
||||
|
||||
// CHECK-LABEL: hw.module @TestDanglingValidReady() {
|
||||
// CHECK-NEXT: hw.output
|
||||
hw.module @TestDanglingValidReady() {
|
||||
%c0 = hw.constant 0 : i1
|
||||
%chanOutput, %ready = esi.wrap.vr %c0, %c0 : i1
|
||||
}
|
Loading…
Reference in New Issue