-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathLoopFinder.java
More file actions
87 lines (80 loc) · 2.89 KB
/
LoopFinder.java
File metadata and controls
87 lines (80 loc) · 2.89 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
package com.compilerprogramming.ezlang.compiler;
import java.util.*;
import java.util.stream.Collectors;
public class LoopFinder {
// Based on Compilers: Principles, Techniques and Tools
// p 604
// 1986 ed
public static LoopNest getNaturalLoop(BasicBlock head, BasicBlock backedge) {
Stack<BasicBlock> stack = new Stack<>();
LoopNest loop = new LoopNest(head);
loop.insert(backedge, stack);
// trace back up from backedge to head
while (!stack.isEmpty()) {
BasicBlock m = stack.pop();
for (BasicBlock pred : m.predecessors) {
loop.insert(pred, stack);
}
}
return loop;
}
// Based on Compilers: Principles, Techniques and Tools
// p 604
// 1986 ed
public static List<LoopNest> findLoops(List<BasicBlock> nodes) {
List<LoopNest> list = new ArrayList<>();
for (BasicBlock n : nodes) {
for (BasicBlock input : n.predecessors) {
if (n.dominates(input)) {
list.add(getNaturalLoop(n, input));
}
}
}
return list;
}
public static List<LoopNest> mergeLoopsWithSameHead(List<LoopNest> loopNests) {
HashMap<Integer, LoopNest> map = new HashMap<>();
for (LoopNest loopNest : loopNests) {
LoopNest sameHead = map.get(loopNest._loopHead.bid);
if (sameHead == null) map.put(loopNest._loopHead.bid, loopNest);
else sameHead._blocks.addAll(loopNest._blocks);
}
return map.values().stream().collect(Collectors.toList());
}
public static LoopNest buildLoopTree(List<LoopNest> loopNests) {
for (LoopNest nest1 : loopNests) {
for (LoopNest nest2 : loopNests) {
boolean isNested = nest1.contains(nest2);
if (isNested) {
if (nest2._parent == null) nest2._parent = nest1;
else if (nest1._loopHead.domDepth > nest2._parent._loopHead.domDepth) nest2._parent = nest1;
}
}
}
LoopNest top = null;
for (LoopNest nest : loopNests) {
if (nest._parent != null) nest._parent._kids.add(nest);
else top = nest;
}
return top;
}
public static void annotateBasicBlocks(LoopNest loop, Set<LoopNest> visited) {
if (visited.contains(loop))
return;
visited.add(loop);
for (LoopNest kid: loop._kids) {
kid._depth = loop._depth+1;
annotateBasicBlocks(kid, visited);
}
for (BasicBlock block: loop._blocks) {
if (block.loop == null)
block.loop = loop;
}
}
public static void annotateBasicBlocks(LoopNest top) {
if (top == null) // No loop
return;
top._depth = 1;
annotateBasicBlocks(top, new HashSet<>());
}
}