From 16846b86fd6ee03514b4629a1f86dfe65e74d1b4 Mon Sep 17 00:00:00 2001 From: Chick Markley Date: Tue, 4 Apr 2017 10:47:59 -0700 Subject: [PATCH] DiGraph was being being confused with the DigGraph in firrtl. This led to pathological exceptions (#22) No such method error on accessing a lazy val. InstanceGraph seemed also to be a duplicate of firrtl code --- IOPadSpec fails no two tests but these seem to be at least an ordinary error. And should be debugged separately --- .../main/scala/transforms/utils/DiGraph.scala | 158 ------------------ .../transforms/utils/InstanceGraph.scala | 51 ------ 2 files changed, 209 deletions(-) delete mode 100644 tapeout/src/main/scala/transforms/utils/DiGraph.scala delete mode 100644 tapeout/src/main/scala/transforms/utils/InstanceGraph.scala diff --git a/tapeout/src/main/scala/transforms/utils/DiGraph.scala b/tapeout/src/main/scala/transforms/utils/DiGraph.scala deleted file mode 100644 index 8e0db078..00000000 --- a/tapeout/src/main/scala/transforms/utils/DiGraph.scala +++ /dev/null @@ -1,158 +0,0 @@ -package firrtl - -import scala.collection.immutable.{HashSet, HashMap} -import scala.collection.mutable -import scala.collection.mutable.MultiMap - -class MutableDiGraph[T]( - val edgeData: MultiMap[T,T] = new mutable.HashMap[T, mutable.Set[T]] with MultiMap[T, T]) { - def contains(v: T) = edgeData.contains(v) - def getVertices = edgeData.keys - def getEdges(v: T) = edgeData(v) - def addVertex(v: T): T = { - edgeData.getOrElseUpdate(v,new mutable.HashSet[T]) - v - } - // Add v to keys to maintain invariant - def addEdge(u: T, v: T) = { - edgeData.getOrElseUpdate(v, new mutable.HashSet[T]) - edgeData.addBinding(u,v) - } -} - -object DiGraph { - def apply[T](mdg: MutableDiGraph[T]) = new DiGraph((mdg.edgeData mapValues { _.toSet }).toMap[T, Set[T]]) - def apply[T](edgeData: MultiMap[T,T]) = new DiGraph((edgeData mapValues { _.toSet }).toMap[T, Set[T]]) -} - -class DiGraph[T] (val edges: Map[T, Set[T]]) { - - def getVertices = edges.keys - def getEdges(v: T) = edges.getOrElse(v, new HashSet[T]) - - // Graph must be acyclic for valid linearization - def linearize(root: T) = { - val order = new mutable.ArrayBuffer[T] - val visited = new mutable.HashSet[T] - def explore(v: T): Unit = { - visited += v - for (u <- getEdges(v)) { - if (!visited.contains(u)) { - explore(u) - } - } - order.append(v) - } - explore(root) - order.reverse.toList - } - - def doBFS(root: T) = { - val prev = new mutable.HashMap[T,T] - val queue = new mutable.Queue[T] - queue.enqueue(root) - while (!queue.isEmpty) { - val u = queue.dequeue - for (v <- getEdges(u)) { - if (!prev.contains(v)) { - prev(v) = u - queue.enqueue(v) - } - } - } - prev - } - - def reachabilityBFS(root: T) = doBFS(root).keys.toSet - - def path(start: T, end: T) = { - val nodePath = new mutable.ArrayBuffer[T] - val prev = doBFS(start) - nodePath += end - while (nodePath.last != start) { - nodePath += prev(nodePath.last) - } - nodePath.toList.reverse - } - - def findSCCs = { - var counter: BigInt = 0 - val stack = new mutable.Stack[T] - val onstack = new mutable.HashSet[T] - val indices = new mutable.HashMap[T, BigInt] - val lowlinks = new mutable.HashMap[T, BigInt] - val sccs = new mutable.ArrayBuffer[List[T]] - - def strongConnect(v: T): Unit = { - indices(v) = counter - lowlinks(v) = counter - counter = counter + 1 - stack.push(v) - onstack += v - for (w <- getEdges(v)) { - if (!indices.contains(w)) { - strongConnect(w) - lowlinks(v) = lowlinks(v).min(lowlinks(w)) - } else if (onstack.contains(w)) { - lowlinks(v) = lowlinks(v).min(indices(w)) - } - } - if (lowlinks(v) == indices(v)) { - val scc = new mutable.ArrayBuffer[T] - do { - val w = stack.pop - onstack -= w - scc += w - } - while (scc.last != v); - sccs.append(scc.toList) - } - } - - for (v <- getVertices) { - strongConnect(v) - } - - sccs.toList - } - - def pathsInDAG(start: T): Map[T,List[List[T]]] = { - // paths(v) holds the set of paths from start to v - val paths = new mutable.HashMap[T,mutable.Set[List[T]]] with mutable.MultiMap[T,List[T]] - val queue = new mutable.Queue[T] - val visited = new mutable.HashSet[T] - paths.addBinding(start,List(start)) - queue.enqueue(start) - visited += start - while (!queue.isEmpty) { - val current = queue.dequeue - for (v <- getEdges(current)) { - if (!visited.contains(v)) { - queue.enqueue(v) - visited += v - } - for (p <- paths(current)) { - paths.addBinding(v, p :+ v) - } - } - } - (paths map { case (k,v) => (k,v.toList) }).toMap - } - - def reverse = { - val mdg = new MutableDiGraph[T] - edges foreach { case (u,edges) => edges.foreach({ v => mdg.addEdge(v,u) }) } - DiGraph(mdg) - } - - def simplify(vprime: Set[T]) = { - val eprime = vprime.map( v => (v,reachabilityBFS(v) & vprime) ).toMap - new DiGraph(eprime) - } - - def transformNodes[Q](f: (T) => Q): DiGraph[Q] = { - val eprime = edges.map({ case (k,v) => (f(k),v.map(f(_))) }) - new DiGraph(eprime) - } - -} \ No newline at end of file diff --git a/tapeout/src/main/scala/transforms/utils/InstanceGraph.scala b/tapeout/src/main/scala/transforms/utils/InstanceGraph.scala deleted file mode 100644 index 10b37ea8..00000000 --- a/tapeout/src/main/scala/transforms/utils/InstanceGraph.scala +++ /dev/null @@ -1,51 +0,0 @@ -package firrtl.analyses - -import scala.collection.mutable - -import firrtl._ -import firrtl.ir._ -import firrtl.Utils._ -import firrtl.Mappers._ - -class InstanceGraph(c: Circuit) { - - private def collectInstances(insts: mutable.Set[WDefInstance])(s: Statement): Statement = s match { - case i: WDefInstance => - insts += i - i - case _ => - s map collectInstances(insts) - s - } - - val moduleMap = c.modules.map({m => (m.name,m) }).toMap - val childInstances = - new mutable.HashMap[String,mutable.Set[WDefInstance]] - for (m <- c.modules) { - childInstances(m.name) = new mutable.HashSet[WDefInstance] - m map collectInstances(childInstances(m.name)) - } - val instanceGraph = new MutableDiGraph[WDefInstance] - val instanceQueue = new mutable.Queue[WDefInstance] - val topInstance = WDefInstance(c.main,c.main) // top instance - instanceQueue.enqueue(topInstance) - while (!instanceQueue.isEmpty) { - val current = instanceQueue.dequeue - for (child <- childInstances(current.module)) { - if (!instanceGraph.contains(child)) { - instanceQueue.enqueue(child) - } - instanceGraph.addEdge(current,child) - } - } - - val graph = DiGraph(instanceGraph) - - lazy val fullHierarchy = graph.pathsInDAG(topInstance) - - def findInstancesInHierarchy(module: String): List[List[WDefInstance]] = { - val instances = graph.getVertices.filter(_.module == module).toList - instances flatMap { i => fullHierarchy(i) } - } - -}