FIR CFA: add control flow between default parameter values
function enter -> default 1 -> default 2 -> rest of function
\----------^ \----------^
This probably has no effect (in non-stupid code, at least), but it makes
graph construction more architecturally correct (now value parameters'
subgraphs get attached to a node).
This commit is contained in:
+6
-3
@@ -252,12 +252,15 @@ abstract class FirDataFlowAnalyzer(
|
||||
// ----------------------------------- Value parameters (and it's defaults) -----------------------------------
|
||||
|
||||
fun enterValueParameter(valueParameter: FirValueParameter) {
|
||||
graphBuilder.enterValueParameter(valueParameter)?.mergeIncomingFlow()
|
||||
val (outerNode, innerNode) = graphBuilder.enterValueParameter(valueParameter) ?: return
|
||||
outerNode.mergeIncomingFlow()
|
||||
innerNode.mergeIncomingFlow()
|
||||
}
|
||||
|
||||
fun exitValueParameter(valueParameter: FirValueParameter): ControlFlowGraph? {
|
||||
val (node, graph) = graphBuilder.exitValueParameter(valueParameter) ?: return null
|
||||
node.mergeIncomingFlow()
|
||||
val (innerNode, outerNode, graph) = graphBuilder.exitValueParameter(valueParameter) ?: return null
|
||||
innerNode.mergeIncomingFlow()
|
||||
outerNode.mergeIncomingFlow()
|
||||
return graph
|
||||
}
|
||||
|
||||
|
||||
+19
-13
@@ -542,29 +542,35 @@ class ControlFlowGraphBuilder {
|
||||
|
||||
// ----------------------------------- Value parameters (and it's defaults) -----------------------------------
|
||||
|
||||
fun enterValueParameter(valueParameter: FirValueParameter): EnterDefaultArgumentsNode? {
|
||||
fun enterValueParameter(valueParameter: FirValueParameter): Pair<EnterValueParameterNode, EnterDefaultArgumentsNode>? {
|
||||
if (valueParameter.defaultValue == null) return null
|
||||
|
||||
val outerEnterNode = createEnterValueParameterNode(valueParameter)
|
||||
val graph = ControlFlowGraph(valueParameter, "default value of ${valueParameter.name}", ControlFlowGraph.Kind.DefaultArgument)
|
||||
currentGraph.addSubGraph(graph)
|
||||
pushGraph(graph, Mode.Body)
|
||||
|
||||
createExitDefaultArgumentsNode(valueParameter).also {
|
||||
exitTargetsForTry.push(it)
|
||||
}
|
||||
|
||||
return createEnterDefaultArgumentsNode(valueParameter).also {
|
||||
addEdge(lastNode, it)
|
||||
lastNodes.push(it)
|
||||
}
|
||||
val innerExitNode = createExitDefaultArgumentsNode(valueParameter)
|
||||
val innerEnterNode = createEnterDefaultArgumentsNode(valueParameter)
|
||||
addNewSimpleNode(outerEnterNode)
|
||||
addEdge(outerEnterNode, innerEnterNode)
|
||||
lastNodes.push(innerEnterNode)
|
||||
exitTargetsForTry.push(innerExitNode)
|
||||
return outerEnterNode to innerEnterNode
|
||||
}
|
||||
|
||||
fun exitValueParameter(valueParameter: FirValueParameter): Pair<ExitDefaultArgumentsNode, ControlFlowGraph>? {
|
||||
fun exitValueParameter(valueParameter: FirValueParameter): Triple<ExitDefaultArgumentsNode, ExitValueParameterNode, ControlFlowGraph>? {
|
||||
if (valueParameter.defaultValue == null) return null
|
||||
|
||||
val exitNode = exitTargetsForTry.pop() as ExitDefaultArgumentsNode
|
||||
popAndAddEdge(exitNode)
|
||||
val graph = popGraph()
|
||||
require(exitNode == graph.exitNode)
|
||||
return exitNode to graph
|
||||
val outerEnterNode = lastNode as EnterValueParameterNode
|
||||
val outerExitNode = createExitValueParameterNode(valueParameter)
|
||||
addNewSimpleNode(outerExitNode)
|
||||
addEdge(exitNode, outerExitNode, propagateDeadness = false)
|
||||
outerEnterNode.addSubGraph(graph)
|
||||
currentGraph.addSubGraph(graph)
|
||||
return Triple(exitNode, outerExitNode, graph)
|
||||
}
|
||||
|
||||
// ----------------------------------- Block -----------------------------------
|
||||
|
||||
+6
@@ -256,12 +256,18 @@ fun ControlFlowGraphBuilder.createClassExitNode(fir: FirClass): ClassExitNode =
|
||||
fun ControlFlowGraphBuilder.createLocalClassExitNode(fir: FirRegularClass): LocalClassExitNode =
|
||||
LocalClassExitNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
fun ControlFlowGraphBuilder.createEnterValueParameterNode(fir: FirValueParameter): EnterValueParameterNode =
|
||||
EnterValueParameterNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
fun ControlFlowGraphBuilder.createEnterDefaultArgumentsNode(fir: FirValueParameter): EnterDefaultArgumentsNode =
|
||||
EnterDefaultArgumentsNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
fun ControlFlowGraphBuilder.createExitDefaultArgumentsNode(fir: FirValueParameter): ExitDefaultArgumentsNode =
|
||||
ExitDefaultArgumentsNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
fun ControlFlowGraphBuilder.createExitValueParameterNode(fir: FirValueParameter): ExitValueParameterNode =
|
||||
ExitValueParameterNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
fun ControlFlowGraphBuilder.createComparisonExpressionNode(fir: FirComparisonExpression): ComparisonExpressionNode =
|
||||
ComparisonExpressionNode(currentGraph, fir, levelCounter, createId())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user