11 #include "mlir/Pass/Pass.h"
12 #include "llvm/ADT/SCCIterator.h"
16 #define GEN_PASS_DEF_CHECKRECURSIVEINSTANTIATION
17 #include "circt/Dialect/FIRRTL/Passes.h.inc"
21 using namespace circt;
22 using namespace firrtl;
25 ArrayRef<InstanceGraphNode *> nodes) {
26 assert(nodes.size() > 0 &&
"an scc should have at least one node");
28 emitError(nodes.front()->getModule().getLoc(),
"recursive instantiation");
29 llvm::SmallPtrSet<InstanceGraphNode *, 8> scc(nodes.begin(), nodes.end());
30 for (
auto *node : nodes) {
31 for (
auto *record : *node) {
32 auto *target = record->getTarget();
33 if (!scc.contains(target))
35 auto ¬e = diag.attachNote(record->getInstance().getLoc());
36 note << record->getParent()->getModule().getModuleName();
37 note <<
" instantiates "
38 << record->getTarget()->getModule().getModuleName() <<
" here";
44 class CheckRecursiveInstantiationPass
45 :
public impl::CheckRecursiveInstantiationBase<
46 CheckRecursiveInstantiationPass> {
48 void runOnOperation()
override {
49 auto &instanceGraph = getAnalysis<InstanceGraph>();
50 for (
auto it = llvm::scc_begin(&instanceGraph),
51 end = llvm::scc_end(&instanceGraph);
58 markAllAnalysesPreserved();
64 return std::make_unique<CheckRecursiveInstantiationPass>();
assert(baseType &&"element must be base type")
static void printPath(InstanceGraph &instanceGraph, ArrayRef< InstanceGraphNode * > nodes)
This graph tracks modules and where they are instantiated.
std::unique_ptr< mlir::Pass > createCheckRecursiveInstantiation()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.