[devirtualization] Replaced List<Int> with custom IntArrayList

This commit is contained in:
Igor Chevdar
2020-03-02 19:59:26 +03:00
parent 19240d21ee
commit 914cf96278
2 changed files with 87 additions and 26 deletions
@@ -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 {
@@ -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++)
}
}