Added <throws> node for a function’s DFG

This commit is contained in:
Igor Chevdar
2017-12-14 23:29:45 +03:00
parent 56a214c454
commit 013a4abba3
3 changed files with 18 additions and 9 deletions
@@ -272,7 +272,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
} }
val function = FunctionDFGBuilder(expressionValuesExtractor, visitor.variableValues, val function = FunctionDFGBuilder(expressionValuesExtractor, visitor.variableValues,
descriptor, visitor.expressions, visitor.returnValues).build() descriptor, visitor.expressions, visitor.returnValues, visitor.thrownValues).build()
DEBUG_OUTPUT(1) { DEBUG_OUTPUT(1) {
function.debugOutput() function.debugOutput()
@@ -306,6 +306,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
val expressions = mutableListOf<IrExpression>() val expressions = mutableListOf<IrExpression>()
val variableValues = VariableValues() val variableValues = VariableValues()
val returnValues = mutableListOf<IrExpression>() val returnValues = mutableListOf<IrExpression>()
val thrownValues = mutableListOf<IrExpression>()
private val returnableBlocks = mutableMapOf<FunctionDescriptor, IrReturnableBlock>() private val returnableBlocks = mutableMapOf<FunctionDescriptor, IrReturnableBlock>()
private val suspendableExpressionStack = mutableListOf<IrSuspendableExpression>() private val suspendableExpressionStack = mutableListOf<IrSuspendableExpression>()
@@ -369,6 +370,11 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
super.visitReturn(expression) super.visitReturn(expression)
} }
override fun visitThrow(expression: IrThrow) {
thrownValues += expression.value
super.visitThrow(expression)
}
override fun visitSetVariable(expression: IrSetVariable) { override fun visitSetVariable(expression: IrSetVariable) {
super.visitSetVariable(expression) super.visitSetVariable(expression)
assignVariable(expression.descriptor, expression.value) assignVariable(expression.descriptor, expression.value)
@@ -389,7 +395,8 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
val variableValues: VariableValues, val variableValues: VariableValues,
val descriptor: CallableDescriptor, val descriptor: CallableDescriptor,
val expressions: List<IrExpression>, val expressions: List<IrExpression>,
val returnValues: List<IrExpression>) { val returnValues: List<IrExpression>,
val thrownValues: List<IrExpression>) {
private val allParameters = (descriptor as? FunctionDescriptor)?.allParameters ?: emptyList() private val allParameters = (descriptor as? FunctionDescriptor)?.allParameters ?: emptyList()
private val templateParameters = allParameters.withIndex().associateBy({ it.value }, { DataFlowIR.Node.Parameter(it.index) }) private val templateParameters = allParameters.withIndex().associateBy({ it.value }, { DataFlowIR.Node.Parameter(it.index) })
@@ -414,19 +421,20 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
fun build(): DataFlowIR.Function { fun build(): DataFlowIR.Function {
expressions.forEach { getNode(it) } expressions.forEach { getNode(it) }
val returnsNode = DataFlowIR.Node.Variable(returnValues.map { expressionToEdge(it) }, true) val returnsNode = DataFlowIR.Node.Variable(returnValues.map { expressionToEdge(it) }, true)
val throwsNode = DataFlowIR.Node.Variable(thrownValues.map { expressionToEdge(it) }, true)
variables.forEach { descriptor, node -> variables.forEach { descriptor, node ->
variableValues.elementData[descriptor]!!.forEach { variableValues.elementData[descriptor]!!.forEach {
node.values += expressionToEdge(it) node.values += expressionToEdge(it)
} }
} }
val allNodes = nodes.values + variables.values + templateParameters.values + returnsNode + val allNodes = nodes.values + variables.values + templateParameters.values + returnsNode + throwsNode +
(if (descriptor.isSuspend) listOf(continuationParameter!!) else emptyList()) (if (descriptor.isSuspend) listOf(continuationParameter!!) else emptyList())
return DataFlowIR.Function( return DataFlowIR.Function(
symbol = symbolTable.mapFunction(descriptor), symbol = symbolTable.mapFunction(descriptor),
isGlobalInitializer = descriptor is PropertyDescriptor, isGlobalInitializer = descriptor is PropertyDescriptor,
numberOfParameters = templateParameters.size + if (descriptor.isSuspend) 1 else 0, numberOfParameters = templateParameters.size + if (descriptor.isSuspend) 1 else 0,
body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode) body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode, throwsNode)
) )
} }
@@ -582,13 +582,14 @@ internal object DFGSerializer {
} }
} }
class FunctionBody(val nodes: Array<Node>, val returns: Int) { class FunctionBody(val nodes: Array<Node>, val returns: Int, val throws: Int) {
constructor(data: ArraySlice) : this(data.readArray { Node.read(this) }, data.readInt()) constructor(data: ArraySlice) : this(data.readArray { Node.read(this) }, data.readInt(), data.readInt())
fun write(result: ArraySlice) { fun write(result: ArraySlice) {
result.writeArray(nodes) { it.write(this) } result.writeArray(nodes) { it.write(this) }
result.writeInt(returns) result.writeInt(returns)
result.writeInt(throws)
} }
} }
@@ -737,7 +738,7 @@ internal object DFGSerializer {
functionSymbolMap[function.symbol]!!, functionSymbolMap[function.symbol]!!,
function.isGlobalInitializer, function.isGlobalInitializer,
function.numberOfParameters, function.numberOfParameters,
FunctionBody(nodes, nodeMap[body.returns]!!) FunctionBody(nodes, nodeMap[body.returns]!!, nodeMap[body.throws]!!)
) )
} }
.toTypedArray() .toTypedArray()
@@ -985,7 +986,7 @@ internal object DFGSerializer {
else -> { } else -> { }
} }
} }
return DataFlowIR.FunctionBody(nodes, nodes[body.returns] as DataFlowIR.Node.Variable) return DataFlowIR.FunctionBody(nodes, nodes[body.returns] as DataFlowIR.Node.Variable, nodes[body.throws] as DataFlowIR.Node.Variable)
} }
moduleDataFlowGraph.functions.forEach { moduleDataFlowGraph.functions.forEach {
@@ -193,7 +193,7 @@ internal object DataFlowIR {
} }
} }
class FunctionBody(val nodes: List<Node>, val returns: Node.Variable) class FunctionBody(val nodes: List<Node>, val returns: Node.Variable, val throws: Node.Variable)
class Function(val symbol: FunctionSymbol, class Function(val symbol: FunctionSymbol,
val isGlobalInitializer: Boolean, val isGlobalInitializer: Boolean,