aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSchuyler Eldridge2020-02-12 20:27:22 -0500
committerGitHub2020-02-12 20:27:22 -0500
commitdd6bbd4f6b21025913005658c562d2ad530aa3b1 (patch)
tree917554e156a798242cd635ea5b6e5b978b10f019 /src
parenteabc38559b7634ff7147aa0ab3d71e78558d5162 (diff)
parent1909e216b8e7748d97ac34d91b18ec0f54fde46a (diff)
Merge pull request #1388 from freechipsproject/allow-self-renames
Allow self renames
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/RenameMap.scala38
-rw-r--r--src/test/scala/firrtlTests/RenameMapSpec.scala28
2 files changed, 52 insertions, 14 deletions
diff --git a/src/main/scala/firrtl/RenameMap.scala b/src/main/scala/firrtl/RenameMap.scala
index 03f01991..bdcb785a 100644
--- a/src/main/scala/firrtl/RenameMap.scala
+++ b/src/main/scala/firrtl/RenameMap.scala
@@ -33,12 +33,16 @@ object RenameMap {
*
* Transforms that modify names should return a [[RenameMap]] with the [[CircuitState]]
* These are mutable datastructures for convenience
+ * @define noteSelfRename @note Self renames *will* be recorded
+ * @define noteDistinct @note Rename to/tos will be made distinct
*/
// TODO This should probably be refactored into immutable and mutable versions
final class RenameMap private (val underlying: mutable.HashMap[CompleteTarget, Seq[CompleteTarget]] = mutable.HashMap[CompleteTarget, Seq[CompleteTarget]](), val chained: Option[RenameMap] = None) {
/** Chain a [[RenameMap]] with this [[RenameMap]]
* @param next the map to chain with this map
+ * $noteSelfRename
+ * $noteDistinct
*/
def andThen(next: RenameMap): RenameMap = {
if (next.chained.isEmpty) {
@@ -52,6 +56,8 @@ final class RenameMap private (val underlying: mutable.HashMap[CompleteTarget, S
* [[firrtl.annotations.CircuitTarget CircuitTarget]]
* @param from
* @param to
+ * $noteSelfRename
+ * $noteDistinct
*/
def record(from: CircuitTarget, to: CircuitTarget): Unit = completeRename(from, Seq(to))
@@ -59,6 +65,8 @@ final class RenameMap private (val underlying: mutable.HashMap[CompleteTarget, S
* [[firrtl.annotations.CircuitTarget CircuitTarget]]s
* @param from
* @param tos
+ * $noteSelfRename
+ * $noteDistinct
*/
def record(from: CircuitTarget, tos: Seq[CircuitTarget]): Unit = completeRename(from, tos)
@@ -66,6 +74,8 @@ final class RenameMap private (val underlying: mutable.HashMap[CompleteTarget, S
* IsMember]]
* @param from
* @param to
+ * $noteSelfRename
+ * $noteDistinct
*/
def record(from: IsMember, to: IsMember): Unit = completeRename(from, Seq(to))
@@ -73,6 +83,8 @@ final class RenameMap private (val underlying: mutable.HashMap[CompleteTarget, S
* [[firrtl.annotations.IsMember IsMember]]s
* @param from
* @param tos
+ * $noteSelfRename
+ * $noteDistinct
*/
def record(from: IsMember, tos: Seq[IsMember]): Unit = completeRename(from, tos)
@@ -81,6 +93,8 @@ final class RenameMap private (val underlying: mutable.HashMap[CompleteTarget, S
* and ([[firrtl.annotations.IsMember IsMember]] -> Seq[ [[firrtl.annotations.IsMember IsMember]] ]) key/value
* allowed
* @param map
+ * $noteSelfRename
+ * $noteDistinct
*/
def recordAll(map: collection.Map[CompleteTarget, Seq[CompleteTarget]]): Unit =
map.foreach{
@@ -479,24 +493,20 @@ final class RenameMap private (val underlying: mutable.HashMap[CompleteTarget, S
}
}
- /** Fully renames from to tos
+ /** Fully rename `from` to `tos`
* @param from
* @param tos
*/
private def completeRename(from: CompleteTarget, tos: Seq[CompleteTarget]): Unit = {
- (from, tos) match {
- case (x, Seq(y)) if x == y =>
- case _ =>
- tos.foreach{recordSensitivity(from, _)}
- val existing = underlying.getOrElse(from, Vector.empty)
- val updated = existing ++ tos
- underlying(from) = updated
- getCache.clear()
- traverseTokensCache.clear()
- traverseHierarchyCache.clear()
- traverseLeftCache.clear()
- traverseRightCache.clear()
- }
+ tos.foreach{recordSensitivity(from, _)}
+ val existing = underlying.getOrElse(from, Vector.empty)
+ val updated = (existing ++ tos).distinct
+ underlying(from) = updated
+ getCache.clear()
+ traverseTokensCache.clear()
+ traverseHierarchyCache.clear()
+ traverseLeftCache.clear()
+ traverseRightCache.clear()
}
/* DEPRECATED ACCESSOR/SETTOR METHODS WITH [[firrtl.ir.Named Named]] */
diff --git a/src/test/scala/firrtlTests/RenameMapSpec.scala b/src/test/scala/firrtlTests/RenameMapSpec.scala
index 2da10b7f..dc091b0a 100644
--- a/src/test/scala/firrtlTests/RenameMapSpec.scala
+++ b/src/test/scala/firrtlTests/RenameMapSpec.scala
@@ -752,4 +752,32 @@ class RenameMapSpec extends FirrtlFlatSpec {
Some(Seq(bar2))
}
}
+
+ it should "record a self-rename" in {
+ val top = CircuitTarget("Top").module("Top")
+ val foo = top.instOf("foo", "Mod")
+ val bar = top.instOf("bar", "Mod")
+
+ val r = RenameMap()
+
+ r.record(foo, bar)
+ r.record(foo, foo)
+
+ r.get(foo) should not be (empty)
+ r.get(foo).get should contain allOf (foo, bar)
+ }
+
+ it should "not record the same rename multiple times" in {
+ val top = CircuitTarget("Top").module("Top")
+ val foo = top.instOf("foo", "Mod")
+ val bar = top.instOf("bar", "Mod")
+
+ val r = RenameMap()
+
+ r.record(foo, bar)
+ r.record(foo, bar)
+
+ r.get(foo) should not be (empty)
+ r.get(foo).get should contain theSameElementsAs Seq(bar)
+ }
}