All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.wala.dataflow.IFDS.CallFlowEdges Maven / Gradle / Ivy

/*
 * Copyright (c) 2002 - 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.dataflow.IFDS;

import com.ibm.wala.util.collections.SparseVector;
import com.ibm.wala.util.intset.BasicNaturalRelation;
import com.ibm.wala.util.intset.BimodalMutableIntSet;
import com.ibm.wala.util.intset.IBinaryNaturalRelation;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableIntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
import com.ibm.wala.util.intset.SparseIntSet;

/** A set of call flow edges which lead to a particular procedure entry s_p. */
public class CallFlowEdges {

  /**
   * A map from integer -> (IBinaryNonNegativeIntRelation)
   *
   * 

For a fact d2, edges[d2] gives a relation R=(c,d1) s.t. (<c, d1> -> <s_p,d2>) * was recorded as a call flow edge. * *

Note that we handle paths of the form <c, d1> -> <s_p,d1> specially, below. * *

TODO: more representation optimization. A special representation for triples? sparse * representations for CFG? exploit shorts for ints? */ private final SparseVector edges = new SparseVector<>(1, 1.1f); /** * a map from integer d1 -> int set. * *

for fact d1, identityPaths[d1] gives the set of block numbers C s.t. for c \in C, <c, * d1> -> <s_p, d1> is an edge. */ private final SparseVector identityEdges = new SparseVector<>(1, 1.1f); public CallFlowEdges() {} /** * Record that we've discovered a call edge <c,d1> -> <s_p, d2> * * @param c global number identifying the call site node * @param d1 source fact at the call edge * @param d2 result fact (result of the call flow function) */ @SuppressWarnings("unused") public void addCallEdge(int c, int d1, int d2) { if (TabulationSolver.DEBUG_LEVEL > 0) { System.err.println("addCallEdge " + c + ' ' + d1 + ' ' + d2); } if (d1 == d2) { BimodalMutableIntSet s = (BimodalMutableIntSet) identityEdges.get(d1); if (s == null) { s = new BimodalMutableIntSet(); identityEdges.set(d1, s); } s.add(c); } else { IBinaryNaturalRelation R = edges.get(d2); if (R == null) { // we expect the first dimension of R to be dense, the second sparse R = new BasicNaturalRelation( new byte[] {BasicNaturalRelation.TWO_LEVEL}, BasicNaturalRelation.TWO_LEVEL); edges.set(d2, R); } R.add(c, d1); } } /** * @return set of d1 s.t. {@literal -> } was recorded as call flow, or null if * none found. */ @SuppressWarnings("unused") public IntSet getCallFlowSources(int c, int d2) { if (c < 0) { throw new IllegalArgumentException("invalid c : " + c); } if (d2 < 0) { throw new IllegalArgumentException("invalid d2: " + d2); } IntSet s = identityEdges.get(d2); IBinaryNaturalRelation R = edges.get(d2); IntSet result = null; if (R == null) { if (s != null) { result = s.contains(c) ? SparseIntSet.singleton(d2) : null; } } else { if (s == null) { result = R.getRelated(c); } else { if (s.contains(c)) { if (R.getRelated(c) == null) { result = SparseIntSet.singleton(d2); } else { result = MutableSparseIntSet.make(R.getRelated(c)); ((MutableSparseIntSet) result).add(d2); } } else { result = R.getRelated(c); } } } if (TabulationSolver.DEBUG_LEVEL > 0) { System.err.println("getCallFlowSources " + c + ' ' + d2 + ' ' + result); } return result; } /** * @return set of c s.t. {@literal -> } was recorded as call flow (for some d1), * or null if none found. */ @SuppressWarnings("unused") public IntSet getCallFlowSourceNodes(int d2) { IntSet s = identityEdges.get(d2); IBinaryNaturalRelation R = edges.get(d2); IntSet result = null; if (R == null) { if (s != null) { result = s; } } else { if (s == null) { result = getDomain(R); } else { result = MutableSparseIntSet.make(s); ((MutableSparseIntSet) result).addAll(getDomain(R)); } } if (TabulationSolver.DEBUG_LEVEL > 0) { System.err.println("getCallFlowSources " + d2 + ' ' + result); } return result; } // TODO optimize private static IntSet getDomain(IBinaryNaturalRelation r) { MutableIntSet result = MutableSparseIntSet.makeEmpty(); int maxKeyValue = r.maxKeyValue(); for (int i = 0; i <= maxKeyValue; i++) { if (r.getRelated(i) != null) { result.add(i); } } return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy