aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/annotations
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/annotations
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/annotations')
-rw-r--r--src/main/scala/firrtl/annotations/TargetUtils.scala46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/main/scala/firrtl/annotations/TargetUtils.scala b/src/main/scala/firrtl/annotations/TargetUtils.scala
new file mode 100644
index 00000000..164c430b
--- /dev/null
+++ b/src/main/scala/firrtl/annotations/TargetUtils.scala
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: Apache-2.0
+
+package firrtl.annotations
+
+import firrtl._
+import firrtl.analyses.InstanceKeyGraph
+import firrtl.analyses.InstanceKeyGraph.InstanceKey
+import firrtl.annotations.TargetToken._
+
+object TargetUtils {
+
+ /** Turns an instance path into a corresponding [[IsModule]]
+ *
+ * @note First InstanceKey is treated as the [[CircuitTarget]]
+ * @param path Instance path
+ * @param start Module in instance path to be starting [[ModuleTarget]]
+ * @return [[IsModule]] corresponding to Instance path
+ */
+ def instKeyPathToTarget(path: Seq[InstanceKey], start: Option[String] = None): IsModule = {
+ val head = path.head
+ val startx = start.getOrElse(head.module)
+ val top: IsModule = CircuitTarget(head.module).module(startx) // ~Top|Start
+ val pathx = path.dropWhile(_.module != startx)
+ if (pathx.isEmpty) top
+ else pathx.tail.foldLeft(top) { case (acc, key) => acc.instOf(key.name, key.module) }
+ }
+
+ /** Calculates all [[InstanceTarget]]s that refer to the given [[IsModule]]
+ *
+ * {{{
+ * ~Top|Top/a:A/b:B/c:C unfolds to:
+ * * ~Top|Top/a:A/b:B/c:C
+ * * ~Top|A/b:B/c:C
+ * * ~Top|B/c:C
+ * }}}
+ * @note [[ModuleTarget]] arguments return an empty Iterable
+ */
+ def unfoldInstanceTargets(ismod: IsModule): Iterable[InstanceTarget] = {
+ // concretely use List which is fast in practice
+ def rec(im: IsModule): List[InstanceTarget] = im match {
+ case inst: InstanceTarget => inst :: rec(inst.stripHierarchy(1))
+ case _ => Nil
+ }
+ rec(ismod)
+ }
+}