mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-08 07:54:11 -08:00
wasm/c: fix bugs in coroutine transformation
This commit is contained in:
parent
d655f01d14
commit
70d0658b47
|
@ -17,7 +17,6 @@ package org.teavm.backend.lowlevel.transform;
|
||||||
|
|
||||||
import com.carrotsearch.hppc.IntHashSet;
|
import com.carrotsearch.hppc.IntHashSet;
|
||||||
import com.carrotsearch.hppc.IntIntHashMap;
|
import com.carrotsearch.hppc.IntIntHashMap;
|
||||||
import com.carrotsearch.hppc.IntIntMap;
|
|
||||||
import com.carrotsearch.hppc.IntSet;
|
import com.carrotsearch.hppc.IntSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -57,6 +56,7 @@ import org.teavm.model.instructions.MonitorEnterInstruction;
|
||||||
import org.teavm.model.instructions.NullConstantInstruction;
|
import org.teavm.model.instructions.NullConstantInstruction;
|
||||||
import org.teavm.model.instructions.SwitchInstruction;
|
import org.teavm.model.instructions.SwitchInstruction;
|
||||||
import org.teavm.model.instructions.SwitchTableEntry;
|
import org.teavm.model.instructions.SwitchTableEntry;
|
||||||
|
import org.teavm.model.optimization.RedundantJumpElimination;
|
||||||
import org.teavm.model.util.BasicBlockMapper;
|
import org.teavm.model.util.BasicBlockMapper;
|
||||||
import org.teavm.model.util.BasicBlockSplitter;
|
import org.teavm.model.util.BasicBlockSplitter;
|
||||||
import org.teavm.model.util.DefinitionExtractor;
|
import org.teavm.model.util.DefinitionExtractor;
|
||||||
|
@ -125,6 +125,7 @@ public class CoroutineTransformation {
|
||||||
}
|
}
|
||||||
splitter.fixProgram();
|
splitter.fixProgram();
|
||||||
processIrreducibleCfg();
|
processIrreducibleCfg();
|
||||||
|
RedundantJumpElimination.optimize(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSplitPrologue() {
|
private void createSplitPrologue() {
|
||||||
|
@ -485,9 +486,9 @@ public class CoroutineTransformation {
|
||||||
@Override
|
@Override
|
||||||
public int[] split(int[] domain, int[] nodes) {
|
public int[] split(int[] domain, int[] nodes) {
|
||||||
int[] copies = new int[nodes.length];
|
int[] copies = new int[nodes.length];
|
||||||
IntIntMap map = new IntIntHashMap();
|
var map = new IntIntHashMap();
|
||||||
IntSet nodeSet = IntHashSet.from(nodes);
|
IntSet nodeSet = IntHashSet.from(nodes);
|
||||||
List<List<Incoming>> outputs = ProgramUtils.getPhiOutputs(program);
|
var outputs = ProgramUtils.getPhiOutputs(program);
|
||||||
for (int i = 0; i < nodes.length; ++i) {
|
for (int i = 0; i < nodes.length; ++i) {
|
||||||
int node = nodes[i];
|
int node = nodes[i];
|
||||||
BasicBlock block = program.basicBlockAt(node);
|
BasicBlock block = program.basicBlockAt(node);
|
||||||
|
@ -497,7 +498,7 @@ public class CoroutineTransformation {
|
||||||
map.put(node, copies[i] + 1);
|
map.put(node, copies[i] + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBlockMapper copyBlockMapper = new BasicBlockMapper((int block) -> {
|
var copyBlockMapper = new BasicBlockMapper((int block) -> {
|
||||||
int mappedIndex = map.get(block);
|
int mappedIndex = map.get(block);
|
||||||
return mappedIndex == 0 ? block : mappedIndex - 1;
|
return mappedIndex == 0 ? block : mappedIndex - 1;
|
||||||
});
|
});
|
||||||
|
@ -508,6 +509,7 @@ public class CoroutineTransformation {
|
||||||
copyBlockMapper.transformWithoutPhis(program.basicBlockAt(domainNode));
|
copyBlockMapper.transformWithoutPhis(program.basicBlockAt(domainNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var domainSet = IntHashSet.from(domain);
|
||||||
for (int i = 0; i < nodes.length; ++i) {
|
for (int i = 0; i < nodes.length; ++i) {
|
||||||
int node = nodes[i];
|
int node = nodes[i];
|
||||||
BasicBlock blockCopy = program.basicBlockAt(copies[i]);
|
BasicBlock blockCopy = program.basicBlockAt(copies[i]);
|
||||||
|
@ -519,6 +521,15 @@ public class CoroutineTransformation {
|
||||||
output.getPhi().getIncomings().add(outputCopy);
|
output.getPhi().getIncomings().add(outputCopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var block = program.basicBlockAt(node);
|
||||||
|
for (var phi : block.getPhis()) {
|
||||||
|
phi.getIncomings().removeIf(incoming -> domainSet.contains(incoming.getSource().getIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var phi : blockCopy.getPhis()) {
|
||||||
|
phi.getIncomings().removeIf(incoming -> !domainSet.contains(incoming.getSource().getIndex()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return copies;
|
return copies;
|
||||||
|
|
|
@ -71,18 +71,13 @@ public class RedundantJumpElimination implements MethodOptimization {
|
||||||
assign.setAssignee(incoming.getValue());
|
assign.setAssignee(incoming.getValue());
|
||||||
block.add(assign);
|
block.add(assign);
|
||||||
}
|
}
|
||||||
while (target.getFirstInstruction() != null) {
|
|
||||||
Instruction instruction = target.getFirstInstruction();
|
|
||||||
instruction.delete();
|
|
||||||
block.add(instruction);
|
|
||||||
}
|
|
||||||
|
|
||||||
Instruction lastInsn = block.getLastInstruction();
|
var lastInsn = target.getLastInstruction();
|
||||||
if (lastInsn != null) {
|
if (lastInsn != null) {
|
||||||
lastInsn.acceptVisitor(transitionExtractor);
|
lastInsn.acceptVisitor(transitionExtractor);
|
||||||
BasicBlock[] successors = transitionExtractor.getTargets();
|
var successors = transitionExtractor.getTargets();
|
||||||
if (successors != null) {
|
if (successors != null) {
|
||||||
for (BasicBlock successor : successors) {
|
for (var successor : successors) {
|
||||||
successor.getPhis().stream()
|
successor.getPhis().stream()
|
||||||
.flatMap(phi -> phi.getIncomings().stream())
|
.flatMap(phi -> phi.getIncomings().stream())
|
||||||
.filter(incoming -> incoming.getSource() == target)
|
.filter(incoming -> incoming.getSource() == target)
|
||||||
|
@ -91,6 +86,12 @@ public class RedundantJumpElimination implements MethodOptimization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (target.getFirstInstruction() != null) {
|
||||||
|
Instruction instruction = target.getFirstInstruction();
|
||||||
|
instruction.delete();
|
||||||
|
block.add(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
for (TryCatchBlock tryCatch : target.getTryCatchBlocks()) {
|
for (TryCatchBlock tryCatch : target.getTryCatchBlocks()) {
|
||||||
for (Phi phi : tryCatch.getHandler().getPhis()) {
|
for (Phi phi : tryCatch.getHandler().getPhis()) {
|
||||||
phi.getIncomings().removeIf(incoming -> incoming.getSource() == target);
|
phi.getIncomings().removeIf(incoming -> incoming.getSource() == target);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user