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

View File

@ -27,24 +27,10 @@ class InterferenceGraphBuilder {
} }
UsageExtractor useExtractor = new UsageExtractor(); UsageExtractor useExtractor = new UsageExtractor();
DefinitionExtractor defExtractor = new DefinitionExtractor(); 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) { for (int i = 0; i < program.basicBlockCount(); ++i) {
BasicBlock block = program.basicBlockAt(i); BasicBlock block = program.basicBlockAt(i);
block.getLastInstruction().acceptVisitor(succExtractor);
BitSet liveOut = liveness.liveOut(i); BitSet live = 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());
}
for (Instruction insn = block.getLastInstruction(); insn != null; insn = insn.getPrevious()) { for (Instruction insn = block.getLastInstruction(); insn != null; insn = insn.getPrevious()) {
insn.acceptVisitor(useExtractor); 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()) { for (Phi phi : block.getPhis()) {
connect(nodes, phi.getReceiver().getIndex(), live); 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.Phi;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.ProgramReader; import org.teavm.model.ProgramReader;
import org.teavm.model.TextLocation;
import org.teavm.model.Variable; import org.teavm.model.Variable;
import org.teavm.model.instructions.AssignInstruction; import org.teavm.model.instructions.AssignInstruction;
import org.teavm.model.instructions.JumpInstruction; import org.teavm.model.instructions.JumpInstruction;
@ -188,41 +189,22 @@ public class RegisterAllocator {
DefinitionExtractor definitionExtractor = new DefinitionExtractor(); DefinitionExtractor definitionExtractor = new DefinitionExtractor();
List<Instruction> nextInstructions = new ArrayList<>(); List<Instruction> nextInstructions = new ArrayList<>();
for (BasicBlock block : program.getBasicBlocks()) { 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) { for (Instruction instruction : block) {
instruction.acceptVisitor(definitionExtractor); instruction.acceptVisitor(definitionExtractor);
Variable[] definedVariables = definitionExtractor.getDefinedVariables(); Variable[] definedVariables = definitionExtractor.getDefinedVariables();
for (Variable definedVariable : definedVariables) { for (Variable definedVariable : definedVariables) {
if (definedVariable.getIndex() >= catchIncomingsByVariable.size()) { addExceptionHandlingCopies(catchIncomingsByVariable, definedVariable, block,
continue; program, instruction.getLocation(), nextInstructions);
}
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);
} }
if (!nextInstructions.isEmpty()) { if (!nextInstructions.isEmpty()) {
@ -242,18 +224,48 @@ public class RegisterAllocator {
Variable copy = program.createVariable(); Variable copy = program.createVariable();
copy.setLabel(incoming.getPhi().getReceiver().getLabel()); copy.setLabel(incoming.getPhi().getReceiver().getLabel());
copy.setDebugName(incoming.getPhi().getReceiver().getDebugName()); copy.setDebugName(incoming.getPhi().getReceiver().getDebugName());
incoming.setValue(copy);
AssignInstruction copyInstruction = new AssignInstruction(); AssignInstruction copyInstruction = new AssignInstruction();
copyInstruction.setReceiver(copy); copyInstruction.setReceiver(copy);
copyInstruction.setAssignee(incoming.getValue()); copyInstruction.setAssignee(incoming.getValue());
copyInstruction.setLocation(block.getFirstInstruction().getLocation()); copyInstruction.setLocation(block.getFirstInstruction().getLocation());
incoming.setValue(copy);
block.addFirst(copyInstruction); 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) { private void insertCopy(Incoming incoming, Map<BasicBlock, BasicBlock> blockMap) {
Phi phi = incoming.getPhi(); Phi phi = incoming.getPhi();
Program program = phi.getBasicBlock().getProgram(); 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) { static char16_t* teavm_utf16ToUtf32(char16_t* source, char32_t* target) {
char16_t c = *source; char16_t c = *source;
if (c & 0xFC00 == 0xD800) { if ((c & 0xFC00) == 0xD800) {
char16_t n = *(source + 1); char16_t n = *(source + 1);
if (n & 0xFC00 == 0xDC00) { if ((n & 0xFC00) == 0xDC00) {
*target = (((c & ~0xFC00) << 10) | (n & ~0xFC00)) + 0x10000; *target = (((c & ~0xFC00) << 10) | (n & ~0xFC00)) + 0x10000;
return source + 2; return source + 2;
} }

View File

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