aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/options/DependencyManager.scala
diff options
context:
space:
mode:
authorchick2020-08-14 19:47:53 -0700
committerJack Koenig2020-08-14 19:47:53 -0700
commit6fc742bfaf5ee508a34189400a1a7dbffe3f1cac (patch)
tree2ed103ee80b0fba613c88a66af854ae9952610ce /src/main/scala/firrtl/options/DependencyManager.scala
parentb516293f703c4de86397862fee1897aded2ae140 (diff)
All of src/ formatted with scalafmt
Diffstat (limited to 'src/main/scala/firrtl/options/DependencyManager.scala')
-rw-r--r--src/main/scala/firrtl/options/DependencyManager.scala181
1 files changed, 98 insertions, 83 deletions
diff --git a/src/main/scala/firrtl/options/DependencyManager.scala b/src/main/scala/firrtl/options/DependencyManager.scala
index ee6a7404..561e32ab 100644
--- a/src/main/scala/firrtl/options/DependencyManager.scala
+++ b/src/main/scala/firrtl/options/DependencyManager.scala
@@ -3,7 +3,7 @@
package firrtl.options
import firrtl.AnnotationSeq
-import firrtl.graph.{DiGraph, CyclicException}
+import firrtl.graph.{CyclicException, DiGraph}
import scala.collection.Set
import scala.collection.immutable.{Set => ISet}
@@ -22,7 +22,6 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
override def prerequisites = currentState
-
override def optionalPrerequisites = Seq.empty
override def optionalPrerequisiteOf = Seq.empty
@@ -34,13 +33,13 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
*/
def targets: Seq[Dependency[B]]
private lazy val _targets: LinkedHashSet[Dependency[B]] = targets
- .foldLeft(new LinkedHashSet[Dependency[B]]()){ case (a, b) => a += b }
+ .foldLeft(new LinkedHashSet[Dependency[B]]()) { case (a, b) => a += b }
/** A sequence of [[firrtl.Transform]]s that have been run. Internally, this will be converted to an ordered set.
*/
def currentState: Seq[Dependency[B]]
private lazy val _currentState: LinkedHashSet[Dependency[B]] = currentState
- .foldLeft(new LinkedHashSet[Dependency[B]]()){ case (a, b) => a += b }
+ .foldLeft(new LinkedHashSet[Dependency[B]]()) { case (a, b) => a += b }
/** Existing transform objects that have already been constructed */
def knownObjects: Set[B]
@@ -64,9 +63,10 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
* requirements. This is used to solve sub-problems arising from invalidations.
*/
protected def copy(
- targets: Seq[Dependency[B]],
+ targets: Seq[Dependency[B]],
currentState: Seq[Dependency[B]],
- knownObjects: ISet[B] = dependencyToObject.values.toSet): B
+ knownObjects: ISet[B] = dependencyToObject.values.toSet
+ ): B
/** Implicit conversion from Dependency to B */
private implicit def dToO(d: Dependency[B]): B = dependencyToObject.getOrElseUpdate(d, d.getObject())
@@ -77,14 +77,16 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
/** Modified breadth-first search that supports multiple starting nodes and a custom extractor that can be used to
* generate/filter the edges to explore. Additionally, this will include edges to previously discovered nodes.
*/
- private def bfs( start: LinkedHashSet[Dependency[B]],
- blacklist: LinkedHashSet[Dependency[B]],
- extractor: B => Set[Dependency[B]] ): LinkedHashMap[B, LinkedHashSet[B]] = {
+ private def bfs(
+ start: LinkedHashSet[Dependency[B]],
+ blacklist: LinkedHashSet[Dependency[B]],
+ extractor: B => Set[Dependency[B]]
+ ): LinkedHashMap[B, LinkedHashSet[B]] = {
val (queue, edges) = {
- val a: Queue[Dependency[B]] = Queue(start.toSeq:_*)
- val b: LinkedHashMap[B, LinkedHashSet[B]] = LinkedHashMap[B, LinkedHashSet[B]](
- start.map((dToO(_) -> LinkedHashSet[B]())).toSeq:_*)
+ val a: Queue[Dependency[B]] = Queue(start.toSeq: _*)
+ val b: LinkedHashMap[B, LinkedHashSet[B]] =
+ LinkedHashMap[B, LinkedHashSet[B]](start.map((dToO(_) -> LinkedHashSet[B]())).toSeq: _*)
(a, b)
}
@@ -117,7 +119,8 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
val edges = bfs(
start = _targets &~ _currentState,
blacklist = _currentState,
- extractor = (p: B) => p._prerequisites &~ _currentState)
+ extractor = (p: B) => p._prerequisites &~ _currentState
+ )
DiGraph(edges)
}
@@ -144,11 +147,14 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
val edges = {
val x = new LinkedHashMap ++ _targets
.map(dependencyToObject)
- .map{ a => a -> prerequisiteGraph.getVertices.filter(a._optionalPrerequisiteOf(_)) }
- x
- .values
+ .map { a => a -> prerequisiteGraph.getVertices.filter(a._optionalPrerequisiteOf(_)) }
+ x.values
.reduce(_ ++ _)
- .foldLeft(x){ case (xx, y) => if (xx.contains(y)) { xx } else { xx ++ Map(y -> Set.empty[B]) } }
+ .foldLeft(x) {
+ case (xx, y) =>
+ if (xx.contains(y)) { xx }
+ else { xx ++ Map(y -> Set.empty[B]) }
+ }
}
DiGraph(edges).reverse
}
@@ -165,23 +171,26 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
bfs(
start = v.map(oToD(_)),
blacklist = _currentState,
-
/* Explore all invalidated transforms **EXCEPT** the current transform! */
extractor = (p: B) => {
val filtered = new LinkedHashSet[Dependency[B]]
filtered ++= v.filter(p.invalidates).map(oToD(_))
filtered -= oToD(p)
filtered
- })
+ }
+ )
).reverse
}
/** Wrap a possible [[CyclicException]] thrown by a thunk in a [[DependencyManagerException]] */
- private def cyclePossible[A](a: String, diGraph: DiGraph[_])(thunk: => A): A = try { thunk } catch {
+ private def cyclePossible[A](a: String, diGraph: DiGraph[_])(thunk: => A): A = try { thunk }
+ catch {
case e: CyclicException =>
throw new DependencyManagerException(
s"""|No transform ordering possible due to cyclic dependency in $a with cycles:
- |${diGraph.findSCCs.filter(_.size > 1).mkString(" - ", "\n - ", "")}""".stripMargin, e)
+ |${diGraph.findSCCs.filter(_.size > 1).mkString(" - ", "\n - ", "")}""".stripMargin,
+ e
+ )
}
/** An ordering of [[firrtl.options.TransformLike TransformLike]]s that causes the requested [[DependencyManager.targets
@@ -198,38 +207,39 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
*/
val sorted = {
val edges = {
- val v = cyclePossible("invalidates", invalidateGraph){ invalidateGraph.linearize }.reverse
+ val v = cyclePossible("invalidates", invalidateGraph) { invalidateGraph.linearize }.reverse
/* A comparison function that will sort vertices based on the topological sort of the invalidation graph */
val cmp =
- (l: B, r: B) => v.foldLeft((Map.empty[B, Dependency[B] => Boolean], Set.empty[Dependency[B]])){
- case ((m, s), r) => (m + (r -> ((a: Dependency[B]) => !s(a))), s + r) }._1(l)(r)
+ (l: B, r: B) =>
+ v.foldLeft((Map.empty[B, Dependency[B] => Boolean], Set.empty[Dependency[B]])) {
+ case ((m, s), r) => (m + (r -> ((a: Dependency[B]) => !s(a))), s + r)
+ }._1(l)(r)
new LinkedHashMap() ++
v.map(vv => vv -> (new LinkedHashSet() ++ (dependencyGraph.getEdges(vv).toSeq.sortWith(cmp))))
}
cyclePossible("prerequisites", dependencyGraph) {
- DiGraph(edges)
- .linearize
- .reverse
+ DiGraph(edges).linearize.reverse
.dropWhile(b => _currentState.contains(b))
}
}
/* [todo] Seq is inefficient here, but Array has ClassTag problems. Use something else? */
- val (s, l) = sorted.foldLeft((_currentState, Seq[B]())){ case ((state, out), in) =>
- val prereqs = in._prerequisites ++
- dependencyGraph.getEdges(in).toSeq.map(oToD) ++
- otherPrerequisites.getEdges(in).toSeq.map(oToD)
- val preprocessing: Option[B] = {
- if ((prereqs -- state).nonEmpty) { Some(this.copy(prereqs.toSeq, state.toSeq)) }
- else { None }
- }
- /* "in" is added *after* invalidation because a transform my not invalidate itself! */
- ((state ++ prereqs).map(dToO).filterNot(in.invalidates).map(oToD) + in, out ++ preprocessing :+ in)
+ val (s, l) = sorted.foldLeft((_currentState, Seq[B]())) {
+ case ((state, out), in) =>
+ val prereqs = in._prerequisites ++
+ dependencyGraph.getEdges(in).toSeq.map(oToD) ++
+ otherPrerequisites.getEdges(in).toSeq.map(oToD)
+ val preprocessing: Option[B] = {
+ if ((prereqs -- state).nonEmpty) { Some(this.copy(prereqs.toSeq, state.toSeq)) }
+ else { None }
+ }
+ /* "in" is added *after* invalidation because a transform my not invalidate itself! */
+ ((state ++ prereqs).map(dToO).filterNot(in.invalidates).map(oToD) + in, out ++ preprocessing :+ in)
}
val postprocessing: Option[B] = {
if ((_targets -- s).nonEmpty) { Some(this.copy(_targets.toSeq, s.toSeq)) }
- else { None }
+ else { None }
}
l ++ postprocessing
}
@@ -252,20 +262,21 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
* applied while tracking the state of the underlying A. If the state ever disagrees with a prerequisite, then this
* throws an exception.
*/
- flattenedTransformOrder
- .map{ t =>
- val w = wrappers.foldLeft(t){ case (tx, wrapper) => wrapper(tx) }
- wrapperToClass += (w -> t)
- w
- }.foldLeft((annotations, _currentState)){ case ((a, state), t) =>
- if (!t.prerequisites.toSet.subsetOf(state)) {
- throw new DependencyManagerException(
- s"""|Tried to execute '$t' for which run-time prerequisites were not satisfied:
- | state: ${state.mkString("\n -", "\n -", "")}
- | prerequisites: ${prerequisites.mkString("\n -", "\n -", "")}""".stripMargin)
- }
- (t.transform(a), ((state + wrapperToClass(t)).map(dToO).filterNot(t.invalidates).map(oToD)))
- }._1
+ flattenedTransformOrder.map { t =>
+ val w = wrappers.foldLeft(t) { case (tx, wrapper) => wrapper(tx) }
+ wrapperToClass += (w -> t)
+ w
+ }.foldLeft((annotations, _currentState)) {
+ case ((a, state), t) =>
+ if (!t.prerequisites.toSet.subsetOf(state)) {
+ throw new DependencyManagerException(
+ s"""|Tried to execute '$t' for which run-time prerequisites were not satisfied:
+ | state: ${state.mkString("\n -", "\n -", "")}
+ | prerequisites: ${prerequisites.mkString("\n -", "\n -", "")}""".stripMargin
+ )
+ }
+ (t.transform(a), ((state + wrapperToClass(t)).map(dToO).filterNot(t.invalidates).map(oToD)))
+ }._1
}
/** This colormap uses Colorbrewer's 4-class OrRd color scheme */
@@ -282,13 +293,13 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
def toGraphviz(digraph: DiGraph[B], attributes: String = "", tab: String = " "): Option[String] = {
val edges =
- digraph
- .getEdgeMap
- .collect{ case (v, edges) if edges.nonEmpty => (v -> edges) }
- .map{ case (v, edges) =>
- s"""${transformName(v)} -> ${edges.map(e => transformName(e)).mkString("{ ", " ", " }")}""" }
+ digraph.getEdgeMap.collect { case (v, edges) if edges.nonEmpty => (v -> edges) }.map {
+ case (v, edges) =>
+ s"""${transformName(v)} -> ${edges.map(e => transformName(e)).mkString("{ ", " ", " }")}"""
+ }
- if (edges.isEmpty) { None } else {
+ if (edges.isEmpty) { None }
+ else {
Some(
s"""| { $attributes
|${edges.mkString(tab, "\n" + tab, "")}
@@ -298,16 +309,16 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
}
val connections =
- Seq( (prerequisiteGraph, "edge []"),
- (optionalPrerequisiteOfGraph, """edge [style=bold color="#4292c6"]"""),
- (invalidateGraph, """edge [minlen=2 style=dashed constraint=false color="#fb6a4a"]"""),
- (optionalPrerequisitesGraph, """edge [style=dotted color="#a1d99b"]""") )
- .flatMap{ case (a, b) => toGraphviz(a, b) }
+ Seq(
+ (prerequisiteGraph, "edge []"),
+ (optionalPrerequisiteOfGraph, """edge [style=bold color="#4292c6"]"""),
+ (invalidateGraph, """edge [minlen=2 style=dashed constraint=false color="#fb6a4a"]"""),
+ (optionalPrerequisitesGraph, """edge [style=dotted color="#a1d99b"]""")
+ ).flatMap { case (a, b) => toGraphviz(a, b) }
.mkString("\n")
val nodes =
- (prerequisiteGraph + optionalPrerequisiteOfGraph + invalidateGraph + otherPrerequisites)
- .getVertices
+ (prerequisiteGraph + optionalPrerequisiteOfGraph + invalidateGraph + otherPrerequisites).getVertices
.map(v => s"""${transformName(v)} [label="${v.name}"]""")
s"""|digraph DependencyManager {
@@ -322,9 +333,9 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
def transformOrderToGraphviz(colormap: Seq[String] = colormap): String = {
def rotate[A](a: Seq[A]): Seq[A] = a match {
- case Nil => Nil
+ case Nil => Nil
case car :: cdr => cdr :+ car
- case car => car
+ case car => car
}
val sorted = ArrayBuffer.empty[String]
@@ -340,7 +351,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
|$tab labeljust=l
|$tab node [fillcolor="${cm.head}"]""".stripMargin
- val body = pm.transformOrder.map{
+ val body = pm.transformOrder.map {
case a: DependencyManager[A, B] =>
val (str, d) = rec(a, rotate(cm), tab + " ", offset + 1)
offset = d
@@ -369,9 +380,10 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
* @param size the number of nodes at the current level of the tree
*/
def customPrintHandling(
- tab: String,
+ tab: String,
charSet: CharSet,
- size: Int): Option[PartialFunction[(B, Int), Seq[String]]] = None
+ size: Int
+ ): Option[PartialFunction[(B, Int), Seq[String]]] = None
/** Helper utility when recursing during pretty printing
* @param tab an indentation string to use for every line of output
@@ -386,9 +398,9 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
val defaultHandling: PartialFunction[(B, Int), Seq[String]] = {
case (a: DependencyManager[_, _], `last`) =>
Seq(s"$tab$l ${a.name}") ++ a.prettyPrintRec(s"""$tab${" " * c.size} """, charSet)
- case (a: DependencyManager[_, _], _) => Seq(s"$tab$n ${a.name}") ++ a.prettyPrintRec(s"$tab$c ", charSet)
- case (a, `last`) => Seq(s"$tab$l ${a.name}")
- case (a, _) => Seq(s"$tab$n ${a.name}")
+ case (a: DependencyManager[_, _], _) => Seq(s"$tab$n ${a.name}") ++ a.prettyPrintRec(s"$tab$c ", charSet)
+ case (a, `last`) => Seq(s"$tab$l ${a.name}")
+ case (a, _) => Seq(s"$tab$n ${a.name}")
}
val handling = customPrintHandling(tab, charSet, transformOrder.size) match {
@@ -396,8 +408,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
case None => defaultHandling
}
- transformOrder
- .zipWithIndex
+ transformOrder.zipWithIndex
.flatMap(handling)
}
@@ -406,8 +417,9 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
* @param charSet a collection of characters to use when printing
*/
def prettyPrint(
- tab: String = "",
- charSet: DependencyManagerUtils.CharSet = DependencyManagerUtils.PrettyCharSet): String = {
+ tab: String = "",
+ charSet: DependencyManagerUtils.CharSet = DependencyManagerUtils.PrettyCharSet
+ ): String = {
(Seq(s"$tab$name") ++ prettyPrintRec(tab, charSet)).mkString("\n")
@@ -422,9 +434,11 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
* @param targets the [[Phase]]s you want to run
*/
class PhaseManager(
- val targets: Seq[PhaseManager.PhaseDependency],
+ val targets: Seq[PhaseManager.PhaseDependency],
val currentState: Seq[PhaseManager.PhaseDependency] = Seq.empty,
- val knownObjects: Set[Phase] = Set.empty) extends DependencyManager[AnnotationSeq, Phase] with Phase {
+ val knownObjects: Set[Phase] = Set.empty)
+ extends DependencyManager[AnnotationSeq, Phase]
+ with Phase {
import PhaseManager.PhaseDependency
protected def copy(a: Seq[PhaseDependency], b: Seq[PhaseDependency], c: ISet[Phase]) = new PhaseManager(a, b, c)
@@ -444,6 +458,7 @@ object DependencyManagerUtils {
* @see [[ASCIICharSet]]
*/
trait CharSet {
+
/** Used when printing the last node */
val lastNode: String
@@ -456,15 +471,15 @@ object DependencyManagerUtils {
/** Uses prettier characters, but possibly not supported by all fonts */
object PrettyCharSet extends CharSet {
- val lastNode = "└──"
- val notLastNode = "├──"
+ val lastNode = "└──"
+ val notLastNode = "├──"
val continuation = "│ "
}
/** Basic ASCII output */
object ASCIICharSet extends CharSet {
- val lastNode = "\\--"
- val notLastNode = "|--"
+ val lastNode = "\\--"
+ val notLastNode = "|--"
val continuation = "| "
}