|
16 | 16 | #include "circt/Dialect/FIRRTL/FIRRTLUtils.h"
|
17 | 17 | #include "circt/Dialect/FIRRTL/Namespace.h"
|
18 | 18 | #include "circt/Dialect/FIRRTL/Passes.h"
|
| 19 | +#include "circt/Dialect/HW/HierPathBuilder.h" |
19 | 20 | #include "circt/Dialect/HW/InnerSymbolNamespace.h"
|
20 | 21 | #include "circt/Dialect/SV/SVOps.h"
|
21 | 22 | #include "mlir/IR/ImplicitLocOpBuilder.h"
|
@@ -130,6 +131,11 @@ class LowerXMRPass : public circt::firrtl::impl::LowerXMRBase<LowerXMRPass> {
|
130 | 131 | CircuitNamespace ns(getOperation());
|
131 | 132 | circuitNamespace = &ns;
|
132 | 133 |
|
| 134 | + hw::HierPathBuilder pb( |
| 135 | + &ns, OpBuilder::InsertPoint(getOperation().getBodyBlock(), |
| 136 | + getOperation().getBodyBlock()->begin())); |
| 137 | + hierPathBuilder = &pb; |
| 138 | + |
133 | 139 | llvm::EquivalenceClasses<Value> eq;
|
134 | 140 | dataFlowClasses = &eq;
|
135 | 141 |
|
@@ -408,8 +414,7 @@ class LowerXMRPass : public circt::firrtl::impl::LowerXMRBase<LowerXMRPass> {
|
408 | 414 | opsToRemove.clear();
|
409 | 415 | xmrPathSuffix.clear();
|
410 | 416 | circuitNamespace = nullptr;
|
411 |
| - pathCache.clear(); |
412 |
| - pathInsertPoint = {}; |
| 417 | + hierPathBuilder = nullptr; |
413 | 418 | }
|
414 | 419 |
|
415 | 420 | /// Generate the ABI ref_<module> prefix string into `prefix`.
|
@@ -496,7 +501,8 @@ class LowerXMRPass : public circt::firrtl::impl::LowerXMRBase<LowerXMRPass> {
|
496 | 501 | if (!refSendPath.empty())
|
497 | 502 | // Compute the HierPathOp that stores the path.
|
498 | 503 | ref = FlatSymbolRefAttr::get(
|
499 |
| - getOrCreatePath(builder.getArrayAttr(refSendPath), builder) |
| 504 | + hierPathBuilder |
| 505 | + ->getOrCreatePath(builder.getArrayAttr(refSendPath), builder) |
500 | 506 | .getSymNameAttr());
|
501 | 507 |
|
502 | 508 | return success();
|
@@ -828,43 +834,6 @@ class LowerXMRPass : public circt::firrtl::impl::LowerXMRBase<LowerXMRPass> {
|
828 | 834 |
|
829 | 835 | bool isZeroWidth(FIRRTLBaseType t) { return t.getBitWidthOrSentinel() == 0; }
|
830 | 836 |
|
831 |
| - /// Return a HierPathOp for the provided pathArray. This will either return |
832 |
| - /// an existing HierPathOp or it will create and return a new one. |
833 |
| - hw::HierPathOp getOrCreatePath(ArrayAttr pathArray, |
834 |
| - ImplicitLocOpBuilder &builder) { |
835 |
| - assert(pathArray && !pathArray.empty()); |
836 |
| - // Return an existing HierPathOp if one exists with the same path. |
837 |
| - auto pathIter = pathCache.find(pathArray); |
838 |
| - if (pathIter != pathCache.end()) |
839 |
| - return pathIter->second; |
840 |
| - |
841 |
| - // Reset the insertion point after this function returns. |
842 |
| - OpBuilder::InsertionGuard guard(builder); |
843 |
| - |
844 |
| - // Set the insertion point to either the known location where the pass |
845 |
| - // inserts HierPathOps or to the start of the circuit. |
846 |
| - if (pathInsertPoint.isSet()) |
847 |
| - builder.restoreInsertionPoint(pathInsertPoint); |
848 |
| - else |
849 |
| - builder.setInsertionPointToStart(getOperation().getBodyBlock()); |
850 |
| - |
851 |
| - // Create the new HierPathOp and insert it into the pathCache. |
852 |
| - hw::HierPathOp path = |
853 |
| - pathCache |
854 |
| - .insert({pathArray, |
855 |
| - builder.create<hw::HierPathOp>( |
856 |
| - circuitNamespace->newName("xmrPath"), pathArray)}) |
857 |
| - .first->second; |
858 |
| - path.setVisibility(SymbolTable::Visibility::Private); |
859 |
| - |
860 |
| - // Save the insertion point so other unique HierPathOps will be created |
861 |
| - // after this one. |
862 |
| - pathInsertPoint = builder.saveInsertionPoint(); |
863 |
| - |
864 |
| - // Return the new path. |
865 |
| - return path; |
866 |
| - } |
867 |
| - |
868 | 837 | private:
|
869 | 838 | /// Cached module namespaces.
|
870 | 839 | DenseMap<Operation *, hw::InnerSymbolNamespace> moduleNamespaces;
|
@@ -897,12 +866,9 @@ class LowerXMRPass : public circt::firrtl::impl::LowerXMRBase<LowerXMRPass> {
|
897 | 866 |
|
898 | 867 | CircuitNamespace *circuitNamespace;
|
899 | 868 |
|
900 |
| - /// A cache of already created HierPathOps. This is used to avoid repeatedly |
901 |
| - /// creating the same HierPathOp. |
902 |
| - DenseMap<Attribute, hw::HierPathOp> pathCache; |
903 |
| - |
904 |
| - /// The insertion point where the pass inserts HierPathOps. |
905 |
| - OpBuilder::InsertPoint pathInsertPoint = {}; |
| 869 | + /// Utility to create HerPathOps at a predefined location in the circuit. |
| 870 | + /// This handles caching and keeps the order consistent. |
| 871 | + hw::HierPathBuilder *hierPathBuilder; |
906 | 872 |
|
907 | 873 | /// Per-module helpers for creating operations within modules.
|
908 | 874 | DenseMap<FModuleOp, ModuleState> moduleStates;
|
|
0 commit comments