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.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
// This is what Context collects about IR.
|
||||
|
||||
+4
@@ -40,6 +40,10 @@ internal class KonanLower(val context: Context) {
|
||||
fun lowerModule(irModule: IrModuleFragment) {
|
||||
val phaser = PhaseManager(context)
|
||||
|
||||
phaser.phase(KonanPhase.LOWER_SPECIAL_CALLS) {
|
||||
irModule.files.forEach(SpecialCallsLowering(context)::lower)
|
||||
}
|
||||
|
||||
phaser.phase(KonanPhase.LOWER_INLINE_CONSTRUCTORS) {
|
||||
InlineConstructorsTransformation(context).lower(irModule)
|
||||
}
|
||||
|
||||
+3
-2
@@ -28,8 +28,9 @@ enum class KonanPhase(val description: String,
|
||||
/* */ SERIALIZER("Serialize descriptor tree and inline IR bodies"),
|
||||
/* */ BACKEND("All backend"),
|
||||
/* ... */ LOWER("IR Lowering"),
|
||||
/* ... ... */ LOWER_INLINE_CONSTRUCTORS("Inline constructors transformation"),
|
||||
/* ... ... */ LOWER_INLINE("Functions inlining", LOWER_INLINE_CONSTRUCTORS),
|
||||
/* ... ... */ LOWER_SPECIAL_CALLS("Special calls processing before inlining"),
|
||||
/* ... ... */ LOWER_INLINE_CONSTRUCTORS("Inline constructors transformation", LOWER_SPECIAL_CALLS),
|
||||
/* ... ... */ LOWER_INLINE("Functions inlining", LOWER_INLINE_CONSTRUCTORS, LOWER_SPECIAL_CALLS),
|
||||
/* ... ... ... */ DESERIALIZER("Deserialize inline bodies"),
|
||||
/* ... ... */ LOWER_INTEROP_PART1("Interop lowering, part 1", LOWER_INLINE),
|
||||
/* ... ... */ 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.atMostOne
|
||||
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.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.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.isNullConst
|
||||
import org.jetbrains.kotlin.ir.util.type
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
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.isSubtypeOf
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
|
||||
/**
|
||||
* 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 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 {
|
||||
expression.transformChildrenVoid(this)
|
||||
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) {
|
||||
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