mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-12-15 02:10:30 +08:00
Complete liveness analyzer (not tested)
This commit is contained in:
parent
c8ac2a8b98
commit
c704956ca1
@ -15,28 +15,71 @@
|
|||||||
*/
|
*/
|
||||||
package org.teavm.model.util;
|
package org.teavm.model.util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayDeque;
|
||||||
import java.util.List;
|
import java.util.BitSet;
|
||||||
import org.teavm.common.DominatorTree;
|
import java.util.Deque;
|
||||||
import org.teavm.common.Graph;
|
import org.teavm.common.Graph;
|
||||||
import org.teavm.common.GraphUtils;
|
import org.teavm.common.GraphUtils;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class LivenessAnalyzer {
|
public class LivenessAnalyzer {
|
||||||
private BackNode[] backNodeGraph;
|
private BitSet[] liveVars;
|
||||||
private int[] domLeft;
|
private int[] domLeft;
|
||||||
private int[] domRight;
|
private int[] domRight;
|
||||||
|
|
||||||
|
public boolean liveIn(int block, int var) {
|
||||||
|
return liveVars[block].get(var);
|
||||||
|
}
|
||||||
|
|
||||||
public void analyze(Program program) {
|
public void analyze(Program program) {
|
||||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||||
DominatorTree domTree = GraphUtils.buildDominatorTree(cfg);
|
computeDomLeftRight(GraphUtils.buildDominatorGraph(GraphUtils.buildDominatorTree(cfg), cfg.size()));
|
||||||
Graph domGraph = GraphUtils.buildDominatorGraph(domTree, cfg.size());
|
liveVars = new BitSet[cfg.size()];
|
||||||
computeDomLeftRight(domGraph);
|
for (int i = 0; i < liveVars.length; ++i) {
|
||||||
prepareBackGraph(domTree, cfg);
|
liveVars[i] = new BitSet(program.basicBlockCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
UsageExtractor usageExtractor = new UsageExtractor();
|
||||||
|
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
||||||
|
Deque<Task> stack = new ArrayDeque<>();
|
||||||
|
int[] definitions = new int[program.variableCount()];
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
for (Instruction insn : block.getInstructions()) {
|
||||||
|
insn.acceptVisitor(usageExtractor);
|
||||||
|
for (Variable var : usageExtractor.getUsedVariables()) {
|
||||||
|
Task task = new Task();
|
||||||
|
task.block = i;
|
||||||
|
task.var = var.getIndex();
|
||||||
|
stack.push(task);
|
||||||
|
}
|
||||||
|
insn.acceptVisitor(defExtractor);
|
||||||
|
for (Variable var : defExtractor.getDefinedVariables()) {
|
||||||
|
definitions[var.getIndex()] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Phi phi : block.getPhis()) {
|
||||||
|
definitions[phi.getReceiver().getIndex()] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (stack.isEmpty()) {
|
||||||
|
Task task = stack.pop();
|
||||||
|
if (liveVars[task.block].get(task.var) || !dominates(definitions[task.var], task.block)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
liveVars[task.block].set(task.var, true);
|
||||||
|
for (int pred : cfg.incomingEdges(task.block)) {
|
||||||
|
Task nextTask = new Task();
|
||||||
|
nextTask.block = pred;
|
||||||
|
nextTask.var = task.var;
|
||||||
|
stack.push(nextTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeDomLeftRight(Graph domGraph) {
|
private void computeDomLeftRight(Graph domGraph) {
|
||||||
@ -66,26 +109,12 @@ public class LivenessAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareBackGraph(DominatorTree domTree, Graph cfg) {
|
|
||||||
backNodeGraph = new BackNode[cfg.size() * 2];
|
|
||||||
int[] stack = new int[cfg.size() * 2];
|
|
||||||
int top = 0;
|
|
||||||
for (int i = 0; i < cfg.size(); ++i) {
|
|
||||||
if (cfg.outgoingEdgesCount(i) == 0) {
|
|
||||||
stack[top++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (top > 0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean dominates(int a, int b) {
|
private boolean dominates(int a, int b) {
|
||||||
return domLeft[a] <= domLeft[b] && domRight[a] >= domRight[b];
|
return domLeft[a] <= domLeft[b] && domRight[a] >= domRight[b];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BackNode {
|
private static class Task {
|
||||||
final List<BackNode> successors = new ArrayList<>();
|
int block;
|
||||||
int blockIndex;
|
int var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user