15#include "llvm/ADT/PostOrderIterator.h"
19#define GEN_PASS_DEF_CHECKLAYERS
20#include "circt/Dialect/FIRRTL/Passes.h.inc"
25using namespace firrtl;
31 : iGraph(instanceGraph), iInfo(instanceInfo) {}
36 void run(FModuleOp moduleOp) {
43 if (!iInfo.anyInstanceUnderLayer(moduleOp))
48 SmallVector<Operation *> layerBlockOps;
49 moduleOp->walk([&](LayerBlockOp layerBlockOp) {
50 layerBlockOps.push_back(layerBlockOp);
61 if (!isGCCompanion && !transitiveModules.contains(moduleOp) &&
62 layerBlockOps.empty())
67 SmallVector<Operation *> instUnderLayerBlock, instUnderLayerModule;
68 for (
auto *instNode : iGraph.lookup(moduleOp)->uses()) {
69 auto *instOp = instNode->getInstance().getOperation();
70 if (instOp->getParentOfType<LayerBlockOp>())
71 instUnderLayerBlock.push_back(instOp);
72 else if (
auto parent = instOp->getParentOfType<FModuleOp>();
73 iInfo.anyInstanceUnderLayer(parent)) {
74 transitiveModules.insert(parent);
75 instUnderLayerModule.push_back(instOp);
81 if (layerBlockOps.empty() && instUnderLayerBlock.empty() &&
82 instUnderLayerModule.empty())
88 auto diag = moduleOp->emitOpError();
91 <<
"is a Grand Central companion that either contains layerblocks or";
94 diag <<
"either contains layerblocks or";
95 diag <<
" has at least one instance that is or contains a Grand Central "
96 "companion or layerblocks";
98 for (
auto *layerBlockOp : layerBlockOps)
99 diag.attachNote(layerBlockOp->
getLoc()) <<
"illegal layerblock here";
100 for (
auto *instUnderLayerBlock : instUnderLayerBlock)
101 diag.attachNote(instUnderLayerBlock->
getLoc())
102 <<
"illegal instantiation under a layerblock here";
103 for (
auto *instUnderLayerModule : instUnderLayerModule)
104 diag.attachNote(instUnderLayerModule->
getLoc())
105 <<
"illegal instantiation in a module under a layer here";
111 CheckLayers checkLayers(instanceGraph, instanceInfo);
113 if (
auto moduleOp = dyn_cast<FModuleOp>(*node.getModule()))
114 checkLayers.run(moduleOp);
116 return failure(checkLayers.error);
128 DenseSet<Operation *> transitiveModules;
139 if (failed(CheckLayers::run(getAnalysis<InstanceGraph>(),
140 getAnalysis<InstanceInfo>())))
141 return signalPassFailure();
142 markAllAnalysesPreserved();
static Location getLoc(DefSlot slot)
void runOnOperation() override
bool hasAnnotation(StringRef className) const
Return true if we have an annotation with the specified class name.
This graph tracks modules and where they are instantiated.
decltype(auto) walkPostOrder(Fn &&fn)
Perform a post-order walk across the modules.
constexpr const char * companionAnnoClass
void error(Twine message)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
int run(Type[Generator] generator=CppGenerator, cmdline_args=sys.argv)