aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/RenameMap.scala
diff options
context:
space:
mode:
authorJack Koenig2020-12-15 16:41:53 -0800
committerGitHub2020-12-15 16:41:53 -0800
commit15013df6f6ac2dafeb35d7ed15cf95c7ac8a5bef (patch)
tree778a57914de512748d93c6aca6c2a2e4ded0a06d /src/main/scala/firrtl/RenameMap.scala
parent93869ccec89aa9739b6fe9f0e3bd62ae8cf155cd (diff)
Improve performance of LowerTypes renaming (#2024)
This is done by having LowerTypes uses two RenameMaps instead of one for each module. There is one for renaming instance paths, and one for renaming everything within modules. Also add some utilities: * TargetUtils for dealing with InstanceTargets * RenameMap.fromInstanceRenames
Diffstat (limited to 'src/main/scala/firrtl/RenameMap.scala')
-rw-r--r--src/main/scala/firrtl/RenameMap.scala54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/RenameMap.scala b/src/main/scala/firrtl/RenameMap.scala
index df98f72f..82c00ca5 100644
--- a/src/main/scala/firrtl/RenameMap.scala
+++ b/src/main/scala/firrtl/RenameMap.scala
@@ -4,7 +4,9 @@ package firrtl
import annotations._
import firrtl.RenameMap.IllegalRenameException
+import firrtl.analyses.InstanceKeyGraph
import firrtl.annotations.TargetToken.{Field, Index, Instance, OfModule}
+import TargetUtils.{instKeyPathToTarget, unfoldInstanceTargets}
import scala.collection.mutable
@@ -21,6 +23,58 @@ object RenameMap {
rm
}
+ /** RenameMap factory for simple renaming of instances
+ *
+ * @param graph [[InstanceKeyGraph]] from *before* renaming
+ * @param renames Mapping of old instance name to new within Modules
+ */
+ private[firrtl] def fromInstanceRenames(
+ graph: InstanceKeyGraph,
+ renames: Map[OfModule, Map[Instance, Instance]]
+ ): RenameMap = {
+ def renameAll(it: InstanceTarget): InstanceTarget = {
+ var prevMod = OfModule(it.module)
+ val pathx = it.path.map {
+ case (inst, of) =>
+ val instx = renames
+ .get(prevMod)
+ .flatMap(_.get(inst))
+ .getOrElse(inst)
+ prevMod = of
+ instx -> of
+ }
+ // Sanity check, the last one should always be a rename (or we wouldn't be calling this method)
+ val instx = renames(prevMod)(Instance(it.instance))
+ it.copy(path = pathx, instance = instx.value)
+ }
+ val underlying = new mutable.HashMap[CompleteTarget, Seq[CompleteTarget]]
+ val instOf: String => Map[String, String] =
+ graph.getChildInstances.toMap
+ // Laziness here is desirable, we only access each key once, some we don't access
+ .mapValues(_.map(k => k.name -> k.module).toMap)
+ for ((OfModule(module), instMapping) <- renames) {
+ val modLookup = instOf(module)
+ val parentInstances = graph.findInstancesInHierarchy(module)
+ for {
+ // For every instance of the Module where the renamed instance resides
+ parent <- parentInstances
+ parentTarget = instKeyPathToTarget(parent)
+ // Create the absolute InstanceTarget to be renamed
+ (Instance(from), _) <- instMapping // The to is given by renameAll
+ instMod = modLookup(from)
+ fromTarget = parentTarget.instOf(from, instMod)
+ // Ensure all renames apply to the InstanceTarget
+ toTarget = renameAll(fromTarget)
+ // RenameMap only allows 1 hit when looking up InstanceTargets, so rename all possible
+ // paths to this instance
+ (fromx, tox) <- unfoldInstanceTargets(fromTarget).zip(unfoldInstanceTargets(toTarget))
+ } yield {
+ underlying(fromx) = List(tox)
+ }
+ }
+ new RenameMap(underlying)
+ }
+
/** Initialize a new RenameMap */
def apply(): RenameMap = new RenameMap