JCL tests pass with loop invariant motion enabled

This commit is contained in:
Alexey Andreev 2014-03-27 21:19:55 +04:00
parent b96c5038ce
commit cfd0f3e998

View File

@ -20,6 +20,7 @@ import java.util.List;
import org.teavm.common.*; import org.teavm.common.*;
import org.teavm.model.*; import org.teavm.model.*;
import org.teavm.model.instructions.*; import org.teavm.model.instructions.*;
import org.teavm.model.util.BasicBlockMapper;
import org.teavm.model.util.DefinitionExtractor; import org.teavm.model.util.DefinitionExtractor;
import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.ProgramUtils;
import org.teavm.model.util.UsageExtractor; import org.teavm.model.util.UsageExtractor;
@ -88,10 +89,13 @@ public class LoopInvariantMotion implements MethodOptimization {
commonUseLoop = useLoop; commonUseLoop = useLoop;
} }
} }
block.getInstructions().set(i, new EmptyInstruction());
while (defLoop.getParent() != commonUseLoop) { while (defLoop.getParent() != commonUseLoop) {
defLoop = defLoop.getParent(); defLoop = defLoop.getParent();
if (defLoop == null) {
continue insnLoop;
} }
}
block.getInstructions().set(i, new EmptyInstruction());
int preheader = getPreheader(defLoop.getHead()); int preheader = getPreheader(defLoop.getHead());
List<Instruction> preheaderInstructions = program.basicBlockAt(preheader).getInstructions(); List<Instruction> preheaderInstructions = program.basicBlockAt(preheader).getInstructions();
preheaderInstructions.add(preheaderInstructions.size() - 1, insn); preheaderInstructions.add(preheaderInstructions.size() - 1, insn);
@ -108,7 +112,7 @@ public class LoopInvariantMotion implements MethodOptimization {
if (preheader < 0) { if (preheader < 0) {
int[] entries = getLoopEntries(header); int[] entries = getLoopEntries(header);
if (entries.length == 1) { if (entries.length == 1) {
preheader = graph.incomingEdges(header)[0]; preheader = entries[0];
} else { } else {
preheader = insertPreheader(header); preheader = insertPreheader(header);
} }
@ -130,9 +134,9 @@ public class LoopInvariantMotion implements MethodOptimization {
} }
private int insertPreheader(int headerIndex) { private int insertPreheader(int headerIndex) {
BasicBlock preheader = program.createBasicBlock(); final BasicBlock preheader = program.createBasicBlock();
JumpInstruction escapeInsn = new JumpInstruction(); JumpInstruction escapeInsn = new JumpInstruction();
BasicBlock header = program.basicBlockAt(headerIndex); final BasicBlock header = program.basicBlockAt(headerIndex);
escapeInsn.setTarget(header); escapeInsn.setTarget(header);
preheader.getInstructions().add(escapeInsn); preheader.getInstructions().add(escapeInsn);
for (int i = 0; i < header.getPhis().size(); ++i) { for (int i = 0; i < header.getPhis().size(); ++i) {
@ -153,10 +157,23 @@ public class LoopInvariantMotion implements MethodOptimization {
if (preheaderPhi != null) { if (preheaderPhi != null) {
Incoming incoming = new Incoming(); Incoming incoming = new Incoming();
incoming.setSource(preheader); incoming.setSource(preheader);
incoming.setValue(phi.getReceiver()); incoming.setValue(preheaderPhi.getReceiver());
phi.getIncomings().add(incoming); phi.getIncomings().add(incoming);
} }
} }
for (int predIndex : graph.incomingEdges(headerIndex)) {
if (!dom.dominates(headerIndex, predIndex)) {
BasicBlock pred = program.basicBlockAt(predIndex);
pred.getLastInstruction().acceptVisitor(new BasicBlockMapper() {
@Override protected BasicBlock map(BasicBlock block) {
if (block == header) {
block = preheader;
}
return block;
}
});
}
}
return preheader.getIndex(); return preheader.getIndex();
} }