K2: optimize out empty maps in CFG nodes
This commit is contained in:
committed by
Space Team
parent
ab4603c9a3
commit
cc53671395
@@ -57,14 +57,14 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
|
|||||||
// It's hard to define label merging, hence overwritten with the latest one.
|
// It's hard to define label merging, hence overwritten with the latest one.
|
||||||
// One day, if we allow multiple edges between nodes with different labels, we won't even need kind merging.
|
// One day, if we allow multiple edges between nodes with different labels, we won't even need kind merging.
|
||||||
if (kind != EdgeKind.Forward || label != NormalPath) {
|
if (kind != EdgeKind.Forward || label != NormalPath) {
|
||||||
val fromToKind = from._outgoingEdges[to]?.kind ?: runIf(edgeExists) { EdgeKind.Forward }
|
val fromToKind = from._outgoingEdges?.get(to)?.kind ?: runIf(edgeExists) { EdgeKind.Forward }
|
||||||
merge(kind, fromToKind)?.let {
|
merge(kind, fromToKind)?.let {
|
||||||
from._outgoingEdges[to] = Edge.create(label, it)
|
from.insertOutgoingEdge(to, Edge.create(label, it))
|
||||||
} ?: from._outgoingEdges.remove(to)
|
} ?: from._outgoingEdges?.remove(to)
|
||||||
val toFromKind = to._incomingEdges[from]?.kind ?: runIf(edgeExists) { EdgeKind.Forward }
|
val toFromKind = to._incomingEdges?.get(from)?.kind ?: runIf(edgeExists) { EdgeKind.Forward }
|
||||||
merge(kind, toFromKind)?.let {
|
merge(kind, toFromKind)?.let {
|
||||||
to._incomingEdges[from] = Edge.create(label, it)
|
to.insertIncomingEdge(from, Edge.create(label, it))
|
||||||
} ?: to._incomingEdges.remove(from)
|
} ?: to._incomingEdges?.remove(from)
|
||||||
}
|
}
|
||||||
if (propagateDeadness && kind == EdgeKind.DeadForward) {
|
if (propagateDeadness && kind == EdgeKind.DeadForward) {
|
||||||
to.isDead = true
|
to.isDead = true
|
||||||
@@ -87,8 +87,8 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
|
|||||||
fun removeAllIncomingEdges(to: CFGNode<*>) {
|
fun removeAllIncomingEdges(to: CFGNode<*>) {
|
||||||
for (from in to._previousNodes) {
|
for (from in to._previousNodes) {
|
||||||
from._followingNodes.remove(to)
|
from._followingNodes.remove(to)
|
||||||
from._outgoingEdges.remove(to)
|
from._outgoingEdges?.remove(to)
|
||||||
to._incomingEdges.remove(from)
|
to._incomingEdges?.remove(from)
|
||||||
}
|
}
|
||||||
to._previousNodes.clear()
|
to._previousNodes.clear()
|
||||||
}
|
}
|
||||||
@@ -97,11 +97,14 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
|
|||||||
fun removeAllOutgoingEdges(from: CFGNode<*>) {
|
fun removeAllOutgoingEdges(from: CFGNode<*>) {
|
||||||
for (to in from._followingNodes) {
|
for (to in from._followingNodes) {
|
||||||
to._previousNodes.remove(from)
|
to._previousNodes.remove(from)
|
||||||
from._outgoingEdges.remove(to)
|
from._outgoingEdges?.remove(to)
|
||||||
to._incomingEdges.remove(from)
|
to._incomingEdges?.remove(from)
|
||||||
}
|
}
|
||||||
from._followingNodes.clear()
|
from._followingNodes.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createEmptyEdgeMapWithDefault(): MutableMap<CFGNode<*>, Edge> =
|
||||||
|
mutableMapOf<CFGNode<*>, Edge>().withDefault { Edge.Normal_Forward }
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -115,11 +118,34 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
|
|||||||
val previousNodes: List<CFGNode<*>> get() = _previousNodes
|
val previousNodes: List<CFGNode<*>> get() = _previousNodes
|
||||||
val followingNodes: List<CFGNode<*>> get() = _followingNodes
|
val followingNodes: List<CFGNode<*>> get() = _followingNodes
|
||||||
|
|
||||||
private val _incomingEdges = mutableMapOf<CFGNode<*>, Edge>().withDefault { Edge.Normal_Forward }
|
private var _incomingEdges: MutableMap<CFGNode<*>, Edge>? = null
|
||||||
private val _outgoingEdges = mutableMapOf<CFGNode<*>, Edge>().withDefault { Edge.Normal_Forward }
|
private var _outgoingEdges: MutableMap<CFGNode<*>, Edge>? = null
|
||||||
|
|
||||||
val incomingEdges: Map<CFGNode<*>, Edge> get() = _incomingEdges
|
private fun insertIncomingEdge(to: CFGNode<*>, edge: Edge) {
|
||||||
val outgoingEdges: Map<CFGNode<*>, Edge> get() = _outgoingEdges
|
if (_incomingEdges == null) {
|
||||||
|
_incomingEdges = createEmptyEdgeMapWithDefault()
|
||||||
|
}
|
||||||
|
_incomingEdges?.put(to, edge)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun insertOutgoingEdge(to: CFGNode<*>, edge: Edge) {
|
||||||
|
if (_outgoingEdges == null) {
|
||||||
|
_outgoingEdges = createEmptyEdgeMapWithDefault()
|
||||||
|
}
|
||||||
|
_outgoingEdges?.put(to, edge)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: may be it should be made MapWithImplicitDefault and override getOrImplicitDefault and not get
|
||||||
|
// However, it works even in the current form
|
||||||
|
private object EmptyEdgesMap : AbstractMap<CFGNode<*>, Edge>() {
|
||||||
|
override val entries: Set<Map.Entry<CFGNode<*>, Edge>>
|
||||||
|
get() = emptySet()
|
||||||
|
|
||||||
|
override fun get(key: CFGNode<*>): Edge = Edge.Normal_Forward
|
||||||
|
}
|
||||||
|
|
||||||
|
val incomingEdges: Map<CFGNode<*>, Edge> get() = _incomingEdges ?: EmptyEdgesMap
|
||||||
|
val outgoingEdges: Map<CFGNode<*>, Edge> get() = _outgoingEdges ?: EmptyEdgesMap
|
||||||
|
|
||||||
abstract val fir: E
|
abstract val fir: E
|
||||||
var isDead: Boolean = false
|
var isDead: Boolean = false
|
||||||
|
|||||||
Reference in New Issue
Block a user