Skip to content

Commit a30c8a9

Browse files
committed
[hw] Add HierPathBuilder utility
Add a utility for building `hw::HierPathOp`s at a specific location in the IR in a sane order and reusing ops when possible. This is added because this is a pattern that is used in `LowerXMR` and I'd like to reuse it in `LowerLayers`. Signed-off-by: Schuyler Eldridge <[email protected]>
1 parent 87f7feb commit a30c8a9

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===- HierPathBuilder.h - HierPathOp Builder Utility ---------------------===//
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+
// The HierPathBuilder is a utility for creating hierarchical paths at some
10+
// location in a circuit. This exists to help with a common pattern where you
11+
// are running a transform and you need to build HierPathOps, but you don't know
12+
// when you are going to do it. You also don't want to create the same
13+
// HierPathOp multiple times. This utility will maintain a cache of existing
14+
// ops and only create new ones when necessary. Additionally, this creates the
15+
// ops in nice, predictable order. I.e., all the ops are inserted into the IR
16+
// in the order they are created, not in reverse order.
17+
//
18+
//===----------------------------------------------------------------------===//
19+
20+
#ifndef CIRCT_DIALECT_HW_HIERPATHBUILDER_H
21+
#define CIRCT_DIALECT_HW_HIERPATHBUILDER_H
22+
23+
#include "circt/Dialect/HW/HWOps.h"
24+
#include "circt/Support/Namespace.h"
25+
#include <mlir/IR/Attributes.h>
26+
27+
namespace circt {
28+
namespace hw {
29+
30+
class HierPathBuilder {
31+
public:
32+
HierPathBuilder(Namespace *ns, OpBuilder::InsertPoint insertionPoint)
33+
: ns(ns), pathInsertPoint(insertionPoint) {}
34+
35+
HierPathOp getOrCreatePath(ArrayAttr pathArray,
36+
ImplicitLocOpBuilder &builder);
37+
38+
private:
39+
/// A namespace in which symbols for hierarchical path ops will be created.
40+
Namespace *ns;
41+
42+
/// A cache of already created HierPathOps. This is used to avoid repeatedly
43+
/// creating the same HierPathOp.
44+
DenseMap<mlir::Attribute, hw::HierPathOp> pathCache;
45+
46+
/// The insertion point where the pass inserts HierPathOps.
47+
OpBuilder::InsertPoint pathInsertPoint;
48+
};
49+
50+
} // namespace hw
51+
} // namespace circt
52+
53+
#endif // CIRCT_DIALECT_HW_HIERPATHBUILDER_H

lib/Dialect/HW/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(CIRCT_HW_Sources
22
ConversionPatterns.cpp
33
CustomDirectiveImpl.cpp
4+
HierPathBuilder.cpp
45
HWAttributes.cpp
56
HWEnums.cpp
67
HWDialect.cpp

lib/Dialect/HW/HierPathBuilder.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===- HierPathBuilder.cpp - HierPathOp Builder Utility -------------------===//
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+
// Implementation of a utility for creating Hierarchical Path operation.s
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "circt/Dialect/HW/HierPathBuilder.h"
14+
#include "circt/Dialect/HW/HWOps.h"
15+
16+
namespace circt {
17+
namespace hw {
18+
19+
HierPathOp HierPathBuilder::getOrCreatePath(ArrayAttr pathArray,
20+
ImplicitLocOpBuilder &builder) {
21+
22+
assert(pathArray && !pathArray.empty());
23+
// Return an existing HierPathOp if one exists with the same path.
24+
auto pathIter = pathCache.find(pathArray);
25+
if (pathIter != pathCache.end())
26+
return pathIter->second;
27+
28+
// Reset the insertion point after this function returns.
29+
OpBuilder::InsertionGuard guard(builder);
30+
31+
builder.restoreInsertionPoint(pathInsertPoint);
32+
33+
// Create the new HierPathOp and insert it into the pathCache.
34+
hw::HierPathOp path =
35+
pathCache
36+
.insert({pathArray, builder.create<hw::HierPathOp>(
37+
ns->newName("xmrPath"), pathArray)})
38+
.first->second;
39+
path.setVisibility(SymbolTable::Visibility::Private);
40+
41+
// Save the insertion point so other unique HierPathOps will be created
42+
// after this one.
43+
pathInsertPoint = builder.saveInsertionPoint();
44+
45+
// Return the new path.
46+
return path;
47+
}
48+
49+
} // namespace hw
50+
} // namespace circt

0 commit comments

Comments
 (0)