Fix bugs in nullness checker. Use it in LICM

This commit is contained in:
Alexey Andreev 2016-11-25 00:30:45 +03:00 committed by Alexey Andreev
parent 2894c541f7
commit 6f92dadad5
5 changed files with 37 additions and 8 deletions

View File

@ -51,7 +51,7 @@ public class NullnessChecker {
notNullIncomings = new HashSet<>();
notNull = new boolean[program.variableCount()];
nullLiteral = new boolean[program.variableCount()];
phiOutputs = ProgramUtils.getPhiOutputs(program);
phiOutputs = ProgramUtils.getPhiOutputsByVariable(program);
graphBuilder = new GraphBuilder(program.variableCount());
Graph cfg = ProgramUtils.buildControlFlowGraph(program);

View File

@ -57,10 +57,15 @@ import org.teavm.model.instructions.SwitchInstruction;
import org.teavm.model.instructions.UnwrapArrayInstruction;
public class LoopInvariantAnalyzer implements InstructionVisitor {
private boolean[] notNull;
public boolean canMove;
public boolean constant;
public boolean sideEffect;
public LoopInvariantAnalyzer(boolean[] notNull) {
this.notNull = notNull;
}
public void reset() {
canMove = false;
constant = false;
@ -187,7 +192,9 @@ public class LoopInvariantAnalyzer implements InstructionVisitor {
@Override
public void visit(ArrayLengthInstruction insn) {
canMove = true;
sideEffect = true;
if (!notNull[insn.getArray().getIndex()]) {
sideEffect = true;
}
}
@Override
@ -197,7 +204,9 @@ public class LoopInvariantAnalyzer implements InstructionVisitor {
@Override
public void visit(UnwrapArrayInstruction insn) {
canMove = true;
sideEffect = true;
if (!notNull[insn.getArray().getIndex()]) {
sideEffect = true;
}
}
@Override
@ -228,16 +237,16 @@ public class LoopInvariantAnalyzer implements InstructionVisitor {
@Override
public void visit(NullCheckInstruction insn) {
canMove = true;
sideEffect = true;
if (!notNull[insn.getValue().getIndex()]) {
sideEffect = true;
}
}
@Override
public void visit(MonitorEnterInstruction insn) {
}
@Override
public void visit(MonitorExitInstruction insn) {
}
}

View File

@ -20,6 +20,7 @@ import java.util.Arrays;
import java.util.List;
import org.teavm.common.*;
import org.teavm.model.*;
import org.teavm.model.analysis.NullnessChecker;
import org.teavm.model.instructions.*;
import org.teavm.model.util.*;
@ -53,7 +54,7 @@ public class LoopInvariantMotion implements MethodOptimization {
DefinitionExtractor defExtractor = new DefinitionExtractor();
UsageExtractor useExtractor = new UsageExtractor();
LoopInvariantAnalyzer analyzer = new LoopInvariantAnalyzer();
LoopInvariantAnalyzer analyzer = new LoopInvariantAnalyzer(new NullnessChecker().check(program));
CopyConstantVisitor constantCopier = new CopyConstantVisitor();
int[][] loopExits = ControlFlowUtils.findLoopExits(graph);

View File

@ -41,6 +41,7 @@ import org.teavm.model.Program;
import org.teavm.model.TryCatchBlock;
import org.teavm.model.TryCatchJoint;
import org.teavm.model.Variable;
import org.teavm.model.analysis.NullnessChecker;
import org.teavm.model.util.BasicBlockMapper;
import org.teavm.model.util.DefinitionExtractor;
import org.teavm.model.util.InstructionCopyReader;
@ -222,7 +223,8 @@ class LoopInversionImpl {
private boolean isInversionProfitable(IntSet nodesToCopy) {
UsageExtractor useExtractor = new UsageExtractor();
DefinitionExtractor defExtractor = new DefinitionExtractor();
LoopInvariantAnalyzer invariantAnalyzer = new LoopInvariantAnalyzer();
boolean[] notNull = new NullnessChecker().check(program);
LoopInvariantAnalyzer invariantAnalyzer = new LoopInvariantAnalyzer(notNull);
for (int node : nodes.toArray()) {
if (nodesToCopy.contains(node)) {
continue;

View File

@ -163,6 +163,23 @@ public final class ProgramUtils {
return outputs;
}
public static List<List<Incoming>> getPhiOutputsByVariable(Program program) {
List<List<Incoming>> outputs = new ArrayList<>(program.variableCount());
for (int i = 0; i < program.variableCount(); ++i) {
outputs.add(new ArrayList<>());
}
for (BasicBlock block : program.getBasicBlocks()) {
for (Phi phi : block.getPhis()) {
for (Incoming incoming : phi.getIncomings()) {
outputs.get(incoming.getValue().getIndex()).add(incoming);
}
}
}
return outputs;
}
public static BasicBlock[] getVariableDefinitionPlaces(Program program) {
BasicBlock[] places = new BasicBlock[program.variableCount()];
DefinitionExtractor defExtractor = new DefinitionExtractor();