aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Koenig2017-02-06 17:21:48 -0800
committerGitHub2017-02-06 17:21:48 -0800
commitfc6c84bc3ee75aaeb7a64a9b05823b9443fdca13 (patch)
treee3898d875a7021d3551c1c9de3e3937b8445c139
parent4f83c9b610a23893b0c83ab36c62f21f6c0a8e94 (diff)
Fix stack overflow from massive MaxWidth chains during width inference (#407)
Fixes ucb-bar/chisel3#420
-rw-r--r--src/main/scala/firrtl/passes/InferWidths.scala13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/main/scala/firrtl/passes/InferWidths.scala b/src/main/scala/firrtl/passes/InferWidths.scala
index 36466c09..397a5d91 100644
--- a/src/main/scala/firrtl/passes/InferWidths.scala
+++ b/src/main/scala/firrtl/passes/InferWidths.scala
@@ -18,13 +18,16 @@ object InferWidths extends Pass {
def solve_constraints(l: Seq[WGeq]): ConstraintMap = {
def unique(ls: Seq[Width]) : Seq[Width] =
(ls map (new WrappedWidth(_))).distinct map (_.w)
+ // Combines constraints on the same VarWidth into the same constraint
def make_unique(ls: Seq[WGeq]): ListMap[String,Width] = {
- (ls foldLeft ListMap[String, Width]())((h, g) => g.loc match {
- case w: VarWidth => h get w.name match {
- case None => h + (w.name -> g.exp)
- case Some(p) => h + (w.name -> MaxWidth(Seq(g.exp, p)))
+ ls.foldLeft(ListMap.empty[String, Width])((acc, wgeq) => wgeq.loc match {
+ case VarWidth(name) => acc.get(name) match {
+ case None => acc + (name -> wgeq.exp)
+ // Avoid constructing massive MaxWidth chains
+ case Some(MaxWidth(args)) => acc + (name -> MaxWidth(wgeq.exp +: args))
+ case Some(width) => acc + (name -> MaxWidth(Seq(wgeq.exp, width)))
}
- case _ => h
+ case _ => acc
})
}
def pullMinMax(w: Width): Width = w map pullMinMax match {