diff options
| author | Jack Koenig | 2020-12-15 16:41:53 -0800 |
|---|---|---|
| committer | GitHub | 2020-12-15 16:41:53 -0800 |
| commit | 15013df6f6ac2dafeb35d7ed15cf95c7ac8a5bef (patch) | |
| tree | 778a57914de512748d93c6aca6c2a2e4ded0a06d /src/main/scala/firrtl/RenameMap.scala | |
| parent | 93869ccec89aa9739b6fe9f0e3bd62ae8cf155cd (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.scala | 54 |
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 |
