Added control flow data for entering each vertex (instruction) as well as for exit
This commit is contained in:
+14
-14
@@ -3,10 +3,8 @@ package org.jetbrains.jet.lang.cfg;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.Instruction;
|
import com.intellij.openapi.util.Pair;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.LocalDeclarationInstruction;
|
import org.jetbrains.jet.lang.cfg.pseudocode.*;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
|
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.SubroutineEnterInstruction;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -17,15 +15,15 @@ import java.util.Map;
|
|||||||
* @author svtk
|
* @author svtk
|
||||||
*/
|
*/
|
||||||
public class JetControlFlowGraphTraverser {
|
public class JetControlFlowGraphTraverser {
|
||||||
public static <D> Map<Instruction, D> traverseInstructionGraphUntilFactsStabilization(
|
public static <D> Map<Instruction, Pair<D, D>> traverseInstructionGraphUntilFactsStabilization(
|
||||||
Pseudocode pseudocode,
|
Pseudocode pseudocode,
|
||||||
InstructionsMergeStrategy<D> instructionsMergeStrategy,
|
InstructionsMergeStrategy<D> instructionsMergeStrategy,
|
||||||
D initialDataValue,
|
D initialDataValue,
|
||||||
D initialDataValueForEnterInstruction,
|
D initialDataValueForEnterInstruction,
|
||||||
boolean straightDirection) {
|
boolean straightDirection) {
|
||||||
Map<Instruction, D> dataMap = Maps.newHashMap();
|
Map<Instruction, Pair<D, D>> dataMap = Maps.newLinkedHashMap();
|
||||||
initializeDataMap(dataMap, pseudocode, initialDataValue);
|
initializeDataMap(dataMap, pseudocode, initialDataValue);
|
||||||
dataMap.put(pseudocode.getEnterInstruction(), initialDataValueForEnterInstruction);
|
dataMap.put(pseudocode.getEnterInstruction(), Pair.create(initialDataValueForEnterInstruction, initialDataValueForEnterInstruction));
|
||||||
|
|
||||||
boolean[] changed = new boolean[1];
|
boolean[] changed = new boolean[1];
|
||||||
changed[0] = true;
|
changed[0] = true;
|
||||||
@@ -37,12 +35,13 @@ public class JetControlFlowGraphTraverser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static <D> void initializeDataMap(
|
private static <D> void initializeDataMap(
|
||||||
Map<Instruction, D> dataMap,
|
Map<Instruction, Pair<D, D>> dataMap,
|
||||||
Pseudocode pseudocode,
|
Pseudocode pseudocode,
|
||||||
D initialDataValue) {
|
D initialDataValue) {
|
||||||
List<Instruction> instructions = pseudocode.getInstructions();
|
List<Instruction> instructions = pseudocode.getInstructions();
|
||||||
|
Pair<D, D> initialPair = Pair.create(initialDataValue, initialDataValue);
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
dataMap.put(instruction, initialDataValue);
|
dataMap.put(instruction, initialPair);
|
||||||
if (instruction instanceof LocalDeclarationInstruction) {
|
if (instruction instanceof LocalDeclarationInstruction) {
|
||||||
initializeDataMap(dataMap, ((LocalDeclarationInstruction) instruction).getBody(), initialDataValue);
|
initializeDataMap(dataMap, ((LocalDeclarationInstruction) instruction).getBody(), initialDataValue);
|
||||||
}
|
}
|
||||||
@@ -54,7 +53,7 @@ public class JetControlFlowGraphTraverser {
|
|||||||
InstructionsMergeStrategy<D> instructionsMergeStrategy,
|
InstructionsMergeStrategy<D> instructionsMergeStrategy,
|
||||||
Collection<Instruction> previousSubGraphInstructions,
|
Collection<Instruction> previousSubGraphInstructions,
|
||||||
boolean straightDirection,
|
boolean straightDirection,
|
||||||
Map<Instruction, D> dataMap,
|
Map<Instruction, Pair<D, D>> dataMap,
|
||||||
boolean[] changed,
|
boolean[] changed,
|
||||||
boolean isLocal) {
|
boolean isLocal) {
|
||||||
List<Instruction> instructions = pseudocode.getInstructions();
|
List<Instruction> instructions = pseudocode.getInstructions();
|
||||||
@@ -79,14 +78,14 @@ public class JetControlFlowGraphTraverser {
|
|||||||
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
|
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
|
||||||
traverseSubGraph(subroutinePseudocode, instructionsMergeStrategy, previousInstructions, straightDirection, dataMap, changed, true);
|
traverseSubGraph(subroutinePseudocode, instructionsMergeStrategy, previousInstructions, straightDirection, dataMap, changed, true);
|
||||||
}
|
}
|
||||||
D previousDataValue = dataMap.get(instruction);
|
Pair<D, D> previousDataValue = dataMap.get(instruction);
|
||||||
|
|
||||||
Collection<D> incomingEdgesData = Sets.newHashSet();
|
Collection<D> incomingEdgesData = Sets.newHashSet();
|
||||||
|
|
||||||
for (Instruction previousInstruction : allPreviousInstructions) {
|
for (Instruction previousInstruction : allPreviousInstructions) {
|
||||||
incomingEdgesData.add(dataMap.get(previousInstruction));
|
incomingEdgesData.add(dataMap.get(previousInstruction).getSecond());
|
||||||
}
|
}
|
||||||
D mergedData = instructionsMergeStrategy.execute(instruction, incomingEdgesData);
|
Pair<D, D> mergedData = instructionsMergeStrategy.execute(instruction, incomingEdgesData);
|
||||||
if (!mergedData.equals(previousDataValue)) {
|
if (!mergedData.equals(previousDataValue)) {
|
||||||
changed[0] = true;
|
changed[0] = true;
|
||||||
dataMap.put(instruction, mergedData);
|
dataMap.put(instruction, mergedData);
|
||||||
@@ -99,6 +98,7 @@ public class JetControlFlowGraphTraverser {
|
|||||||
InstructionDataAnalyzeStrategy instructionDataAnalyzeStrategy) {
|
InstructionDataAnalyzeStrategy instructionDataAnalyzeStrategy) {
|
||||||
List<Instruction> instructions = pseudocode.getInstructions();
|
List<Instruction> instructions = pseudocode.getInstructions();
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
|
if (((InstructionImpl)instruction).isDead()) continue;
|
||||||
if (instruction instanceof LocalDeclarationInstruction) {
|
if (instruction instanceof LocalDeclarationInstruction) {
|
||||||
traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody(), instructionDataAnalyzeStrategy);
|
traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody(), instructionDataAnalyzeStrategy);
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ public class JetControlFlowGraphTraverser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface InstructionsMergeStrategy<D> {
|
interface InstructionsMergeStrategy<D> {
|
||||||
D execute(Instruction instruction, Collection<D> incomingEdgesData);
|
Pair<D, D> execute(Instruction instruction, Collection<D> incomingEdgesData);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InstructionDataAnalyzeStrategy {
|
interface InstructionDataAnalyzeStrategy {
|
||||||
|
|||||||
Reference in New Issue
Block a user