[Wasm] Better preserve IR types after inlining
This commit is contained in:
+27
-7
@@ -74,7 +74,8 @@ open class DefaultInlineFunctionResolver(open val context: CommonBackendContext)
|
||||
class FunctionInlining(
|
||||
val context: CommonBackendContext,
|
||||
val inlineFunctionResolver: InlineFunctionResolver,
|
||||
val innerClassesSupport: InnerClassesSupport? = null
|
||||
val innerClassesSupport: InnerClassesSupport? = null,
|
||||
val insertAdditionalImplicitCasts: Boolean = false
|
||||
) : IrElementTransformerVoidWithContext(), BodyLoweringPass {
|
||||
|
||||
constructor(context: CommonBackendContext) : this(context, DefaultInlineFunctionResolver(context), null)
|
||||
@@ -83,6 +84,12 @@ class FunctionInlining(
|
||||
DefaultInlineFunctionResolver(context),
|
||||
innerClassesSupport
|
||||
)
|
||||
constructor(context: CommonBackendContext, innerClassesSupport: InnerClassesSupport?, insertAdditionalImplicitCasts: Boolean) : this(
|
||||
context,
|
||||
DefaultInlineFunctionResolver(context),
|
||||
innerClassesSupport,
|
||||
insertAdditionalImplicitCasts
|
||||
)
|
||||
|
||||
private var containerScope: ScopeWithIr? = null
|
||||
|
||||
@@ -210,8 +217,14 @@ class FunctionInlining(
|
||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
if (expression.returnTargetSymbol == copiedCallee.symbol)
|
||||
return irBuilder.at(expression).irReturn(expression.value)
|
||||
if (expression.returnTargetSymbol == copiedCallee.symbol) {
|
||||
val expr =
|
||||
if (insertAdditionalImplicitCasts)
|
||||
expression.value.implicitCastIfNeededTo(callSite.type)
|
||||
else
|
||||
expression.value
|
||||
return irBuilder.at(expression).irReturn(expr)
|
||||
}
|
||||
return expression
|
||||
}
|
||||
})
|
||||
@@ -229,9 +242,15 @@ class FunctionInlining(
|
||||
|
||||
argument.transformChildrenVoid(this) // Default argument can contain subjects for substitution.
|
||||
|
||||
return if (argument is IrGetValueWithoutLocation)
|
||||
argument.withLocation(newExpression.startOffset, newExpression.endOffset)
|
||||
else (copyIrElement.copy(argument) as IrExpression)
|
||||
var ret =
|
||||
if (argument is IrGetValueWithoutLocation)
|
||||
argument.withLocation(newExpression.startOffset, newExpression.endOffset)
|
||||
else
|
||||
(copyIrElement.copy(argument) as IrExpression)
|
||||
|
||||
if (insertAdditionalImplicitCasts)
|
||||
ret = ret.implicitCastIfNeededTo(newExpression.type)
|
||||
return ret
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
@@ -388,7 +407,8 @@ class FunctionInlining(
|
||||
}
|
||||
|
||||
private fun IrExpression.implicitCastIfNeededTo(type: IrType) =
|
||||
if (type == this.type)
|
||||
// No need to cast expressions of type nothing
|
||||
if (type == this.type || (insertAdditionalImplicitCasts && this.type == context.irBuiltIns.nothingType))
|
||||
this
|
||||
else
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, this)
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ private val wrapInlineDeclarationsWithReifiedTypeParametersPhase = makeWasmModul
|
||||
|
||||
private val functionInliningPhase = makeCustomWasmModulePhase(
|
||||
{ context, module ->
|
||||
FunctionInlining(context).inline(module)
|
||||
FunctionInlining(context, null, true).inline(module)
|
||||
module.patchDeclarationParents()
|
||||
},
|
||||
name = "FunctionInliningPhase",
|
||||
|
||||
+6
@@ -177,6 +177,12 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
}
|
||||
}
|
||||
|
||||
// A bit of a hack. Inliner tends to insert null casts from nothing to any. It's hard to express in wasm, so we simply replace
|
||||
// them with single const null.
|
||||
if (toType == builtIns.anyNType && fromType == builtIns.nothingNType && value is IrConst<*> && value.kind == IrConstKind.Null) {
|
||||
return builder.irNull(builtIns.nothingNType)
|
||||
}
|
||||
|
||||
// Handled by autoboxing transformer
|
||||
if (toType.isInlined() && !fromType.isInlined()) {
|
||||
return builder.irCall(
|
||||
|
||||
Reference in New Issue
Block a user