diff --git a/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java b/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java new file mode 100644 index 000000000..43fbf9a35 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/util/GraphColorer.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.model.util; + +import org.teavm.common.Graph; + +/** + * + * @author Alexey Andreev + */ +public class GraphColorer { + public void colorize(Graph graph) { + + } + + 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]) { + continue; + } + visited[node] = true; + for (int succ : graph.outgoingEdges(node)) { + if (visited[succ]) { + + } + } + graph.outgoingEdges(node); + } + return next; + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java b/teavm-core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java new file mode 100644 index 000000000..9079b922b --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/util/InterferenceGraphBuilder.java @@ -0,0 +1,86 @@ +/* + * Copyright 2014 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.model.util; + +import java.util.*; +import org.teavm.common.Graph; +import org.teavm.common.GraphBuilder; +import org.teavm.model.*; + +/** + * + * @author Alexey Andreev + */ +public class InterferenceGraphBuilder { + public Graph build(Program program, LivenessAnalyzer liveness) { + List> edges = new ArrayList<>(); + for (int i = 0; i < program.variableCount(); ++i) { + edges.add(new HashSet()); + } + UsageExtractor useExtractor = new UsageExtractor(); + DefinitionExtractor defExtractor = new DefinitionExtractor(); + InstructionTransitionExtractor succExtractor = new InstructionTransitionExtractor(); + for (int i = 0; i < program.basicBlockCount(); ++i) { + BasicBlock block = program.basicBlockAt(i); + block.getLastInstruction().acceptVisitor(succExtractor); + BitSet liveOut = new BitSet(program.variableCount()); + for (BasicBlock succ : succExtractor.getTargets()) { + liveOut.or(liveness.liveIn(succ.getIndex())); + } + Set live = new HashSet<>(); + for (int j = 0; j < liveOut.length(); ++j) { + if (liveOut.get(j)) { + live.add(j); + } + } + for (int j = block.getInstructions().size() - 1; j >= 0; --j) { + Instruction insn = block.getInstructions().get(j); + insn.acceptVisitor(useExtractor); + insn.acceptVisitor(defExtractor); + for (Variable var : defExtractor.getDefinedVariables()) { + edges.get(var.getIndex()).addAll(live); + } + for (Variable var : defExtractor.getDefinedVariables()) { + live.remove(var.getIndex()); + } + for (Variable var : useExtractor.getUsedVariables()) { + live.add(var.getIndex()); + } + } + BitSet liveIn = liveness.liveIn(i); + live = new HashSet<>(); + for (int j = 0; j < liveOut.length(); ++j) { + if (liveIn.get(j)) { + live.add(j); + } + } + for (Phi phi : block.getPhis()) { + live.add(phi.getReceiver().getIndex()); + } + for (Phi phi : block.getPhis()) { + edges.get(phi.getReceiver().getIndex()).addAll(live); + } + } + GraphBuilder builder = new GraphBuilder(); + for (int i = 0; i < edges.size(); ++i) { + for (Integer j : edges.get(i)) { + builder.addEdge(i, j); + builder.addEdge(j, i); + } + } + return builder.build(); + } +} diff --git a/teavm-core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java b/teavm-core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java index 2314eaf8e..8af0c581f 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java +++ b/teavm-core/src/main/java/org/teavm/model/util/LivenessAnalyzer.java @@ -35,6 +35,10 @@ public class LivenessAnalyzer { return liveVars[block].get(var); } + public BitSet liveIn(int block) { + return (BitSet)liveVars[block].clone(); + } + public void analyze(Program program) { Graph cfg = ProgramUtils.buildControlFlowGraph(program); computeDomLeftRight(GraphUtils.buildDominatorGraph(GraphUtils.buildDominatorTree(cfg), cfg.size())); @@ -64,6 +68,12 @@ public class LivenessAnalyzer { } for (Phi phi : block.getPhis()) { definitions[phi.getReceiver().getIndex()] = i; + for (Incoming incoming : phi.getIncomings()) { + Task task = new Task(); + task.block = incoming.getSource().getIndex(); + task.var = incoming.getValue().getIndex(); + stack.push(task); + } } }