List<Unit> tails = this.getTails();
TailsLoop:
for(Iterator<Unit> itr = tails.iterator(); itr.hasNext(); )
{
Unit tail = itr.next();
if(!(tail instanceof ThrowStmt))
continue;
DominatorNode x = dom.getDode(tail);
DominatorNode parentOfX = dom.getParentOf(x);
Object xgode = x.getGode();
DominatorNode xpdomDode = pdom.getDode(xgode);
Object parentXGode = parentOfX.getGode();
DominatorNode parentpdomDode = pdom.getDode(parentXGode);
//while x post-dominates its dominator (parent in dom)
while(pdom.isDominatorOf(xpdomDode, parentpdomDode))
{
x = parentOfX;
parentOfX = dom.getParentOf(x);
//If parent is null we must be at the head of the graph
if(parentOfX == null)
//throw new RuntimeException("This should never have happened!");
break;
xgode = x.getGode();
xpdomDode = pdom.getDode(xgode);
parentXGode = parentOfX.getGode();
parentpdomDode = pdom.getDode(parentXGode);
}
if(parentOfX != null)
x = parentOfX;
xgode = x.getGode();
xpdomDode = pdom.getDode(xgode);
Unit mergePoint = null;
if(x2mergePoint.containsKey(xgode))
mergePoint = x2mergePoint.get(xgode);
else
{
//Now get all the children of x in the dom
List<DominatorNode> domChilds = dom.getChildrenOf(x);
Object child1god = null;
Object child2god = null;
for(Iterator<DominatorNode> domItr = domChilds.iterator(); domItr.hasNext(); )
{
DominatorNode child = domItr.next();
Object childGode = child.getGode();
DominatorNode childpdomDode = pdom.getDode(childGode);
//we don't want to make a loop!
List<Unit> path = this.getExtendedBasicBlockPathBetween((Unit)childGode, tail);
//if(dom.isDominatorOf(child, dom.getDode(tail)))
if(!(path == null || path.size() == 0))
continue;
if(pdom.isDominatorOf(childpdomDode, xpdomDode))
{
mergePoint = (Unit) child.getGode();
break;
}
//gather two eligible childs
if(child1god == null)
child1god = childGode;
else if(child2god == null)
child2god = childGode;
}
if(mergePoint == null)
{
if(child1god != null && child2god != null)
{
DominatorNode child1 = pdom.getDode(child1god);
DominatorNode child2 = pdom.getDode(child2god);
//go up the pdom tree and find the common parent of child1 and child2
DominatorNode comParent = child1.getParent();
while(comParent != null)
{
if(pdom.isDominatorOf(comParent, child2))
{
mergePoint = (Unit) comParent.getGode();
break;
}
comParent = comParent.getParent();
}
}
else if(child1god != null || child2god != null){
DominatorNode y = null;
if(child1god != null)
y = pdom.getDode(child1god);
else if(child2god != null)
y = pdom.getDode(child2god);
DominatorNode initialY = dom.getDode(y.getGode());
DominatorNode yDodeInDom = initialY;
while(dom.isDominatorOf(x, yDodeInDom))
{
y = y.getParent();
//If this is a case where the childs of a conditional
//are all throws, or returns, just forget it!
if(y == null)
{
break ;
}
yDodeInDom = dom.getDode(y.getGode());
}
if(y != null)
mergePoint = (Unit) y.getGode();
else
mergePoint = (Unit) initialY.getGode();
}
}
//This means no (dom) child of x post-dominates x, so just use the child that is
//immediately
/*if(mergePoint == null)
{
//throw new RuntimeException("No child post-dominates x.");
mergePoint = potentialMergePoint;
}*/
//This means no (dom) child of x post-dominates x, so just use the child that is
//immediately. this means there is no good reliable merge point. So we just fetch the succ
//of x in CFg so that the succ does not dominate the throw, and find the first
//post-dom of the succ so that x does not dom it.
//
if(mergePoint == null)
{
List<Unit> xSucc = this.unitToSuccs.get(x.getGode());
for(Iterator<Unit> uItr = xSucc.iterator(); uItr.hasNext(); )
{
Unit u = uItr.next();
if(dom.isDominatorOf(dom.getDode(u), dom.getDode(tail)))
continue;
DominatorNode y = pdom.getDode(u);