mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-21 01:00:54 +08:00
Fix register allocator
This commit is contained in:
parent
1074293aad
commit
a5ba6f247e
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user