diff options
| author | Kevin Laeufer | 2020-07-17 18:07:54 -0700 |
|---|---|---|
| committer | GitHub | 2020-07-18 01:07:54 +0000 |
| commit | 1b9f4ddff4102fee72ae4dd8c111c82c32e42d5d (patch) | |
| tree | fee6379c83e4026edcf3d577a2a9474024ed0b59 /src/test | |
| parent | 5f70175d24cbeeef2ffae3fb00b99e06c5462bd0 (diff) | |
Faster dedup instance graph (#1732)
* dedup: add faster InstanceGraph implementation and use it in dedup
The new implementation takes care not to hash the instance
types contained in DefInstance nodes.
This should make dedup considerably faster.
* FastInstanceGraph: cache vertices for faster findInstancesInHierarchy
* FastInstanceGraph: remove the parent name field since it isn't actually necessary
* FastInstanceGraph -> InstanceKeyGraph
* InstanceGraph: describe performance problems.
* InstanceKeyGraph: turn moduleMap into a def instead of a val
This will make changing implementation details much easier
in the future.
* InstanceKeyGraph: return childInstances as Seq instead of Map
This ensures a deterministic iteration order and it
can easily be turned into a Map for O(1) accesses.
* InstanceKeyGraph: add tests for public methods
* InstanceKeyGraph: group public methods together
* InstanceKeyGraphSpec: fix wording of a comment
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/scala/firrtlTests/analyses/InstanceKeyGraphSpec.scala | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/analyses/InstanceKeyGraphSpec.scala b/src/test/scala/firrtlTests/analyses/InstanceKeyGraphSpec.scala new file mode 100644 index 00000000..8d073ecb --- /dev/null +++ b/src/test/scala/firrtlTests/analyses/InstanceKeyGraphSpec.scala @@ -0,0 +1,124 @@ +// See LICENSE for license details. + +package firrtlTests.analyses + +import firrtl.analyses.InstanceKeyGraph +import firrtl.analyses.InstanceKeyGraph.InstanceKey +import firrtl.testutils.FirrtlFlatSpec + +class InstanceKeyGraphSpec extends FirrtlFlatSpec { + behavior of "InstanceKeyGraph" + + // Note that due to optimized implementations of Map1-4, at least 5 entries are needed to + // experience non-determinism + it should "preserve Module declaration order" in { + val input = """ + |circuit Top : + | module Top : + | inst c1 of Child1 + | inst c2 of Child2 + | module Child1 : + | inst a of Child1a + | inst b of Child1b + | skip + | module Child1a : + | skip + | module Child1b : + | skip + | module Child2 : + | skip + |""".stripMargin + val circuit = parse(input) + val instGraph = new InstanceKeyGraph(circuit) + val childMap = instGraph.getChildInstances + childMap.map(_._1) should equal (Seq("Top", "Child1", "Child1a", "Child1b", "Child2")) + } + + // Note that due to optimized implementations of Map1-4, at least 5 entries are needed to + // experience non-determinism + it should "preserve Instance declaration order" in { + val input = """ + |circuit Top : + | module Top : + | inst a of Child + | inst b of Child + | inst c of Child + | inst d of Child + | inst e of Child + | inst f of Child + | module Child : + | skip + |""".stripMargin + val circuit = parse(input) + val instGraph = new InstanceKeyGraph(circuit) + val childMap = instGraph.getChildInstances.toMap + val insts = childMap("Top").map(_.name) + insts should equal (Seq("a", "b", "c", "d", "e", "f")) + } + + it should "compute a correct and deterministic module order" in { + val input = """ + |circuit Top : + | module Top : + | inst c1 of Child1 + | inst c2 of Child2 + | inst c4 of Child4 + | inst c3 of Child3 + | module Child1 : + | inst a of Child1a + | inst b of Child1b + | skip + | module Child1a : + | skip + | module Child1b : + | skip + | module Child2 : + | skip + | module Child3 : + | skip + | module Child4 : + | skip + |""".stripMargin + val circuit = parse(input) + val instGraph = new InstanceKeyGraph(circuit) + val order = instGraph.moduleOrder.map(_.name) + // Where it has freedom, the instance declaration order will be reversed. + order should equal (Seq("Top", "Child3", "Child4", "Child2", "Child1", "Child1b", "Child1a")) + } + + it should "find hierarchical instances correctly in disconnected hierarchies" in { + val input = + """circuit Top : + | module Top : + | inst c of Child1 + | module Child1 : + | skip + | + | module Top2 : + | inst a of Child2 + | inst b of Child3 + | skip + | module Child2 : + | inst a of Child2a + | inst b of Child2b + | skip + | module Child2a : + | skip + | module Child2b : + | skip + | module Child3 : + | skip + |""".stripMargin + + val circuit = parse(input) + val iGraph = new InstanceKeyGraph(circuit) + iGraph.findInstancesInHierarchy("Top") shouldBe Seq(Seq(InstanceKey("Top", "Top"))) + iGraph.findInstancesInHierarchy("Child1") shouldBe Seq(Seq(InstanceKey("Top", "Top"), InstanceKey("c", "Child1"))) + iGraph.findInstancesInHierarchy("Top2") shouldBe Nil + iGraph.findInstancesInHierarchy("Child2") shouldBe Nil + iGraph.findInstancesInHierarchy("Child2a") shouldBe Nil + iGraph.findInstancesInHierarchy("Child2b") shouldBe Nil + iGraph.findInstancesInHierarchy("Child3") shouldBe Nil + } + +} |
