package xsched.wala.optimizations;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
public class GlobalPointsToInfo {
private final Map<CGNode, LocalPointsToInfo> info = new HashMap<CGNode, LocalPointsToInfo>();
public static GlobalPointsToInfo make(PointerAnalysis pa, CallGraph cg, Set<Variable> variables) {
GlobalPointsToInfo result = new GlobalPointsToInfo();
for(Variable variable : variables) {
for(CGNode node : cg.getNodes(variable.method.getReference())) {
//we somehow jump wildly through the callgraph because we iterate variables first, then nodes; therefore this is a little less elegant than it would be otherwise
LocalPointsToInfo local = result.pointsToSet(node);
if(local == null) {
local = new LocalPointsToInfo();
result.set(node, local);
}
local.addAll(variable, Util.computeInstanceKeysForVariableAtNode(pa, node, variable));
}
}
return result;
}
public GlobalPointsToInfo() {
}
public LocalPointsToInfo pointsToSet(CGNode node) {
LocalPointsToInfo byVariable = info.get(node);
if(byVariable == null)
return new LocalPointsToInfo();
else
return byVariable;
}
public Map<CGNode, LocalPointsToInfo> info() {
return info;
}
public void set(CGNode node, LocalPointsToInfo local) {
assert ! info.containsKey(node);
info.put(node, local);
}
public Map<CGNode, Set<InstanceKey>> mapToInstanceKeys(Set<InstanceKey> filter) {
Map<CGNode, Set<InstanceKey>> result = new HashMap<CGNode, Set<InstanceKey>>();
for(Entry<CGNode, LocalPointsToInfo> entry : info.entrySet()) {
result.put(entry.getKey(), entry.getValue().allInstanceKeys(filter));
}
return result;
}
//collect all the local points to infos of all nodes reachable by task
public LocalPointsToInfo collectLocalPointsToSetsReachableByTask(Reachability<CGNode, CGNode> reachability, CGNode task) {
LocalPointsToInfo result = new LocalPointsToInfo();
result.addAll(this.pointsToSet(task));
for(CGNode nonTask : reachability.nonTaskNodesReachableByTask(task)) {
result.addAll(this.pointsToSet(nonTask));
}
return result;
}
//filter can be null
public Map<CGNode, LocalPointsToInfo> collectLocalPointsToSetsForTasks(Reachability<CGNode, CGNode> reachability, Collection<CGNode> tasks) {
Map<CGNode, LocalPointsToInfo> result = new HashMap<CGNode, LocalPointsToInfo>();
for(CGNode task : tasks) {
LocalPointsToInfo local = collectLocalPointsToSetsReachableByTask(reachability, task);
result.put(task, local);
}
return result;
}
}