mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -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.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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user