Skip to content

Commit 23a0942

Browse files
Refactoring
1 parent 6718564 commit 23a0942

File tree

4 files changed

+78
-80
lines changed

4 files changed

+78
-80
lines changed

Source/Graph/Graph.cs

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,26 @@ internal static class Util
5757
}
5858
}
5959

60-
public class DomRelation<Node>
60+
public class DomRelation<TNode>
6161
{
6262
// doms maps (unique) node numbers to the node numbers of the immediate dominator
6363
// to use it on Nodes, one needs the two way mapping between nodes and their numbers.
64-
private int[] doms; // 0 is unused: means undefined
64+
private int[] nodeNumberToImmediateDominator; // 0 is unused: means undefined
6565

6666
// here are the two mappings
67-
private Node[] postOrderNumberToNode;
68-
private Dictionary<Node, int> nodeToPostOrderNumber;
67+
private TNode[] postOrderNumberToNode;
68+
private Dictionary<TNode, int> nodeToPostOrderNumber;
6969
private int sourceNum; // (number for) root of the graph
70-
private Node source; // root of the graph
71-
private Graph<Node> graph;
72-
private Dictionary<Node, List<Node>> immediateDominatorMap;
70+
private TNode source; // root of the graph
71+
private Graph<TNode> graph;
72+
private Dictionary<TNode, List<TNode>> immediateDominatorMap;
7373

7474
[NotDelayed]
75-
internal DomRelation(Graph<Node> g, Node source)
75+
internal DomRelation(Graph<TNode> g, TNode source)
7676
{
77+
// TODO should we enable saying that the graph is a DAG, to enable an O(N) dominance algorithm?
78+
// Or is the algorithm already O(N) for DAG graphs?
79+
7780
this.graph = g;
7881
// slot 0 not used: nodes are numbered from 1 to n so zero
7982
// can represent undefined.
@@ -82,7 +85,7 @@ internal DomRelation(Graph<Node> g, Node source)
8285
this.NewComputeDominators();
8386
}
8487

85-
public Dictionary<Node, List<Node>> ImmediateDominatorMap
88+
public Dictionary<TNode, List<TNode>> ImmediateDominatorMap
8689
{
8790
get
8891
{
@@ -91,60 +94,57 @@ public Dictionary<Node, List<Node>> ImmediateDominatorMap
9194
}
9295
}
9396

94-
public bool DominatedBy(Node dominee, Node dominator, List<Node> path = null)
97+
public bool DominatedBy(TNode dominee, TNode dominator, List<TNode> path = null)
9598
{
9699
Contract.Assume(this.nodeToPostOrderNumber != null);
97-
Contract.Assume(this.doms != null);
100+
Contract.Assume(this.nodeNumberToImmediateDominator != null);
98101
int domineeNum = this.nodeToPostOrderNumber[dominee];
99102
int dominatorNum = this.nodeToPostOrderNumber[dominator];
100103
if (domineeNum == dominatorNum)
101104
{
102105
return true;
103106
}
104107

105-
int currentNodeNum = this.doms[domineeNum];
108+
int currentDominator = nodeNumberToImmediateDominator[domineeNum];
106109
while (true)
107110
{
108-
if (currentNodeNum == dominatorNum)
111+
if (currentDominator == dominatorNum)
109112
{
110113
return true;
111114
}
112115

113-
if (currentNodeNum == this.sourceNum)
116+
if (currentDominator == sourceNum)
114117
{
115118
return false;
116119
}
117120

118-
if (path != null)
119-
{
120-
path.Add(postOrderNumberToNode[currentNodeNum]);
121-
}
121+
path?.Add(postOrderNumberToNode[currentDominator]);
122122

123-
currentNodeNum = this.doms[currentNodeNum];
123+
currentDominator = nodeNumberToImmediateDominator[currentDominator];
124124
}
125125
}
126126

127-
private Dictionary<Node, List<Node>> domMap = null;
127+
private Dictionary<TNode, List<TNode>> domMap = null;
128128

129129
[Pure]
130130
public override string ToString()
131131
{
132-
Contract.Assume(this.doms != null);
133-
int[] localDoms = this.doms;
132+
Contract.Assume(this.nodeNumberToImmediateDominator != null);
133+
int[] localDoms = this.nodeNumberToImmediateDominator;
134134
Contract.Assume(this.postOrderNumberToNode != null);
135135
if (domMap == null)
136136
{
137-
domMap = new Dictionary<Node, List<Node>>();
137+
domMap = new Dictionary<TNode, List<TNode>>();
138138
for (int i = 1; i < localDoms.Length; i++)
139139
{
140140
// 0 slot is not used
141141
int domineeNum = i;
142142
int currentNodeNum = domineeNum;
143-
List<Node> dominators = new List<Node>();
143+
List<TNode> dominators = new List<TNode>();
144144
while (currentNodeNum != this.sourceNum)
145145
{
146146
dominators.Add(this.postOrderNumberToNode[currentNodeNum]);
147-
currentNodeNum = this.doms[currentNodeNum];
147+
currentNodeNum = this.nodeNumberToImmediateDominator[currentNodeNum];
148148
}
149149

150150
dominators.Add(this.postOrderNumberToNode[this.sourceNum]);
@@ -155,14 +155,14 @@ public override string ToString()
155155
StringBuilder sb = new StringBuilder();
156156
sb.Append("{");
157157
bool first = true;
158-
foreach (KeyValuePair<Node, List<Node>> de in domMap)
158+
foreach (KeyValuePair<TNode, List<TNode>> de in domMap)
159159
{
160160
if (!first)
161161
{
162162
sb.Append(", ");
163163
}
164164

165-
Contract.Assert(!object.Equals(de.Key, default(Node)));
165+
Contract.Assert(!object.Equals(de.Key, default(TNode)));
166166
sb.Append(de.Key.ToString());
167167
sb.Append("~>");
168168
sb.Append(ListToString(de.Value));
@@ -235,18 +235,18 @@ public void PrintList<T>(IEnumerable<T> xs)
235235
private void NewComputeDominators()
236236
{
237237
int n = this.graph.Nodes.Count;
238-
this.postOrderNumberToNode = new Node[n + 1];
239-
this.nodeToPostOrderNumber = new Dictionary<Node, int>();
238+
this.postOrderNumberToNode = new TNode[n + 1];
239+
this.nodeToPostOrderNumber = new Dictionary<TNode, int>();
240240
//HashSet<Node> visited = new HashSet<Node>();
241241
//int currentNumber = 1;
242242
Contract.Assume(this.source != null);
243243
//this.PostOrderVisit(this.source, visited, ref currentNumber);
244244
this.PostOrderVisitIterative(this.source);
245245
this.sourceNum = this.nodeToPostOrderNumber[source];
246246
// for (int i = 1; i <= n; i++){ Console.WriteLine(postOrderNumberToNode[i]); }
247-
this.doms = new int[n + 1]; // 0 is unused: means undefined
248-
Node start_node = this.source;
249-
this.doms[this.nodeToPostOrderNumber[start_node]] = this.nodeToPostOrderNumber[start_node];
247+
this.nodeNumberToImmediateDominator = new int[n + 1]; // 0 is unused: means undefined
248+
TNode start_node = this.source;
249+
this.nodeNumberToImmediateDominator[this.nodeToPostOrderNumber[start_node]] = this.nodeToPostOrderNumber[start_node];
250250
bool changed = true;
251251
// PrintIntArray(doms);
252252
while (changed)
@@ -255,18 +255,18 @@ private void NewComputeDominators()
255255
// for all nodes, b, in reverse postorder (except start_node)
256256
for (int nodeNum = n - 1; 1 <= nodeNum; nodeNum--)
257257
{
258-
Node b = this.postOrderNumberToNode[nodeNum];
259-
IEnumerable<Node> predecessors = this.graph.Predecessors(b);
258+
TNode b = this.postOrderNumberToNode[nodeNum];
259+
IEnumerable<TNode> predecessors = this.graph.Predecessors(b);
260260
// find a predecessor (i.e., a higher number) for which
261261
// the doms array has been set
262262
int new_idom = 0;
263263
int first_processed_predecessor = 0;
264264

265265
#region new_idom <- number of first (processed) predecessor of b (pick one)
266266

267-
foreach (Node p in predecessors)
267+
foreach (TNode p in predecessors)
268268
{
269-
if (this.doms[this.nodeToPostOrderNumber[p]] != 0)
269+
if (this.nodeNumberToImmediateDominator[this.nodeToPostOrderNumber[p]] != 0)
270270
{
271271
int x = this.nodeToPostOrderNumber[p];
272272
new_idom = x;
@@ -279,24 +279,24 @@ private void NewComputeDominators()
279279

280280
#region for all other predecessors, p, of b
281281

282-
foreach (Node p in predecessors)
282+
foreach (TNode p in predecessors)
283283
{
284284
if (this.nodeToPostOrderNumber[p] == first_processed_predecessor)
285285
{
286286
continue;
287287
}
288288

289-
if (this.doms[this.nodeToPostOrderNumber[p]] != 0)
289+
if (this.nodeNumberToImmediateDominator[this.nodeToPostOrderNumber[p]] != 0)
290290
{
291-
new_idom = intersect(this.nodeToPostOrderNumber[p], new_idom, this.doms);
291+
new_idom = Intersect(this.nodeToPostOrderNumber[p], new_idom, this.nodeNumberToImmediateDominator);
292292
}
293293
}
294294

295295
#endregion
296296

297-
if (this.doms[this.nodeToPostOrderNumber[b]] != new_idom)
297+
if (this.nodeNumberToImmediateDominator[this.nodeToPostOrderNumber[b]] != new_idom)
298298
{
299-
this.doms[this.nodeToPostOrderNumber[b]] = new_idom;
299+
this.nodeNumberToImmediateDominator[this.nodeToPostOrderNumber[b]] = new_idom;
300300
changed = true;
301301
}
302302
}
@@ -305,12 +305,12 @@ private void NewComputeDominators()
305305
#region Populate the Immediate Dominator Map
306306

307307
int sourceNum = this.nodeToPostOrderNumber[this.source];
308-
immediateDominatorMap = new Dictionary<Node, List<Node>>();
308+
immediateDominatorMap = new Dictionary<TNode, List<TNode>>();
309309
for (int i = 1; i <= n; i++)
310310
{
311-
Node node = this.postOrderNumberToNode[i];
312-
Node idomNode = this.postOrderNumberToNode[this.doms[i]];
313-
if (i == sourceNum && this.doms[i] == sourceNum)
311+
TNode node = this.postOrderNumberToNode[i];
312+
TNode idomNode = this.postOrderNumberToNode[this.nodeNumberToImmediateDominator[i]];
313+
if (i == sourceNum && this.nodeNumberToImmediateDominator[i] == sourceNum)
314314
{
315315
continue;
316316
}
@@ -321,7 +321,7 @@ private void NewComputeDominators()
321321
}
322322
else
323323
{
324-
List<Node> l = new List<Node>();
324+
List<TNode> l = new List<TNode>();
325325
l.Add(node);
326326
immediateDominatorMap.Add(idomNode, l);
327327
}
@@ -330,7 +330,7 @@ private void NewComputeDominators()
330330
#endregion
331331
}
332332

333-
private int intersect(int b1, int b2, int[] doms)
333+
private int Intersect(int b1, int b2, int[] doms)
334334
{
335335
int finger1 = b1;
336336
int finger2 = b2;
@@ -350,7 +350,7 @@ private int intersect(int b1, int b2, int[] doms)
350350
return finger1;
351351
}
352352

353-
private void PostOrderVisit(Node /*!*/ n, HashSet<Node> visited, ref int currentNumber)
353+
private void PostOrderVisit(TNode /*!*/ n, HashSet<TNode> visited, ref int currentNumber)
354354
{
355355
Contract.Requires(n != null);
356356
if (visited.Contains(n))
@@ -359,7 +359,7 @@ private void PostOrderVisit(Node /*!*/ n, HashSet<Node> visited, ref int current
359359
}
360360

361361
visited.Add(n);
362-
foreach (Node /*!*/ child in this.graph.Successors(n))
362+
foreach (TNode /*!*/ child in this.graph.Successors(n))
363363
{
364364
Contract.Assert(child != null);
365365
PostOrderVisit(child, visited, ref currentNumber);
@@ -374,12 +374,12 @@ private void PostOrderVisit(Node /*!*/ n, HashSet<Node> visited, ref int current
374374
}
375375

376376
// Iterative version: mimics the above recursive procedure
377-
private void PostOrderVisitIterative(Node n)
377+
private void PostOrderVisitIterative(TNode n)
378378
{
379379
Contract.Requires(n != null);
380-
var visited = new HashSet<Node>();
381-
var grey = new HashSet<Node>();
382-
var stack = new Stack<Node>();
380+
var visited = new HashSet<TNode>();
381+
var grey = new HashSet<TNode>();
382+
var stack = new Stack<TNode>();
383383

384384
int currentNumber = 1;
385385

@@ -402,7 +402,7 @@ private void PostOrderVisitIterative(Node n)
402402
{
403403
grey.Add(curr);
404404
stack.Push(curr);
405-
foreach (Node /*!*/ child in this.graph.Successors(curr))
405+
foreach (TNode /*!*/ child in this.graph.Successors(curr))
406406
{
407407
Contract.Assert(child != null);
408408
if (!visited.Contains(child))
@@ -415,10 +415,10 @@ private void PostOrderVisitIterative(Node n)
415415
}
416416
}
417417

418-
public Node LeastCommonAncestor(Node n1, Node n2)
418+
public TNode LeastCommonAncestor(TNode n1, TNode n2)
419419
{
420420
int num1 = nodeToPostOrderNumber[n1], num2 = nodeToPostOrderNumber[n2];
421-
int lca = intersect(num1, num2, this.doms);
421+
int lca = Intersect(num1, num2, this.nodeNumberToImmediateDominator);
422422
return postOrderNumberToNode[lca];
423423
}
424424
}
@@ -661,7 +661,7 @@ public static HashSet<T> Intersection<T>(IEnumerable<ISet<T>> sets) {
661661
}
662662

663663
if (result == null) {
664-
return ImmutableHashSet<T>.Empty;
664+
return new HashSet<T>();
665665
}
666666

667667
return result;
@@ -710,10 +710,10 @@ public List<Node> ImmediatelyDominatedBy(Node /*!*/ n)
710710
{
711711
Contract.Requires(n != null);
712712
this.ImmediateDominatorMap.TryGetValue(n, out var dominees);
713-
return dominees == null ? new List<Node>() : dominees;
713+
return dominees ?? new List<Node>();
714714
}
715715

716-
public IEnumerable<Node /*?*/> TopologicalSort(bool reversed = false)
716+
public List<Node> TopologicalSort(bool reversed = false)
717717
{
718718
TarjanTopSort(out var acyclic, out var sortedList, reversed);
719719
return acyclic ? sortedList : new List<Node>();

Source/VCGeneration/Splits/FocusApplier.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ public static class FocusApplier
2222
public static List<ManualSplit> GetFocusParts(VCGenOptions options, ImplementationRun run,
2323
Func<ImplementationPartOrigin, List<Block>, ManualSplit> createPart)
2424
{
25-
var impl = run.Implementation;
26-
var dag = Program.GraphFromImpl(impl);
27-
var topologicallySortedBlocks = dag.TopologicalSort().ToList();
25+
var implementation = run.Implementation;
26+
var dag = Program.GraphFromImpl(implementation);
27+
var topologicallySortedBlocks = dag.TopologicalSort();
2828
var blocksReversed = Enumerable.Reverse(topologicallySortedBlocks).ToList();
2929
// By default, we process the foci in a top-down fashion, i.e., in the topological order.
3030
// If the user sets the RelaxFocus flag, we use the reverse (topological) order.
@@ -33,7 +33,7 @@ public static List<ManualSplit> GetFocusParts(VCGenOptions options, Implementati
3333
focusBlocks.Reverse();
3434
}
3535
if (!focusBlocks.Any()) {
36-
return new List<ManualSplit> { createPart(new ImplementationRootOrigin(run.Implementation), impl.Blocks) };
36+
return new List<ManualSplit> { createPart(new ImplementationRootOrigin(run.Implementation), implementation.Blocks) };
3737
}
3838

3939
var ancestorsPerBlock = new Dictionary<Block, HashSet<Block>>();
@@ -43,18 +43,19 @@ public static List<ManualSplit> GetFocusParts(VCGenOptions options, Implementati
4343
reachables.Remove(fb.Block);
4444
ancestorsPerBlock[fb.Block] = reachables;
4545
});
46+
var dominators = dag.DominatorMap;
4647
focusBlocks.ForEach(fb => descendantsPerBlock[fb.Block] = dag.ComputeReachability(fb.Block).ToHashSet());
4748
var result = new List<ManualSplit>();
4849

49-
AddSplitsFromIndex(ImmutableStack<IToken>.Empty, 0, impl.Blocks.ToHashSet(), ImmutableHashSet<Block>.Empty);
50+
AddSplitsFromIndex(ImmutableStack<Block>.Empty, 0, implementation.Blocks.ToHashSet(), ImmutableHashSet<Block>.Empty);
5051
return result;
5152

52-
void AddSplitsFromIndex(ImmutableStack<IToken> path, int focusIndex, ISet<Block> blocksToInclude, ISet<Block> freeAssumeBlocks) {
53+
void AddSplitsFromIndex(ImmutableStack<Block> path, int focusIndex, ISet<Block> blocksToInclude, ISet<Block> freeAssumeBlocks) {
5354
var allFocusBlocksHaveBeenProcessed = focusIndex == focusBlocks.Count;
5455
if (allFocusBlocksHaveBeenProcessed) {
5556
var newBlocks = ComputeNewBlocks(options, blocksToInclude, blocksReversed, freeAssumeBlocks);
5657
ImplementationPartOrigin token = path.Any()
57-
? new PathOrigin(run.Implementation.tok, path)
58+
? new PathOrigin(run.Implementation.tok, path, dominators)
5859
: new ImplementationRootOrigin(run.Implementation);
5960
result.Add(createPart(token, newBlocks));
6061
} else {
@@ -76,7 +77,7 @@ void AddSplitsFromIndex(ImmutableStack<IToken> path, int focusIndex, ISet<Block>
7677

7778
// Recursive call that does focus the block
7879
// Contains all the ancestors, the focus block, and the descendants.
79-
AddSplitsFromIndex(path.Push(nextToken), focusIndex + 1,
80+
AddSplitsFromIndex(path.Push(focusBlock), focusIndex + 1,
8081
ancestors.Union(descendants).Intersect(blocksToInclude).ToHashSet(),
8182
ancestors.Union(freeAssumeBlocks).ToHashSet());
8283
}

0 commit comments

Comments
 (0)