JVM_IR: make ToArrayLowering linear in complexity
by not running DFS from every node visited during another DFS.
This commit is contained in:
+9
-18
@@ -39,19 +39,10 @@ internal val toArrayPhase = makeIrFilePhase(
|
|||||||
private class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
private class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
if (irClass.isJvmInterface) return
|
if (irClass.isJvmInterface || !irClass.isDirectCollectionSubClass()) return
|
||||||
|
|
||||||
val irBuiltIns = context.irBuiltIns
|
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 toArrayName = Name.identifier("toArray")
|
||||||
val genericToArray = irClass.declarations.find { it.isGenericToArray() }
|
val genericToArray = irClass.declarations.find { it.isGenericToArray() }
|
||||||
val nonGenericToArray = irClass.declarations.find { it.isNonGenericToArray() }
|
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 =
|
private val IrClass.superClasses
|
||||||
DFS.ifAny(
|
get() = superTypes.mapNotNull { it.getClass() }
|
||||||
listOf(this),
|
|
||||||
{ irClass -> irClass.superTypes.mapNotNull { ((it as? IrSimpleType)?.classifier as? IrClassSymbol)?.owner } },
|
|
||||||
pred
|
|
||||||
)
|
|
||||||
|
|
||||||
// Have to check by name, since irBuiltins is unreliable.
|
// Have to check by name, since irBuiltins is unreliable.
|
||||||
private fun IrClass.isCollectionSubClass() =
|
private fun IrClass.isCollectionSubClass() =
|
||||||
hasSuperClass {
|
DFS.ifAny(listOf(this), IrClass::superClasses) { it.defaultType.isCollection() }
|
||||||
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()
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user