|
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