diff options
| author | Albert Chen | 2020-09-09 12:25:20 -0700 |
|---|---|---|
| committer | GitHub | 2020-09-09 19:25:20 +0000 |
| commit | bc7ac7013ecdf956b7cd61f0f0a60c7272d49cd6 (patch) | |
| tree | 5bc54ffb5d87fa363b2edfbc4a0b6e6cae7ad3fd /src/main | |
| parent | e420f99d87ece9f56504b3afc2e37d40b6e8c7b1 (diff) | |
Loosen inlining restrictions (#1882)
* test multiinfo comparison and mux cond inlining
* loosen inlining conditions
* fix typo
* include dshlw
* fix test
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala b/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala index b405f353..29bdde0f 100644 --- a/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala +++ b/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala @@ -61,20 +61,21 @@ class InlineBooleanExpressions extends Transform with DependencyAPIMigration { } private val fileLineRegex = """(.*) ([0-9]+):[0-9]+""".r - private def sameFileAndLineInfo(info1: Info, info2: Info): Boolean = { - (info1, info2) match { - case (FileInfo(fileLineRegex(file1, line1)), FileInfo(fileLineRegex(file2, line2))) => - (file1 == file2) && (line1 == line2) - case (MultiInfo(infos1), MultiInfo(infos2)) if infos1.size == infos2.size => - infos1.zip(infos2).forall { - case (i1, i2) => - sameFileAndLineInfo(i1, i2) - } - case (NoInfo, NoInfo) => true - case _ => false + private def getFileAndLineNumbers(info: Info): Set[(String, String)] = { + info match { + case FileInfo(fileLineRegex(file, line)) => Set(file -> line) + case FileInfo(file) => Set(file -> "0") + case MultiInfo(infos) => infos.flatMap(getFileAndLineNumbers).toSet + case NoInfo => Set.empty[(String, String)] } } + private def sameFileAndLineInfo(info1: Info, info2: Info): Boolean = { + val set1 = getFileAndLineNumbers(info1) + val set2 = getFileAndLineNumbers(info2) + set1.subsetOf(set2) + } + /** A helper class to initialize and store mutable state that the expression * and statement map functions need access to. This makes it easier to pass * information around without having to plump arguments through the onExpr @@ -86,22 +87,34 @@ class InlineBooleanExpressions extends Transform with DependencyAPIMigration { var inlineCount: Int = 1 /** Whether or not an can be inlined + * @param ref the WRef that references refExpr * @param refExpr the expression to check for inlining * @param outerExpr the parent expression of refExpr, if any */ - def canInline(refExpr: Expression, outerExpr: Option[Expression]): Boolean = { + def canInline(ref: WRef, refExpr: Expression, outerExpr: Option[Expression]): Boolean = { val contextInsensitiveDetOps: Set[PrimOp] = Set(Lt, Leq, Gt, Geq, Eq, Neq, Andr, Orr, Xorr) outerExpr match { case None => true - case Some(o) if (o.tpe == Utils.BoolType) => - refExpr match { - case _: Mux => false - case e => e.tpe == Utils.BoolType - } case Some(o) => - refExpr match { - case DoPrim(op, _, _, Utils.BoolType) => contextInsensitiveDetOps(op) - case _ => false + if ((refExpr.tpe != Utils.BoolType) || refExpr.isInstanceOf[Mux]) { + false + } else { + o match { + // if outer expression is also boolean context does not affect width + case o if o.tpe == Utils.BoolType => true + + // mux condition argument is self-determined + case m: Mux if m.cond eq ref => true + + // dshl/dshr second argument is self-determined + case DoPrim(Dshl | Dshlw | Dshr, Seq(_, shamt), _, _) if shamt eq ref => true + + case o => + refExpr match { + case DoPrim(op, _, _, _) => contextInsensitiveDetOps(op) + case _ => false + } + } } } } @@ -118,10 +131,10 @@ class InlineBooleanExpressions extends Transform with DependencyAPIMigration { case ref: WRef if !dontTouches.contains(ref.name.Ref) && ref.name.head == '_' => val refKey = ref.name.Ref netlist.get(we(ref)) match { - case Some((refExpr, refInfo)) if sameFileAndLineInfo(info, refInfo) => + case Some((refExpr, refInfo)) if sameFileAndLineInfo(refInfo, info) => val inlineNum = inlineCounts.getOrElse(refKey, 1) val notTooDeep = !outerExpr.isDefined || ((inlineNum + inlineCount) <= maxInlineCount) - if (canInline(refExpr, outerExpr) && notTooDeep) { + if (canInline(ref, refExpr, outerExpr) && notTooDeep) { inlineCount += inlineNum refExpr } else { |
