[DFG] Added node type <Null> + test
This commit is contained in:
+6
-1
@@ -542,9 +542,14 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
is IrGetValue -> getNode(value)
|
is IrGetValue -> getNode(value)
|
||||||
|
|
||||||
is IrVararg,
|
is IrVararg,
|
||||||
is IrConst<*>,
|
|
||||||
is IrFunctionReference -> DataFlowIR.Node.Const(symbolTable.mapType(value.type))
|
is IrFunctionReference -> DataFlowIR.Node.Const(symbolTable.mapType(value.type))
|
||||||
|
|
||||||
|
is IrConst<*> ->
|
||||||
|
if (value.value == null)
|
||||||
|
DataFlowIR.Node.Null
|
||||||
|
else
|
||||||
|
DataFlowIR.Node.Const(symbolTable.mapType(value.type))
|
||||||
|
|
||||||
is IrGetObjectValue -> DataFlowIR.Node.Singleton(
|
is IrGetObjectValue -> DataFlowIR.Node.Singleton(
|
||||||
symbolTable.mapType(value.type),
|
symbolTable.mapType(value.type),
|
||||||
if (value.type.isNothing()) // <Nothing> is not a singleton though its instance is get with <IrGetObject> operation.
|
if (value.type.isNothing()) // <Nothing> is not a singleton though its instance is get with <IrGetObject> operation.
|
||||||
|
|||||||
+10
@@ -587,6 +587,7 @@ internal object DFGSerializer {
|
|||||||
UNKNOWN,
|
UNKNOWN,
|
||||||
PARAMETER,
|
PARAMETER,
|
||||||
CONST,
|
CONST,
|
||||||
|
NULL,
|
||||||
STATIC_CALL,
|
STATIC_CALL,
|
||||||
NEW_OBJECT,
|
NEW_OBJECT,
|
||||||
VTABLE_CALL,
|
VTABLE_CALL,
|
||||||
@@ -603,6 +604,7 @@ internal object DFGSerializer {
|
|||||||
class Node {
|
class Node {
|
||||||
var parameter : Parameter? = null
|
var parameter : Parameter? = null
|
||||||
var const : Const? = null
|
var const : Const? = null
|
||||||
|
var nil : Boolean = false
|
||||||
var staticCall : StaticCall? = null
|
var staticCall : StaticCall? = null
|
||||||
var newObject : NewObject? = null
|
var newObject : NewObject? = null
|
||||||
var vtableCall : VtableCall? = null
|
var vtableCall : VtableCall? = null
|
||||||
@@ -629,6 +631,7 @@ internal object DFGSerializer {
|
|||||||
arrayRead != null -> NodeType.ARRAY_READ
|
arrayRead != null -> NodeType.ARRAY_READ
|
||||||
arrayWrite != null -> NodeType.ARRAY_WRITE
|
arrayWrite != null -> NodeType.ARRAY_WRITE
|
||||||
variable != null -> NodeType.VARIABLE
|
variable != null -> NodeType.VARIABLE
|
||||||
|
nil -> NodeType.NULL
|
||||||
else -> NodeType.UNKNOWN
|
else -> NodeType.UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,6 +659,8 @@ internal object DFGSerializer {
|
|||||||
fun const(type: Int) =
|
fun const(type: Int) =
|
||||||
Node().also { it.const = Const(type) }
|
Node().also { it.const = Const(type) }
|
||||||
|
|
||||||
|
fun nil() = Node().also { it.nil = true }
|
||||||
|
|
||||||
fun staticCall(call: Call, receiverType: Int?) =
|
fun staticCall(call: Call, receiverType: Int?) =
|
||||||
Node().also { it.staticCall = StaticCall(call, receiverType) }
|
Node().also { it.staticCall = StaticCall(call, receiverType) }
|
||||||
|
|
||||||
@@ -695,6 +700,7 @@ internal object DFGSerializer {
|
|||||||
when (type) {
|
when (type) {
|
||||||
NodeType.PARAMETER -> result.parameter = Parameter (data)
|
NodeType.PARAMETER -> result.parameter = Parameter (data)
|
||||||
NodeType.CONST -> result.const = Const (data)
|
NodeType.CONST -> result.const = Const (data)
|
||||||
|
NodeType.NULL -> result.nil = true
|
||||||
NodeType.STATIC_CALL -> result.staticCall = StaticCall (data)
|
NodeType.STATIC_CALL -> result.staticCall = StaticCall (data)
|
||||||
NodeType.NEW_OBJECT -> result.newObject = NewObject (data)
|
NodeType.NEW_OBJECT -> result.newObject = NewObject (data)
|
||||||
NodeType.VTABLE_CALL -> result.vtableCall = VtableCall (data)
|
NodeType.VTABLE_CALL -> result.vtableCall = VtableCall (data)
|
||||||
@@ -887,6 +893,8 @@ internal object DFGSerializer {
|
|||||||
|
|
||||||
is DataFlowIR.Node.Const -> Node.const(typeMap[node.type]!!)
|
is DataFlowIR.Node.Const -> Node.const(typeMap[node.type]!!)
|
||||||
|
|
||||||
|
DataFlowIR.Node.Null -> Node.nil()
|
||||||
|
|
||||||
is DataFlowIR.Node.StaticCall ->
|
is DataFlowIR.Node.StaticCall ->
|
||||||
Node.staticCall(buildCall(node), node.receiverType?.let { typeMap[it]!! })
|
Node.staticCall(buildCall(node), node.receiverType?.let { typeMap[it]!! })
|
||||||
|
|
||||||
@@ -1106,6 +1114,8 @@ internal object DFGSerializer {
|
|||||||
NodeType.CONST ->
|
NodeType.CONST ->
|
||||||
DataFlowIR.Node.Const(types[it.const!!.type])
|
DataFlowIR.Node.Const(types[it.const!!.type])
|
||||||
|
|
||||||
|
NodeType.NULL -> DataFlowIR.Node.Null
|
||||||
|
|
||||||
NodeType.STATIC_CALL -> {
|
NodeType.STATIC_CALL -> {
|
||||||
val staticCall = it.staticCall!!
|
val staticCall = it.staticCall!!
|
||||||
val call = deserializeCall(staticCall.call)
|
val call = deserializeCall(staticCall.call)
|
||||||
|
|||||||
+5
@@ -223,6 +223,8 @@ internal object DataFlowIR {
|
|||||||
|
|
||||||
class Const(val type: Type) : Node()
|
class Const(val type: Type) : Node()
|
||||||
|
|
||||||
|
object Null : Node()
|
||||||
|
|
||||||
open class Call(val callee: FunctionSymbol, val arguments: List<Edge>,
|
open class Call(val callee: FunctionSymbol, val arguments: List<Edge>,
|
||||||
open val irCallSite: IrFunctionAccessExpression?) : Node()
|
open val irCallSite: IrFunctionAccessExpression?) : Node()
|
||||||
|
|
||||||
@@ -286,6 +288,9 @@ internal object DataFlowIR {
|
|||||||
is Node.Const ->
|
is Node.Const ->
|
||||||
" CONST ${node.type}\n"
|
" CONST ${node.type}\n"
|
||||||
|
|
||||||
|
Node.Null ->
|
||||||
|
" NULL\n"
|
||||||
|
|
||||||
is Node.Parameter ->
|
is Node.Parameter ->
|
||||||
" PARAM ${node.index}\n"
|
" PARAM ${node.index}\n"
|
||||||
|
|
||||||
|
|||||||
+2
@@ -866,6 +866,8 @@ internal object Devirtualization {
|
|||||||
is DataFlowIR.Node.Const ->
|
is DataFlowIR.Node.Const ->
|
||||||
sourceNode(concreteType(node.type.resolved())) { "Const\$${function.symbol}" }
|
sourceNode(concreteType(node.type.resolved())) { "Const\$${function.symbol}" }
|
||||||
|
|
||||||
|
DataFlowIR.Node.Null -> constraintGraph.voidNode
|
||||||
|
|
||||||
is DataFlowIR.Node.Parameter ->
|
is DataFlowIR.Node.Parameter ->
|
||||||
function.parameters[node.index]
|
function.parameters[node.index]
|
||||||
|
|
||||||
|
|||||||
@@ -2233,6 +2233,11 @@ task args0(type: RunStandaloneKonanTest) {
|
|||||||
source = "runtime/basic/args0.kt"
|
source = "runtime/basic/args0.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task devirtualization_lateinitInterface(type: RunStandaloneKonanTest) {
|
||||||
|
goldValue = "42\n"
|
||||||
|
source = "codegen/devirtualization/lateinitInterface.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task multiargs(type: RunStandaloneKonanTest) {
|
task multiargs(type: RunStandaloneKonanTest) {
|
||||||
arguments = ["AAA", "BB", "C"]
|
arguments = ["AAA", "BB", "C"]
|
||||||
multiRuns = true
|
multiRuns = true
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
interface I {
|
||||||
|
fun foo(): Int
|
||||||
|
}
|
||||||
|
|
||||||
|
class A : I {
|
||||||
|
override fun foo() = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
lateinit var a: I
|
||||||
|
if (args.size == 0)
|
||||||
|
a = A()
|
||||||
|
println(a.foo())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user