15#include "llvm/ADT/PostOrderIterator.h"
19#define GEN_PASS_DEF_CHECKLAYERS
20#include "circt/Dialect/FIRRTL/Passes.h.inc"
30 CheckLayers(
InstanceGraph &instanceGraph, InstanceInfo &instanceInfo)
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";
109 static LogicalResult
run(InstanceGraph &instanceGraph,
110 InstanceInfo &instanceInfo) {
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();
false return failure()
Parse an optional keyword or string and set instance into 'result'.
void runOnOperation() override
bool hasAnnotation(StringRef className) const
Return true if we have an annotation with the specified class name.
decltype(auto) walkPostOrder(Fn &&fn)
Perform a post-order walk across the modules.
std::map< std::string, std::set< std::string > > InstanceGraph
Iterates over the handshake::FuncOp's in the program to build an instance graph.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
int run(Type[Generator] generator=CppGenerator, List[str] cmdline_args=sys.argv)