DFG: added array reading & writing
This commit is contained in:
+8
@@ -160,6 +160,14 @@ internal class KonanSymbols(context: Context, val symbolTable: SymbolTable): Sym
|
|||||||
symbol.descriptor to symbolTable.referenceSimpleFunction(functionDescriptor)
|
symbol.descriptor to symbolTable.referenceSimpleFunction(functionDescriptor)
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
|
val arrayGet = array.descriptor.unsubstitutedMemberScope
|
||||||
|
.getContributedFunctions(Name.identifier("get"), NoLookupLocation.FROM_BACKEND)
|
||||||
|
.single().let { symbolTable.referenceSimpleFunction(it) }
|
||||||
|
|
||||||
|
val arraySet = array.descriptor.unsubstitutedMemberScope
|
||||||
|
.getContributedFunctions(Name.identifier("set"), NoLookupLocation.FROM_BACKEND)
|
||||||
|
.single().let { symbolTable.referenceSimpleFunction(it) }
|
||||||
|
|
||||||
val valuesForEnum = symbolTable.referenceSimpleFunction(
|
val valuesForEnum = symbolTable.referenceSimpleFunction(
|
||||||
context.getInternalFunctions("valuesForEnum").single())
|
context.getInternalFunctions("valuesForEnum").single())
|
||||||
|
|
||||||
|
|||||||
+13
-4
@@ -410,6 +410,9 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
.getContributedFunctions(Name.identifier("doResume"), NoLookupLocation.FROM_BACKEND).single()
|
.getContributedFunctions(Name.identifier("doResume"), NoLookupLocation.FROM_BACKEND).single()
|
||||||
private val getContinuationSymbol = context.ir.symbols.getContinuation
|
private val getContinuationSymbol = context.ir.symbols.getContinuation
|
||||||
|
|
||||||
|
private val arrayGetSymbol = context.ir.symbols.arrayGet
|
||||||
|
private val arraySetSymbol = context.ir.symbols.arraySet
|
||||||
|
|
||||||
private inner class FunctionDFGBuilder(val expressionValuesExtractor: ExpressionValuesExtractor,
|
private inner class FunctionDFGBuilder(val expressionValuesExtractor: ExpressionValuesExtractor,
|
||||||
val variableValues: VariableValues,
|
val variableValues: VariableValues,
|
||||||
val descriptor: CallableDescriptor,
|
val descriptor: CallableDescriptor,
|
||||||
@@ -501,10 +504,16 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
else symbolTable.mapFunction(value.descriptor.constructors.single())
|
else symbolTable.mapFunction(value.descriptor.constructors.single())
|
||||||
)
|
)
|
||||||
|
|
||||||
is IrCall -> {
|
is IrCall -> when (value.symbol) {
|
||||||
if (value.symbol == getContinuationSymbol) {
|
getContinuationSymbol -> getContinuation()
|
||||||
getContinuation()
|
|
||||||
} else {
|
arrayGetSymbol -> DataFlowIR.Node.ArrayRead(expressionToEdge(value.dispatchReceiver!!),
|
||||||
|
expressionToEdge(value.getValueArgument(0)!!), value)
|
||||||
|
|
||||||
|
arraySetSymbol -> DataFlowIR.Node.ArrayWrite(expressionToEdge(value.dispatchReceiver!!),
|
||||||
|
expressionToEdge(value.getValueArgument(0)!!), expressionToEdge(value.getValueArgument(1)!!))
|
||||||
|
|
||||||
|
else -> {
|
||||||
val callee = value.descriptor
|
val callee = value.descriptor
|
||||||
val arguments = value.getArguments()
|
val arguments = value.getArguments()
|
||||||
.map { expressionToEdge(it.second) }
|
.map { expressionToEdge(it.second) }
|
||||||
|
|||||||
+68
@@ -493,6 +493,27 @@ internal object DFGSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ArrayRead(val array: Edge, val index: Edge) {
|
||||||
|
|
||||||
|
constructor(data: ArraySlice) : this(Edge(data), Edge(data))
|
||||||
|
|
||||||
|
fun write(result: ArraySlice) {
|
||||||
|
array.write(result)
|
||||||
|
index.write(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ArrayWrite(val array: Edge, val index: Edge, val value: Edge) {
|
||||||
|
|
||||||
|
constructor(data: ArraySlice) : this(Edge(data), Edge(data), Edge(data))
|
||||||
|
|
||||||
|
fun write(result: ArraySlice) {
|
||||||
|
array.write(result)
|
||||||
|
index.write(result)
|
||||||
|
value.write(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Variable(val values: Array<Edge>, val temp: Boolean) {
|
class Variable(val values: Array<Edge>, val temp: Boolean) {
|
||||||
|
|
||||||
constructor(data: ArraySlice) : this(data.readArray { Edge(this) }, data.readBoolean())
|
constructor(data: ArraySlice) : this(data.readArray { Edge(this) }, data.readBoolean())
|
||||||
@@ -514,6 +535,8 @@ internal object DFGSerializer {
|
|||||||
SINGLETON,
|
SINGLETON,
|
||||||
FIELD_READ,
|
FIELD_READ,
|
||||||
FIELD_WRITE,
|
FIELD_WRITE,
|
||||||
|
ARRAY_READ,
|
||||||
|
ARRAY_WRITE,
|
||||||
VARIABLE
|
VARIABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +550,8 @@ internal object DFGSerializer {
|
|||||||
var singleton : Singleton? = null
|
var singleton : Singleton? = null
|
||||||
var fieldRead : FieldRead? = null
|
var fieldRead : FieldRead? = null
|
||||||
var fieldWrite : FieldWrite? = null
|
var fieldWrite : FieldWrite? = null
|
||||||
|
var arrayRead : ArrayRead? = null
|
||||||
|
var arrayWrite : ArrayWrite? = null
|
||||||
var variable : Variable? = null
|
var variable : Variable? = null
|
||||||
|
|
||||||
val type get() = when {
|
val type get() = when {
|
||||||
@@ -539,6 +564,8 @@ internal object DFGSerializer {
|
|||||||
singleton != null -> NodeType.SINGLETON
|
singleton != null -> NodeType.SINGLETON
|
||||||
fieldRead != null -> NodeType.FIELD_READ
|
fieldRead != null -> NodeType.FIELD_READ
|
||||||
fieldWrite != null -> NodeType.FIELD_WRITE
|
fieldWrite != null -> NodeType.FIELD_WRITE
|
||||||
|
arrayRead != null -> NodeType.ARRAY_READ
|
||||||
|
arrayWrite != null -> NodeType.ARRAY_WRITE
|
||||||
variable != null -> NodeType.VARIABLE
|
variable != null -> NodeType.VARIABLE
|
||||||
else -> NodeType.UNKNOWN
|
else -> NodeType.UNKNOWN
|
||||||
}
|
}
|
||||||
@@ -554,6 +581,8 @@ internal object DFGSerializer {
|
|||||||
singleton ?.write(result)
|
singleton ?.write(result)
|
||||||
fieldRead ?.write(result)
|
fieldRead ?.write(result)
|
||||||
fieldWrite?.write(result)
|
fieldWrite?.write(result)
|
||||||
|
arrayRead ?.write(result)
|
||||||
|
arrayWrite?.write(result)
|
||||||
variable ?.write(result)
|
variable ?.write(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -585,6 +614,12 @@ internal object DFGSerializer {
|
|||||||
fun fieldWrite(receiver: Edge?, field: Field, value: Edge) =
|
fun fieldWrite(receiver: Edge?, field: Field, value: Edge) =
|
||||||
Node().also { it.fieldWrite = FieldWrite(receiver, field, value) }
|
Node().also { it.fieldWrite = FieldWrite(receiver, field, value) }
|
||||||
|
|
||||||
|
fun arrayRead(array: Edge, index: Edge) =
|
||||||
|
Node().also { it.arrayRead = ArrayRead(array, index) }
|
||||||
|
|
||||||
|
fun arrayWrite(array: Edge, index: Edge, value: Edge) =
|
||||||
|
Node().also { it.arrayWrite = ArrayWrite(array, index, value) }
|
||||||
|
|
||||||
fun variable(values: Array<Edge>, temp: Boolean) =
|
fun variable(values: Array<Edge>, temp: Boolean) =
|
||||||
Node().also { it.variable = Variable(values, temp) }
|
Node().also { it.variable = Variable(values, temp) }
|
||||||
|
|
||||||
@@ -601,6 +636,8 @@ internal object DFGSerializer {
|
|||||||
NodeType.SINGLETON -> result.singleton = Singleton (data)
|
NodeType.SINGLETON -> result.singleton = Singleton (data)
|
||||||
NodeType.FIELD_READ -> result.fieldRead = FieldRead (data)
|
NodeType.FIELD_READ -> result.fieldRead = FieldRead (data)
|
||||||
NodeType.FIELD_WRITE -> result.fieldWrite = FieldWrite(data)
|
NodeType.FIELD_WRITE -> result.fieldWrite = FieldWrite(data)
|
||||||
|
NodeType.ARRAY_READ -> result.arrayRead = ArrayRead (data)
|
||||||
|
NodeType.ARRAY_WRITE -> result.arrayWrite = ArrayWrite(data)
|
||||||
NodeType.VARIABLE -> result.variable = Variable (data)
|
NodeType.VARIABLE -> result.variable = Variable (data)
|
||||||
else -> { }
|
else -> { }
|
||||||
}
|
}
|
||||||
@@ -756,6 +793,12 @@ internal object DFGSerializer {
|
|||||||
is DataFlowIR.Node.FieldWrite ->
|
is DataFlowIR.Node.FieldWrite ->
|
||||||
Node.fieldWrite(node.receiver?.let { buildEdge(it) }, buildField(node.field), buildEdge(node.value))
|
Node.fieldWrite(node.receiver?.let { buildEdge(it) }, buildField(node.field), buildEdge(node.value))
|
||||||
|
|
||||||
|
is DataFlowIR.Node.ArrayRead ->
|
||||||
|
Node.arrayRead(buildEdge(node.array), buildEdge(node.index))
|
||||||
|
|
||||||
|
is DataFlowIR.Node.ArrayWrite ->
|
||||||
|
Node.arrayWrite(buildEdge(node.array), buildEdge(node.index), buildEdge(node.value))
|
||||||
|
|
||||||
is DataFlowIR.Node.Variable ->
|
is DataFlowIR.Node.Variable ->
|
||||||
Node.variable(node.values.map { buildEdge(it) }.toTypedArray(), node.temp)
|
Node.variable(node.values.map { buildEdge(it) }.toTypedArray(), node.temp)
|
||||||
|
|
||||||
@@ -965,6 +1008,16 @@ internal object DFGSerializer {
|
|||||||
DataFlowIR.Node.FieldWrite(receiver, deserializeField(fieldWrite.field), deserializeEdge(fieldWrite.value))
|
DataFlowIR.Node.FieldWrite(receiver, deserializeField(fieldWrite.field), deserializeEdge(fieldWrite.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeType.ARRAY_READ -> {
|
||||||
|
val arrayRead = it.arrayRead!!
|
||||||
|
DataFlowIR.Node.ArrayRead(deserializeEdge(arrayRead.array), deserializeEdge(arrayRead.index), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeType.ARRAY_WRITE -> {
|
||||||
|
val arrayWrite = it.arrayWrite!!
|
||||||
|
DataFlowIR.Node.ArrayWrite(deserializeEdge(arrayWrite.array), deserializeEdge(arrayWrite.index), deserializeEdge(arrayWrite.value))
|
||||||
|
}
|
||||||
|
|
||||||
NodeType.VARIABLE -> {
|
NodeType.VARIABLE -> {
|
||||||
val variable = it.variable!!
|
val variable = it.variable!!
|
||||||
DataFlowIR.Node.Variable(variable.values.map { deserializeEdge(it) }, variable.temp)
|
DataFlowIR.Node.Variable(variable.values.map { deserializeEdge(it) }, variable.temp)
|
||||||
@@ -1009,6 +1062,21 @@ internal object DFGSerializer {
|
|||||||
deserializedFieldWrite.value.node = nodes[fieldWrite.value.node]
|
deserializedFieldWrite.value.node = nodes[fieldWrite.value.node]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeType.ARRAY_READ -> {
|
||||||
|
val deserializedArrayRead = deserializedNode as DataFlowIR.Node.ArrayRead
|
||||||
|
val arrayRead = node.arrayRead!!
|
||||||
|
deserializedArrayRead.array.node = nodes[arrayRead.array.node]
|
||||||
|
deserializedArrayRead.index.node = nodes[arrayRead.index.node]
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeType.ARRAY_WRITE -> {
|
||||||
|
val deserializedArrayWrite = deserializedNode as DataFlowIR.Node.ArrayWrite
|
||||||
|
val arrayWrite = node.arrayWrite!!
|
||||||
|
deserializedArrayWrite.array.node = nodes[arrayWrite.array.node]
|
||||||
|
deserializedArrayWrite.index.node = nodes[arrayWrite.index.node]
|
||||||
|
deserializedArrayWrite.value.node = nodes[arrayWrite.value.node]
|
||||||
|
}
|
||||||
|
|
||||||
NodeType.VARIABLE ->
|
NodeType.VARIABLE ->
|
||||||
node.variable!!.values.forEachIndexed { i, value ->
|
node.variable!!.values.forEachIndexed { i, value ->
|
||||||
(deserializedNode as DataFlowIR.Node.Variable).values[i].node = nodes[value.node]
|
(deserializedNode as DataFlowIR.Node.Variable).values[i].node = nodes[value.node]
|
||||||
|
|||||||
+41
@@ -217,6 +217,10 @@ internal object DataFlowIR {
|
|||||||
|
|
||||||
class FieldWrite(val receiver: Edge?, val field: Field, val value: Edge) : Node()
|
class FieldWrite(val receiver: Edge?, val field: Field, val value: Edge) : Node()
|
||||||
|
|
||||||
|
class ArrayRead(val array: Edge, val index: Edge, val callSite: IrCall?) : Node()
|
||||||
|
|
||||||
|
class ArrayWrite(val array: Edge, val index: Edge, val value: Edge) : Node()
|
||||||
|
|
||||||
class Variable(values: List<Edge>, val temp: Boolean) : Node() {
|
class Variable(values: List<Edge>, val temp: Boolean) : Node() {
|
||||||
val values = mutableListOf<Edge>().also { it += values }
|
val values = mutableListOf<Edge>().also { it += values }
|
||||||
}
|
}
|
||||||
@@ -339,6 +343,43 @@ internal object DataFlowIR {
|
|||||||
result.toString()
|
result.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is Node.ArrayRead -> {
|
||||||
|
val result = StringBuilder()
|
||||||
|
result.appendln(" ARRAY READ")
|
||||||
|
result.append(" ARRAY #${ids[node.array.node]}")
|
||||||
|
if (node.array.castToType == null)
|
||||||
|
result.appendln()
|
||||||
|
else
|
||||||
|
result.appendln(" CASTED TO ${node.array.castToType}")
|
||||||
|
result.append(" INDEX #${ids[node.index.node]!!}")
|
||||||
|
if (node.index.castToType == null)
|
||||||
|
result.appendln()
|
||||||
|
else
|
||||||
|
result.appendln(" CASTED TO ${node.index.castToType}")
|
||||||
|
result.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
is Node.ArrayWrite -> {
|
||||||
|
val result = StringBuilder()
|
||||||
|
result.appendln(" ARRAY WRITE")
|
||||||
|
result.append(" ARRAY #${ids[node.array.node]}")
|
||||||
|
if (node.array.castToType == null)
|
||||||
|
result.appendln()
|
||||||
|
else
|
||||||
|
result.appendln(" CASTED TO ${node.array.castToType}")
|
||||||
|
result.append(" INDEX #${ids[node.index.node]!!}")
|
||||||
|
if (node.index.castToType == null)
|
||||||
|
result.appendln()
|
||||||
|
else
|
||||||
|
result.appendln(" CASTED TO ${node.index.castToType}")
|
||||||
|
print(" VALUE #${ids[node.value.node]!!}")
|
||||||
|
if (node.value.castToType == null)
|
||||||
|
result.appendln()
|
||||||
|
else
|
||||||
|
result.appendln(" CASTED TO ${node.value.castToType}")
|
||||||
|
result.toString()
|
||||||
|
}
|
||||||
|
|
||||||
is Node.Variable -> {
|
is Node.Variable -> {
|
||||||
val result = StringBuilder()
|
val result = StringBuilder()
|
||||||
result.appendln(" ${if (node.temp) "TEMP VAR" else "VARIABLE"} ")
|
result.appendln(" ${if (node.temp) "TEMP VAR" else "VARIABLE"} ")
|
||||||
|
|||||||
Reference in New Issue
Block a user