Begin implementing irreducible cfg node splitting. Implement DJ graph.

This commit is contained in:
konsoletyper 2015-02-21 21:51:04 +04:00
parent 34aeb6e3c9
commit a882a4c956
2 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,89 @@
/*
* Copyright 2015 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.common;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class DJGraph {
private DominatorTree domTree;
private Graph graph;
private Graph backEdges;
public DJGraph(Graph src) {
domTree = GraphUtils.buildDominatorTree(src);
buildGraph(src);
dfs();
}
private void buildGraph(Graph graph) {
GraphBuilder builder = new GraphBuilder(graph.size());
for (int i = 0; i < graph.size(); ++i) {
for (int j : graph.outgoingEdges(i)) {
builder.addEdge(i, j);
}
}
for (int i = 1; i < graph.size(); ++i) {
int j = domTree.immediateDominatorOf(i);
boolean needsDomEdge = true;
for (int k : graph.incomingEdges(i)) {
if (k == j) {
needsDomEdge = false;
break;
}
}
if (needsDomEdge) {
builder.addEdge(j, i);
}
}
graph = builder.build();
}
private void dfs() {
GraphBuilder builder = new GraphBuilder();
boolean[] visited = new boolean[graph.size()];
IntegerStack stack = new IntegerStack(graph.size() * 2);
stack.push(0);
stack.push(-1);
while (!stack.isEmpty()) {
int node = stack.pop();
int source = stack.pop();
if (visited[node]) {
builder.addEdge(node, source);
continue;
}
visited[node] = true;
for (int succ : graph.outgoingEdges(node)) {
stack.push(node);
stack.push(succ);
}
}
backEdges = builder.build();
}
public DominatorTree getDomTree() {
return domTree;
}
public Graph getGraph() {
return graph;
}
public int[] getSpanningTreeBackEdges(int node) {
return backEdges.outgoingEdges(node);
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2015 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.ArrayList;
import java.util.List;
import org.teavm.common.DisjointSet;
import org.teavm.common.Graph;
import org.teavm.common.MutableGraphNode;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class IrreducibleGraphConverter {
List<MutableGraphNode> nodes = new ArrayList<>();
DisjointSet nodeClasses = new DisjointSet();
public void convertToReducible(Graph graph) {
buildMutableCFG(graph);
}
private void buildMutableCFG(Graph graph) {
nodes.clear();
for (int i = 0; i < graph.size(); ++i) {
nodes.add(new MutableGraphNode(i));
}
for (int i = 0; i < graph.size(); ++i) {
for (int j : graph.outgoingEdges(i)) {
nodes.get(i).connect(nodes.get(j));
}
}
}
}