From dab9f6997ae6dd9485dad626db64e198210afcb4 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Mon, 3 Mar 2014 14:31:53 +0400 Subject: [PATCH] rollback: moved 'collectData' to PseudocodeTraverser --- .../jet/lang/cfg/PseudocodeTraverser.kt | 113 ++++++++++++++++- .../cfg/PseudocodeVariableDataCollector.kt | 120 +----------------- .../jet/lang/cfg/PseudocodeVariablesData.java | 6 +- 3 files changed, 122 insertions(+), 117 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeTraverser.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeTraverser.kt index 5be1b079e04..35b5e538cae 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeTraverser.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeTraverser.kt @@ -74,6 +74,117 @@ fun Pseudocode.traverse( } } +public fun Pseudocode.collectData( + traversalOrder: TraversalOrder, + mergeDataWithLocalDeclarations: Boolean, + mergeEdges: (Instruction, Collection) -> Edges, + updateEdge: (Instruction, Instruction, D) -> D, + initialDataValue: D +): Map> { + val edgesMap = LinkedHashMap>() + initializeEdgesMap(edgesMap, initialDataValue) + edgesMap.put(getStartInstruction(traversalOrder), Edges(initialDataValue, initialDataValue)) + + val changed = BooleanArray(1) + changed[0] = true + while (changed[0]) { + changed[0] = false + collectDataFromSubgraph( + traversalOrder, mergeDataWithLocalDeclarations, edgesMap, + mergeEdges, updateEdge, Collections.emptyList(), changed, false) + } + return edgesMap +} + +private fun Pseudocode.initializeEdgesMap( + edgesMap: MutableMap>, + initialDataValue: D +) { + val instructions = getInstructions() + val initialEdge = Edges(initialDataValue, initialDataValue) + for (instruction in instructions) { + edgesMap.put(instruction, initialEdge) + if (instruction is LocalFunctionDeclarationInstruction) { + instruction.getBody().initializeEdgesMap(edgesMap, initialDataValue) + } + } +} + +private fun Pseudocode.collectDataFromSubgraph( + traversalOrder: TraversalOrder, + mergeDataWithLocalDeclarations: Boolean, + edgesMap: MutableMap>, + mergeEdges: (Instruction, Collection) -> Edges, + updateEdge: (Instruction, Instruction, D) -> D, + previousSubGraphInstructions: Collection, + changed: BooleanArray, + isLocal: Boolean +) { + val instructions = getInstructions(traversalOrder) + val startInstruction = getStartInstruction(traversalOrder) + + for (instruction in instructions) { + val isStart = instruction.isStartInstruction(traversalOrder) + if (!isLocal && isStart) + continue + + fun getPreviousIncludingSubGraphInstructions(): Collection { + val previous = instruction.getPreviousInstructions(traversalOrder) + if (instruction != startInstruction || previousSubGraphInstructions.isEmpty()) { + return previous + } + val result = ArrayList(previous) + result.addAll(previousSubGraphInstructions) + return result + } + val previousInstructions = getPreviousIncludingSubGraphInstructions() + + fun updateEdgeDataForInstruction( + previousValue: Edges?, + newValue: Edges? + ) { + if (previousValue != newValue && newValue != null) { + changed[0] = true + edgesMap.put(instruction, newValue) + } + } + + if (instruction is LocalFunctionDeclarationInstruction) { + val subroutinePseudocode = instruction.getBody() + val previous = if (mergeDataWithLocalDeclarations) previousInstructions else Collections.emptyList() + subroutinePseudocode.collectDataFromSubgraph( + traversalOrder, mergeDataWithLocalDeclarations, + edgesMap, mergeEdges, updateEdge, previous, changed, true) + if (mergeDataWithLocalDeclarations) { + val lastInstruction = subroutinePseudocode.getLastInstruction(traversalOrder) + val previousValue = edgesMap.get(instruction) + val newValue = edgesMap.get(lastInstruction) + val updatedValue = + if (newValue == null) + null + else + Edges(updateEdge(lastInstruction, instruction, newValue.`in`), + updateEdge(lastInstruction, instruction, newValue.out)) + updateEdgeDataForInstruction(previousValue, updatedValue) + continue + } + } + val previousDataValue = edgesMap.get(instruction) + + val incomingEdgesData = HashSet() + + for (previousInstruction in previousInstructions) { + val previousData = edgesMap.get(previousInstruction) + if (previousData != null) { + incomingEdgesData.add(updateEdge( + previousInstruction, instruction, previousData.out)) + } + } + val mergedData = mergeEdges(instruction, incomingEdgesData) + updateEdgeDataForInstruction(previousDataValue, mergedData) + } +} + trait InstructionDataMergeStrategy : (Instruction, Collection) -> Edges trait InstructionDataAnalyzeStrategy : (Instruction, D, D) -> Unit @@ -87,7 +198,7 @@ fun traverseFollowingInstructions( visited: MutableSet, order: TraversalOrder, // true to continue traversal - handler: ((Instruction)->Boolean)? + handler: ((Instruction) -> Boolean)? ): Boolean { val stack = ArrayDeque() stack.push(rootInstruction) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariableDataCollector.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariableDataCollector.kt index dcaa7e7f8f1..1e5e8b379e4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariableDataCollector.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariableDataCollector.kt @@ -38,124 +38,18 @@ public class PseudocodeVariableDataCollector( val lexicalScopeVariableInfo = computeLexicalScopeVariableInfo(pseudocode) suppress("UNCHECKED_CAST") - public fun collectDataJ( + public fun collectData( traversalOrder: TraversalOrder, mergeDataWithLocalDeclarations: Boolean, instructionDataMergeStrategy: InstructionDataMergeStrategy> ): MutableMap>> { - //see KT-4605 - return collectData( + val result = pseudocode.collectData( traversalOrder, mergeDataWithLocalDeclarations, - instructionDataMergeStrategy as InstructionDataMergeStrategy> - ) as MutableMap>> - } - - public fun collectData( - traversalOrder: TraversalOrder, - mergeDataWithLocalDeclarations: Boolean, - instructionDataMergeStrategy: InstructionDataMergeStrategy> - ): Map>> { - val initialDataValue : Map = Collections.emptyMap() - val edgesMap = LinkedHashMap>>() - initializeEdgesMap(pseudocode, edgesMap, initialDataValue) - edgesMap.put(pseudocode.getStartInstruction(traversalOrder), Edges(initialDataValue, initialDataValue)) - - val changed = BooleanArray(1) - changed[0] = true - while (changed[0]) { - changed[0] = false - collectDataFromSubgraph( - pseudocode, traversalOrder, mergeDataWithLocalDeclarations, edgesMap, - instructionDataMergeStrategy, Collections.emptyList(), changed, false) - } - return edgesMap - } - - private fun initializeEdgesMap( - pseudocode: Pseudocode, - edgesMap: MutableMap>, - initialDataValue: M - ) { - val instructions = pseudocode.getInstructions() - val initialEdge = Edges(initialDataValue, initialDataValue) - for (instruction in instructions) { - edgesMap.put(instruction, initialEdge) - if (instruction is LocalFunctionDeclarationInstruction) { - initializeEdgesMap(instruction.getBody(), edgesMap, initialDataValue) - } - } - } - - private fun collectDataFromSubgraph( - pseudocode: Pseudocode, - traversalOrder: TraversalOrder, - mergeDataWithLocalDeclarations: Boolean, - edgesMap: MutableMap>>, - instructionDataMergeStrategy: InstructionDataMergeStrategy>, - previousSubGraphInstructions: Collection, - changed: BooleanArray, - isLocal: Boolean - ) { - val instructions = pseudocode.getInstructions(traversalOrder) - val startInstruction = pseudocode.getStartInstruction(traversalOrder) - - for (instruction in instructions) { - val isStart = instruction.isStartInstruction(traversalOrder) - if (!isLocal && isStart) - continue - - fun getPreviousIncludingSubGraphInstructions(): Collection { - val previous = instruction.getPreviousInstructions(traversalOrder) - if (instruction != startInstruction || previousSubGraphInstructions.isEmpty()) { - return previous - } - val result = ArrayList(previous) - result.addAll(previousSubGraphInstructions) - return result - } - val previousInstructions = getPreviousIncludingSubGraphInstructions() - - fun updateEdgeDataForInstruction( - previousValue: Edges>?, - newValue: Edges>? - ) { - if (previousValue != newValue && newValue != null) { - changed[0] = true - edgesMap.put(instruction, newValue) - } - } - - if (instruction is LocalFunctionDeclarationInstruction) { - val subroutinePseudocode = instruction.getBody() - val previous = if (mergeDataWithLocalDeclarations) previousInstructions else Collections.emptyList() - collectDataFromSubgraph( - subroutinePseudocode, traversalOrder, mergeDataWithLocalDeclarations, - edgesMap, instructionDataMergeStrategy, previous, changed, true) - if (mergeDataWithLocalDeclarations) { - val lastInstruction = subroutinePseudocode.getLastInstruction(traversalOrder) - val previousValue = edgesMap.get(instruction) - val newValue = edgesMap.get(lastInstruction) - val updatedValue = if (newValue == null) null else - Edges(filterOutVariablesOutOfScope(lastInstruction, instruction, newValue.`in`), - filterOutVariablesOutOfScope(lastInstruction, instruction, newValue.out)) - updateEdgeDataForInstruction(previousValue, updatedValue) - continue - } - } - val previousDataValue = edgesMap.get(instruction) - - val incomingEdgesData = HashSet>() - - for (previousInstruction in previousInstructions) { - val previousData = edgesMap.get(previousInstruction) - if (previousData != null) { - incomingEdgesData.add(filterOutVariablesOutOfScope( - previousInstruction, instruction, previousData.out)) - } - } - val mergedData = instructionDataMergeStrategy(instruction, incomingEdgesData) - updateEdgeDataForInstruction(previousDataValue, mergedData) - } + instructionDataMergeStrategy as InstructionDataMergeStrategy>, + { (from, to, data) -> filterOutVariablesOutOfScope(from, to, data)}, + Collections.emptyMap()) + //see KT-4605 + return result as MutableMap>> } private fun filterOutVariablesOutOfScope( diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java index 0a7355b609a..aed54128222 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java @@ -146,7 +146,7 @@ public class PseudocodeVariablesData { final LexicalScopeVariableInfo lexicalScopeVariableInfo = pseudocodeVariableDataCollector.getLexicalScopeVariableInfo(); - return pseudocodeVariableDataCollector.collectDataJ( + return pseudocodeVariableDataCollector.collectData( FORWARD, /*mergeDataWithLocalDeclarations=*/ false, new InstructionDataMergeStrategy>() { @NotNull @@ -159,7 +159,7 @@ public class PseudocodeVariablesData { Map enterInstructionData = mergeIncomingEdgesDataForInitializers(incomingEdgesData); Map exitInstructionData = addVariableInitStateFromCurrentInstructionIfAny( - instruction, enterInstructionData, lexicalScopeVariableInfo); + instruction, enterInstructionData, lexicalScopeVariableInfo); return createEdges(enterInstructionData, exitInstructionData); } } @@ -246,7 +246,7 @@ public class PseudocodeVariablesData { @NotNull public Map>> getVariableUseStatusData() { - return pseudocodeVariableDataCollector.collectDataJ( + return pseudocodeVariableDataCollector.collectData( BACKWARD, /*mergeDataWithLocalDeclarations=*/ true, new InstructionDataMergeStrategy>() { @NotNull