diff options
| author | Schuyler Eldridge | 2020-06-16 21:18:18 -0400 |
|---|---|---|
| committer | Schuyler Eldridge | 2020-06-25 13:46:15 -0400 |
| commit | 4c0ab1892c683d5b96708d39a239eee214e702b8 (patch) | |
| tree | 06e0e870e36e59743405ff447b3c01d2a001bf5a /src | |
| parent | 33bdea461c22d9941b061bab3d4a86f4b16d01f7 (diff) | |
Add ManipulateNamesAllowlistResultAnnotation
Add a new annotation that stores the resulting name of an allowlist
name to be manipulated.
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/transforms/ManipulateNames.scala | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/main/scala/firrtl/transforms/ManipulateNames.scala b/src/main/scala/firrtl/transforms/ManipulateNames.scala index 51c0a06f..956b39e6 100644 --- a/src/main/scala/firrtl/transforms/ManipulateNames.scala +++ b/src/main/scala/firrtl/transforms/ManipulateNames.scala @@ -84,6 +84,47 @@ case class ManipulateNamesAllowlistAnnotation[A <: ManipulateNames[_]]( } +/** Records the result of name changes for any targets included in a [[ManipulateNamesAllowlistAnnotation]] + * + * If targets are later removed, then a target and old target will be removed from this annotation. If all targets are + * removed, then this annotation will be deleted. + * + * @param targets the new targets + * @param transform the transform that performed this rename + * @param oldTargets the old targets + */ +case class ManipulateNamesAllowlistResultAnnotation[A <: ManipulateNames[_]]( + targets: Seq[Seq[Target]], + transform: Dependency[A], + oldTargets: Seq[Seq[Target]]) extends MultiTargetAnnotation { + + override def duplicate(a: Seq[Seq[Target]]) = this.copy(targets = a) + + override def update(renames: RenameMap) = { + val (targetsx, oldTargetsx) = targets.zip(oldTargets).foldLeft((Seq.empty[Seq[Target]], Seq.empty[Seq[Target]])) { + case ((accT, accO), (t, o)) => t.flatMap(renames(_)) match { + /* If the target was deleted, delete the old target */ + case tx if tx.isEmpty => (accT, accO) + case tx => (Seq(tx) ++ accT, Seq(o) ++ accO) + } + } + targetsx match { + /* If all targets were deleted, delete the annotation */ + case Nil => Seq.empty + case _ => Seq(this.copy(targets = targetsx, oldTargets = oldTargetsx)) + } + } + + /** Return [[firrtl.RenameMap RenameMap]] from old targets to new targets */ + def toRenameMap: RenameMap = { + val m = oldTargets.zip(targets).flatMap { + case (a, b) => a.map(_ -> b) + }.toMap.asInstanceOf[Map[CompleteTarget, Seq[CompleteTarget]]] + RenameMap.create(m) + } + +} + /** A datastructure used to do single-pass name manipulation * @param circuit the [[ir.Circuit]] that will be manipulated * @param renames a rename map @@ -402,7 +443,19 @@ abstract class ManipulateNames[A <: ManipulateNames[_] : ClassTag] extends Trans } val renames = RenameMap() - state.copy(circuit = run(state.circuit, renames, block, allow), renames = Some(renames)) + val circuitx = run(state.circuit, renames, block, allow) + + val annotationsx = state.annotations.flatMap { + /* Consume blocklist annotations */ + case ManipulateNamesBlocklistAnnotation(_, _: Dependency[A]) => None + /* Convert allowlist annotations to result annotations */ + case ManipulateNamesAllowlistAnnotation(a, t: Dependency[A]) => (a, a.map(_.map(renames(_)).flatten)) match { + case (a, b) => Some(ManipulateNamesAllowlistResultAnnotation(b, t, a)) + } + case a => Some(a) + } + + state.copy(circuit = circuitx, annotations = annotationsx, renames = Some(renames)) } } |
