-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathInterferenceGraph.java
More file actions
144 lines (129 loc) · 4.1 KB
/
InterferenceGraph.java
File metadata and controls
144 lines (129 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package com.compilerprogramming.ezlang.compiler;
import java.util.*;
public class InterferenceGraph {
private Map<Integer, Set<Integer>> edges = new HashMap<>();
private Set<Integer> addNode(Integer node) {
var set = edges.get(node);
if (set == null) {
set = new HashSet<>();
edges.put(node, set);
}
return set;
}
public void addEdge(Integer from, Integer to) {
if (from == to) {
return;
}
var set1 = addNode(from);
var set2 = addNode(to);
set1.add(to);
set2.add(from);
}
/**
* Remove a node from the interference graph
* deleting it from all adjacency lists
*/
public InterferenceGraph subtract(Integer node) {
edges.remove(node);
for (var key : edges.keySet()) {
var neighbours = edges.get(key);
neighbours.remove(key);
}
return this;
}
/**
* Duplicate an interference graph
*/
public InterferenceGraph dup() {
var igraph = new InterferenceGraph();
igraph.edges = new HashMap<>();
for (var key : edges.keySet()) {
var neighbours = edges.get(key);
igraph.edges.put(key, new HashSet<>(neighbours));
}
return igraph;
}
public boolean interfere(Integer from, Integer to) {
var set = edges.get(from);
return set != null && set.contains(to);
}
/**
* The source is replaced by target in the graph.
* All nodes that interfered with source are made to interfere with target.
*/
public void rename(Integer source, Integer target) {
// Move all interferences
var fromSet = edges.remove(source);
if (fromSet == null) {
// FIXME figure out why
// Test case testSSA21 / when run using Boissinot SSA Destruction without coalescing
// This is eq() function in mergesort test case
return;
}
var toSet = edges.get(target);
if (toSet == null) {
//throw new RuntimeException("Cannot find edge " + target + " from " + source);
return; // FIXME this is workaround to handle scenario where target is arg register but we need a better way
}
toSet.addAll(fromSet);
// If any node interfered with from
// it should now interfere with to
for (var k: edges.keySet()) {
var set = edges.get(k);
if (set.contains(source)) {
set.remove(source);
if (k != target)
set.add(target);
}
}
}
/**
* Get neighbours of the node
* Chaitin: neighbors()
*/
public Set<Integer> neighbors(Integer node) {
var adjacents = edges.get(node);
if (adjacents == null)
adjacents = Collections.emptySet();
return adjacents;
}
public static final class Edge {
public final int from;
public final int to;
public Edge(int from, int to) {
this.from = from;
this.to = to;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Edge edge = (Edge) o;
return (from == edge.from && to == edge.to)
|| (from == edge.to && to == edge.from);
}
@Override
public int hashCode() {
return from+to;
}
}
public Set<Edge> getEdges() {
Set<Edge> all = new HashSet<>();
for (Integer from: edges.keySet()) {
var set = edges.get(from);
for (Integer to: set) {
all.add(new Edge(from, to));
}
}
return all;
}
public String generateDotOutput() {
StringBuilder sb = new StringBuilder();
sb.append("digraph IGraph {\n");
for (var edge: getEdges()) {
sb.append(edge.from).append("->").append(edge.to).append(";\n");
}
sb.append("}\n");
return sb.toString();
}
}