com.ibm.wala.ipa.modref.GenReach Maven / Gradle / Ivy
/*
* Copyright (c) 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*/
package com.ibm.wala.ipa.modref;
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
import com.ibm.wala.dataflow.graph.BitVectorFramework;
import com.ibm.wala.dataflow.graph.BitVectorUnion;
import com.ibm.wala.dataflow.graph.BitVectorUnionVector;
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
import com.ibm.wala.fixpoint.BitVectorVariable;
import com.ibm.wala.fixpoint.UnaryOperator;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.intset.BitVector;
import com.ibm.wala.util.intset.MutableMapping;
import com.ibm.wala.util.intset.OrdinalSetMapping;
import java.util.Collection;
import java.util.Map;
/** Generic dataflow framework to accumulate reachable gen'ned values in a graph. */
public class GenReach extends BitVectorFramework {
@SuppressWarnings("unchecked")
public GenReach(Graph flowGraph, Map> gen) {
super(flowGraph, new GenFunctions<>(gen), makeDomain(gen));
// ugly but necessary, in order to avoid computing the domain twice.
GenReach.GenFunctions g = (GenReach.GenFunctions) getTransferFunctionProvider();
g.domain = getLatticeValues();
}
private static OrdinalSetMapping makeDomain(Map> gen) {
MutableMapping result = MutableMapping.make();
if (gen == null) {
throw new IllegalArgumentException("null gen");
}
for (Collection c : gen.values()) {
for (L p : c) {
result.add(p);
}
}
return result;
}
static class GenFunctions implements ITransferFunctionProvider {
private final Map> gen;
private OrdinalSetMapping domain;
public GenFunctions(Map> gen) {
this.gen = gen;
}
@Override
public AbstractMeetOperator getMeetOperator() {
return BitVectorUnion.instance();
}
@Override
public UnaryOperator getNodeTransferFunction(T node) {
BitVector v = getGen(node);
return new BitVectorUnionVector(v);
}
private BitVector getGen(T node) {
Collection g = gen.get(node);
if (g == null) {
return new BitVector();
} else {
BitVector result = new BitVector();
for (L p : g) {
result.set(domain.getMappedIndex(p));
}
return result;
}
}
@Override
public boolean hasEdgeTransferFunctions() {
return false;
}
@Override
public boolean hasNodeTransferFunctions() {
return true;
}
@Override
public UnaryOperator getEdgeTransferFunction(T src, T dst) {
Assertions.UNREACHABLE();
return null;
}
}
}