Dead code finding moved to pseudocode construction

This commit is contained in:
svtk
2011-10-24 13:01:02 +04:00
parent b31f4b5251
commit 23278d1427
3 changed files with 89 additions and 21 deletions
@@ -118,18 +118,26 @@ public class JetFlowInformationProvider {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
Set<Instruction> visited = new HashSet<Instruction>();
collectReachable(enterInstruction, visited, null);
for (Instruction instruction : pseudocode.getInstructions()) {
if (!visited.contains(instruction) &&
instruction instanceof JetElementInstruction &&
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
if (deadInstruction instanceof JetElementInstruction &&
// TODO : do {return} while (1 > a)
!(instruction instanceof ReadUnitValueInstruction)) {
unreachableElements.add(((JetElementInstruction) instruction).getElement());
!(deadInstruction instanceof ReadUnitValueInstruction)) {
unreachableElements.add(((JetElementInstruction) deadInstruction).getElement());
}
}
// SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
// Set<Instruction> visited = new HashSet<Instruction>();
// collectReachable(enterInstruction, visited, null);
//
// for (Instruction instruction : pseudocode.getInstructions()) {
// if (!visited.contains(instruction) &&
// instruction instanceof JetElementInstruction &&
// // TODO : do {return} while (1 > a)
// !(instruction instanceof ReadUnitValueInstruction)) {
// unreachableElements.add(((JetElementInstruction) instruction).getElement());
// }
// }
}
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
// Instruction dominatorInstruction = representativeInstructions.get(dominator);
@@ -248,7 +256,11 @@ public class JetFlowInformationProvider {
// }
// }
private <D> Map<Instruction, D> traverseInstructionGraphUntilFactsStabilization(Pseudocode pseudocode, InstructionsMergeHandler<D> instructionsMergeHandler, D initialDataValue, boolean straightDirection) {
private <D> Map<Instruction, D> traverseInstructionGraphUntilFactsStabilization(
Pseudocode pseudocode,
InstructionsMergeHandler<D> instructionsMergeHandler,
D initialDataValue,
boolean straightDirection) {
Map<Instruction, D> dataMap = Maps.newHashMap();
initializeDataMap(dataMap, pseudocode, initialDataValue);
@@ -261,7 +273,10 @@ public class JetFlowInformationProvider {
return dataMap;
}
private <D> void initializeDataMap(Map<Instruction, D> dataMap, Pseudocode pseudocode, D initialDataValue) {
private <D> void initializeDataMap(
Map<Instruction, D> dataMap,
Pseudocode pseudocode,
D initialDataValue) {
List<Instruction> instructions = pseudocode.getInstructions();
for (Instruction instruction : instructions) {
dataMap.put(instruction, initialDataValue);
@@ -271,7 +286,13 @@ public class JetFlowInformationProvider {
}
}
private <D> void traverseSubGraph(Pseudocode pseudocode, InstructionsMergeHandler<D> instructionsMergeHandler, Collection<Instruction> previousSubGraphInstructions, boolean straightDirection, Map<Instruction, D> dataMap, boolean[] changed) {
private <D> void traverseSubGraph(
Pseudocode pseudocode,
InstructionsMergeHandler<D> instructionsMergeHandler,
Collection<Instruction> previousSubGraphInstructions,
boolean straightDirection,
Map<Instruction, D> dataMap,
boolean[] changed) {
List<Instruction> instructions = pseudocode.getInstructions();
SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
for (Instruction instruction : instructions) {
@@ -317,22 +338,28 @@ public class JetFlowInformationProvider {
public Set<LocalVariableDescriptor> merge(Instruction instruction, Set<LocalVariableDescriptor> previousDataValue, Collection<Set<LocalVariableDescriptor>> incomingEdgesData) {
Set<LocalVariableDescriptor> initializedVariables = Sets.newHashSet();
initializedVariables.addAll(previousDataValue);
for (Set<LocalVariableDescriptor> edgeDataValue : incomingEdgesData) {
initializedVariables.addAll(edgeDataValue);
Set<LocalVariableDescriptor> edgesDataIntersection = Sets.newHashSet();
boolean isFirst = true;
for (Set<LocalVariableDescriptor> edgeData : incomingEdgesData) {
if (isFirst) {
edgesDataIntersection.addAll(edgeData);
}
else {
edgesDataIntersection = Sets.intersection(edgesDataIntersection, edgeData).immutableCopy();
}
isFirst = false;
}
initializedVariables.addAll(edgesDataIntersection);
if (instruction instanceof WriteValueInstruction) {
DeclarationDescriptor descriptor = null;
JetElement lValue = ((WriteValueInstruction) instruction).getlValue();
if (lValue instanceof JetProperty) {
if (lValue instanceof JetProperty || lValue instanceof JetParameter) {
descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue);
}
else if (lValue instanceof JetSimpleNameExpression) {
descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) lValue);
}
else if (lValue instanceof JetParameter) {
descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue);
}
if (descriptor instanceof LocalVariableDescriptor) {
initializedVariables.add((LocalVariableDescriptor) descriptor);
}
@@ -357,16 +384,16 @@ public class JetFlowInformationProvider {
}
}
else if (instruction instanceof WriteValueInstruction) {
JetElement element = ((WriteValueInstruction) instruction).getElement();
JetElement element = ((WriteValueInstruction) instruction).getlValue();
if (element instanceof JetSimpleNameExpression) {
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
if (descriptor instanceof LocalVariableDescriptor) {
if (initializedVariables.contains(descriptor) && ((LocalVariableDescriptor) descriptor).isVar()) {
if (initializedVariables.contains(descriptor) && !((LocalVariableDescriptor) descriptor).isVar()) {
trace.report(Errors.VAL_REASSIGNMENT.on((JetSimpleNameExpression) element, descriptor));
}
}
}
}
}
}
};
traverseInstructionGraphAndReportErrors(instructions, dataMap, instructionDataAnalyzer);
@@ -12,6 +12,7 @@ import java.util.LinkedHashSet;
public abstract class InstructionImpl implements Instruction {
private Pseudocode owner;
private final Collection<Instruction> previousInstructions = new LinkedHashSet<Instruction>();
protected boolean isDead = false;
protected InstructionImpl() {
}
@@ -42,4 +43,11 @@ public abstract class InstructionImpl implements Instruction {
return target;
}
public void die() {
isDead = true;
}
public boolean isDead() {
return isDead;
}
}
@@ -1,5 +1,7 @@
package org.jetbrains.jet.lang.cfg.pseudocode;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.Label;
@@ -77,6 +79,17 @@ public class Pseudocode {
public List<Instruction> getInstructions() {
return instructions;
}
@NotNull
public List<Instruction> getDeadInstructions() {
List<Instruction> deadInstructions = Lists.newArrayList();
for (Instruction instruction : instructions) {
if (((InstructionImpl)instruction).isDead()) {
deadInstructions.add(instruction);
}
}
return deadInstructions;
}
@Deprecated //for tests only
public List<PseudocodeLabel> getLabels() {
@@ -166,6 +179,26 @@ public class Pseudocode {
}
});
}
removeDeadInstructions();
}
private void removeDeadInstructions() {
boolean hasRemovedInstruction = true;
Collection<Instruction> processedInstructions = Sets.newHashSet();
while (hasRemovedInstruction) {
hasRemovedInstruction = false;
for (Instruction instruction : instructions) {
if (!(instruction instanceof SubroutineEnterInstruction || instruction instanceof SubroutineExitInstruction) &&
instruction.getPreviousInstructions().isEmpty() && !processedInstructions.contains(instruction)) {
hasRemovedInstruction = true;
for (Instruction nextInstruction : instruction.getNextInstructions()) {
nextInstruction.getPreviousInstructions().remove(instruction);
}
((InstructionImpl)instruction).die();
processedInstructions.add(instruction);
}
}
}
}
@NotNull