Skip to content

Commit

Permalink
m
Browse files Browse the repository at this point in the history
  • Loading branch information
AbdullinAM committed Nov 7, 2023
1 parent 0642b8f commit c5406f9
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.vorpal.research.kfg.KfgException
import org.vorpal.research.kfg.ir.value.UsageContext
import org.vorpal.research.kfg.ir.value.instruction.PhiInst
import org.vorpal.research.kfg.type.Type
import org.vorpal.research.kfg.type.mergeTypes
import org.vorpal.research.kfg.type.commonSupertype
import org.vorpal.research.kfg.visitor.MethodVisitor

class TypeMergeFailedException(val types: Set<Type>) : KfgException()
Expand All @@ -16,7 +16,7 @@ class NullTypeAdapter(override val cm: ClassManager, val ctx: UsageContext) : Me
override fun visitPhiInst(inst: PhiInst) = with(ctx) {
if (inst.type == types.nullType) {
val incomingTypes = inst.incomingValues.mapTo(mutableSetOf()) { it.type }
val actualType = mergeTypes(types, incomingTypes) ?: throw TypeMergeFailedException(incomingTypes)
val actualType = commonSupertype(incomingTypes) ?: throw TypeMergeFailedException(incomingTypes)
val newPhi = inst(cm) { phi(actualType, inst.incomings) }
inst.parent.insertBefore(inst, newPhi)
inst.replaceAllUsesWith(newPhi)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import org.vorpal.research.kfg.ir.value.instruction.ReturnInst
import org.vorpal.research.kfg.type.Integer
import org.vorpal.research.kfg.type.Type
import org.vorpal.research.kfg.type.TypeFactory
import org.vorpal.research.kfg.type.mergeTypes
import org.vorpal.research.kfg.type.commonSupertype
import org.vorpal.research.kfg.visitor.MethodVisitor
import org.vorpal.research.kthelper.assert.ktassert
import kotlin.math.abs
Expand Down Expand Up @@ -61,7 +61,7 @@ class RetvalBuilder(override val cm: ClassManager, override val ctx: UsageContex
val returnInstruction = when {
returnType.isVoid -> `return`()
else -> {
val type = mergeTypes(types, incomings.values.mapTo(mutableSetOf()) { it.type }) ?: returnType
val type = commonSupertype(incomings.values.mapTo(mutableSetOf()) { it.type }) ?: returnType

val returnValuePhi = phi("retval", type, incomings)
instructions.add(returnValuePhi)
Expand Down
42 changes: 27 additions & 15 deletions src/main/kotlin/org/vorpal/research/kfg/type/util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,28 @@ val Type.internalDesc: String
else -> throw InvalidStateException("Unknown type ${this.name}")
}

fun mergeTypes(tf: TypeFactory, types: Set<Type>): Type? = when {
tf.nullType in types -> {
val filtered = types.filterNotTo(mutableSetOf()) { it == tf.nullType }
@Suppress("RecursivePropertyAccessor")
val Type.typeFactory: TypeFactory? get() = when (this) {
is PrimitiveType -> null
is ClassType -> klass.cm.type
is ArrayType -> component.typeFactory
else -> null
}

fun commonSupertype(types: Set<Type>): Type? = when {
NullType in types -> {
val filtered = types.filterNotTo(mutableSetOf()) { it == NullType }
when {
filtered.isEmpty() -> tf.nullType
else -> mergeTypes(tf, filtered)
filtered.isEmpty() -> NullType
else -> commonSupertype(filtered)
}
}

types.size == 1 -> types.first()
types.all { it is Integer } -> types.maxByOrNull { (it as Integer).width }
types.all { it is ClassType } -> {
val classes = types.map { it as ClassType }
val tf = classes.firstNotNullOf { it.typeFactory }
var result = tf.objectType
for (i in classes.indices) {
val isAncestor = classes.fold(true) { acc, klass ->
Expand All @@ -43,18 +52,21 @@ fun mergeTypes(tf: TypeFactory, types: Set<Type>): Type? = when {
result
}

types.all { it is Reference } -> when {
types.any { it is ClassType } -> tf.objectType
types.map { it as ArrayType }.mapTo(mutableSetOf()) { it.component }.size == 1 -> types.first()
types.all { it is ArrayType } -> {
val components = types.mapTo(mutableSetOf()) { (it as ArrayType).component }
when (val merged = mergeTypes(tf, components)) {
null -> tf.objectType
else -> tf.getArrayType(merged)
types.all { it is Reference } -> {
val tf = types.firstNotNullOfOrNull { it.typeFactory }
when {
types.any { it is ClassType } -> tf?.objectType
types.map { it as ArrayType }.mapTo(mutableSetOf()) { it.component }.size == 1 -> types.first()
types.all { it is ArrayType } -> {
val components = types.mapTo(mutableSetOf()) { (it as ArrayType).component }
when (val merged = commonSupertype(components)) {
null -> tf?.objectType
else -> merged.asArray
}
}
}

else -> tf.objectType
else -> tf?.objectType
}
}

else -> null
Expand Down

0 comments on commit c5406f9

Please sign in to comment.