q
public void forEachBlockDepthFirst(boolean reverse,
SsaBasicBlock.Visitor v) {
BitSet visited = new BitSet(blocks.size());
// We push the parent first, then the child on the stack.
Stack<SsaBasicBlock> stack = new Stack<SsaBasicBlock>();
SsaBasicBlock rootBlock = reverse ? getExitBlock() : getEntryBlock();
if (rootBlock == null) {
// in the case there's no exit block
return;
}
stack.add(null); // Start with null parent.
stack.add(rootBlock);
while (stack.size() > 0) {// 0元素为null ,向上看两行 ,stack.add(null)的原因
SsaBasicBlock cur = stack.pop();
SsaBasicBlock parent = stack.pop();
if (!visited.get(cur.getIndex())) {
BitSet children
= reverse ? cur.getPredecessors() : cur.getSuccessors();
for (int i = children.nextSetBit(0); i >= 0
; i = children.nextSetBit(i + 1)) {
stack.add(cur);
stack.add(blocks.get(i));// cur 的一个 child
}
visited.set(cur.getIndex());// 1L << very big???
v.visitBlock(cur, parent);// size++
}
}
}
q
public void visitBlock(SsaBasicBlock v, SsaBasicBlock parent) {
DFSInfo bbInfo = new DFSInfo();
bbInfo.semidom = ++dfsNum;
bbInfo.rep = v;
bbInfo.parent = parent;
vertex.add(v);
info[v.getIndex()] = bbInfo;
}
q
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
int predSemidom = info[eval(predBlock).getIndex()].semidom;
private SsaBasicBlock eval(SsaBasicBlock v) {
DFSInfo bbInfo = info[v.getIndex()];
if (bbInfo.ancestor == null) {
return v;
}
compress(v);
return bbInfo.rep;
}
11
private void compress(SsaBasicBlock in) {
DFSInfo bbInfo = info[in.getIndex()];
DFSInfo ancestorbbInfo = info[bbInfo.ancestor.getIndex()];
if (ancestorbbInfo.ancestor != null) {
ArrayList<SsaBasicBlock> worklist = new ArrayList<SsaBasicBlock>();
HashSet<SsaBasicBlock> visited = new HashSet<SsaBasicBlock>();
worklist.add(in);
while (!worklist.isEmpty()) {
int wsize = worklist.size();
SsaBasicBlock v = worklist.get(wsize - 1);
DFSInfo vbbInfo = info[v.getIndex()];
SsaBasicBlock vAncestor = vbbInfo.ancestor;
DFSInfo vabbInfo = info[vAncestor.getIndex()];
// Make sure we process our ancestor before ourselves.
if (visited.add(vAncestor) && vabbInfo.ancestor != null) {
worklist.add(vAncestor);
continue;
}
worklist.remove(wsize - 1);
// Update based on ancestor info.
if (vabbInfo.ancestor == null) {
continue;
}
SsaBasicBlock vAncestorRep = vabbInfo.rep;
SsaBasicBlock vRep = vbbInfo.rep;
if (info[vAncestorRep.getIndex()].semidom
< info[vRep.getIndex()].semidom) {
vbbInfo.rep = vAncestorRep;
}
vbbInfo.ancestor = vabbInfo.ancestor;
}
}
}
q
private void buildDomTree() {
int szNodes = nodes.size();
for (int i = 0; i < szNodes; i++) {
DomInfo info = domInfos[i];
if (info.idom == -1) continue;
SsaBasicBlock domParent = nodes.get(info.idom);
domParent.addDomChild(nodes.get(i));
}
}