diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index d0da240b44d..5375b8e65c2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -258,15 +258,16 @@ public class JetFlowInformationProvider { private Set collectUnreachableCode() { Set unreachableElements = Sets.newHashSet(); - for (Instruction deadInstruction : pseudocode.getDeadInstructions()) { - if (!(deadInstruction instanceof JetElementInstruction) - || deadInstruction instanceof LoadUnitValueInstruction - || deadInstruction instanceof MergeInstruction - || (deadInstruction instanceof MagicInstruction && ((MagicInstruction) deadInstruction).getSynthetic())) continue; + for (Instruction instruction : pseudocode.getDeadInstructions()) { + if (!PseudocodeUtil.isDeadInAllCopies(instruction)) continue; + if (!(instruction instanceof JetElementInstruction) + || instruction instanceof LoadUnitValueInstruction + || instruction instanceof MergeInstruction + || (instruction instanceof MagicInstruction && ((MagicInstruction) instruction).getSynthetic())) continue; - JetElement element = ((JetElementInstruction) deadInstruction).getElement(); + JetElement element = ((JetElementInstruction) instruction).getElement(); - if (deadInstruction instanceof JumpInstruction) { + if (instruction instanceof JumpInstruction) { boolean isJumpElement = element instanceof JetBreakExpression || element instanceof JetContinueExpression || element instanceof JetReturnExpression diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java index e86b008fd7d..91044d06959 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java @@ -45,7 +45,7 @@ public interface Pseudocode { List getReversedInstructions(); @NotNull - List getDeadInstructions(); + List getInstructionsIncludingDeadCode(); @NotNull SubroutineExitInstruction getExitInstruction(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java index 650d9123af3..9613b7a0f40 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeImpl.java @@ -183,30 +183,10 @@ public class PseudocodeImpl implements Pseudocode { return Lists.newArrayList(traversedInstructions); } - //for tests only - @NotNull - public List getAllInstructions() { - return mutableInstructionList; - } - @Override @NotNull - public List getDeadInstructions() { - List deadInstructions = Lists.newArrayList(); - for (Instruction instruction : mutableInstructionList) { - if (isDead(instruction)) { - deadInstructions.add(instruction); - } - } - return deadInstructions; - } - - private static boolean isDead(@NotNull Instruction instruction) { - if (!((InstructionImpl)instruction).getDead()) return false; - for (Instruction copy : instruction.getCopies()) { - if (!((InstructionImpl)copy).getDead()) return false; - } - return true; + public List getInstructionsIncludingDeadCode() { + return mutableInstructionList; } //for tests only diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java index 8ad89af03b5..b6e5bdc5db8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/PseudocodeUtil.java @@ -85,4 +85,12 @@ public class PseudocodeUtil { } return BindingContextUtils.extractVariableDescriptorIfAny(bindingContext, element, onlyReference); } + + public static boolean isDeadInAllCopies(@NotNull Instruction instruction) { + boolean allCopiesAreDead = instruction.getDead(); + for (Instruction copy : instruction.getCopies()) { + allCopiesAreDead = allCopiesAreDead && copy.getDead(); + } + return allCopiesAreDead; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/Instruction.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/Instruction.kt index 17fbcaaeffe..e98ff49cdb0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/Instruction.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/Instruction.kt @@ -26,6 +26,8 @@ public trait Instruction { public val previousInstructions: MutableCollection public val nextInstructions: Collection + public val dead: Boolean + public val lexicalScope: LexicalScope public val inputValues: List diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionImpl.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionImpl.kt index bb367a57f1b..a57b75dd7c2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionImpl.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/instructions/InstructionImpl.kt @@ -53,7 +53,7 @@ public abstract class InstructionImpl(public override val lexicalScope: LexicalS _dead = true } - public val dead: Boolean get() = _dead + override val dead: Boolean get() = _dead public fun copy(): Instruction { return updateCopyInfo(createCopy()) diff --git a/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java index 64a552fb074..cea52dc1fa4 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/AbstractControlFlowTest.java @@ -19,9 +19,8 @@ package org.jetbrains.jet.cfg; import kotlin.Function3; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.cfg.pseudocode.instructions.Instruction; -import org.jetbrains.jet.lang.cfg.pseudocode.instructions.InstructionImpl; import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeImpl; +import org.jetbrains.jet.lang.cfg.pseudocode.instructions.Instruction; import org.jetbrains.jet.lang.resolve.BindingContext; import java.util.*; @@ -34,7 +33,7 @@ public abstract class AbstractControlFlowTest extends AbstractPseudocodeTest { @NotNull StringBuilder out, @NotNull BindingContext bindingContext ) { - final int nextInstructionsColumnWidth = countNextInstructionsColumnWidth(pseudocode.getAllInstructions()); + final int nextInstructionsColumnWidth = countNextInstructionsColumnWidth(pseudocode.getInstructionsIncludingDeadCode()); dumpInstructions(pseudocode, out, new Function3() { @Override @@ -107,9 +106,9 @@ public abstract class AbstractControlFlowTest extends AbstractPseudocodeTest { @Override protected void checkPseudocode(PseudocodeImpl pseudocode) { //check edges directions - Collection instructions = pseudocode.getAllInstructions(); + Collection instructions = pseudocode.getInstructionsIncludingDeadCode(); for (Instruction instruction : instructions) { - if (!((InstructionImpl)instruction).getDead()) { + if (!instruction.getDead()) { for (Instruction nextInstruction : instruction.getNextInstructions()) { assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa", nextInstruction.getPreviousInstructions().contains(instruction)); diff --git a/compiler/tests/org/jetbrains/jet/cfg/AbstractDataFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/AbstractDataFlowTest.java index 64b095a31ed..27b37d7a209 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/AbstractDataFlowTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/AbstractDataFlowTest.java @@ -49,7 +49,7 @@ public abstract class AbstractDataFlowTest extends AbstractPseudocodeTest { pseudocodeVariablesData.getVariableUseStatusData(); final String initPrefix = " INIT:"; final String usePrefix = " USE:"; - final int initializersColumnWidth = countDataColumnWidth(initPrefix, pseudocode.getAllInstructions(), variableInitializers); + final int initializersColumnWidth = countDataColumnWidth(initPrefix, pseudocode.getInstructionsIncludingDeadCode(), variableInitializers); dumpInstructions(pseudocode, out, new Function3() { @Override diff --git a/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java b/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java index 1d8315db966..1dc9d51d6d1 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/AbstractPseudocodeTest.java @@ -179,7 +179,7 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment { @NotNull StringBuilder out, @NotNull Function3 getInstructionData ) { - List instructions = pseudocode.getAllInstructions(); + List instructions = pseudocode.getInstructionsIncludingDeadCode(); Set remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions()); List labels = pseudocode.getLabels(); int instructionColumnWidth = countInstructionColumnWidth(instructions); diff --git a/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java b/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java index 4dc51c2b970..878996e3845 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java +++ b/compiler/tests/org/jetbrains/jet/cfg/CFGraphToDotFilePrinter.java @@ -44,7 +44,7 @@ public class CFGraphToDotFilePrinter { int[] count = new int[1]; Map nodeToName = new HashMap(); for (Pseudocode pseudocode : pseudocodes) { - dumpNodes(((PseudocodeImpl)pseudocode).getAllInstructions(), out, count, nodeToName, Sets + dumpNodes(pseudocode.getInstructionsIncludingDeadCode(), out, count, nodeToName, Sets .newHashSet(pseudocode.getInstructions())); } int i = 0; @@ -61,7 +61,7 @@ public class CFGraphToDotFilePrinter { out.println("subgraph cluster_" + i + " {\n" + "label=\"" + label + "\";\n" + "color=blue;\n"); - dumpEdges(((PseudocodeImpl)pseudocode).getAllInstructions(), out, count, nodeToName); + dumpEdges(pseudocode.getInstructionsIncludingDeadCode(), out, count, nodeToName); out.println("}"); i++; } @@ -76,7 +76,7 @@ public class CFGraphToDotFilePrinter { public void visitLocalFunctionDeclarationInstruction(LocalFunctionDeclarationInstruction instruction) { int index = count[0]; // instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName); - printEdge(out, nodeToName.get(instruction), nodeToName.get(((PseudocodeImpl)instruction.getBody()).getAllInstructions().get(0)), null); + printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getBody().getInstructionsIncludingDeadCode().get(0)), null); visitInstructionWithNext(instruction); }