14 #include "mlir/Pass/Pass.h"
15 #include "llvm/ADT/DepthFirstIterator.h"
16 #include "llvm/ADT/PostOrderIterator.h"
20 #define GEN_PASS_DEF_CHECKLAYERS
21 #include "circt/Dialect/FIRRTL/Passes.h.inc"
25 using namespace circt;
26 using namespace firrtl;
32 : iGraph(instanceGraph), iInfo(instanceInfo) {}
36 void run(FModuleOp moduleOp) {
38 if (!iInfo.anyInstanceUnderLayer(moduleOp))
42 LayerBlockOp layerBlockOp;
43 moduleOp.getBodyBlock()->walk([&](LayerBlockOp op) {
45 return WalkResult::interrupt();
54 for (
auto *node : llvm::inverse_depth_first(iGraph.lookup(moduleOp))) {
55 auto modOp = node->getModule();
56 if (previousErrors.contains(node) || !iInfo.anyInstanceUnderLayer(modOp))
58 for (
auto *instNode : node->uses()) {
59 auto instanceOp = instNode->getInstance();
60 if (instanceOp->getParentOfType<LayerBlockOp>()) {
61 auto moduleName = modOp.getModuleNameAttr();
62 auto diag = emitError(instanceOp.getLoc())
63 <<
"cannot instantiate " << moduleName
64 <<
" under a layerblock, because " << moduleName
65 <<
" contains a layerblock";
66 diag.attachNote(layerBlockOp->getLoc()) <<
"layerblock here";
67 previousErrors.insert(node);
77 CheckLayers checkLayers(instanceGraph, instanceInfo);
78 DenseSet<InstanceGraphNode *> visited;
79 for (
auto *root : instanceGraph) {
80 for (
auto *node : llvm::inverse_post_order_ext(root, visited)) {
81 if (
auto moduleOp = dyn_cast<FModuleOp>(node->getModule<Operation *>()))
82 checkLayers.run(moduleOp);
85 return failure(checkLayers.error);
95 DenseSet<const InstanceGraphNode *> previousErrors;
107 getAnalysis<InstanceInfo>())))
108 return signalPassFailure();
109 markAllAnalysesPreserved();
114 return std::make_unique<CheckLayersPass>();
void runOnOperation() override
This graph tracks modules and where they are instantiated.
std::unique_ptr< mlir::Pass > createCheckLayers()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
int run(Type[Generator] generator=CppGenerator, cmdline_args=sys.argv)