aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack Koenig2017-06-21 09:35:15 -0700
committerJack Koenig2017-06-21 10:18:20 -0700
commit5135e9c6aeb1c9d472a5b29adb44a4acaf504fb8 (patch)
treebaa097e2bae57ac8f15e95793e5d53b170f1a656 /src
parent4613ad2b519ae85fbab89e58d3304cf455514552 (diff)
Add --no-dce command-line option to skip DCE
Diffstat (limited to 'src')
-rw-r--r--src/main/scala/firrtl/Driver.scala5
-rw-r--r--src/main/scala/firrtl/ExecutionOptionsManager.scala10
-rw-r--r--src/main/scala/firrtl/transforms/DeadCodeElimination.scala16
-rw-r--r--src/main/scala/firrtl/transforms/OptimizationAnnotations.scala11
-rw-r--r--src/test/resources/features/HasDeadCode.fir7
-rw-r--r--src/test/scala/firrtlTests/DCETests.scala27
6 files changed, 69 insertions, 7 deletions
diff --git a/src/main/scala/firrtl/Driver.scala b/src/main/scala/firrtl/Driver.scala
index 6c4c450b..264ba44c 100644
--- a/src/main/scala/firrtl/Driver.scala
+++ b/src/main/scala/firrtl/Driver.scala
@@ -12,7 +12,7 @@ import logger.Logger
import Parser.{IgnoreInfo, InfoMode}
import annotations._
import firrtl.annotations.AnnotationYamlProtocol._
-import firrtl.transforms.{BlackBoxSourceHelper, BlackBoxTargetDir, DontCheckCombLoopsAnnotation}
+import firrtl.transforms._
import Utils.throwInternalError
@@ -167,7 +167,8 @@ object Driver {
// Should these and outputAnnos be moved to loadAnnotations?
val globalAnnos = Seq(TargetDirAnnotation(optionsManager.targetDirName)) ++
- (if (firrtlConfig.dontCheckCombLoops) Seq(DontCheckCombLoopsAnnotation()) else Seq())
+ (if (firrtlConfig.dontCheckCombLoops) Seq(DontCheckCombLoopsAnnotation()) else Seq()) ++
+ (if (firrtlConfig.noDCE) Seq(NoDCEAnnotation()) else Seq())
val finalState = firrtlConfig.compiler.compile(
CircuitState(parsedInput,
diff --git a/src/main/scala/firrtl/ExecutionOptionsManager.scala b/src/main/scala/firrtl/ExecutionOptionsManager.scala
index ebe27a7d..8aa23f70 100644
--- a/src/main/scala/firrtl/ExecutionOptionsManager.scala
+++ b/src/main/scala/firrtl/ExecutionOptionsManager.scala
@@ -157,7 +157,8 @@ case class FirrtlExecutionOptions(
annotationFileNameOverride: String = "",
forceAppendAnnoFile: Boolean = false,
emitOneFilePerModule: Boolean = false,
- dontCheckCombLoops: Boolean = false)
+ dontCheckCombLoops: Boolean = false,
+ noDCE: Boolean = false)
extends ComposableOptions {
require(!(emitOneFilePerModule && outputFileNameOverride.nonEmpty),
@@ -420,6 +421,13 @@ trait HasFirrtlOptions {
"Do NOT check for combinational loops (not recommended)"
}
+ parser.opt[Unit]("no-dce")
+ .foreach { _ =>
+ firrtlOptions = firrtlOptions.copy(noDCE = true)
+ }.text {
+ "Do NOT run dead code elimination"
+ }
+
parser.note("")
}
diff --git a/src/main/scala/firrtl/transforms/DeadCodeElimination.scala b/src/main/scala/firrtl/transforms/DeadCodeElimination.scala
index 91a5dd5a..aa147733 100644
--- a/src/main/scala/firrtl/transforms/DeadCodeElimination.scala
+++ b/src/main/scala/firrtl/transforms/DeadCodeElimination.scala
@@ -286,7 +286,7 @@ class DeadCodeElimination extends Transform {
}
def execute(state: CircuitState): CircuitState = {
- val (dontTouches: Seq[LogicNode], doTouchExtMods: Seq[String]) =
+ val (dontTouches: Seq[LogicNode], doTouchExtMods: Seq[String], noDCE: Option[Boolean]) =
state.annotations match {
case Some(aMap) =>
// TODO Do with single walk over annotations
@@ -296,9 +296,17 @@ class DeadCodeElimination extends Transform {
val optExtMods = aMap.annotations.collect {
case OptimizableExtModuleAnnotation(ModuleName(name, _)) => name
}
- (dontTouches, optExtMods)
- case None => (Seq.empty, Seq.empty)
+ val noDCE = aMap.annotations.collectFirst {
+ case NoDCEAnnotation() => true
+ }
+ (dontTouches, optExtMods, noDCE)
+ case None => (Seq.empty, Seq.empty, None)
}
- run(state, dontTouches, doTouchExtMods.toSet)
+ if (noDCE.getOrElse(false)) {
+ logger.info("Skipping DCE")
+ state
+ } else {
+ run(state, dontTouches, doTouchExtMods.toSet)
+ }
}
}
diff --git a/src/main/scala/firrtl/transforms/OptimizationAnnotations.scala b/src/main/scala/firrtl/transforms/OptimizationAnnotations.scala
index 23723a60..2336710a 100644
--- a/src/main/scala/firrtl/transforms/OptimizationAnnotations.scala
+++ b/src/main/scala/firrtl/transforms/OptimizationAnnotations.scala
@@ -5,6 +5,17 @@ package transforms
import firrtl.annotations._
import firrtl.passes.PassException
+/** Indicate that DCE should not be run */
+object NoDCEAnnotation {
+ val marker = "noDCE!"
+ val transform = classOf[DeadCodeElimination]
+ def apply(): Annotation = Annotation(CircuitTopName, transform, marker)
+ def unapply(a: Annotation): Boolean = a match {
+ case Annotation(_, targetXform, value) if targetXform == transform && value == marker => true
+ case _ => false
+ }
+}
+
/** A component that should be preserved
*
* DCE treats the component as a top-level sink of the circuit
diff --git a/src/test/resources/features/HasDeadCode.fir b/src/test/resources/features/HasDeadCode.fir
new file mode 100644
index 00000000..db87ff7a
--- /dev/null
+++ b/src/test/resources/features/HasDeadCode.fir
@@ -0,0 +1,7 @@
+circuit HasDeadCode :
+ module HasDeadCode :
+ input i : UInt<1>
+ output o : UInt<1>
+ wire a : UInt<1>
+ a <= not(i)
+ o <= i
diff --git a/src/test/scala/firrtlTests/DCETests.scala b/src/test/scala/firrtlTests/DCETests.scala
index 129460e1..41edfa8b 100644
--- a/src/test/scala/firrtlTests/DCETests.scala
+++ b/src/test/scala/firrtlTests/DCETests.scala
@@ -9,6 +9,9 @@ import firrtl.transforms._
import firrtl.annotations._
import firrtl.passes.memlib.SimpleTransform
+import java.io.File
+import java.nio.file.Paths
+
class DCETests extends FirrtlFlatSpec {
// Not using executeTest because it is for positive testing, we need to check that stuff got
// deleted
@@ -387,3 +390,27 @@ class DCETests extends FirrtlFlatSpec {
exec(input, check)
}
}
+
+class DCECommandLineSpec extends FirrtlFlatSpec {
+
+ val testDir = createTestDirectory("dce")
+ val inputFile = Paths.get(getClass.getResource("/features/HasDeadCode.fir").toURI()).toFile()
+ val outFile = new File(testDir, "HasDeadCode.v")
+ val args = Array("-i", inputFile.getAbsolutePath, "-o", outFile.getAbsolutePath, "-X", "verilog")
+
+ "Dead Code Elimination" should "run by default" in {
+ firrtl.Driver.execute(args) match {
+ case FirrtlExecutionSuccess(_, verilog) =>
+ verilog should not include regex ("wire +a;")
+ case _ => fail("Unexpected compilation failure")
+ }
+ }
+
+ it should "not run when given --no-dce option" in {
+ firrtl.Driver.execute(args :+ "--no-dce") match {
+ case FirrtlExecutionSuccess(_, verilog) =>
+ verilog should include regex ("wire +a;")
+ case _ => fail("Unexpected compilation failure")
+ }
+ }
+}