Skip to content

Commit e478497

Browse files
committed
More changes
1 parent fb90ba2 commit e478497

File tree

4 files changed

+94
-536
lines changed

4 files changed

+94
-536
lines changed

lib/Dialect/FIRRTL/Transforms/InferDomains.cpp

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,6 @@ class DomainTable {
488488
/// For a hardware value, get the term which represents the row of associated
489489
/// domains.
490490
Term *getDomainAssociation(Value value) const {
491-
llvm::errs() << "value = " << value << "\n";
492491
auto *term = getOptDomainAssociation(value);
493492
assert(term);
494493
return term;
@@ -1256,7 +1255,7 @@ LogicalResult inferModule(const DomainInfo &info,
12561255
// module.
12571256
//====--------------------------------------------------------------------------
12581257

1259-
/// Check that a module has complete domain information for its ports.
1258+
/// Check that a module's hardware ports have complete domain associations.
12601259
LogicalResult checkModulePorts(const DomainInfo &info, FModuleLike module) {
12611260
auto numDomains = info.getNumDomains();
12621261
auto domainInfo = module.getDomainInfoAttr();
@@ -1309,20 +1308,79 @@ LogicalResult checkModulePorts(const DomainInfo &info, FModuleLike module) {
13091308
return success();
13101309
}
13111310

1312-
LogicalResult checkModuleBody(const DomainInfo &info,
1313-
ModuleUpdateTable &updateTable,
1314-
FModuleOp module) {
1311+
/// Check that output domain ports are driven.
1312+
LogicalResult checkModuleDomainPortDrivers(const DomainInfo &info,
1313+
FModuleOp module) {
1314+
for (size_t i = 0, e = module.getNumPorts(); i < e; ++i) {
1315+
auto port = module.getArgument(i);
1316+
auto type = port.getType();
1317+
if (!isa<DomainType>(type) ||
1318+
module.getPortDirection(i) != Direction::Out || isDriven(port))
1319+
continue;
1320+
1321+
auto name = module.getPortNameAttr(i);
1322+
emitError(module.getPortLocation(i)) << "undriven domain port " << name;
1323+
return failure();
1324+
}
1325+
1326+
return success();
1327+
}
1328+
1329+
/// Check that the input domain ports are driven.
1330+
template <typename T>
1331+
LogicalResult checkInstanceDomainPortDrivers(T op) {
1332+
for (size_t i = 0, e = op.getNumResults(); i < e; ++i) {
1333+
auto port = op.getResult(i);
1334+
auto type = port.getType();
1335+
if (!isa<DomainType>(type) || op.getPortDirection(i) != Direction::In ||
1336+
isDriven(port))
1337+
continue;
1338+
1339+
auto name = op.getPortNameAttr(i);
1340+
emitError(op.getPortLocation(i)) << "undriven domain port " << name;
1341+
return failure();
1342+
}
1343+
1344+
return success();
1345+
}
1346+
1347+
LogicalResult checkOp(Operation *op) {
1348+
if (auto inst = dyn_cast<InstanceOp>(op))
1349+
return checkInstanceDomainPortDrivers(inst);
1350+
if (auto inst = dyn_cast<InstanceChoiceOp>(op))
1351+
return checkInstanceDomainPortDrivers(inst);
13151352
return success();
13161353
}
13171354

1355+
/// Check that instances under this module have driven domain input ports.
1356+
LogicalResult checkModuleBody(FModuleOp module) {
1357+
LogicalResult result = success();
1358+
module.getBody().walk([&](Operation *op) -> WalkResult {
1359+
if (failed(checkOp(op))) {
1360+
result = failure();
1361+
return WalkResult::interrupt();
1362+
}
1363+
return WalkResult::advance();
1364+
});
1365+
return result;
1366+
}
1367+
13181368
/// Check that a module's ports are fully annotated, before performing domain
13191369
/// inference on the module.
1320-
LogicalResult checkModule(const DomainInfo &info,
1321-
ModuleUpdateTable &updateTable, FModuleOp module) {
1370+
LogicalResult checkModule(const DomainInfo &info, FModuleOp module) {
13221371
if (failed(checkModulePorts(info, module)))
13231372
return failure();
13241373

1325-
return checkModuleBody(info, updateTable, module);
1374+
if (failed(checkModuleDomainPortDrivers(info, module)))
1375+
return failure();
1376+
1377+
if (failed(checkModuleBody(module)))
1378+
return failure();
1379+
1380+
TermAllocator allocator;
1381+
DomainTable table;
1382+
ModuleUpdateTable updateTable;
1383+
return processModule(info, allocator, table, updateTable, module);
13261384
}
13271385

13281386
/// Check that an extmodule's ports are fully annotated.
@@ -1352,15 +1410,15 @@ LogicalResult checkAndInferModule(const DomainInfo &info,
13521410

13531411
LogicalResult runOnModuleLike(InferDomainsMode mode, const DomainInfo &info,
13541412
ModuleUpdateTable &updateTable, Operation *op) {
1355-
llvm::errs() << "********\n";
1356-
llvm::errs() << *op << "\n";
1413+
// llvm::errs() << "********\n";
1414+
// llvm::errs() << *op << "\n";
13571415

13581416
if (auto module = dyn_cast<FModuleOp>(op)) {
13591417
if (mode == InferDomainsMode::Check)
1360-
return checkModule(info, updateTable, module);
1418+
return checkModule(info, module);
13611419
if (mode == InferDomainsMode::InferAll || module.isPrivate())
13621420
return inferModule(info, updateTable, module);
1363-
1421+
13641422
return checkAndInferModule(info, updateTable, module);
13651423
}
13661424

test/Dialect/FIRRTL/infer-domains-check-errors.mlir

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// RUN: circt-opt -pass-pipeline='builtin.module(firrtl.circuit(firrtl-infer-domains{mode=check}))' %s --verify-diagnostics --split-input-file
1+
// RUN: circt-opt -pass-pipeline='builtin.module(firrtl.circuit(firrtl-infer-domains{mode=check}))' %s --verify-diagnostics
2+
3+
// in "check" mode, infer-domains will require that all ops are fully annotated
4+
// with domains. No inference is run.
25

3-
// In check-mode, we check that the interface of public modules is fully annotated
4-
// with domain inference
56
// CHECK-LABEL: MissingDomain
67
firrtl.circuit "MissingDomain" {
78
firrtl.domain @ClockDomain
@@ -29,7 +30,7 @@ firrtl.circuit "UndrivenOutputDomain" {
2930
firrtl.domain @ClockDomain
3031

3132
firrtl.module @UndrivenOutputDomain(
32-
// expected-error @below {{unable to infer value for undriven domain port "c"}}
33+
// expected-error @below {{undriven domain port "c"}}
3334
out %c : !firrtl.domain of @ClockDomain
3435
) {}
3536
}
@@ -41,7 +42,7 @@ firrtl.circuit "UndrivenInstanceDomainPort" {
4142
firrtl.extmodule @Foo(in c : !firrtl.domain of @ClockDomain)
4243

4344
firrtl.module @UndrivenInstanceDomainPort() {
44-
// expected-error @below {{unable to infer value for undriven domain port "c"}}
45+
// expected-error @below {{undriven domain port "c"}}
4546
%foo_c = firrtl.instance foo @Foo(in c : !firrtl.domain of @ClockDomain)
4647
}
4748
}
@@ -58,7 +59,24 @@ firrtl.circuit "UndrivenInstanceChoiceDomainPort" {
5859
firrtl.extmodule @Bar(in c : !firrtl.domain of @ClockDomain)
5960

6061
firrtl.module @UndrivenInstanceChoiceDomainPort() {
61-
// expected-error @below {{unable to infer value for undriven domain port "c"}}
62+
// expected-error @below {{undriven domain port "c"}}
6263
%inst_c = firrtl.instance_choice inst @Foo alternatives @Option { @X -> @Bar } (in c : !firrtl.domain of @ClockDomain)
6364
}
6465
}
66+
67+
// Test that domain crossing errors are still caught when in check-only mode.
68+
// Catching this involves processing the module without writing back to the IR.
69+
firrtl.circuit "IllegalDomainCrossing" {
70+
firrtl.domain @ClockDomain
71+
firrtl.module @IllegalDomainCrossing(
72+
in %A: !firrtl.domain of @ClockDomain,
73+
in %B: !firrtl.domain of @ClockDomain,
74+
// expected-note @below {{2nd operand has domains: [ClockDomain: A]}}
75+
in %a: !firrtl.uint<1> domains [%A],
76+
// expected-note @below {{1st operand has domains: [ClockDomain: B]}}
77+
out %b: !firrtl.uint<1> domains [%B]
78+
) {
79+
// expected-error @below {{illegal domain crossing in operation}}
80+
firrtl.matchingconnect %b, %a : !firrtl.uint<1>
81+
}
82+
}

test/Dialect/FIRRTL/infer-domains-errors.mlir

Lines changed: 0 additions & 195 deletions
This file was deleted.

0 commit comments

Comments
 (0)