JVM_IR: make ToArrayLowering linear in complexity

by not running DFS from every node visited during another DFS.
This commit is contained in:
pyos
2019-04-25 10:52:06 +02:00
parent f118b007f0
commit 4b0b9e1f80
@@ -39,19 +39,10 @@ internal val toArrayPhase = makeIrFilePhase(
private class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
override fun lower(irClass: IrClass) {
if (irClass.isJvmInterface) return
if (irClass.isJvmInterface || !irClass.isDirectCollectionSubClass()) return
val irBuiltIns = context.irBuiltIns
if (!irClass.isCollectionSubClass()) return
if (irClass.hasSuperClass {
it != irClass &&
it.isClass &&
it.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB &&
it.isCollectionSubClass()
}) return
val toArrayName = Name.identifier("toArray")
val genericToArray = irClass.declarations.find { it.isGenericToArray() }
val nonGenericToArray = irClass.declarations.find { it.isNonGenericToArray() }
@@ -305,15 +296,15 @@ private class ToArrayLowering(private val context: JvmBackendContext) : ClassLow
}
}
private fun IrClass.hasSuperClass(pred: (IrClass) -> Boolean): Boolean =
DFS.ifAny(
listOf(this),
{ irClass -> irClass.superTypes.mapNotNull { ((it as? IrSimpleType)?.classifier as? IrClassSymbol)?.owner } },
pred
)
private val IrClass.superClasses
get() = superTypes.mapNotNull { it.getClass() }
// Have to check by name, since irBuiltins is unreliable.
private fun IrClass.isCollectionSubClass() =
hasSuperClass {
it.defaultType.isCollection()
}
DFS.ifAny(listOf(this), IrClass::superClasses) { it.defaultType.isCollection() }
// If this class inherits from another Kotlin class that implements Collection, it already has toArray.
private fun IrClass.isDirectCollectionSubClass() =
isCollectionSubClass() && !superClasses.any {
it.isClass && it.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && it.isCollectionSubClass()
}