aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Koenig2020-08-21 13:05:38 -0700
committerGitHub2020-08-21 13:05:38 -0700
commit266ac5fc32865d001409194f426b4126f5d9001b (patch)
tree882b568677ed3578023bc8987ac0b4ee601c5db3 /src
parent73868fc6e8110282ce545c296540d3ebbafadfeb (diff)
Deprecate Uniquify and move its useful utilities (#1856)
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Namespace.scala17
-rw-r--r--src/main/scala/firrtl/Utils.scala41
-rw-r--r--src/main/scala/firrtl/annotations/analysis/DuplicationHelper.scala2
-rw-r--r--src/main/scala/firrtl/passes/Inline.scala32
-rw-r--r--src/main/scala/firrtl/passes/RemoveAccesses.scala4
-rw-r--r--src/main/scala/firrtl/passes/Uniquify.scala75
-rw-r--r--src/main/scala/firrtl/transforms/RemoveKeywordCollisions.scala3
7 files changed, 98 insertions, 76 deletions
diff --git a/src/main/scala/firrtl/Namespace.scala b/src/main/scala/firrtl/Namespace.scala
index 196539c8..c036b5f7 100644
--- a/src/main/scala/firrtl/Namespace.scala
+++ b/src/main/scala/firrtl/Namespace.scala
@@ -3,6 +3,7 @@
package firrtl
import scala.collection.mutable
+import scala.annotation.tailrec
import firrtl.ir._
class Namespace private {
@@ -80,4 +81,20 @@ object Namespace {
namespace.namespace ++= names
namespace
}
+
+ /** Appends delim to prefix until no collisions of prefix + elts in names We don't add an _ in the collision check
+ * because elts could be Seq("") In this case, we're just really checking if prefix itself collides
+ */
+ def findValidPrefix(
+ prefix: String,
+ elts: Iterable[String],
+ namespace: String => Boolean
+ ): String = {
+ @tailrec
+ def rec(p: String): String = {
+ val found = elts.exists(elt => namespace(p + elt))
+ if (found) rec(p + "_") else p
+ }
+ rec(prefix)
+ }
}
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
index bc285ef3..e8a00518 100644
--- a/src/main/scala/firrtl/Utils.scala
+++ b/src/main/scala/firrtl/Utils.scala
@@ -709,6 +709,47 @@ object Utils extends LazyLogging {
}
}
+ /** Creates a Bundle Type from a Stmt */
+ def stmtToType(s: Statement): BundleType = {
+ // Recursive helper
+ def recStmtToType(s: Statement): Seq[Field] = s match {
+ case sx: DefWire => Seq(Field(sx.name, Default, sx.tpe))
+ case sx: DefRegister => Seq(Field(sx.name, Default, sx.tpe))
+ case sx: WDefInstance => Seq(Field(sx.name, Default, sx.tpe))
+ case sx: DefMemory =>
+ sx.dataType match {
+ case (_: UIntType | _: SIntType | _: FixedType) =>
+ Seq(Field(sx.name, Default, passes.MemPortUtils.memType(sx)))
+ case tpe: BundleType =>
+ val newFields = tpe.fields
+ .map(f =>
+ DefMemory(
+ sx.info,
+ f.name,
+ f.tpe,
+ sx.depth,
+ sx.writeLatency,
+ sx.readLatency,
+ sx.readers,
+ sx.writers,
+ sx.readwriters
+ )
+ )
+ .flatMap(recStmtToType)
+ Seq(Field(sx.name, Default, BundleType(newFields)))
+ case tpe: VectorType =>
+ val newFields =
+ (0 until tpe.size).map(i => sx.copy(name = i.toString, dataType = tpe.tpe)).flatMap(recStmtToType)
+ Seq(Field(sx.name, Default, BundleType(newFields)))
+ }
+ case sx: DefNode => Seq(Field(sx.name, Default, sx.value.tpe))
+ case sx: Conditionally => recStmtToType(sx.conseq) ++ recStmtToType(sx.alt)
+ case sx: Block => (sx.stmts.map(recStmtToType)).flatten
+ case sx => Seq()
+ }
+ BundleType(recStmtToType(s))
+ }
+
// format: off
val v_keywords = Set(
"alias", "always", "always_comb", "always_ff", "always_latch",
diff --git a/src/main/scala/firrtl/annotations/analysis/DuplicationHelper.scala b/src/main/scala/firrtl/annotations/analysis/DuplicationHelper.scala
index 31d13139..d4bac8ba 100644
--- a/src/main/scala/firrtl/annotations/analysis/DuplicationHelper.scala
+++ b/src/main/scala/firrtl/annotations/analysis/DuplicationHelper.scala
@@ -72,7 +72,7 @@ case class DuplicationHelper(existingModules: Set[String]) {
val prefix = path.last._2.value + "___"
val postfix = top + "_" + path.map { case (i, m) => i.value }.mkString("_")
val ns = mutable.HashSet(allModules.toSeq: _*)
- val finalName = firrtl.passes.Uniquify.findValidPrefix(prefix, Seq(postfix), ns) + postfix
+ val finalName = firrtl.Namespace.findValidPrefix(prefix, Seq(postfix), ns) + postfix
allModules += finalName
cachedNames((top, path)) = finalName
finalName
diff --git a/src/main/scala/firrtl/passes/Inline.scala b/src/main/scala/firrtl/passes/Inline.scala
index 316878fb..ad9c108f 100644
--- a/src/main/scala/firrtl/passes/Inline.scala
+++ b/src/main/scala/firrtl/passes/Inline.scala
@@ -20,11 +20,35 @@ case class InlineAnnotation(target: Named) extends SingleTargetAnnotation[Named]
def duplicate(n: Named) = InlineAnnotation(n)
}
+object InlineInstances {
+
+ /** Enumerates all possible names for a given type. For example:
+ * {{{
+ * foo : { bar : { a, b }[2], c }
+ * => foo, foo bar, foo bar 0, foo bar 1, foo bar 0 a, foo bar 0 b, foo bar 1 a, foo bar 1 b, foo c
+ * }}}
+ */
+ private def enumerateNames(tpe: Type): Seq[Seq[String]] = tpe match {
+ case t: BundleType =>
+ t.fields.flatMap { f =>
+ (enumerateNames(f.tpe).map(f.name +: _)) ++ Seq(Seq(f.name))
+ }
+ case t: VectorType =>
+ ((0 until t.size).map(i => Seq(i.toString))) ++
+ ((0 until t.size).flatMap { i =>
+ enumerateNames(t.tpe).map(i.toString +: _)
+ })
+ case _ => Seq()
+ }
+
+}
+
/** Inline instances as indicated by existing [[InlineAnnotation]]s
* @note Only use on legal Firrtl. Specifically, the restriction of instance loops must have been checked, or else this
* pass can infinitely recurse.
*/
class InlineInstances extends Transform with DependencyAPIMigration with RegisteredTransform {
+ import InlineInstances._
override def prerequisites = Forms.LowForm
override def optionalPrerequisites = Seq.empty
@@ -296,16 +320,16 @@ class InlineInstances extends Transform with DependencyAPIMigration with Registe
cache.getOrElseUpdate(module, Block(ports :+ toInline.body).map(onStmt(module)))
}
- val names = "" +: Uniquify
- .enumerateNames(Uniquify.stmtToType(bodyx)(NoInfo, ""))
- .map(_.mkString("_"))
+ val names = "" +:
+ enumerateNames(Utils.stmtToType(bodyx))
+ .map(_.mkString("_"))
/** The returned prefix will not be "prefix unique". It may be the same as other existing prefixes in the namespace.
* However, prepending this prefix to all inlined components is guaranteed to not conflict with this module's
* namespace. To make it prefix unique, this requires expanding all names in the namespace to include their
* prefixes before calling findValidPrefix.
*/
- val safePrefix = Uniquify.findValidPrefix(instName + inlineDelim, names, ns.cloneUnderlying - instName)
+ val safePrefix = Namespace.findValidPrefix(instName + inlineDelim, names, ns.cloneUnderlying - instName)
val prefixMap = mutable.HashMap.empty[String, String]
val inlineTarget = currentModule.instOf(instName, modName)
diff --git a/src/main/scala/firrtl/passes/RemoveAccesses.scala b/src/main/scala/firrtl/passes/RemoveAccesses.scala
index 015346ff..d8d32b26 100644
--- a/src/main/scala/firrtl/passes/RemoveAccesses.scala
+++ b/src/main/scala/firrtl/passes/RemoveAccesses.scala
@@ -25,8 +25,8 @@ object RemoveAccesses extends Pass {
) ++ firrtl.stage.Forms.Deduped
override def invalidates(a: Transform): Boolean = a match {
- case Uniquify | ResolveKinds | ResolveFlows => true
- case _ => false
+ case ResolveKinds | ResolveFlows => true
+ case _ => false
}
private def AND(e1: Expression, e2: Expression) =
diff --git a/src/main/scala/firrtl/passes/Uniquify.scala b/src/main/scala/firrtl/passes/Uniquify.scala
index bc48ebbc..57ef11fa 100644
--- a/src/main/scala/firrtl/passes/Uniquify.scala
+++ b/src/main/scala/firrtl/passes/Uniquify.scala
@@ -31,6 +31,7 @@ import MemPortUtils.memType
* there WOULD be collisions in references a[0] and a_0 so we still have
* to rename a
*/
+@deprecated("Uniquify is now part of LowerTypes", "FIRRTL 1.4.0")
object Uniquify extends Transform with DependencyAPIMigration {
override def prerequisites =
@@ -51,77 +52,17 @@ object Uniquify extends Transform with DependencyAPIMigration {
/** Appends delim to prefix until no collisions of prefix + elts in names We don't add an _ in the collision check
* because elts could be Seq("") In this case, we're just really checking if prefix itself collides
*/
- @tailrec
+ @deprecated("Use firrtl.Namespace.findValidPrefix", "FIRRTL 1.4.0")
def findValidPrefix(
prefix: String,
elts: Seq[String],
namespace: collection.mutable.HashSet[String]
- ): String = {
- elts.find(elt => namespace.contains(prefix + elt)) match {
- case Some(_) => findValidPrefix(prefix + "_", elts, namespace)
- case None => prefix
- }
- }
-
- /** Enumerates all possible names for a given type. For example:
- * {{{
- * foo : { bar : { a, b }[2], c }
- * => foo, foo bar, foo bar 0, foo bar 1, foo bar 0 a, foo bar 0 b, foo bar 1 a, foo bar 1 b, foo c
- * }}}
- */
- private[firrtl] def enumerateNames(tpe: Type): Seq[Seq[String]] = tpe match {
- case t: BundleType =>
- t.fields.flatMap { f =>
- (enumerateNames(f.tpe).map(f.name +: _)) ++ Seq(Seq(f.name))
- }
- case t: VectorType =>
- ((0 until t.size).map(i => Seq(i.toString))) ++
- ((0 until t.size).flatMap { i =>
- enumerateNames(t.tpe).map(i.toString +: _)
- })
- case _ => Seq()
- }
+ ): String = Namespace.findValidPrefix(prefix, elts, namespace)
/** Creates a Bundle Type from a Stmt */
- def stmtToType(s: Statement)(implicit sinfo: Info, mname: String): BundleType = {
- // Recursive helper
- def recStmtToType(s: Statement): Seq[Field] = s match {
- case sx: DefWire => Seq(Field(sx.name, Default, sx.tpe))
- case sx: DefRegister => Seq(Field(sx.name, Default, sx.tpe))
- case sx: WDefInstance => Seq(Field(sx.name, Default, sx.tpe))
- case sx: DefMemory =>
- sx.dataType match {
- case (_: UIntType | _: SIntType | _: FixedType) =>
- Seq(Field(sx.name, Default, memType(sx)))
- case tpe: BundleType =>
- val newFields = tpe.fields
- .map(f =>
- DefMemory(
- sx.info,
- f.name,
- f.tpe,
- sx.depth,
- sx.writeLatency,
- sx.readLatency,
- sx.readers,
- sx.writers,
- sx.readwriters
- )
- )
- .flatMap(recStmtToType)
- Seq(Field(sx.name, Default, BundleType(newFields)))
- case tpe: VectorType =>
- val newFields =
- (0 until tpe.size).map(i => sx.copy(name = i.toString, dataType = tpe.tpe)).flatMap(recStmtToType)
- Seq(Field(sx.name, Default, BundleType(newFields)))
- }
- case sx: DefNode => Seq(Field(sx.name, Default, sx.value.tpe))
- case sx: Conditionally => recStmtToType(sx.conseq) ++ recStmtToType(sx.alt)
- case sx: Block => (sx.stmts.map(recStmtToType)).flatten
- case sx => Seq()
- }
- BundleType(recStmtToType(s))
- }
+ @deprecated("Use firrtl.Utils.stmtToType", "FIRRTL 1.4.0")
+ def stmtToType(s: Statement)(implicit sinfo: Info, mname: String): BundleType =
+ Utils.stmtToType(s)
// Accepts a Type and an initial namespace
// Returns new Type with uniquified names
@@ -136,7 +77,7 @@ object Uniquify extends Transform with DependencyAPIMigration {
case tx: BundleType =>
// First add everything
val newFieldsAndElts = tx.fields.map { f =>
- val newName = findValidPrefix(f.name, Seq(""), namespace)
+ val newName = Namespace.findValidPrefix(f.name, Seq(""), namespace)
namespace += newName
Field(newName, f.flip, f.tpe)
}.map { f =>
@@ -146,7 +87,7 @@ object Uniquify extends Transform with DependencyAPIMigration {
val (tpe, eltsx) = recUniquifyNames(f.tpe, collection.mutable.HashSet())
// Need leading _ for findValidPrefix, it doesn't add _ for checks
val eltsNames: Seq[String] = eltsx.map(e => "_" + e)
- val prefix = findValidPrefix(f.name, eltsNames, namespace)
+ val prefix = Namespace.findValidPrefix(f.name, eltsNames, namespace)
// We added f.name in previous map, delete if we change it
if (prefix != f.name) {
namespace -= f.name
diff --git a/src/main/scala/firrtl/transforms/RemoveKeywordCollisions.scala b/src/main/scala/firrtl/transforms/RemoveKeywordCollisions.scala
index ae3bc693..216dd7c1 100644
--- a/src/main/scala/firrtl/transforms/RemoveKeywordCollisions.scala
+++ b/src/main/scala/firrtl/transforms/RemoveKeywordCollisions.scala
@@ -6,7 +6,6 @@ import firrtl._
import firrtl.Utils.v_keywords
import firrtl.options.Dependency
-import firrtl.passes.Uniquify
/** Transform that removes collisions with reserved keywords
* @param keywords a set of reserved words
@@ -23,7 +22,7 @@ class RemoveKeywordCollisions(keywords: Set[String]) extends ManipulateNames {
*/
override def manipulate = (n: String, ns: Namespace) =>
keywords.contains(n) match {
- case true => Some(Uniquify.findValidPrefix(n + inlineDelim, Seq(""), ns.cloneUnderlying ++ keywords))
+ case true => Some(Namespace.findValidPrefix(n + inlineDelim, Seq(""), ns.cloneUnderlying ++ keywords))
case false => None
}