Fix register allocator

This commit is contained in:
Alexey Andreev 2019-07-30 10:58:08 +03:00
parent 1074293aad
commit a5ba6f247e
5 changed files with 64 additions and 65 deletions

View File

@ -48,6 +48,7 @@ import org.teavm.model.MethodReference;
import org.teavm.model.Program;
import org.teavm.model.TextLocation;
import org.teavm.model.TryCatchBlock;
import org.teavm.model.instructions.AssignInstruction;
import org.teavm.model.instructions.BinaryBranchingInstruction;
import org.teavm.model.instructions.BranchingInstruction;
import org.teavm.model.instructions.JumpInstruction;
@ -299,13 +300,24 @@ public class Decompiler {
if (exceptionHandlers[block.getIndex()]) {
return false;
}
if (block.instructionCount() != 1 || block.getExceptionVariable() != null) {
if (block.getExceptionVariable() != null) {
return false;
}
Instruction instruction = block.getLastInstruction();
return instruction instanceof JumpInstruction
|| instruction instanceof BranchingInstruction
|| instruction instanceof BinaryBranchingInstruction;
if (!(instruction instanceof JumpInstruction)
&& !(instruction instanceof BranchingInstruction)
&& !(instruction instanceof BinaryBranchingInstruction)) {
return false;
}
while (instruction.getPrevious() != null) {
instruction = instruction.getPrevious();
if (!(instruction instanceof AssignInstruction)) {
return false;
}
}
return true;
}
private void closeExpiredBookmarks(StatementGenerator generator, List<TryCatchBlock> tryCatchBlocks) {

View File

@ -27,24 +27,10 @@ class InterferenceGraphBuilder {
}
UsageExtractor useExtractor = new UsageExtractor();
DefinitionExtractor defExtractor = new DefinitionExtractor();
TransitionExtractor succExtractor = new TransitionExtractor();
List<List<Incoming>> outgoings = ProgramUtils.getPhiOutputs(program);
BitSet live = new BitSet();
for (int i = 0; i < program.basicBlockCount(); ++i) {
BasicBlock block = program.basicBlockAt(i);
block.getLastInstruction().acceptVisitor(succExtractor);
BitSet liveOut = liveness.liveOut(i);
live.clear();
for (int j = 0; j < liveOut.length(); ++j) {
if (liveOut.get(j)) {
live.set(j);
}
}
for (Incoming outgoing : outgoings.get(i)) {
live.set(outgoing.getValue().getIndex());
}
BitSet live = liveness.liveOut(i);
for (Instruction insn = block.getLastInstruction(); insn != null; insn = insn.getPrevious()) {
insn.acceptVisitor(useExtractor);
@ -69,18 +55,6 @@ class InterferenceGraphBuilder {
}
}
BitSet liveIn = liveness.liveIn(i);
live.clear();
for (int j = 0; j < liveOut.length(); ++j) {
if (liveIn.get(j)) {
live.set(j);
}
}
for (Phi phi : block.getPhis()) {
live.set(phi.getReceiver().getIndex());
}
for (Phi phi : block.getPhis()) {
connect(nodes, phi.getReceiver().getIndex(), live);
}

View File

@ -32,6 +32,7 @@ import org.teavm.model.MethodReference;
import org.teavm.model.Phi;
import org.teavm.model.Program;
import org.teavm.model.ProgramReader;
import org.teavm.model.TextLocation;
import org.teavm.model.Variable;
import org.teavm.model.instructions.AssignInstruction;
import org.teavm.model.instructions.JumpInstruction;
@ -188,41 +189,22 @@ public class RegisterAllocator {
DefinitionExtractor definitionExtractor = new DefinitionExtractor();
List<Instruction> nextInstructions = new ArrayList<>();
for (BasicBlock block : program.getBasicBlocks()) {
for (Phi phi : block.getPhis()) {
addExceptionHandlingCopies(catchIncomingsByVariable, phi.getReceiver(), block,
program, block.getFirstInstruction().getLocation(), nextInstructions);
}
if (!nextInstructions.isEmpty()) {
block.addFirstAll(nextInstructions);
nextInstructions.clear();
}
for (Instruction instruction : block) {
instruction.acceptVisitor(definitionExtractor);
Variable[] definedVariables = definitionExtractor.getDefinedVariables();
for (Variable definedVariable : definedVariables) {
if (definedVariable.getIndex() >= catchIncomingsByVariable.size()) {
continue;
}
List<Incoming> catchIncomings = catchIncomingsByVariable.get(definedVariable.getIndex());
if (catchIncomings == null) {
continue;
}
Incoming incoming = null;
for (Iterator<Incoming> iter = catchIncomings.iterator(); iter.hasNext();) {
if (iter.next().getValue() == definedVariable) {
iter.remove();
break;
}
}
if (incoming == null) {
continue;
}
Variable copy = program.createVariable();
copy.setLabel(incoming.getPhi().getReceiver().getLabel());
copy.setDebugName(incoming.getPhi().getReceiver().getDebugName());
AssignInstruction copyInstruction = new AssignInstruction();
copyInstruction.setReceiver(copy);
copyInstruction.setAssignee(incoming.getValue());
copyInstruction.setLocation(instruction.getLocation());
incoming.setValue(copy);
nextInstructions.add(copyInstruction);
addExceptionHandlingCopies(catchIncomingsByVariable, definedVariable, block,
program, instruction.getLocation(), nextInstructions);
}
if (!nextInstructions.isEmpty()) {
@ -242,18 +224,48 @@ public class RegisterAllocator {
Variable copy = program.createVariable();
copy.setLabel(incoming.getPhi().getReceiver().getLabel());
copy.setDebugName(incoming.getPhi().getReceiver().getDebugName());
incoming.setValue(copy);
AssignInstruction copyInstruction = new AssignInstruction();
copyInstruction.setReceiver(copy);
copyInstruction.setAssignee(incoming.getValue());
copyInstruction.setLocation(block.getFirstInstruction().getLocation());
incoming.setValue(copy);
block.addFirst(copyInstruction);
}
}
}
private void addExceptionHandlingCopies(List<List<Incoming>> catchIncomingsByVariable, Variable definedVariable,
BasicBlock block, Program program, TextLocation location, List<Instruction> nextInstructions) {
if (definedVariable.getIndex() >= catchIncomingsByVariable.size()) {
return;
}
List<Incoming> catchIncomings = catchIncomingsByVariable.get(definedVariable.getIndex());
if (catchIncomings == null) {
return;
}
for (Iterator<Incoming> iter = catchIncomings.iterator(); iter.hasNext();) {
Incoming incoming = iter.next();
if (incoming.getSource() == block) {
Variable copy = program.createVariable();
copy.setLabel(incoming.getPhi().getReceiver().getLabel());
copy.setDebugName(incoming.getPhi().getReceiver().getDebugName());
AssignInstruction copyInstruction = new AssignInstruction();
copyInstruction.setReceiver(copy);
copyInstruction.setAssignee(incoming.getValue());
copyInstruction.setLocation(location);
incoming.setValue(copy);
nextInstructions.add(copyInstruction);
iter.remove();
}
}
}
private void insertCopy(Incoming incoming, Map<BasicBlock, BasicBlock> blockMap) {
Phi phi = incoming.getPhi();
Program program = phi.getBasicBlock().getProgram();

View File

@ -276,9 +276,9 @@ void teavm_outOfMemory() {
static char16_t* teavm_utf16ToUtf32(char16_t* source, char32_t* target) {
char16_t c = *source;
if (c & 0xFC00 == 0xD800) {
if ((c & 0xFC00) == 0xD800) {
char16_t n = *(source + 1);
if (n & 0xFC00 == 0xDC00) {
if ((n & 0xFC00) == 0xDC00) {
*target = (((c & ~0xFC00) << 10) | (n & ~0xFC00)) + 0x10000;
return source + 2;
}

View File

@ -90,6 +90,7 @@ public class VMTest {
int a = 23;
try {
a = Integer.parseInt("not a number");
fail("Exception not thrown");
} catch (NumberFormatException e) {
// do nothing
}