diff --git a/include/circt/Dialect/Moore/MooreOps.td b/include/circt/Dialect/Moore/MooreOps.td index 5f48cc72a824..a9e3f926d466 100644 --- a/include/circt/Dialect/Moore/MooreOps.td +++ b/include/circt/Dialect/Moore/MooreOps.td @@ -291,6 +291,7 @@ def ReadOp : MooreOp<"read", [ let assemblyFormat = [{ $input attr-dict `:` type($input) }]; + let hasCanonicalizeMethod = true; } def AddressOp : MooreOp<"address", [ diff --git a/lib/Dialect/Moore/MooreOps.cpp b/lib/Dialect/Moore/MooreOps.cpp index 6e6cd538688d..7b32f031e850 100644 --- a/lib/Dialect/Moore/MooreOps.cpp +++ b/lib/Dialect/Moore/MooreOps.cpp @@ -909,11 +909,15 @@ LogicalResult BlockingAssignOp::canonicalize(BlockingAssignOp op, if (auto refOp = op.getDst().getDefiningOp()) { auto input = refOp.getInput(); if (isa(input.getDefiningOp()->getParentOp())) { + auto value = rewriter.create( + op->getLoc(), cast(input.getType()).getNestedType(), input); auto newOp = rewriter.create( - op->getLoc(), input.getType(), input, refOp.getFieldNameAttr(), + op->getLoc(), value.getType(), value, refOp.getFieldNameAttr(), op.getSrc()); + auto newOpAddress = rewriter.create( + op.getLoc(), RefType::get(newOp.getType()), newOp); rewriter.replaceOpUsesWithIf( - input.getDefiningOp(), newOp->getResults(), + input.getDefiningOp(), newOpAddress->getResults(), [&op](OpOperand &operand) { return !operand.getOwner()->isBeforeInBlock(op); }); @@ -962,6 +966,16 @@ ReadOp::removeBlockingUses(const MemorySlot &slot, return DeletionKind::Delete; } +LogicalResult ReadOp::canonicalize(ReadOp op, PatternRewriter &rewriter) { + if (auto addr = op.getInput().getDefiningOp()) { + auto value = addr.getInput(); + op.replaceAllUsesWith(value); + op.erase(); + return success(); + } + return failure(); +} + //===----------------------------------------------------------------------===// // TableGen generated logic. //===----------------------------------------------------------------------===// diff --git a/test/Dialect/Moore/canonicalizers.mlir b/test/Dialect/Moore/canonicalizers.mlir index 1d2207093467..ad0e90639e09 100644 --- a/test/Dialect/Moore/canonicalizers.mlir +++ b/test/Dialect/Moore/canonicalizers.mlir @@ -70,20 +70,17 @@ func.func @StructInjectFold1(%arg0: !moore.struct<{a: i32, b: i32}>) -> (!moore. } // CHECK-LABEL: moore.module @structExtractRefLower2Inject -moore.module @structExtractRefLower2Inject(out a : !moore.ref>) { +moore.module @structExtractRefLower2Inject(out a : !moore.struct<{a: i32, b: i32}>) { // CHECK: %0 = moore.constant 0 : i32 - // CHECK: %1 = moore.constant 0 : i32 - // CHECK: %2 = moore.struct_create %0, %1 : !moore.i32, !moore.i32 -> struct<{a: i32, b: i32}> - // CHECK: %3 = moore.address %2 : > - // CHECK: %4 = moore.constant 1 : i32 - // CHECK: %5 = moore.struct_inject %3, "a", %4 : !moore.ref> - // CHECK: moore.output %5 : !moore.ref> + // CHECK: %1 = moore.constant 1 : i32 + // CHECK: %2 = moore.struct_create %1, %0 : !moore.i32, !moore.i32 -> struct<{a: i32, b: i32}> + // CHECK: moore.output %2 : !moore.struct<{a: i32, b: i32}> %ii = moore.variable : > %0 = moore.struct_extract_ref %ii, "a" : > -> %1 = moore.constant 1 : i32 - %2 = moore.conversion %1 : !moore.i32 -> !moore.i32 - moore.blocking_assign %0, %2 : i32 - moore.output %ii : !moore.ref> + moore.blocking_assign %0, %1 : i32 + %2 = moore.read %ii : > + moore.output %2 : !moore.struct<{a: i32, b: i32}> } // CHECK-LABEL: func.func @StructInjectFold2