rework InterferenceGraph

This commit is contained in:
ChUrl
2021-01-31 16:21:14 +01:00
parent d5f480d763
commit 81d8f4e92e
2 changed files with 60 additions and 33 deletions

View File

@ -12,57 +12,62 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
public final class InterferenceGraph implements Iterable<InterferenceNode> { public final class InterferenceGraph implements Iterable<InterferenceNode> {
private final List<InterferenceNode> nodes; private final List<InterferenceNode> interferenceNodes;
private InterferenceGraph(List<InterferenceNode> nodes) { private InterferenceGraph(List<InterferenceNode> interferenceNodes) {
this.nodes = nodes; this.interferenceNodes = interferenceNodes;
} }
public static InterferenceGraph fromDataFlowGraph(DataFlowGraph graph, Map<String, Integer> varMap) { public static InterferenceGraph fromDataFlowGraph(DataFlowGraph dataFlowGraph, Map<String, Integer> varMap) {
final List<InterferenceNode> interferenceGraph = new ArrayList<>(); final List<InterferenceNode> interferenceNodes = new ArrayList<>();
// Init graph // Init graph
for (Map.Entry<String, Integer> var : varMap.entrySet()) { for (int symbol : varMap.values()) {
interferenceGraph.add(new InterferenceNode(var.getValue().toString())); interferenceNodes.add(new InterferenceNode(symbol));
} }
final InterferenceGraph interferenceGraph = new InterferenceGraph(interferenceNodes);
// Determine neighbours // Determine neighbours
for (DataFlowNode node : graph) { for (DataFlowNode node : dataFlowGraph) {
Logger.log("NODE " + node.getInst() + " - OUT: " + node.getOutSet());
for (String left : node.getOutSet()) { for (String left : node.getOutSet()) {
if (left.isBlank()) {
continue;
}
for (String right : node.getOutSet()) { for (String right : node.getOutSet()) {
if (right.isBlank()) {
continue; final Optional<InterferenceNode> leftNode = getNodeBySymbol(left, interferenceGraph);
final Optional<InterferenceNode> rightNode = getNodeBySymbol(right, interferenceGraph);
if (leftNode.isPresent() && rightNode.isPresent()) {
final boolean change = leftNode.get().addNeighbour(rightNode.get());
Logger.logIfTrue(change, "Added interference neighbour: " + left + " -> " + right);
} }
getNodeBySymbol(left, interferenceGraph).addNeighbour(getNodeBySymbol(right, interferenceGraph));
Logger.log("Add interference neighbour: " + left + " <-> " + right);
} }
} }
} }
return new InterferenceGraph(interferenceGraph); return interferenceGraph;
} }
private static InterferenceNode getNodeBySymbol(String symbol, List<InterferenceNode> interferenceGraph) { private static Optional<InterferenceNode> getNodeBySymbol(String symbol, InterferenceGraph interferenceGraph) {
return interferenceGraph.stream() return interferenceGraph.stream()
.filter(node -> node.getSymbol().equals(symbol)) .filter(node -> node.getSymbol().equals(symbol))
.findFirst() .findFirst();
.orElse(null); }
public Stream<InterferenceNode> stream() {
return this.interferenceNodes.stream();
} }
// Printing // Printing
public String printToImage() { public String printToImage() {
if (this.nodes.isEmpty()) { if (this.interferenceNodes.isEmpty()) {
return "Empty Graph"; return "Empty Graph";
} }
@ -71,7 +76,7 @@ public final class InterferenceGraph implements Iterable<InterferenceNode> {
dot.append("digraph dfd {\n") dot.append("digraph dfd {\n")
.append("node[shape=Mrecord]\n"); .append("node[shape=Mrecord]\n");
for (InterferenceNode node : this.nodes) { for (InterferenceNode node : this.interferenceNodes) {
dot.append(node.getSymbol()) dot.append(node.getSymbol())
.append(" [label=\"{<f0> Symbol: ") .append(" [label=\"{<f0> Symbol: ")
.append(node.getSymbol()) .append(node.getSymbol())
@ -80,9 +85,11 @@ public final class InterferenceGraph implements Iterable<InterferenceNode> {
.append("}\"];\n"); .append("}\"];\n");
} }
for (InterferenceNode node : this.nodes) { for (InterferenceNode node : this.interferenceNodes) {
for (InterferenceNode neigh : node.getNeighbours()) { for (InterferenceNode neigh : node.getNeighbourSet()) {
if (!dot.toString().contains(neigh.getSymbol() + " -> " + node.getSymbol())) { // No double lines if (!dot.toString().contains(neigh.getSymbol() + " -> " + node.getSymbol())) {
// No double lines
dot.append(node.getSymbol()).append(" -> ").append(neigh.getSymbol()).append(" [arrowhead=\"none\"];\n"); dot.append(node.getSymbol()).append(" -> ").append(neigh.getSymbol()).append(" [arrowhead=\"none\"];\n");
} }
} }
@ -113,6 +120,6 @@ public final class InterferenceGraph implements Iterable<InterferenceNode> {
@Override @Override
public Iterator<InterferenceNode> iterator() { public Iterator<InterferenceNode> iterator() {
return this.nodes.iterator(); return this.interferenceNodes.iterator();
} }
} }

View File

@ -4,10 +4,24 @@ import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
/**
* Repräsentiert eine Variable und ihre Farbe im Interferenzgraph.
*/
public class InterferenceNode { public class InterferenceNode {
/**
* Der Name der Variable.
*/
private final String symbol; private final String symbol;
/**
* Alle Nachbarn dieses Nodes.
* Benachbart bedeutet, dass beide Variablen zu gleichen Zeiten live sind.
* Benachbarte Variablen können sich kein Register teilen.
*/
private final Set<InterferenceNode> neighbours; private final Set<InterferenceNode> neighbours;
/**
* Der Integer repräsentiert die "Farbe".
*/
private int color; private int color;
public InterferenceNode(String symbol) { public InterferenceNode(String symbol) {
@ -16,6 +30,10 @@ public class InterferenceNode {
this.neighbours = new HashSet<>(); this.neighbours = new HashSet<>();
} }
public InterferenceNode(int symbol) {
this(String.valueOf(symbol));
}
// Getters, Setters // Getters, Setters
public String getSymbol() { public String getSymbol() {
@ -30,14 +48,16 @@ public class InterferenceNode {
this.color = color; this.color = color;
} }
public void addNeighbour(InterferenceNode node) { public Set<InterferenceNode> getNeighbourSet() {
if (!node.equals(this)) { return this.neighbours;
this.neighbours.add(node);
}
} }
public Set<InterferenceNode> getNeighbours() { public boolean addNeighbour(InterferenceNode node) {
return this.neighbours; if (!node.equals(this)) {
return this.neighbours.add(node);
}
return false;
} }
// Overrides // Overrides