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:
Ilya Matveev
2017-07-24 16:42:11 +07:00
committed by ilmat192
parent 0e67fbb7ad
commit 12f815eabb
5 changed files with 50 additions and 19 deletions
@@ -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.
@@ -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)
}
@@ -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"),
@@ -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)
}
@@ -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
}
})
}
}