@@ -40,18 +40,14 @@ trait PhaseAssembly {
40
40
var phaseobj : Option [List [SubComponent ]] = None
41
41
val after = new mutable.HashSet [Edge ]()
42
42
var before = new mutable.HashSet [Edge ]()
43
- var visited : VisitStatus = NotVisited
43
+ var visited = false
44
44
var level = 0
45
45
46
46
def allPhaseNames (): String = phaseobj match {
47
47
case None => phasename
48
48
case Some (lst) => lst.map(_.phaseName).reduceLeft(_+ " , " + _)
49
49
}
50
50
}
51
- sealed abstract class VisitStatus
52
- case object NotVisited extends VisitStatus
53
- case object Visiting extends VisitStatus
54
- case object Visited extends VisitStatus
55
51
56
52
val nodes = new mutable.HashMap [String ,Node ]()
57
53
val edges = new mutable.HashSet [Edge ]()
@@ -108,69 +104,45 @@ trait PhaseAssembly {
108
104
/* Test if there are cycles in the graph, assign levels to the nodes
109
105
* and collapse hard links into nodes
110
106
*/
111
- def collapseHardLinks () {
112
- for (node <- nodes.valuesIterator.toList) {
113
- val hardBefores = node.before.iterator.filter(_.hard).toList
114
- for (hl <- hardBefores) {
115
- val effectiveNode : Node = if (nodes.contains(node.name)) node else {
116
- nodes.find(_._2.phaseobj.exists(_.exists(_.phaseName == node.name))).get._2
117
- }
118
- effectiveNode.phaseobj = Some (effectiveNode.phaseobj.get ++ hl.frm.phaseobj.get)
119
- effectiveNode.before = hl.frm.before
120
- nodes -= hl.frm.phasename
121
- edges -= hl
122
- }
107
+ def collapseHardLinksAndLevels (node : Node , lvl : Int ) {
108
+ if (node.visited) {
109
+ dump(" phase-cycle" )
110
+ throw new FatalError (s " Cycle in phase dependencies detected at ${node.phasename}, created phase-cycle.dot " )
123
111
}
124
- }
125
112
126
- /* Test if there are cycles in the graph, assign levels to the nodes
127
- * and collapse hard links into nodes
128
- */
129
- def assignLevelsAndDetectCycles (node : Node ) {
130
- val stack = mutable.ArrayStack [Node ]()
131
- def visitNode (node : Node ): Unit = {
132
- node.visited = Visiting
133
- for (edge <- node.before) {
134
- val from = edge.frm
135
- from.visited match {
136
- case NotVisited =>
137
- visitNode(edge.frm)
138
- case Visiting =>
139
- dump(" phase-cycle" )
140
- throw new FatalError (s " Cycle in phase dependencies detected at ${node.phasename}, created phase-cycle.dot " )
141
- case Visited =>
142
- }
113
+ val initLevel = node.level
114
+ val levelUp = initLevel < lvl
115
+ if (levelUp) {
116
+ node.level = lvl
117
+ }
118
+ if (initLevel != 0 ) {
119
+ if (! levelUp) {
120
+ // no need to revisit
121
+ node.visited = false
122
+ return
143
123
}
144
- node.visited = Visited
145
- stack.push(node)
146
124
}
147
- try {
148
- visitNode(node)
149
- } finally {
150
- nodes.values.foreach(_.visited = NotVisited )
125
+ var befores = node.before
126
+ def hasHardLinks () = befores.exists(_.hard)
127
+ while (hasHardLinks()) {
128
+ for (hl <- befores) {
129
+ if (hl.hard) {
130
+ node.phaseobj = Some (node.phaseobj.get ++ hl.frm.phaseobj.get)
131
+ node.before = hl.frm.before
132
+ nodes -= hl.frm.phasename
133
+ edges -= hl
134
+ for (edge <- node.before) edge.to = node
135
+ }
136
+ }
137
+ befores = node.before
151
138
}
139
+ node.visited = true
152
140
153
- val topoSort : Map [Node , Int ] = stack.zipWithIndex.toMap
154
- val root = node
155
- assert(stack.head == root, stack)
156
- root.level = 1
157
-
158
- // Nodes that have been collapsed into their hard-linked predecessor
159
- val collapsed : Map [String , Node ] = stack.iterator.flatMap(p => p.phaseobj.toList.flatMap(_.map(x => (x.phaseName, p)))).toMap
160
- def followHard (node : Node ): Node = collapsed.getOrElse(node.phasename, node)
161
-
162
- // find the longest path to the root node to assign as the level.
163
- stack.iterator.drop(1 ).foreach { node =>
164
- var n = node
165
- var level = 1
166
- while (n != root && n.after.nonEmpty) {
167
- n = n.after.maxBy(edge => topoSort.get(followHard(edge.to))).to
168
- level += 1
169
- }
170
- node.level = level
141
+ for (edge <- node.before) {
142
+ collapseHardLinksAndLevels( edge.frm, lvl + 1 )
171
143
}
172
- def phaseDebug = stack.toSeq.groupBy(_.level).toList.sortBy(_._1).map { case (level, nodes) => (level, nodes.sortBy(_.phasename).map(_.phaseobj.map(_.map(_.phaseName).mkString( " : " )).mkString( " " )).mkString( " " ))}.mkString( " \n " )
173
- debuglog( " Phase assembly levels: " + phaseDebug)
144
+
145
+ node.visited = false
174
146
}
175
147
176
148
/* Find all edges in the given graph that are hard links. For each hard link we
@@ -263,16 +235,11 @@ trait PhaseAssembly {
263
235
264
236
dump(3 )
265
237
266
- // collapse hard links into nodes
267
- graph.collapseHardLinks( )
238
+ // test for cycles, assign levels and collapse hard links into nodes
239
+ graph.collapseHardLinksAndLevels(graph.getNodeByPhase( " parser " ), 1 )
268
240
269
241
dump(4 )
270
242
271
- // test for cycles, assign levels
272
- graph.assignLevelsAndDetectCycles(graph.getNodeByPhase(" parser" ))
273
-
274
- dump(5 )
275
-
276
243
// assemble the compiler
277
244
graph.compilerPhaseList()
278
245
}
0 commit comments