package soot.jimple.toolkits.thread.mhp;
import soot.toolkits.scalar.*;
import soot.toolkits.graph.*;
import soot.util.*;
import java.util.*;
// *** USE AT YOUR OWN RISK ***
// May Happen in Parallel (MHP) analysis by Lin Li.
// This code should be treated as beta-quality code.
// It was written in 2003, but not incorporated into Soot until 2006.
// As such, it may contain incorrect assumptions about the usage
// of certain Soot classes.
// Some portions of this MHP analysis have been quality-checked, and are
// now used by the Transactions toolkit.
//
// -Richard L. Halpert, 2006-11-30
public class DominatorsFinder{
private final Map<Object, FlowSet> unitToDominators;
private final DirectedGraph peg;
DominatorsFinder(Chain chain, DirectedGraph pegGraph){
unitToDominators = new HashMap<Object, FlowSet>();
peg = pegGraph;
find(chain);
//testUnitToDominators();
}
private void find(Chain chain) {
boolean change = true;
Iterator chainIt;
FlowSet fullSet = new ArraySparseSet();
FlowSet temp = new ArraySparseSet();
{
chainIt = chain.iterator();
while (chainIt.hasNext()){
fullSet.add(chainIt.next());
}
}
List heads = peg.getHeads();
if (heads.size() != 1){
System.err.println("The size of heads of peg is not equal to 1!");
System.exit(1);
}
else{
FlowSet dominators = new ArraySparseSet();
Object head = heads.get(0);
dominators.add(head);
unitToDominators.put(head, dominators);
}
{
chainIt = chain.iterator();
while (chainIt.hasNext()){
Object n = chainIt.next();
if (heads.contains(n)) continue;
FlowSet domin = new ArraySparseSet();
fullSet.copy(domin);
unitToDominators.put(n, domin);
}
}
System.out.println("===finish init unitToDominators===");
System.err.println("===finish init unitToDominators===");
// testUnitToDominators();
do {
change = false;
Iterator it = chain.iterator();
while(it.hasNext()){
Object n = it.next();
if (heads.contains(n)) continue;
else{
fullSet.copy(temp);
Iterator predsIt = peg.getPredsOf(n).iterator();
while (predsIt.hasNext()){
Object p = predsIt.next();
FlowSet dom = getDominatorsOf(p);
temp.intersection(dom);
}
FlowSet d = new ArraySparseSet();
FlowSet nSet = new ArraySparseSet();
nSet.add(n);
nSet.union(temp, d);
FlowSet dominN = getDominatorsOf(n);
if (!d.equals(dominN)){
change = true;
dominN = d;
}
}
}
}while(!change);
}
public FlowSet getDominatorsOf(Object s){
if(!unitToDominators.containsKey(s))
throw new RuntimeException("Invalid stmt" + s);
return unitToDominators.get(s);
}
}