CIRCT 20.0.0git
Loading...
Searching...
No Matches
ESIAppIDHier.cpp
Go to the documentation of this file.
1//===- ESIAppIDHier.cpp - ESI build AppID hierarchy pass --------*- C++ -*-===//
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
9#include "../PassDetails.h"
10
14
15namespace circt {
16namespace esi {
17#define GEN_PASS_DEF_ESIAPPIDHIER
18#include "circt/Dialect/ESI/ESIPasses.h.inc"
19} // namespace esi
20} // namespace circt
21
22using namespace circt;
23using namespace esi;
24
25namespace {
26struct ESIAppIDHierPass
27 : public circt::esi::impl::ESIAppIDHierBase<ESIAppIDHierPass> {
28 void runOnOperation() override;
29
30private:
31 // Existing node blocks.
32 DenseMap<AppIDPathAttr, Block *> nodeBlock;
33
34 /// Get the AppIDHierNodeOp's or AppIDHierRootOp's block for a particular
35 /// path.
36 // NOLINTNEXTLINE(misc-no-recursion)
37 Block *getBlock(AppIDPathAttr path, ArrayRef<Operation *> opStack) {
38 Block *&block = nodeBlock[path];
39 if (block)
40 return block;
41
42 // Check if we need to create a root node.
43 if (path.getPath().empty()) {
44 auto rootOp = OpBuilder::atBlockEnd(getOperation().getBody())
45 .create<AppIDHierRootOp>(UnknownLoc::get(&getContext()),
46 path.getRoot());
47 block = &rootOp.getChildren().emplaceBlock();
48 } else {
49 Block *parentBlock = getBlock(path.getParent(), opStack.drop_back());
50 Operation *op = opStack.back();
51 if (auto inst = dyn_cast<hw::InstanceOp>(op)) {
52 // Create a normal node underneath the parent AppID.
53 auto node = OpBuilder::atBlockEnd(parentBlock)
54 .create<AppIDHierNodeOp>(UnknownLoc::get(&getContext()),
55 path.getPath().back(),
56 inst.getModuleNameAttr());
57 block = &node.getChildren().emplaceBlock();
58 } else {
59 block = parentBlock;
60 }
61 }
62 return block;
63 };
64};
65} // anonymous namespace
66
67void ESIAppIDHierPass::runOnOperation() {
68 auto mod = getOperation();
69 AppIDIndex index(mod);
70 if (!index.isValid())
71 return signalPassFailure();
72
73 // Clone in manifest data, creating the instance hierarchy as we go.
74 LogicalResult rc = index.walk(
75 top, [&](AppIDPathAttr appidPath, ArrayRef<Operation *> opStack) {
76 assert(appidPath.getPath().size() == opStack.size() &&
77 "path and opStack must be the same size.");
78 auto *block = getBlock(appidPath, opStack);
79 auto *op = opStack.back();
80 if (isa<IsManifestData>(op))
81 OpBuilder::atBlockEnd(block).clone(*op);
82 });
83 if (failed(rc))
84 return signalPassFailure();
85}
86
87std::unique_ptr<OperationPass<ModuleOp>> circt::esi::createESIAppIDHierPass() {
88 return std::make_unique<ESIAppIDHierPass>();
89}
assert(baseType &&"element must be base type")
std::unique_ptr< OperationPass< ModuleOp > > createESIAppIDHierPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition esi.py:1