Skip to content

Conversation

seldridge
Copy link
Member

@seldridge seldridge commented Aug 20, 2025

Add a pass that does domain inference and checking. This is used to verify the legality of a FIRRTL circuit with respect to its domains. E.g., this pass is intended to be used for checking for illegal clock domain crossings.

@seldridge seldridge force-pushed the dev/seldridge/firrtl-infer-domains branch 2 times, most recently from e1ae48d to a17ada0 Compare August 21, 2025 16:29
@seldridge seldridge force-pushed the dev/seldridge/firrtl-domains-operation-approach branch 2 times, most recently from df67311 to 7e543de Compare August 30, 2025 03:42
@seldridge seldridge force-pushed the dev/seldridge/firrtl-infer-domains branch from a17ada0 to f0512f4 Compare August 30, 2025 03:43
Base automatically changed from dev/seldridge/firrtl-domains-operation-approach to main August 30, 2025 19:36
Add a pass that does domain inference and checking.  This is used to
verify the legality of a FIRRTL circuit with respect to its domains.
E.g., this pass is intended to be used for checking for illegal clock
domain crossings.

Signed-off-by: Schuyler Eldridge <[email protected]>
@seldridge seldridge force-pushed the dev/seldridge/firrtl-infer-domains branch from f0512f4 to a12e326 Compare September 2, 2025 15:38
Comment on lines +170 to +179
std::unique_ptr<mlir::Pass> clonePass() const override {
return std::make_unique<InferDomainsPass>();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to define clonePass?

// domains
if (!op->getOperands().empty()) {
Value firstOperand = op->getOperand(0);
for (auto operand : op->getOperands()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop a first operand.

Comment on lines +420 to +422
if (hasErrors) {
signalPassFailure();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (hasErrors) {
signalPassFailure();
}
if (hasErrors)
signalPassFailure();

Comment on lines +61 to +62
// pointer comparison is only stable within a run of MLIR and should not be
// relied upon for determinism outside of a run.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't non-deterministic still visible outside soon after we attached ? I think you can sort by properlyDominate

// Set the merged domain sequence on the new representative
if (!mergedDomains.empty()) {
Value newRep = equivalenceClasses.getLeaderValue(rep1);
concreteDomains[newRep] = mergedDomains;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this has a lifetime issue. mergedDomains points to a reference to concreteDomains but concreteDomains[newRep] could grow capacity and invalidate the mergedDomains. You might want to change the type concreateDomains to DenseMap<Value, std::uninque_ptr<SmallVector<..>>>.

if (isa<DomainType>(port.type)) {
newDomainInfo.push_back(port.domains
? port.domains
: ArrayAttr::get(module.getContext(), {}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Please hoist empty array out of loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants