diff options
| author | Jack Koenig | 2017-06-21 09:35:15 -0700 |
|---|---|---|
| committer | Jack Koenig | 2017-06-21 10:18:20 -0700 |
| commit | 5135e9c6aeb1c9d472a5b29adb44a4acaf504fb8 (patch) | |
| tree | baa097e2bae57ac8f15e95793e5d53b170f1a656 /src | |
| parent | 4613ad2b519ae85fbab89e58d3304cf455514552 (diff) | |
Add --no-dce command-line option to skip DCE
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/firrtl/Driver.scala | 5 | ||||
| -rw-r--r-- | src/main/scala/firrtl/ExecutionOptionsManager.scala | 10 | ||||
| -rw-r--r-- | src/main/scala/firrtl/transforms/DeadCodeElimination.scala | 16 | ||||
| -rw-r--r-- | src/main/scala/firrtl/transforms/OptimizationAnnotations.scala | 11 | ||||
| -rw-r--r-- | src/test/resources/features/HasDeadCode.fir | 7 | ||||
| -rw-r--r-- | src/test/scala/firrtlTests/DCETests.scala | 27 |
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") + } + } +} |
