aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/options
diff options
context:
space:
mode:
authorSchuyler Eldridge2020-04-22 20:26:11 -0400
committerGitHub2020-04-22 20:26:11 -0400
commit404d419a42c33ce4a68eedce636c336adf7d53be (patch)
tree607b55e30774227895c75b60fb8fd67845ed23a8 /src/main/scala/firrtl/options
parent65360f886f9b92438d1b6fe609120b34ebb413cf (diff)
parentffa6958535292d636923739d9d77b566054e2208 (diff)
Merge pull request #1537 from freechipsproject/optionalPrerequisitesOf
Change `dependents` to `optionalPrerequisiteOf`
Diffstat (limited to 'src/main/scala/firrtl/options')
-rw-r--r--src/main/scala/firrtl/options/DependencyManager.scala37
-rw-r--r--src/main/scala/firrtl/options/Phase.scala30
-rw-r--r--src/main/scala/firrtl/options/phases/AddDefaults.scala2
-rw-r--r--src/main/scala/firrtl/options/phases/Checks.scala2
-rw-r--r--src/main/scala/firrtl/options/phases/ConvertLegacyAnnotations.scala2
-rw-r--r--src/main/scala/firrtl/options/phases/DeletedWrapper.scala2
-rw-r--r--src/main/scala/firrtl/options/phases/GetIncludes.scala2
-rw-r--r--src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala2
8 files changed, 50 insertions, 29 deletions
diff --git a/src/main/scala/firrtl/options/DependencyManager.scala b/src/main/scala/firrtl/options/DependencyManager.scala
index 537f87bd..910d44bb 100644
--- a/src/main/scala/firrtl/options/DependencyManager.scala
+++ b/src/main/scala/firrtl/options/DependencyManager.scala
@@ -22,10 +22,11 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
override def prerequisites = currentState
- override def dependents = Seq.empty
override def optionalPrerequisites = Seq.empty
+ override def optionalPrerequisiteOf = Seq.empty
+
override def invalidates(a: B): Boolean = (_currentState &~ _targets)(oToD(a))
/** Requested [[firrtl.options.TransformLike TransformLike]]s that should be run. Internally, this will be converted to
@@ -121,11 +122,11 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
}
/** A directed graph consisting of prerequisites derived from only those transforms which are supposed to run. This
- * pulls in dependents for transforms which are not in the target set.
+ * pulls in optionalPrerequisiteOf for transforms which are not in the target set.
*/
- private lazy val dependentsGraph: DiGraph[B] = {
+ private lazy val optionalPrerequisiteOfGraph: DiGraph[B] = {
val v = new LinkedHashSet() ++ prerequisiteGraph.getVertices
- DiGraph(new LinkedHashMap() ++ v.map(vv => vv -> (v & (vv._dependents).map(dToO)))).reverse
+ DiGraph(new LinkedHashMap() ++ v.map(vv => vv -> (v & (vv._optionalPrerequisiteOf.toSet).map(dToO)))).reverse
}
/** A directed graph of *optional* prerequisites. Each optional prerequisite is promoted to a full prerequisite if the
@@ -139,11 +140,11 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
/** A directed graph consisting of prerequisites derived from ALL targets. This is necessary for defining targets for
* [[DependencyManager]] sub-problems.
*/
- private lazy val otherDependents: DiGraph[B] = {
+ private lazy val otherPrerequisites: DiGraph[B] = {
val edges = {
val x = new LinkedHashMap ++ _targets
.map(dependencyToObject)
- .map{ a => a -> prerequisiteGraph.getVertices.filter(a._dependents(_)) }
+ .map{ a => a -> prerequisiteGraph.getVertices.filter(a._optionalPrerequisiteOf(_)) }
x
.values
.reduce(_ ++ _)
@@ -152,8 +153,10 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
DiGraph(edges).reverse
}
- /** A directed graph consisting of all prerequisites, including prerequisites derived from dependents */
- lazy val dependencyGraph: DiGraph[B] = prerequisiteGraph + dependentsGraph + optionalPrerequisitesGraph
+ /** A directed graph consisting of all prerequisites, including prerequisites derived from optionalPrerequisites and
+ * optionalPrerequisiteOf
+ */
+ lazy val dependencyGraph: DiGraph[B] = prerequisiteGraph + optionalPrerequisiteOfGraph + optionalPrerequisitesGraph
/** A directed graph consisting of invalidation edges */
lazy val invalidateGraph: DiGraph[B] = {
@@ -178,9 +181,9 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
/** An ordering of [[firrtl.options.TransformLike TransformLike]]s that causes the requested [[DependencyManager.targets
* targets]] to be executed starting from the [[DependencyManager.currentState currentState]]. This ordering respects
- * prerequisites, dependents, and invalidates of all constituent [[firrtl.options.TransformLike TransformLike]]s.
- * This uses an algorithm that attempts to reduce the number of re-lowerings due to invalidations. Re-lowerings are
- * implemented as new [[DependencyManager]]s.
+ * prerequisites, optionalPrerequisites, optionalPrerequisiteOf, and invalidates of all constituent
+ * [[firrtl.options.TransformLike TransformLike]]s. This uses an algorithm that attempts to reduce the number of
+ * re-lowerings due to invalidations. Re-lowerings are implemented as new [[DependencyManager]]s.
* @throws DependencyManagerException if a cycle exists in either the [[DependencyManager.dependencyGraph
* dependencyGraph]] or the [[DependencyManager.invalidateGraph invalidateGraph]].
*/
@@ -199,7 +202,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
v.map(vv => vv -> (new LinkedHashSet() ++ (dependencyGraph.getEdges(vv).toSeq.sortWith(cmp))))
}
- cyclePossible("prerequisites/dependents", dependencyGraph) {
+ cyclePossible("prerequisites", dependencyGraph) {
DiGraph(edges)
.linearize
.reverse
@@ -209,10 +212,9 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
/* [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) =>
- /* The prerequisites are both prerequisites AND dependents. */
val prereqs = in._prerequisites ++
dependencyGraph.getEdges(in).toSeq.map(oToD) ++
- otherDependents.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 }
@@ -267,7 +269,8 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
/** Get a name of some [[firrtl.options.TransformLike TransformLike]] */
private def transformName(transform: B, suffix: String = ""): String = s""""${transform.name}$suffix""""
- /** Convert all prerequisites, dependents, and invalidates to a Graphviz representation.
+ /** Convert all prerequisites, optionalPrerequisites, optionalPrerequisiteOf, and invalidates to a Graphviz
+ * representation.
* @param file the name of the output file
*/
def dependenciesToGraphviz: String = {
@@ -291,14 +294,14 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
val connections =
Seq( (prerequisiteGraph, "edge []"),
- (dependentsGraph, """edge [style=bold color="#4292c6"]"""),
+ (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 + dependentsGraph + invalidateGraph + otherDependents)
+ (prerequisiteGraph + optionalPrerequisiteOfGraph + invalidateGraph + otherPrerequisites)
.getVertices
.map(v => s"""${transformName(v)} [label="${v.name}"]""")
diff --git a/src/main/scala/firrtl/options/Phase.scala b/src/main/scala/firrtl/options/Phase.scala
index 847a4cf2..6dd5d969 100644
--- a/src/main/scala/firrtl/options/Phase.scala
+++ b/src/main/scala/firrtl/options/Phase.scala
@@ -106,11 +106,12 @@ trait IdentityLike[A] { this: TransformLike[A] =>
* "transforms")
*
* This trait forms the basis of the Dependency API of the Chisel/FIRRTL Hardware Compiler Framework. Dependencies are
- * defined in terms of prerequisistes, dependents, and invalidates. A prerequisite is a transform that must run before
- * this transform. A dependent is a transform that must run ''after'' this transform. (This can be viewed as a means of
- * injecting a prerequisite into some other transform.) Finally, invalidates define the set of transforms whose effects
- * this transform undos/invalidates. (Invalidation then implies that a transform that is invalidated by this transform
- * and needed by another transform will need to be re-run.)
+ * defined in terms of prerequisistes, optional prerequisites, optional prerequisites of, and invalidates. A
+ * prerequisite is a transform that must run before this transform. An optional prerequisites is transform that should
+ * run before this transform if the other transform is a target (or the prerequisite of a target). An optional
+ * prerequisite of is an optional prerequisite injected into another transform. Finally, invalidates define the set of
+ * transforms whose effects this transform undos/invalidates. (Invalidation then implies that a transform that is
+ * invalidated by this transform and needed by another transform will need to be re-run.)
*
* This Dependency API only defines dependencies. A concrete [[DependencyManager]] is expected to be used to statically
* resolve a linear ordering of transforms that satisfies dependency requirements.
@@ -152,8 +153,25 @@ trait DependencyAPI[A <: DependencyAPI[A]] { this: TransformLike[_] =>
* @see [[firrtl.passes.CheckTypes]] for an example of an optional checking [[firrtl.Transform]]
* $seqNote
*/
+ @deprecated(
+ "Due to confusion, 'dependents' is being renamed to 'optionalPrerequisiteOf'. Override the latter instead.",
+ "FIRRTL 1.3"
+ )
def dependents: Seq[Dependency[A]] = Seq.empty
- private[options] lazy val _dependents: LinkedHashSet[Dependency[A]] = new LinkedHashSet() ++ dependents.toSet
+
+ /** A sequence of transforms to add this transform as an `optionalPrerequisite`. The use of `optionalPrerequisiteOf`
+ * enables the transform declaring them to always run before some other transforms. However, declaring
+ * `optionalPrerequisiteOf` will not result in the sequence of transforms executing.
+ *
+ * This is useful for providing an ordering constraint to guarantee that other transforms (e.g., emitters) will not
+ * be scheduled before you.
+ *
+ * @note This method **will not** result in the listed transforms running. If you want to add multiple transforms at
+ * once, you should use a `DependencyManager` with multiple targets.
+ */
+ def optionalPrerequisiteOf: Seq[Dependency[A]] = dependents
+ private[options] lazy val _optionalPrerequisiteOf: LinkedHashSet[Dependency[A]] =
+ new LinkedHashSet() ++ optionalPrerequisiteOf.toSet
/** A function that, given *another* transform (parameter `a`) will return true if this transform invalidates/undos the
* effects of the *other* transform (parameter `a`).
diff --git a/src/main/scala/firrtl/options/phases/AddDefaults.scala b/src/main/scala/firrtl/options/phases/AddDefaults.scala
index 034c502f..79089194 100644
--- a/src/main/scala/firrtl/options/phases/AddDefaults.scala
+++ b/src/main/scala/firrtl/options/phases/AddDefaults.scala
@@ -14,7 +14,7 @@ class AddDefaults extends Phase with PreservesAll[Phase] {
override def prerequisites = Seq(Dependency[GetIncludes], Dependency[ConvertLegacyAnnotations])
- override def dependents = Seq.empty
+ override def optionalPrerequisiteOf = Seq.empty
def transform(annotations: AnnotationSeq): AnnotationSeq = {
val td = annotations.collectFirst{ case a: TargetDirAnnotation => a}.isEmpty
diff --git a/src/main/scala/firrtl/options/phases/Checks.scala b/src/main/scala/firrtl/options/phases/Checks.scala
index 69cbc7ed..ed2f1a28 100644
--- a/src/main/scala/firrtl/options/phases/Checks.scala
+++ b/src/main/scala/firrtl/options/phases/Checks.scala
@@ -14,7 +14,7 @@ class Checks extends Phase with PreservesAll[Phase] {
override def prerequisites = Seq(Dependency[GetIncludes], Dependency[ConvertLegacyAnnotations], Dependency[AddDefaults])
- override def dependents = Seq.empty
+ override def optionalPrerequisiteOf = Seq.empty
/** Validate an [[AnnotationSeq]] for [[StageOptions]]
* @throws OptionsException if annotations are invalid
diff --git a/src/main/scala/firrtl/options/phases/ConvertLegacyAnnotations.scala b/src/main/scala/firrtl/options/phases/ConvertLegacyAnnotations.scala
index 7611f66f..1eb4c2d9 100644
--- a/src/main/scala/firrtl/options/phases/ConvertLegacyAnnotations.scala
+++ b/src/main/scala/firrtl/options/phases/ConvertLegacyAnnotations.scala
@@ -11,7 +11,7 @@ class ConvertLegacyAnnotations extends Phase with PreservesAll[Phase] {
override def prerequisites = Seq(Dependency[GetIncludes])
- override def dependents = Seq.empty
+ override def optionalPrerequisiteOf = Seq.empty
def transform(annotations: AnnotationSeq): AnnotationSeq = LegacyAnnotation.convertLegacyAnnos(annotations)
diff --git a/src/main/scala/firrtl/options/phases/DeletedWrapper.scala b/src/main/scala/firrtl/options/phases/DeletedWrapper.scala
index 4a112172..76ff21ad 100644
--- a/src/main/scala/firrtl/options/phases/DeletedWrapper.scala
+++ b/src/main/scala/firrtl/options/phases/DeletedWrapper.scala
@@ -17,7 +17,7 @@ class DeletedWrapper(p: Phase) extends Phase with Translator[AnnotationSeq, (Ann
override def prerequisites = Seq.empty
- override def dependents = Seq.empty
+ override def optionalPrerequisiteOf = Seq.empty
override lazy val name: String = p.name
diff --git a/src/main/scala/firrtl/options/phases/GetIncludes.scala b/src/main/scala/firrtl/options/phases/GetIncludes.scala
index 3b26795f..86e451eb 100644
--- a/src/main/scala/firrtl/options/phases/GetIncludes.scala
+++ b/src/main/scala/firrtl/options/phases/GetIncludes.scala
@@ -20,7 +20,7 @@ class GetIncludes extends Phase with PreservesAll[Phase] {
override def prerequisites = Seq.empty
- override def dependents = Seq.empty
+ override def optionalPrerequisiteOf = Seq.empty
/** Read all [[annotations.Annotation]] from a file in JSON or YAML format
* @param filename a JSON or YAML file of [[annotations.Annotation]]
diff --git a/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala b/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala
index 79769a81..2d226de1 100644
--- a/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala
+++ b/src/main/scala/firrtl/options/phases/WriteOutputAnnotations.scala
@@ -20,7 +20,7 @@ class WriteOutputAnnotations extends Phase with PreservesAll[Phase] {
Dependency[AddDefaults],
Dependency[Checks] )
- override def dependents = Seq.empty
+ override def optionalPrerequisiteOf = Seq.empty
/** Write the input [[AnnotationSeq]] to a fie. */
def transform(annotations: AnnotationSeq): AnnotationSeq = {