aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/RenameMap.scala
diff options
context:
space:
mode:
authorJack Koenig2021-05-18 14:54:59 -0700
committerGitHub2021-05-18 14:54:59 -0700
commite0844966cbd2eb44b66c8bf341fa26370e3b4f1c (patch)
treeae71ed0eb031e5b292c493c67aa01b1ec85afd3d /src/main/scala/firrtl/RenameMap.scala
parent97273bff5718cbcbce2673d57bce1a76ec909977 (diff)
Improve performance of RenameMap in LowerTypes (#2233)
LowerTypes creates a lot of mappings for the RenameMap. The built-in .distinct of renames becomes a performance program for designs with deeply nested Aggregates. Because LowerTypes does not create duplicate renames, it can safely eschew the safety of using .distinct via a private internal API.
Diffstat (limited to 'src/main/scala/firrtl/RenameMap.scala')
-rw-r--r--src/main/scala/firrtl/RenameMap.scala16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/RenameMap.scala b/src/main/scala/firrtl/RenameMap.scala
index 82c00ca5..d39d8106 100644
--- a/src/main/scala/firrtl/RenameMap.scala
+++ b/src/main/scala/firrtl/RenameMap.scala
@@ -78,6 +78,11 @@ object RenameMap {
/** Initialize a new RenameMap */
def apply(): RenameMap = new RenameMap
+ // This is a private internal API for transforms where the .distinct operation is very expensive
+ // (eg. LowerTypes). The onus is on the user of this API to be very careful and not inject
+ // duplicates. This is a bad, hacky API that no one should use
+ private[firrtl] def noDistinct(): RenameMap = new RenameMap(doDistinct = false)
+
abstract class RenameTargetException(reason: String) extends Exception(reason)
case class IllegalRenameException(reason: String) extends RenameTargetException(reason)
case class CircularRenameException(reason: String) extends RenameTargetException(reason)
@@ -94,7 +99,11 @@ object RenameMap {
final class RenameMap private (
val underlying: mutable.HashMap[CompleteTarget, Seq[CompleteTarget]] =
mutable.HashMap[CompleteTarget, Seq[CompleteTarget]](),
- val chained: Option[RenameMap] = None) {
+ val chained: Option[RenameMap] = None,
+ // This is a private internal API for transforms where the .distinct operation is very expensive
+ // (eg. LowerTypes). The onus is on the user of this API to be very careful and not inject
+ // duplicates. This is a bad, hacky API that no one should use
+ doDistinct: Boolean = true) {
/** Chain a [[RenameMap]] with this [[RenameMap]]
* @param next the map to chain with this map
@@ -662,7 +671,10 @@ final class RenameMap private (
private def completeRename(from: CompleteTarget, tos: Seq[CompleteTarget]): Unit = {
tos.foreach { recordSensitivity(from, _) }
val existing = underlying.getOrElse(from, Vector.empty)
- val updated = (existing ++ tos).distinct
+ val updated = {
+ val all = (existing ++ tos)
+ if (doDistinct) all.distinct else all
+ }
underlying(from) = updated
traverseTokensCache.clear()
traverseHierarchyCache.clear()