Skip to content

Commit b3a1e6c

Browse files
committed
[FIRRTL] Anonymous domain support in LowerDomains
Add support for the `LowerDomains` pass to lower `DomainCreateAnonOp`. The lowering of this is such that the operation and any wires that it drives are just erased. Signed-off-by: Schuyler Eldridge <[email protected]>
1 parent 3ad3186 commit b3a1e6c

File tree

2 files changed

+64
-13
lines changed

2 files changed

+64
-13
lines changed

lib/Dialect/FIRRTL/Transforms/LowerDomains.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,12 @@ LogicalResult LowerModule::lowerModule() {
518518
return WalkResult::advance();
519519
}
520520

521+
// Track anonymous domains for later traversal and erasure.
522+
if (auto anonDomain = dyn_cast<DomainCreateAnonOp>(walkOp)) {
523+
conversionsToErase.insert(anonDomain);
524+
return WalkResult::advance();
525+
}
526+
521527
// If we see a WireOp of a domain type, then we want to erase it. To do
522528
// this, find what is driving it and what it is driving and then replace
523529
// that triplet of operations with a single domain define inserted before
@@ -576,23 +582,33 @@ LogicalResult LowerModule::lowerModule() {
576582
if (!defineOp)
577583
return WalkResult::advance();
578584

579-
// Only visit domain define ops which have conversioncast source and
580-
// destination.
581-
auto src = dyn_cast<UnrealizedConversionCastOp>(
582-
defineOp.getSrc().getDefiningOp());
585+
// There are only two possibilities for kinds of `DomainDefineOp`s that we
586+
// can see a this point: the destination is always a conversion cast and
587+
// the source is _either_ (1) a conversion cast if the source is a module
588+
// or instance port or (2) an anonymous domain op. This relies on the
589+
// earlier "canonicalization" that erased `WireOp`s to leave only
590+
// `DomainDefineOp`s.
591+
auto *src = defineOp.getSrc().getDefiningOp();
583592
auto dest = dyn_cast<UnrealizedConversionCastOp>(
584593
defineOp.getDest().getDefiningOp());
585594
if (!src || !dest)
586595
return WalkResult::advance();
587-
assert(src.getNumOperands() == 1 && src.getNumResults() == 1);
588-
assert(dest.getNumOperands() == 1 && dest.getNumResults() == 1);
589596

590597
conversionsToErase.insert(src);
591598
conversionsToErase.insert(dest);
592599

593-
OpBuilder builder(defineOp);
594-
PropAssignOp::create(builder, defineOp.getLoc(), dest.getOperand(0),
595-
src.getOperand(0));
600+
if (auto srcCast = dyn_cast<UnrealizedConversionCastOp>(src)) {
601+
assert(srcCast.getNumOperands() == 1 && srcCast.getNumResults() == 1);
602+
OpBuilder builder(defineOp);
603+
PropAssignOp::create(builder, defineOp.getLoc(), dest.getOperand(0),
604+
srcCast.getOperand(0));
605+
} else if (!isa<DomainCreateAnonOp>(src)) {
606+
auto diag = defineOp.emitOpError()
607+
<< "has a source which cannot be lowered by 'LowerDomains'";
608+
diag.attachNote(src->getLoc()) << "unsupported source is here";
609+
return WalkResult::interrupt();
610+
}
611+
596612
defineOp->erase();
597613
return WalkResult::advance();
598614
});

test/Dialect/FIRRTL/lower-domains.mlir

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,30 @@ firrtl.circuit "Foo" {
272272

273273
// -----
274274

275+
// Test an anonymous domain.
276+
firrtl.circuit "Foo" {
277+
firrtl.domain @ClockDomain
278+
firrtl.extmodule @Bar(
279+
in A: !firrtl.domain of @ClockDomain,
280+
in a: !firrtl.uint<1> domains [A]
281+
)
282+
// CHECK-LABEL: firrtl.module @Foo()
283+
firrtl.module @Foo() {
284+
// CHECK-NEXT: %bar_A, %bar_A_out, %bar_a = firrtl.instance bar @Bar
285+
%bar_A, %bar_a = firrtl.instance bar @Bar(
286+
in A: !firrtl.domain of @ClockDomain,
287+
in a: !firrtl.uint<1> domains [A]
288+
)
289+
%anon = firrtl.domain.anon : !firrtl.domain of @ClockDomain
290+
firrtl.domain.define %bar_A, %anon
291+
// CHECK-NOT: firrtl.object
292+
// CHECK-NOT: firrtl.domain.anon
293+
// CHECK-NOT: firrtl.domain.define
294+
}
295+
}
296+
297+
// -----
298+
275299
// Check that unconnected output domains work.
276300
//
277301
// TODO: If there was stronger verification that ExpandWhens ensures
@@ -451,18 +475,29 @@ firrtl.circuit "Foo" {
451475

452476
// -----
453477

454-
// Check that dead/unused wires are deleted.
455-
firrtl.circuit "DeadWires" {
478+
// Check that dead/unused operations inolving domains are deleted.
479+
firrtl.circuit "DeadDomainOps" {
456480
firrtl.domain @ClockDomain
457-
// CHECK-LABEL: firrtl.module @DeadWires
481+
// CHECK-LABEL: firrtl.module @DeadDomainOps
458482
// CHECK-NOT: firrtl.wire
459483
// CHECK-NOT: firrtl.domain.define
460-
firrtl.module @DeadWires(
484+
// CHECK-NOT: firrtl.domain.anon : !firrtl.domain of @ClockDomain
485+
firrtl.module @DeadDomainOps(
461486
) {
487+
// A lone, undriven wire.
462488
%a = firrtl.wire : !firrtl.domain
463489

490+
// One wire that drives another.
464491
%b = firrtl.wire : !firrtl.domain
465492
%c = firrtl.wire : !firrtl.domain
466493
firrtl.domain.define %b, %c
494+
495+
// A lone anonymous domain.
496+
%d = firrtl.domain.anon : !firrtl.domain of @ClockDomain
497+
498+
// A wire driven by an anonymous domain.
499+
%e = firrtl.wire : !firrtl.domain
500+
%f = firrtl.domain.anon : !firrtl.domain of @ClockDomain
501+
firrtl.domain.define %e, %f
467502
}
468503
}

0 commit comments

Comments
 (0)