Skip to content

Commit b0f0c5a

Browse files
Specialize Index for literal indices with LitIndex (backport #4268) (#4274)
* Specialize Index for literal indices with LitIndex (#4268) This saves 16-bytes per Vec element. (cherry picked from commit c107e31) # Conflicts: # core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala # src/main/scala/chisel3/aop/Select.scala # src/main/scala/chisel3/util/SRAM.scala * Resolve backport conflicts --------- Co-authored-by: Jack Koenig <koenig@sifive.com>
1 parent a2382c2 commit b0f0c5a

File tree

8 files changed

+30
-12
lines changed

8 files changed

+30
-12
lines changed

binder/src/main/scala/PanamaCIRCTConverter.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ class PanamaCIRCTConverter extends CIRCTConverter {
368368
binding.parent match {
369369
case vec: Vec[_] =>
370370
data.getRef match {
371+
case LitIndex(_, index) => Reference.SubIndex(index, tpe)
371372
case Index(_, ILit(index)) => Reference.SubIndex(index.toInt, tpe)
372373
case Index(_, dynamicIndex) =>
373374
val index = referTo(dynamicIndex, srcInfo)

core/src/main/scala/chisel3/experimental/hierarchy/core/Lookupable.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import scala.annotation.implicitNotFound
99
import scala.collection.mutable.HashMap
1010
import chisel3._
1111
import chisel3.experimental.dataview.{isView, reify, reifyIdentityView}
12-
import chisel3.internal.firrtl.ir.{Arg, ILit, Index, ModuleIO, Slot, ULit}
12+
import chisel3.internal.firrtl.ir.{Arg, ILit, Index, LitIndex, ModuleIO, Slot, ULit}
1313
import chisel3.internal.{
1414
throwException,
1515
AggregateViewBinding,
@@ -135,7 +135,7 @@ object Lookupable {
135135
def unrollCoordinates(res: List[Arg], d: Data): (List[Arg], Data) = d.binding.get match {
136136
case ChildBinding(parent) =>
137137
d.getRef match {
138-
case arg @ (_: Slot | _: Index | _: ModuleIO) => unrollCoordinates(arg :: res, parent)
138+
case arg @ (_: Slot | _: Index | _: LitIndex | _: ModuleIO) => unrollCoordinates(arg :: res, parent)
139139
case other => err(s"unrollCoordinates failed for '$arg'! Unexpected arg '$other'")
140140
}
141141
case _ => (res, d)
@@ -146,6 +146,7 @@ object Lookupable {
146146
else {
147147
val next = (coor.head, d) match {
148148
case (Slot(_, name), rec: Record) => rec._elements(name)
149+
case (LitIndex(_, n), vec: Vec[_]) => vec.apply(n)
149150
case (Index(_, ILit(n)), vec: Vec[_]) => vec.apply(n.toInt)
150151
case (ModuleIO(_, name), rec: Record) => rec._elements(name)
151152
case (arg, _) => err(s"Unexpected Arg '$arg' applied to '$d'! Root was '$start'.")

core/src/main/scala/chisel3/internal/Builder.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,11 @@ private[chisel3] trait HasId extends chisel3.InstanceId {
264264
else setRef(OpaqueSlot(parent))
265265
}
266266

267-
private[chisel3] def setRef(parent: Node, index: Int): Unit = setRef(Index(parent, ILit(index)))
268-
private[chisel3] def setRef(parent: Node, index: UInt): Unit = setRef(Index(parent, index.ref))
267+
private[chisel3] def setRef(parent: Node, index: Int): Unit = setRef(LitIndex(parent, index))
268+
private[chisel3] def setRef(parent: Node, index: UInt): Unit = index.litOption match {
269+
case Some(lit) if lit.isValidInt => setRef(LitIndex(parent, lit.intValue))
270+
case _ => setRef(Index(parent, index.ref))
271+
}
269272
private[chisel3] def getRef: Arg = _ref.get
270273
private[chisel3] def getOptionRef: Option[Arg] = _ref
271274

@@ -627,6 +630,7 @@ private[chisel3] object Builder extends LazyLogging {
627630
case Slot(_, field) => Some(field) // Record
628631
case OpaqueSlot(_) => None // OpaqueSlots don't contribute to the name
629632
case Index(_, ILit(n)) => Some(n.toString) // Vec static indexing
633+
case LitIndex(_, n) => Some(n.toString) // Vec static indexing
630634
case Index(_, ULit(n, _)) => Some(n.toString) // Vec lit indexing
631635
case Index(_, _: Node) => None // Vec dynamic indexing
632636
case ModuleIO(_, n) => Some(n) // BlackBox port

core/src/main/scala/chisel3/internal/firrtl/Converter.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ private[chisel3] object Converter {
7171
fir.SubField(convert(imm, ctx, info), name, fir.UnknownType)
7272
case OpaqueSlot(imm) =>
7373
convert(imm, ctx, info)
74+
case LitIndex(imm, idx) =>
75+
fir.SubIndex(convert(imm, ctx, info), idx, fir.UnknownType)
7476
case Index(imm, ILit(idx)) =>
7577
fir.SubIndex(convert(imm, ctx, info), castToInt(idx, "Index"), fir.UnknownType)
7678
case Index(imm, value) =>

core/src/main/scala/chisel3/internal/firrtl/IR.scala

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,11 @@ private[chisel3] object ir {
9696
def earlyLocalName(id: HasId, includeRoot: Boolean): String = id.getOptionRef match {
9797
case Some(Index(Node(imm), Node(value))) =>
9898
s"${earlyLocalName(imm, includeRoot)}[${earlyLocalName(value, includeRoot)}]"
99-
case Some(Index(Node(imm), arg)) => s"${earlyLocalName(imm, includeRoot)}[${arg.localName}]"
100-
case Some(Slot(Node(imm), name)) => s"${earlyLocalName(imm, includeRoot)}.$name"
101-
case Some(OpaqueSlot(Node(imm))) => s"${earlyLocalName(imm, includeRoot)}"
102-
case Some(arg) if includeRoot => arg.name
99+
case Some(LitIndex(Node(imm), idx)) => s"${earlyLocalName(imm, includeRoot)}[$idx]"
100+
case Some(Index(Node(imm), arg)) => s"${earlyLocalName(imm, includeRoot)}[${arg.localName}]"
101+
case Some(Slot(Node(imm), name)) => s"${earlyLocalName(imm, includeRoot)}.$name"
102+
case Some(OpaqueSlot(Node(imm))) => s"${earlyLocalName(imm, includeRoot)}"
103+
case Some(arg) if includeRoot => arg.name
103104
case None if includeRoot =>
104105
id match {
105106
case data: Data => data._computeName(Some("?")).get
@@ -251,6 +252,13 @@ private[chisel3] object ir {
251252
override def localName: String = s"${imm.localName}[${value.localName}]"
252253
}
253254

255+
// Like index above, except the index is a literal, used for elements of Vecs
256+
case class LitIndex(imm: Arg, value: Int) extends Arg {
257+
def name: String = s"[$value]"
258+
override def contextualName(ctx: Component): String = s"${imm.contextualName(ctx)}[$value]"
259+
override def localName: String = s"${imm.localName}[$value]"
260+
}
261+
254262
sealed trait ProbeDetails { this: Arg =>
255263
val probe: Arg
256264
override def name: String = s"$probe"

src/main/scala/chisel3/aop/Select.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,9 +474,10 @@ object Select {
474474
// Given a loc, return all subcomponents of id that could be assigned to in connect
475475
private def getEffected(a: Arg): Seq[Data] = a match {
476476
case Node(id: Data) => DataMirror.collectAllMembers(id)
477-
case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name))
478-
case Index(imm, _) => getEffected(imm)
479-
case _ => throw new InternalErrorException("Match error: a=$a")
477+
case Slot(imm, name) => Seq(imm.id.asInstanceOf[Record].elements(name))
478+
case Index(imm, _) => getEffected(imm)
479+
case LitIndex(imm, _) => getEffected(imm)
480+
case _ => throw new InternalErrorException("Match error: a=$a")
480481
}
481482

482483
// Given an arg, return the corresponding id. Don't use on a loc of a connect.

src/test/scala/chiselTests/DataPrint.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class DataPrintSpec extends ChiselFlatSpec with Matchers {
6262
}))
6363
port.vec(idx).toString should be("BoundDataModule.port.vec[idx]: IO[UInt<8>]")
6464
port.vec(jdx.value).toString should be("BoundDataModule.port.vec[jdx.value]: IO[UInt<8>]")
65+
port.vec(3.U).toString should be("BoundDataModule.port.vec[3]: IO[UInt<8>]")
6566

6667
class InnerModule extends Module {
6768
val io = IO(Output(new Bundle {

src/test/scala/chiselTests/Vec.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ class VecSpec extends ChiselPropSpec with Utils {
431431
val out = IO(Output(UInt(8.W)))
432432
out := vec(10.U)
433433
}))
434-
chirrtl should include("""connect out, vec[UInt<2>(0h2)]""")
434+
chirrtl should include("""connect out, vec[2]""")
435435
log should include("Dynamic index with width 4 is too wide for Vec of size 4 (expected index width 2)")
436436
}
437437

0 commit comments

Comments
 (0)