CIRCT 20.0.0git
Loading...
Searching...
No Matches
CheckRecursiveInstantiation.cpp
Go to the documentation of this file.
1//===- CheckRecursiveInstantiation.cpp - Check recurisve instantiation ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "mlir/Pass/Pass.h"
12#include "llvm/ADT/SCCIterator.h"
13
14namespace circt {
15namespace firrtl {
16#define GEN_PASS_DEF_CHECKRECURSIVEINSTANTIATION
17#include "circt/Dialect/FIRRTL/Passes.h.inc"
18} // namespace firrtl
19} // namespace circt
20
21using namespace circt;
22using namespace firrtl;
23
24static void printPath(InstanceGraph &instanceGraph,
25 ArrayRef<InstanceGraphNode *> nodes) {
26 assert(nodes.size() > 0 && "an scc should have at least one node");
27 auto diag =
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))
34 continue;
35 auto &note = diag.attachNote(record->getInstance().getLoc());
36 note << record->getParent()->getModule().getModuleName();
37 note << " instantiates "
38 << record->getTarget()->getModule().getModuleName() << " here";
39 }
40 }
41}
42
43namespace {
44class CheckRecursiveInstantiationPass
45 : public impl::CheckRecursiveInstantiationBase<
46 CheckRecursiveInstantiationPass> {
47public:
48 void runOnOperation() override {
49 auto &instanceGraph = getAnalysis<InstanceGraph>();
50 for (auto it = llvm::scc_begin(&instanceGraph),
51 end = llvm::scc_end(&instanceGraph);
52 it != end; ++it) {
53 if (it.hasCycle()) {
54 printPath(instanceGraph, *it);
55 signalPassFailure();
56 }
57 }
58 markAllAnalysesPreserved();
59 }
60};
61} // namespace
62
64 return std::make_unique<CheckRecursiveInstantiationPass>();
65}
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.