From 81d8f4e92e0cc1f3590f4e164ea80daca4d847d7 Mon Sep 17 00:00:00 2001 From: ChUrl Date: Sun, 31 Jan 2021 16:21:14 +0100 Subject: [PATCH] rework InterferenceGraph --- .../analysis/liveness/InterferenceGraph.java | 61 +++++++++++-------- .../analysis/liveness/InterferenceNode.java | 32 ++++++++-- 2 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/main/java/codegen/analysis/liveness/InterferenceGraph.java b/src/main/java/codegen/analysis/liveness/InterferenceGraph.java index 7453298..a23c250 100644 --- a/src/main/java/codegen/analysis/liveness/InterferenceGraph.java +++ b/src/main/java/codegen/analysis/liveness/InterferenceGraph.java @@ -12,57 +12,62 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; public final class InterferenceGraph implements Iterable { - private final List nodes; + private final List interferenceNodes; - private InterferenceGraph(List nodes) { - this.nodes = nodes; + private InterferenceGraph(List interferenceNodes) { + this.interferenceNodes = interferenceNodes; } - public static InterferenceGraph fromDataFlowGraph(DataFlowGraph graph, Map varMap) { - final List interferenceGraph = new ArrayList<>(); + public static InterferenceGraph fromDataFlowGraph(DataFlowGraph dataFlowGraph, Map varMap) { + final List interferenceNodes = new ArrayList<>(); // Init graph - for (Map.Entry var : varMap.entrySet()) { - interferenceGraph.add(new InterferenceNode(var.getValue().toString())); + for (int symbol : varMap.values()) { + interferenceNodes.add(new InterferenceNode(symbol)); } + final InterferenceGraph interferenceGraph = new InterferenceGraph(interferenceNodes); + // Determine neighbours - for (DataFlowNode node : graph) { - Logger.log("NODE " + node.getInst() + " - OUT: " + node.getOutSet()); + for (DataFlowNode node : dataFlowGraph) { for (String left : node.getOutSet()) { - if (left.isBlank()) { - continue; - } - for (String right : node.getOutSet()) { - if (right.isBlank()) { - continue; + + final Optional leftNode = getNodeBySymbol(left, interferenceGraph); + final Optional 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 interferenceGraph) { + private static Optional getNodeBySymbol(String symbol, InterferenceGraph interferenceGraph) { return interferenceGraph.stream() .filter(node -> node.getSymbol().equals(symbol)) - .findFirst() - .orElse(null); + .findFirst(); + } + + public Stream stream() { + return this.interferenceNodes.stream(); } // Printing public String printToImage() { - if (this.nodes.isEmpty()) { + if (this.interferenceNodes.isEmpty()) { return "Empty Graph"; } @@ -71,7 +76,7 @@ public final class InterferenceGraph implements Iterable { dot.append("digraph dfd {\n") .append("node[shape=Mrecord]\n"); - for (InterferenceNode node : this.nodes) { + for (InterferenceNode node : this.interferenceNodes) { dot.append(node.getSymbol()) .append(" [label=\"{ Symbol: ") .append(node.getSymbol()) @@ -80,9 +85,11 @@ public final class InterferenceGraph implements Iterable { .append("}\"];\n"); } - for (InterferenceNode node : this.nodes) { - for (InterferenceNode neigh : node.getNeighbours()) { - if (!dot.toString().contains(neigh.getSymbol() + " -> " + node.getSymbol())) { // No double lines + for (InterferenceNode node : this.interferenceNodes) { + for (InterferenceNode neigh : node.getNeighbourSet()) { + if (!dot.toString().contains(neigh.getSymbol() + " -> " + node.getSymbol())) { + // No double lines + dot.append(node.getSymbol()).append(" -> ").append(neigh.getSymbol()).append(" [arrowhead=\"none\"];\n"); } } @@ -113,6 +120,6 @@ public final class InterferenceGraph implements Iterable { @Override public Iterator iterator() { - return this.nodes.iterator(); + return this.interferenceNodes.iterator(); } } diff --git a/src/main/java/codegen/analysis/liveness/InterferenceNode.java b/src/main/java/codegen/analysis/liveness/InterferenceNode.java index 6f82f28..12f1224 100644 --- a/src/main/java/codegen/analysis/liveness/InterferenceNode.java +++ b/src/main/java/codegen/analysis/liveness/InterferenceNode.java @@ -4,10 +4,24 @@ import java.util.HashSet; import java.util.Objects; import java.util.Set; +/** + * Repräsentiert eine Variable und ihre Farbe im Interferenzgraph. + */ public class InterferenceNode { + /** + * Der Name der Variable. + */ 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 neighbours; + /** + * Der Integer repräsentiert die "Farbe". + */ private int color; public InterferenceNode(String symbol) { @@ -16,6 +30,10 @@ public class InterferenceNode { this.neighbours = new HashSet<>(); } + public InterferenceNode(int symbol) { + this(String.valueOf(symbol)); + } + // Getters, Setters public String getSymbol() { @@ -30,14 +48,16 @@ public class InterferenceNode { this.color = color; } - public void addNeighbour(InterferenceNode node) { - if (!node.equals(this)) { - this.neighbours.add(node); - } + public Set getNeighbourSet() { + return this.neighbours; } - public Set getNeighbours() { - return this.neighbours; + public boolean addNeighbour(InterferenceNode node) { + if (!node.equals(this)) { + return this.neighbours.add(node); + } + + return false; } // Overrides