mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Fixes register allocator
This commit is contained in:
parent
ba67c34b20
commit
24d40c3c41
|
@ -21,11 +21,15 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.teavm.codegen.*;
|
||||
import org.teavm.common.Graph;
|
||||
import org.teavm.dependency.DependencyChecker;
|
||||
import org.teavm.javascript.ast.ClassNode;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.resource.ClasspathClassHolderSource;
|
||||
import org.teavm.model.util.GraphColorer;
|
||||
import org.teavm.model.util.InterferenceGraphBuilder;
|
||||
import org.teavm.model.util.ListingBuilder;
|
||||
import org.teavm.model.util.LivenessAnalyzer;
|
||||
import org.teavm.optimization.ClassSetOptimizer;
|
||||
|
||||
/**
|
||||
|
@ -161,9 +165,23 @@ public class JavascriptBuilder {
|
|||
printType(writer, parameterTypes[i]);
|
||||
}
|
||||
writer.println(")");
|
||||
if (method.getProgram() != null) {
|
||||
if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
|
||||
ListingBuilder builder = new ListingBuilder();
|
||||
writer.println(builder.buildListing(method.getProgram(), " "));
|
||||
writer.print(builder.buildListing(method.getProgram(), " "));
|
||||
writer.print(" Register allocation:");
|
||||
LivenessAnalyzer analyzer = new LivenessAnalyzer();
|
||||
analyzer.analyze(method.getProgram());
|
||||
InterferenceGraphBuilder interferenceBuilder = new InterferenceGraphBuilder();
|
||||
Graph interferenceGraph = interferenceBuilder.build(method.getProgram(), analyzer);
|
||||
GraphColorer colorer = new GraphColorer();
|
||||
int[] colors = colorer.colorize(interferenceGraph,
|
||||
Math.min(method.parameterCount() + 1, interferenceGraph.size()));
|
||||
for (int i = 0; i < colors.length; ++i) {
|
||||
writer.print(i + ":" + colors[i] + " ");
|
||||
}
|
||||
writer.println();
|
||||
writer.println();
|
||||
writer.flush();
|
||||
} else {
|
||||
writer.println();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.model.util;
|
||||
|
||||
import java.util.BitSet;
|
||||
import org.teavm.common.Graph;
|
||||
|
||||
/**
|
||||
|
@ -22,30 +23,64 @@ import org.teavm.common.Graph;
|
|||
* @author Alexey Andreev
|
||||
*/
|
||||
public class GraphColorer {
|
||||
public void colorize(Graph graph) {
|
||||
|
||||
public int[] colorize(Graph graph, int preservedColors) {
|
||||
int[] colors = new int[graph.size()];
|
||||
boolean[] visited = new boolean[graph.size()];
|
||||
for (int i = 0; i < preservedColors; ++i) {
|
||||
colors[i] = i;
|
||||
visited[i] = true;
|
||||
}
|
||||
BitSet usedColors = new BitSet();
|
||||
for (int v : getOrdering(graph)) {
|
||||
if (v < preservedColors) {
|
||||
continue;
|
||||
}
|
||||
usedColors.clear();
|
||||
usedColors.set(0);
|
||||
for (int succ : graph.outgoingEdges(v)) {
|
||||
if (visited[succ]) {
|
||||
usedColors.set(colors[succ]);
|
||||
}
|
||||
}
|
||||
colors[v] = usedColors.nextClearBit(0);
|
||||
visited[v] = true;
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
|
||||
private int[] getOrdering(Graph graph) {
|
||||
boolean[] visited = new boolean[graph.size()];
|
||||
int[] sets = new int[graph.size()];
|
||||
int[] next = new int[graph.size()];
|
||||
for (int i = 0; i < next.length; ++i) {
|
||||
next[i] = i + 1;
|
||||
}
|
||||
int node = 0;
|
||||
while (node < next.length) {
|
||||
if (visited[node]) {
|
||||
int[] ordering = new int[graph.size()];
|
||||
int index = 0;
|
||||
int[] queue = new int[graph.size() * 2];
|
||||
for (int root = 0; root < graph.size(); ++root) {
|
||||
if (visited[root]) {
|
||||
continue;
|
||||
}
|
||||
visited[node] = true;
|
||||
for (int succ : graph.outgoingEdges(node)) {
|
||||
if (visited[succ]) {
|
||||
|
||||
int head = 0;
|
||||
int tail = 0;
|
||||
queue[head++] = root;
|
||||
while (head != tail) {
|
||||
int v = queue[tail++];
|
||||
if (tail == queue.length) {
|
||||
tail = 0;
|
||||
}
|
||||
if (visited[v]) {
|
||||
continue;
|
||||
}
|
||||
visited[v] = true;
|
||||
ordering[index++] = v;
|
||||
for (int succ : graph.outgoingEdges(v)) {
|
||||
if (visited[succ]) {
|
||||
continue;
|
||||
}
|
||||
if (++head == queue.length) {
|
||||
head = 0;
|
||||
}
|
||||
queue[head] = succ;
|
||||
}
|
||||
}
|
||||
graph.outgoingEdges(node);
|
||||
}
|
||||
return next;
|
||||
return ordering;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,7 @@ public class InstructionStringifier implements InstructionVisitor {
|
|||
} else {
|
||||
sb.append(insn.getField().getClassName());
|
||||
}
|
||||
sb.append(".").append(insn.getField());
|
||||
sb.append(".").append(insn.getField().getFieldName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -263,7 +263,7 @@ public class InstructionStringifier implements InstructionVisitor {
|
|||
} else {
|
||||
sb.append(insn.getField().getClassName());
|
||||
}
|
||||
sb.append(".").append(insn.getField()).append(" := @").append(insn.getValue().getIndex());
|
||||
sb.append(".").append(insn.getField().getFieldName()).append(" := @").append(insn.getValue().getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -332,7 +332,7 @@ public class InstructionStringifier implements InstructionVisitor {
|
|||
@Override
|
||||
public void visit(UnwrapArrayInstruction insn) {
|
||||
sb.append("@").append(insn.getReceiver().getIndex()).append(" := @")
|
||||
.append(insn.getArray()).append(".data");
|
||||
.append(insn.getArray().getIndex()).append(".data");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,7 @@ public class InterferenceGraphBuilder {
|
|||
UsageExtractor useExtractor = new UsageExtractor();
|
||||
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
||||
InstructionTransitionExtractor succExtractor = new InstructionTransitionExtractor();
|
||||
List<List<Incoming>> outgoings = getOutgoings(program);
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
block.getLastInstruction().acceptVisitor(succExtractor);
|
||||
|
@ -46,6 +47,9 @@ public class InterferenceGraphBuilder {
|
|||
live.add(j);
|
||||
}
|
||||
}
|
||||
for (Incoming outgoing : outgoings.get(i)) {
|
||||
live.add(outgoing.getValue().getIndex());
|
||||
}
|
||||
for (int j = block.getInstructions().size() - 1; j >= 0; --j) {
|
||||
Instruction insn = block.getInstructions().get(j);
|
||||
insn.acceptVisitor(useExtractor);
|
||||
|
@ -83,4 +87,20 @@ public class InterferenceGraphBuilder {
|
|||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private List<List<Incoming>> getOutgoings(Program program) {
|
||||
List<List<Incoming>> outgoings = new ArrayList<>();
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
outgoings.add(new ArrayList<Incoming>());
|
||||
}
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
for (Phi phi : block.getPhis()) {
|
||||
for(Incoming incoming : phi.getIncomings()) {
|
||||
outgoings.get(incoming.getSource().getIndex()).add(incoming);
|
||||
}
|
||||
}
|
||||
}
|
||||
return outgoings;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public class LivenessAnalyzer {
|
|||
}
|
||||
}
|
||||
|
||||
while (stack.isEmpty()) {
|
||||
while (!stack.isEmpty()) {
|
||||
Task task = stack.pop();
|
||||
if (liveVars[task.block].get(task.var) || !dominates(definitions[task.var], task.block)) {
|
||||
continue;
|
||||
|
@ -98,23 +98,21 @@ public class LivenessAnalyzer {
|
|||
int index = 1;
|
||||
int[] stack = new int[domGraph.size() * 2];
|
||||
int top = 0;
|
||||
for (int i = domGraph.size(); i >= 0; --i) {
|
||||
for (int i = domGraph.size() - 1; i >= 0; --i) {
|
||||
if (domGraph.incomingEdgesCount(i) == 0) {
|
||||
stack[top++] = i;
|
||||
}
|
||||
}
|
||||
while (top > 0) {
|
||||
int v = stack[top--];
|
||||
int v = stack[--top];
|
||||
if (domLeft[v] == 0) {
|
||||
domLeft[v] = index++;
|
||||
stack[top++] = v;
|
||||
for (int succ : domGraph.outgoingEdges(v)) {
|
||||
stack[top++] = succ;
|
||||
}
|
||||
} else if (domRight[v] == 0) {
|
||||
domRight[v] = index++;
|
||||
if (domGraph.incomingEdgesCount(0) > 0) {
|
||||
stack[top++] = domGraph.incomingEdges(v)[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,11 +184,12 @@ public class UsageExtractor implements InstructionVisitor {
|
|||
public void visit(InvokeInstruction insn) {
|
||||
if (insn.getInstance() != null) {
|
||||
usedVariables = new Variable[insn.getArguments().size() + 1];
|
||||
insn.getArguments().toArray(usedVariables);
|
||||
usedVariables[insn.getArguments().size()] = insn.getInstance();
|
||||
} else {
|
||||
usedVariables = new Variable[insn.getArguments().size()];
|
||||
insn.getArguments().toArray(usedVariables);
|
||||
}
|
||||
insn.getArguments().toArray(usedVariables);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue
Block a user