11 #include "mlir/Pass/Pass.h"
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/SCCIterator.h"
17 #define GEN_PASS_DEF_CHECKRECURSIVEINSTANTIATION
18 #include "circt/Dialect/FIRRTL/Passes.h.inc"
22 using namespace circt;
23 using namespace firrtl;
26 ArrayRef<InstanceGraphNode *> nodes) {
27 assert(nodes.size() > 0 &&
"an scc should have at least one node");
29 emitError(nodes.front()->getModule().getLoc(),
"recursive instantiation");
30 llvm::SmallPtrSet<InstanceGraphNode *, 8> scc(nodes.begin(), nodes.end());
31 for (
auto *node : nodes) {
32 for (
auto *record : *node) {
33 auto *target = record->getTarget();
34 if (!scc.contains(target))
36 auto ¬e = diag.attachNote(record->getInstance().getLoc());
37 note << record->getParent()->getModule().getModuleName();
38 note <<
" instantiates "
39 << record->getTarget()->getModule().getModuleName() <<
" here";
45 class CheckRecursiveInstantiationPass
46 :
public impl::CheckRecursiveInstantiationBase<
47 CheckRecursiveInstantiationPass> {
49 void runOnOperation()
override {
50 auto &instanceGraph = getAnalysis<InstanceGraph>();
51 for (
auto it = llvm::scc_begin(&instanceGraph),
52 end = llvm::scc_end(&instanceGraph);
59 markAllAnalysesPreserved();
65 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.