[devirtualization] Replaced List<Int> with custom IntArrayList
This commit is contained in:
+28
-26
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.util.IntArrayList
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
@@ -119,10 +120,9 @@ internal object Devirtualization {
|
||||
|
||||
private val symbolTable = moduleDFG.symbolTable
|
||||
|
||||
sealed class Node(val id: Int) : DirectedGraphNode<Node> {
|
||||
override var directEdges: MutableList<Node>? = null
|
||||
override var reversedEdges : MutableList<Node>? = null
|
||||
override val key get() = this
|
||||
sealed class Node(val id: Int) {
|
||||
var directEdges: IntArrayList? = null
|
||||
var reversedEdges: IntArrayList? = null
|
||||
|
||||
var directCastEdges: MutableList<CastEdge>? = null
|
||||
var reversedCastEdges: MutableList<CastEdge>? = null
|
||||
@@ -137,10 +137,10 @@ internal object Devirtualization {
|
||||
val multiNodeSize get() = multiNodeEnd - multiNodeStart
|
||||
|
||||
fun addEdge(node: Node) {
|
||||
if (directEdges == null) directEdges = ArrayList(1)
|
||||
directEdges!!.add(node)
|
||||
if (node.reversedEdges == null) node.reversedEdges = ArrayList(1)
|
||||
node.reversedEdges!!.add(this)
|
||||
if (directEdges == null) directEdges = IntArrayList()
|
||||
node.directEdges!!.add(node.id)
|
||||
if (node.reversedEdges == null) node.reversedEdges = IntArrayList()
|
||||
node.reversedEdges!!.add(id)
|
||||
}
|
||||
|
||||
fun addCastEdge(edge: CastEdge) {
|
||||
@@ -177,12 +177,11 @@ internal object Devirtualization {
|
||||
|
||||
class Function(val symbol: DataFlowIR.FunctionSymbol, val parameters: Array<Node>, val returns: Node, val throws: Node)
|
||||
|
||||
inner class ConstraintGraph : DirectedGraph<Node, Node> {
|
||||
inner class ConstraintGraph {
|
||||
|
||||
private var nodesCount = 0
|
||||
|
||||
override val nodes = mutableListOf<Node>()
|
||||
override fun get(key: Node) = key
|
||||
val nodes = mutableListOf<Node>()
|
||||
|
||||
val voidNode = addNode { Node.Ordinary(it, { "Void" }) }
|
||||
val virtualNode = addNode { Node.Source(it, VIRTUAL_TYPE_ID, { "Virtual" }) }
|
||||
@@ -449,11 +448,12 @@ internal object Devirtualization {
|
||||
fun BitSet.copy() = BitSet(this.size()).apply { this.or(this@copy) }
|
||||
|
||||
fun printPathToType(node: Node, type: Int) {
|
||||
val visited = mutableSetOf<Node>()
|
||||
val nodes = constraintGraph.nodes
|
||||
val visited = BitSet()
|
||||
val prev = mutableMapOf<Node, Node>()
|
||||
var front = mutableListOf<Node>()
|
||||
front.add(node)
|
||||
visited.add(node)
|
||||
visited.set(node.id)
|
||||
lateinit var source: Node.Source
|
||||
bfs@while (front.isNotEmpty()) {
|
||||
val prevFront = front
|
||||
@@ -461,9 +461,10 @@ internal object Devirtualization {
|
||||
for (from in prevFront) {
|
||||
val reversedEdges = from.reversedEdges
|
||||
if (reversedEdges != null)
|
||||
for (to in reversedEdges) {
|
||||
if (!visited.contains(to) && to.types[type]) {
|
||||
visited.add(to)
|
||||
for (toId in reversedEdges) {
|
||||
val to = nodes[toId]
|
||||
if (!visited[toId] && to.types[type]) {
|
||||
visited.set(toId)
|
||||
prev[to] = from
|
||||
front.add(to)
|
||||
if (to is Node.Source) {
|
||||
@@ -476,8 +477,8 @@ internal object Devirtualization {
|
||||
if (reversedCastEdges != null)
|
||||
for (castEdge in reversedCastEdges) {
|
||||
val to = castEdge.node
|
||||
if (!visited.contains(to) && castEdge.suitableTypes[type] && to.types[type]) {
|
||||
visited.add(to)
|
||||
if (!visited[to.id] && castEdge.suitableTypes[type] && to.types[type]) {
|
||||
visited.set(to.id)
|
||||
prev[to] = from
|
||||
front.add(to)
|
||||
if (to is Node.Source) {
|
||||
@@ -552,8 +553,8 @@ internal object Devirtualization {
|
||||
private fun findOrder(node: Node, order: IntArray) {
|
||||
visited.set(node.id)
|
||||
node.directEdges?.forEach {
|
||||
if (!visited[it.id])
|
||||
findOrder(it, order)
|
||||
if (!visited[it])
|
||||
findOrder(nodes[it], order)
|
||||
}
|
||||
order[index++] = node.id
|
||||
}
|
||||
@@ -562,8 +563,8 @@ internal object Devirtualization {
|
||||
visited.set(node.id)
|
||||
multiNodes[index++] = node.id
|
||||
node.reversedEdges?.forEach {
|
||||
if (!visited[it.id])
|
||||
paint(it)
|
||||
if (!visited[it])
|
||||
paint(nodes[it])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,7 +573,7 @@ internal object Devirtualization {
|
||||
for (v in multiNode.multiNodeStart until multiNode.multiNodeEnd) {
|
||||
val node = nodes[multiNodes[v]]
|
||||
node.directEdges?.forEach {
|
||||
val nextMultiNode = multiNodes[it.multiNodeStart]
|
||||
val nextMultiNode = multiNodes[nodes[it].multiNodeStart]
|
||||
if (!visited[nextMultiNode])
|
||||
findMultiNodesOrder(nodes[nextMultiNode], order)
|
||||
}
|
||||
@@ -605,7 +606,7 @@ internal object Devirtualization {
|
||||
constraintGraph.nodes.forEach {
|
||||
println(" NODE #${it.id}")
|
||||
it.directEdges?.forEach {
|
||||
println(" EDGE: #${it.id}z")
|
||||
println(" EDGE: #${it}z")
|
||||
}
|
||||
it.directCastEdges?.forEach {
|
||||
println(" CAST EDGE: #${it.node.id}z casted to ${it.suitableTypes.format(allTypes)}")
|
||||
@@ -666,7 +667,7 @@ internal object Devirtualization {
|
||||
continue // A source has no incoming edges.
|
||||
val types = BitSet()
|
||||
condensation.forEachNode(multiNode) { node ->
|
||||
node.reversedEdges?.forEach { types.or(it.types) }
|
||||
node.reversedEdges?.forEach { types.or(constraintGraph.nodes[it].types) }
|
||||
node.reversedCastEdges
|
||||
?.filter { it.node.priority < node.priority } // Doesn't contradict topological order.
|
||||
?.forEach {
|
||||
@@ -720,7 +721,8 @@ internal object Devirtualization {
|
||||
for (i in 0 until prevFrontSize) {
|
||||
marked[prevFront[i]] = false
|
||||
val node = constraintGraph.nodes[prevFront[i]]
|
||||
node.directEdges?.forEach { distNode ->
|
||||
node.directEdges?.forEach { distNodeId ->
|
||||
val distNode = constraintGraph.nodes[distNodeId]
|
||||
if (marked[distNode.id])
|
||||
distNode.types.or(node.types)
|
||||
else {
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.util
|
||||
|
||||
class IntArrayList : Iterable<Int> {
|
||||
private var array = IntArray(3)
|
||||
private var length = 0
|
||||
|
||||
val size get() = length
|
||||
|
||||
fun isEmpty() = size == 0
|
||||
|
||||
fun add(x: Int) {
|
||||
length++
|
||||
ensureCapacity(length)
|
||||
set(length - 1, x)
|
||||
}
|
||||
|
||||
fun reserve(minSize: Int) {
|
||||
if (length >= minSize) return
|
||||
length = minSize
|
||||
ensureCapacity(minSize)
|
||||
}
|
||||
|
||||
operator fun get(index: Int): Int = when {
|
||||
index < 0 || index >= length -> throw IndexOutOfBoundsException("Index out of range: $index")
|
||||
|
||||
else -> array[index]
|
||||
}
|
||||
|
||||
operator fun set(index: Int, x: Int) = when {
|
||||
index < 0 || index >= length -> throw IndexOutOfBoundsException("Index out of range: $index")
|
||||
|
||||
else -> array[index] = x
|
||||
}
|
||||
|
||||
override operator fun iterator(): Iterator<Int> = Itr()
|
||||
|
||||
private fun ensureCapacity(minCapacity: Int) {
|
||||
val oldArray = array
|
||||
if (minCapacity > oldArray.size) {
|
||||
var newSize = oldArray.size * 3 / 2
|
||||
if (minCapacity > newSize)
|
||||
newSize = minCapacity
|
||||
array = oldArray.copyOf(newSize)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Itr : Iterator<Int> {
|
||||
private var index = 0
|
||||
|
||||
override fun hasNext() = index < size
|
||||
|
||||
override fun next() = get(index++)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user