aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/passes/RemoveAccesses.scala
diff options
context:
space:
mode:
authorJack Koenig2021-03-29 10:21:26 -0700
committerGitHub2021-03-29 17:21:26 +0000
commita41af6f0a34f9e13866002f19040a40ef55ee9e5 (patch)
tree6ef270e7cc4e848940c00cda0b9518d5a7481761 /src/main/scala/firrtl/passes/RemoveAccesses.scala
parentabeff01f0714d5474b9d18d78fc13011e5ad6b99 (diff)
Fix RemoveAccesses, delete CSESubAccesses (#2157)
CSESubAccesses was intended to be a simple workaround for a quadratic performance bug in RemoveAccesses but ended up having tricky corner cases and was hard to get right. The solution to the RemoveAccesses bug--quadratic expansion of dynamic indexes of vecs of aggreate type--turned out to be quite simple and makes CSESubAccesses much less useful and not worth fixing. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Diffstat (limited to 'src/main/scala/firrtl/passes/RemoveAccesses.scala')
-rw-r--r--src/main/scala/firrtl/passes/RemoveAccesses.scala63
1 files changed, 35 insertions, 28 deletions
diff --git a/src/main/scala/firrtl/passes/RemoveAccesses.scala b/src/main/scala/firrtl/passes/RemoveAccesses.scala
index 7449db51..073bf49d 100644
--- a/src/main/scala/firrtl/passes/RemoveAccesses.scala
+++ b/src/main/scala/firrtl/passes/RemoveAccesses.scala
@@ -9,7 +9,6 @@ import firrtl.Mappers._
import firrtl.Utils._
import firrtl.WrappedExpression._
import firrtl.options.Dependency
-import firrtl.transforms.CSESubAccesses
import scala.collection.mutable
@@ -22,8 +21,7 @@ object RemoveAccesses extends Pass {
Dependency(PullMuxes),
Dependency(ZeroLengthVecs),
Dependency(ReplaceAccesses),
- Dependency(ExpandConnects),
- Dependency[CSESubAccesses]
+ Dependency(ExpandConnects)
) ++ firrtl.stage.Forms.Deduped
override def invalidates(a: Transform): Boolean = a match {
@@ -122,26 +120,26 @@ object RemoveAccesses extends Pass {
/** Replaces a subaccess in a given source expression
*/
val stmts = mutable.ArrayBuffer[Statement]()
- def removeSource(e: Expression): Expression = e match {
- case (_: WSubAccess | _: WSubField | _: WSubIndex | _: WRef) if hasAccess(e) =>
- val rs = getLocations(e)
- rs.find(x => x.guard != one) match {
- case None => throwInternalError(s"removeSource: shouldn't be here - $e")
- case Some(_) =>
- val (wire, temp) = create_temp(e)
- val temps = create_exps(temp)
- def getTemp(i: Int) = temps(i % temps.size)
- stmts += wire
- rs.zipWithIndex.foreach {
- case (x, i) if i < temps.size =>
- stmts += IsInvalid(get_info(s), getTemp(i))
- stmts += Conditionally(get_info(s), x.guard, Connect(get_info(s), getTemp(i), x.base), EmptyStmt)
- case (x, i) =>
- stmts += Conditionally(get_info(s), x.guard, Connect(get_info(s), getTemp(i), x.base), EmptyStmt)
- }
- temp
- }
- case _ => e
+ // Only called on RefLikes that definitely have a SubAccess
+ // Must accept Expression because that's the output type of fixIndices
+ def removeSource(e: Expression): Expression = {
+ val rs = getLocations(e)
+ rs.find(x => x.guard != one) match {
+ case None => throwInternalError(s"removeSource: shouldn't be here - $e")
+ case Some(_) =>
+ val (wire, temp) = create_temp(e)
+ val temps = create_exps(temp)
+ def getTemp(i: Int) = temps(i % temps.size)
+ stmts += wire
+ rs.zipWithIndex.foreach {
+ case (x, i) if i < temps.size =>
+ stmts += IsInvalid(get_info(s), getTemp(i))
+ stmts += Conditionally(get_info(s), x.guard, Connect(get_info(s), getTemp(i), x.base), EmptyStmt)
+ case (x, i) =>
+ stmts += Conditionally(get_info(s), x.guard, Connect(get_info(s), getTemp(i), x.base), EmptyStmt)
+ }
+ temp
+ }
}
/** Replaces a subaccess in a given sink expression
@@ -162,14 +160,23 @@ object RemoveAccesses extends Pass {
case _ => loc
}
+ /** Recurse until find SubAccess and call fixSource on its index
+ * @note this only accepts [[RefLikeExpression]]s but we can't enforce it because map
+ * requires Expression => Expression
+ */
+ def fixIndices(e: Expression): Expression = e match {
+ case e: SubAccess => e.copy(index = fixSource(e.index))
+ case other => other.map(fixIndices)
+ }
+
/** Recursively walks a source expression and fixes all subaccesses
- * If we see a sub-access, replace it.
- * Otherwise, map to children.
+ *
+ * If we see a RefLikeExpression that contains a SubAccess, we recursively remove
+ * subaccesses from the indices of any SubAccesses, then process modified RefLikeExpression
*/
def fixSource(e: Expression): Expression = e match {
- case w: WSubAccess => removeSource(WSubAccess(w.expr, fixSource(w.index), w.tpe, w.flow))
- //case w: WSubIndex => removeSource(w)
- //case w: WSubField => removeSource(w)
+ case ref: RefLikeExpression =>
+ if (hasAccess(ref)) removeSource(fixIndices(ref)) else ref
case x => x.map(fixSource)
}