backend: Add a call lowering pass before inlining
Some inlined calls may require additional processing before the inlining pass. E.g. assert() calls must be removed if assertions are disabled by compiler flags. This patch adds an additional pass before inlining and uses it for assertions removal.
This commit is contained in:
-1
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.SimpleType
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
// This is what Context collects about IR.
|
// This is what Context collects about IR.
|
||||||
|
|||||||
+4
@@ -40,6 +40,10 @@ internal class KonanLower(val context: Context) {
|
|||||||
fun lowerModule(irModule: IrModuleFragment) {
|
fun lowerModule(irModule: IrModuleFragment) {
|
||||||
val phaser = PhaseManager(context)
|
val phaser = PhaseManager(context)
|
||||||
|
|
||||||
|
phaser.phase(KonanPhase.LOWER_SPECIAL_CALLS) {
|
||||||
|
irModule.files.forEach(SpecialCallsLowering(context)::lower)
|
||||||
|
}
|
||||||
|
|
||||||
phaser.phase(KonanPhase.LOWER_INLINE_CONSTRUCTORS) {
|
phaser.phase(KonanPhase.LOWER_INLINE_CONSTRUCTORS) {
|
||||||
InlineConstructorsTransformation(context).lower(irModule)
|
InlineConstructorsTransformation(context).lower(irModule)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -28,8 +28,9 @@ enum class KonanPhase(val description: String,
|
|||||||
/* */ SERIALIZER("Serialize descriptor tree and inline IR bodies"),
|
/* */ SERIALIZER("Serialize descriptor tree and inline IR bodies"),
|
||||||
/* */ BACKEND("All backend"),
|
/* */ BACKEND("All backend"),
|
||||||
/* ... */ LOWER("IR Lowering"),
|
/* ... */ LOWER("IR Lowering"),
|
||||||
/* ... ... */ LOWER_INLINE_CONSTRUCTORS("Inline constructors transformation"),
|
/* ... ... */ LOWER_SPECIAL_CALLS("Special calls processing before inlining"),
|
||||||
/* ... ... */ LOWER_INLINE("Functions inlining", LOWER_INLINE_CONSTRUCTORS),
|
/* ... ... */ LOWER_INLINE_CONSTRUCTORS("Inline constructors transformation", LOWER_SPECIAL_CALLS),
|
||||||
|
/* ... ... */ LOWER_INLINE("Functions inlining", LOWER_INLINE_CONSTRUCTORS, LOWER_SPECIAL_CALLS),
|
||||||
/* ... ... ... */ DESERIALIZER("Deserialize inline bodies"),
|
/* ... ... ... */ DESERIALIZER("Deserialize inline bodies"),
|
||||||
/* ... ... */ LOWER_INTEROP_PART1("Interop lowering, part 1", LOWER_INLINE),
|
/* ... ... */ LOWER_INTEROP_PART1("Interop lowering, part 1", LOWER_INLINE),
|
||||||
/* ... ... */ LOWER_FOR_LOOPS("For loops lowering"),
|
/* ... ... */ LOWER_FOR_LOOPS("For loops lowering"),
|
||||||
|
|||||||
+4
-16
@@ -19,23 +19,20 @@ package org.jetbrains.kotlin.backend.konan.lower
|
|||||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys.Companion.ENABLE_ASSERTIONS
|
|
||||||
import org.jetbrains.kotlin.backend.konan.isStdlib
|
|
||||||
import org.jetbrains.kotlin.backend.konan.isValueType
|
import org.jetbrains.kotlin.backend.konan.isValueType
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptor
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltinOperatorDescriptor
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.isNullConst
|
import org.jetbrains.kotlin.ir.util.isNullConst
|
||||||
import org.jetbrains.kotlin.ir.util.type
|
import org.jetbrains.kotlin.ir.util.type
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This lowering pass lowers some calls to [IrBuiltinOperatorDescriptor]s.
|
* This lowering pass lowers some calls to [IrBuiltinOperatorDescriptor]s.
|
||||||
@@ -54,20 +51,11 @@ private class BuiltinOperatorTransformer(val context: Context) : IrElementTransf
|
|||||||
|
|
||||||
private val builtIns = context.builtIns
|
private val builtIns = context.builtIns
|
||||||
private val irBuiltins = context.irModule!!.irBuiltins
|
private val irBuiltins = context.irModule!!.irBuiltins
|
||||||
private val enableAssertions = context.config.configuration.getBoolean(ENABLE_ASSERTIONS)
|
|
||||||
|
|
||||||
private val assertSymbols = context.ir.symbols.asserts
|
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
expression.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
val descriptor = expression.descriptor
|
val descriptor = expression.descriptor
|
||||||
|
|
||||||
// Replace assert() call with an empty composite if assertions are not enabled.
|
|
||||||
if (!enableAssertions && expression.symbol in assertSymbols) {
|
|
||||||
assert(expression.type.isUnit())
|
|
||||||
return IrCompositeImpl(expression.startOffset, expression.endOffset, expression.type)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (descriptor is IrBuiltinOperatorDescriptor) {
|
if (descriptor is IrBuiltinOperatorDescriptor) {
|
||||||
return transformBuiltinOperator(expression)
|
return transformBuiltinOperator(expression)
|
||||||
}
|
}
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This pass runs before inlining and performs the following additional transformations over some calls:
|
||||||
|
* - Assertion call removal.
|
||||||
|
*/
|
||||||
|
internal class SpecialCallsLowering(val context: Context) : FileLoweringPass {
|
||||||
|
|
||||||
|
private val asserts = context.ir.symbols.asserts
|
||||||
|
private val enableAssertions = context.config.configuration.getBoolean(KonanConfigKeys.ENABLE_ASSERTIONS)
|
||||||
|
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
expression.transformChildrenVoid(this)
|
||||||
|
|
||||||
|
// Replace assert() call with an empty composite if assertions are not enabled.
|
||||||
|
if (!enableAssertions && expression.symbol in asserts) {
|
||||||
|
assert(expression.type.isUnit())
|
||||||
|
return IrCompositeImpl(expression.startOffset, expression.endOffset, expression.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return expression
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user