Skip to content

Commit dde9647

Browse files
committed
move logic for IrType.findSimpleBound() to frontend (as IrType.concreteUpperBound)
1 parent 9250b2d commit dde9647

7 files changed

Lines changed: 31 additions & 36 deletions

File tree

backend-api/src/main/kotlin/io/github/tmarsteel/emerge/backend/api/ir/type.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,22 @@ sealed interface IrType {
55
val mutability: IrTypeMutability
66

77
fun asNullable(): IrType
8+
9+
/**
10+
* If this type is already concrete (based on [IrSimpleType]), should return itself.
11+
* If this is a generic or composite type, should return a concrete type that is the/an upper bound to
12+
* the generic or compound type. This upper bound errs on the side of being less abstract for the sake of
13+
* making sure that the [concreteUpperBound] is truly a superset of `this` type.
14+
*/
15+
val concreteUpperBound: IrBaseType
816
}
917

1018
interface IrSimpleType : IrType {
1119
val baseType: IrBaseType
1220

1321
override fun asNullable(): IrSimpleType
22+
23+
override val concreteUpperBound get()= baseType
1424
}
1525

1626
interface IrParameterizedType : IrType {
@@ -22,6 +32,8 @@ interface IrParameterizedType : IrType {
2232

2333
override fun asNullable(): IrParameterizedType
2434

35+
override val concreteUpperBound get()= simpleType.concreteUpperBound
36+
2537
interface Argument {
2638
val variance: IrTypeVariance
2739
val type: IrType
@@ -49,6 +61,8 @@ interface IrGenericTypeReference : IrType {
4961
override val mutability get() = effectiveBound.mutability
5062
override val isNullable get() = effectiveBound.isNullable
5163
override fun asNullable(): IrGenericTypeReference
64+
65+
override val concreteUpperBound get()= effectiveBound.concreteUpperBound
5266
}
5367

5468
interface IrIntersectionType : IrType {

frontend/src/main/kotlin/compiler/binding/type/BoundIntersectionTypeReference.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import compiler.diagnostic.simplifiableIntersectionType
1818
import compiler.lexer.Operator
1919
import compiler.lexer.Span
2020
import compiler.util.twoElementPermutationsUnordered
21+
import io.github.tmarsteel.emerge.backend.api.ir.IrBaseType
2122
import io.github.tmarsteel.emerge.backend.api.ir.IrIntersectionType
2223
import io.github.tmarsteel.emerge.backend.api.ir.IrType
2324
import io.github.tmarsteel.emerge.backend.api.ir.IrTypeMutability
@@ -280,6 +281,7 @@ class BoundIntersectionTypeReference private constructor(
280281
components.map { it.toBackendIr() },
281282
this.isNullable,
282283
this.mutability.toBackendIr(),
284+
baseTypeOfLowerBound.toBackendIr(),
283285
)
284286
}
285287
override fun toBackendIr(): IrType {
@@ -541,15 +543,18 @@ private class IrIntersectionTypeImpl(
541543
override val components: List<IrType>,
542544
override val isNullable: Boolean,
543545
override val mutability: IrTypeMutability,
546+
override val concreteUpperBound: IrBaseType,
544547
) : IrIntersectionType {
545548
override fun asNullable(): IrType {
546549
if (isNullable) {
547550
return this
548551
}
552+
549553
return IrIntersectionTypeImpl(
550554
components.map { it.asNullable() },
551555
true,
552556
mutability,
557+
concreteUpperBound,
553558
)
554559
}
555560
}

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/Autoboxer.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import io.github.tmarsteel.emerge.backend.api.ir.IrTemporaryValueReference
88
import io.github.tmarsteel.emerge.backend.api.ir.IrType
99
import io.github.tmarsteel.emerge.backend.api.ir.independentEquals
1010
import io.github.tmarsteel.emerge.backend.llvm.Autoboxer.Companion.autoBoxOrUnbox
11-
import io.github.tmarsteel.emerge.backend.llvm.codegen.findSimpleTypeBound
1211
import io.github.tmarsteel.emerge.backend.llvm.codegen.llvmValue
1312
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder
1413
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder.Companion.retVoid
@@ -120,8 +119,7 @@ internal sealed interface Autoboxer {
120119
return true
121120
}
122121

123-
val valueTypeBound = type.findSimpleTypeBound()
124-
if (valueTypeBound.baseType != primitiveTypeGetter(context)) {
122+
if (type.concreteUpperBound != primitiveTypeGetter(context)) {
125123
return true
126124
}
127125

@@ -220,8 +218,7 @@ internal sealed interface Autoboxer {
220218
return true
221219
}
222220

223-
val valueTypeBound = type.findSimpleTypeBound()
224-
if (valueTypeBound.baseType != context.rawReflectionBaseTypeClazz) {
221+
if (type.concreteUpperBound != context.rawReflectionBaseTypeClazz) {
225222
return true
226223
}
227224

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/codegen/codegen.kt

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ import io.github.tmarsteel.emerge.backend.llvm.IrSimpleTypeImpl
5959
import io.github.tmarsteel.emerge.backend.llvm.StateTackDelegate
6060
import io.github.tmarsteel.emerge.backend.llvm.allDistinctSupertypesExceptAny
6161
import io.github.tmarsteel.emerge.backend.llvm.autoboxer
62-
import io.github.tmarsteel.emerge.backend.llvm.baseBaseType
6362
import io.github.tmarsteel.emerge.backend.llvm.diScope
6463
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder
6564
import io.github.tmarsteel.emerge.backend.llvm.dsl.KotlinLlvmFunction
@@ -354,7 +353,7 @@ internal fun BasicBlockBuilder<EmergeLlvmContext, LlvmType>.emitCode(
354353
if (functionHasNothrowAbi) {
355354
// verify that the catch can even do something about the exception
356355
val isStaticallyASubtypeOfError = code.throwable.type
357-
.findSimpleTypeBound().baseType
356+
.concreteUpperBound
358357
.allDistinctSupertypesExceptAny
359358
.any { it.canonicalName == EmergeConstants.CoreModule.ERROR_TYPE_NAME }
360359
if (isStaticallyASubtypeOfError) {
@@ -517,7 +516,7 @@ internal fun BasicBlockBuilder<EmergeLlvmContext, LlvmType>.emitExpressionCode(
517516
)
518517
}
519518
is IrClassFieldAccessExpression -> {
520-
if (expression.baseBaseType.canonicalName.toString() == "emerge.core.Array") {
519+
if (expression.base.type.concreteUpperBound.canonicalName.toString() == "emerge.core.Array") {
521520
if (expression.memberVariable?.name == "size") {
522521
val memberValue = callIntrinsic(arraySize, listOf(expression.base.declaration.llvmValue))
523522
return ExpressionResult.Value(
@@ -730,7 +729,7 @@ internal fun BasicBlockBuilder<EmergeLlvmContext, LlvmType>.emitExpressionCode(
730729
}
731730
}
732731
is IrNumericComparisonExpression -> {
733-
val operandType = expression.lhs.type.findSimpleTypeBound().baseType
732+
val operandType = expression.lhs.type.concreteUpperBound
734733
if (operandType.canonicalName.simpleName in setOf("F32", "F64")) {
735734
TODO("floating point comparison not implemented yet")
736735
}
@@ -978,20 +977,6 @@ private fun BasicBlockBuilder<EmergeLlvmContext, LlvmType>.getPointerToStructMem
978977
.get()
979978
}
980979

981-
// todo: move to utils package
982-
internal fun IrType.findSimpleTypeBound(): IrSimpleType {
983-
var carry: IrType = this
984-
while (carry !is IrSimpleType) {
985-
carry = when (carry) {
986-
is IrParameterizedType -> carry.simpleType
987-
is IrGenericTypeReference -> carry.effectiveBound
988-
else -> error("how the hell did this happen??")
989-
}
990-
}
991-
992-
return carry
993-
}
994-
995980
private sealed interface ArrayDispatchOverride {
996981
/** there is no override, the regular approach works */
997982
object None : ArrayDispatchOverride
@@ -1016,7 +1001,7 @@ private sealed interface ArrayDispatchOverride {
10161001
private fun findForInstanceFunction(invocation: IrStaticDispatchFunctionInvocationExpression, context: EmergeLlvmContext): ArrayDispatchOverride {
10171002
val elementTypeArg = (invocation.arguments.first().type as IrParameterizedType).arguments.getValue("Element")
10181003

1019-
val elementTypeBound = elementTypeArg.type.findSimpleTypeBound().baseType
1004+
val elementTypeBound = elementTypeArg.type.concreteUpperBound
10201005
val accessType = if (elementTypeBound.canonicalName.toString() == "emerge.core.Any") {
10211006
if (elementTypeArg.type !is IrGenericTypeReference && elementTypeArg.variance == IrTypeVariance.INVARIANT) {
10221007
ArrayAccessType.REFERENCE_TYPE_DIRECT
@@ -1149,7 +1134,7 @@ private sealed interface ArrayDispatchOverride {
11491134
private fun findForStaticFunction(invocation: IrStaticDispatchFunctionInvocationExpression, context: EmergeLlvmContext): ArrayDispatchOverride {
11501135
if (invocation.function.canonicalName.simpleName == "new" && invocation.function.parameters.size == 2) {
11511136
val elementTypeArg = (invocation.evaluatesTo as IrParameterizedType).arguments.getValue("Element")
1152-
val elementTypeBound = elementTypeArg.type.findSimpleTypeBound().baseType
1137+
val elementTypeBound = elementTypeArg.type.concreteUpperBound
11531138
return InvokeIntrinsic(when (elementTypeBound) {
11541139
context.rawS8Clazz -> EmergeS8ArrayType.defaultValueConstructor
11551140
context.rawU8Clazz -> EmergeU8ArrayType.defaultValueConstructor
@@ -1167,7 +1152,7 @@ private sealed interface ArrayDispatchOverride {
11671152
}
11681153

11691154
if (invocation.function.canonicalName.simpleName == "copy" && invocation.function.parameters.size == 5) {
1170-
val elementType = (invocation.typeArgumentsAtCallSite.getValue("T")).findSimpleTypeBound().baseType
1155+
val elementType = (invocation.typeArgumentsAtCallSite.getValue("T")).concreteUpperBound
11711156
return when (elementType) {
11721157
context.rawS8Clazz -> InvokeIntrinsic(EmergeS8ArrayCopyFn)
11731158
context.rawU8Clazz -> InvokeIntrinsic(EmergeU8ArrayCopyFn)

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/intrinsics/EmergeClassType.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import io.github.tmarsteel.emerge.backend.api.ir.IrInterface
88
import io.github.tmarsteel.emerge.backend.llvm.allDistinctSupertypesExceptAny
99
import io.github.tmarsteel.emerge.backend.llvm.associateErrorOnDuplicate
1010
import io.github.tmarsteel.emerge.backend.llvm.codegen.emergeStringLiteral
11-
import io.github.tmarsteel.emerge.backend.llvm.codegen.findSimpleTypeBound
1211
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder
1312
import io.github.tmarsteel.emerge.backend.llvm.dsl.DiBuilder
1413
import io.github.tmarsteel.emerge.backend.llvm.dsl.GetElementPointerStep
@@ -61,7 +60,7 @@ internal class EmergeClassType private constructor(
6160
}
6261

6362
// boxing types have only one field, holding the boxed value. We use the name of that
64-
return irClass.fields.single().type.findSimpleTypeBound().baseType.canonicalName
63+
return irClass.fields.single().type.concreteUpperBound.canonicalName
6564
}
6665

6766
private val typeinfoProvider by lazy {

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/intrinsics/EmergeLlvmContext.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import io.github.tmarsteel.emerge.backend.llvm.codegen.emitCode
3030
import io.github.tmarsteel.emerge.backend.llvm.codegen.emitExpressionCode
3131
import io.github.tmarsteel.emerge.backend.llvm.codegen.emitRead
3232
import io.github.tmarsteel.emerge.backend.llvm.codegen.emitWrite
33-
import io.github.tmarsteel.emerge.backend.llvm.codegen.findSimpleTypeBound
3433
import io.github.tmarsteel.emerge.backend.llvm.codegen.sizeof
3534
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder
3635
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder.Companion.retVoid
@@ -722,13 +721,13 @@ class EmergeLlvmContext(
722721

723722
if (intrinsic == null && fn.canonicalName.parent == CanonicalElementName.Package(listOf("emerge", "core", "safemath")) && fn.parameters.size == 2) {
724723
intrinsic = safemathFns[fn.canonicalName.simpleName]
725-
?.get(fn.parameters.first().type.findSimpleTypeBound().baseType.canonicalName.simpleName)
724+
?.get(fn.parameters.first().type.concreteUpperBound.canonicalName.simpleName)
726725
?.let { registerIntrinsic(it) }
727726
}
728727

729728
if (intrinsic == null && fn.canonicalName.parent == CanonicalElementName.Package(listOf("emerge", "platform")) && fn.canonicalName.simpleName == "panic") {
730729
if (fn.parameters.size == 1) {
731-
val paramType = fn.parameters.single().type.findSimpleTypeBound().baseType
730+
val paramType = fn.parameters.single().type.concreteUpperBound
732731
if (paramType.canonicalName.simpleName == "String") {
733732
intrinsic = registerIntrinsic(panicOnString)
734733
}

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/ir_amendment.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import io.github.tmarsteel.emerge.backend.api.ir.IrSimpleType
1313
import io.github.tmarsteel.emerge.backend.api.ir.IrSoftwareContext
1414
import io.github.tmarsteel.emerge.backend.api.ir.IrType
1515
import io.github.tmarsteel.emerge.backend.api.ir.IrVariableDeclaration
16-
import io.github.tmarsteel.emerge.backend.llvm.codegen.findSimpleTypeBound
1716
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder
1817
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmBooleanType
1918
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmDebugInfo
@@ -147,11 +146,8 @@ internal var IrVariableDeclaration.Scope.diScope: LlvmDebugInfo.Scope.LexicalBlo
147146
internal var IrLoop.emitBreak: (() -> BasicBlockBuilder.Termination)? by tackState { null }
148147
internal var IrLoop.emitContinue: (() -> BasicBlockBuilder.Termination)? by tackState { null }
149148

150-
internal val IrClassFieldAccessExpression.baseBaseType: IrBaseType by tackLazyVal {
151-
base.type.findSimpleTypeBound().baseType
152-
}
153149
internal val IrClassFieldAccessExpression.memberVariable: IrClass.MemberVariable? by tackLazyVal {
154-
val localBaseBaseType = baseBaseType
150+
val localBaseBaseType = base.type.concreteUpperBound
155151
if (localBaseBaseType !is IrClass) {
156152
return@tackLazyVal null
157153
}

0 commit comments

Comments
 (0)