Commit 2276ed07 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

feat: add a vertex to region mapping to the condensed graphs.

Also use the mappings of both IntraSCRGraph and CallSCRGraph.
parent efad178c
Loading
Loading
Loading
Loading
Loading
+11 −21
Original line number Diff line number Diff line
@@ -81,8 +81,6 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
        protected final Map<CallGraph.Edge<?>, List<ControlFlowArc>> callGraphEdge2ICFGArcMap = new HashMap<>();
        /** The strongly connected components of the {@link CallGraph}. */
        protected CallSCRGraph cSCRs;
        /** A map to locate declarations in the {@link #cSCRs}. */
        protected Map<CallableDeclaration<?>, CallSCR> cSCRsMap;
        /** A map to locate the set of {@link #intraSCRs} nodes that correspond (transitively) to a given {@link #cSCRs} node. */
        protected final Map<CallSCR, Set<IntraSCR>> transitiveMap = new HashMap<>();
        /** The strongly connected components of the {@link ICFG}, computed while ignoring
@@ -116,17 +114,12 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<

        private void addEdgesToIntraSCRs(Set<Triple<GraphNode<?>, GraphNode<?>, ControlFlowArc>> deletedArcs) {
            for (Triple<GraphNode<?>, GraphNode<?>, ControlFlowArc> arc : deletedArcs) {
                for (IntraSCR srcSCR : intraSCRs.vertexSet()) {
                    for (IntraSCR tgtSCR : intraSCRs.vertexSet()) {
                        if (srcSCR.containsVertex(arc.getFirst()) && tgtSCR.containsVertex(arc.getSecond())) {
                            if (srcSCR == tgtSCR)
                                srcSCR.addEdge(arc.getFirst(), arc.getSecond(), arc.getThird());
                IntraSCR srcRegion = intraSCRs.getRegion(arc.getFirst());
                IntraSCR tgtRegion = intraSCRs.getRegion(arc.getSecond());
                if (srcRegion.equals(tgtRegion))
                    srcRegion.addEdge(arc.getFirst(), arc.getSecond(), arc.getThird());
                else
                                intraSCRs.addEdge(srcSCR, tgtSCR);
                            break;
                        }
                    }
                }
                    intraSCRs.addEdge(srcRegion, tgtRegion);
            }
        }

@@ -234,7 +227,10 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
                        for (Triple<GraphNode<?>, GraphNode<?>, ControlFlowArc> arc : interprocNonRecArcs) {
                            if (graphNode.equals(arc.getFirst())) {
                                GraphNode<CallableDeclaration<?>> enterNode = (GraphNode<CallableDeclaration<?>>) arc.getSecond();
                                toBeMerged.addAll(transitiveMap.get(cSCRsMap.get(enterNode.getAstNode())));
                                CallGraph.Vertex procVertex = new CallGraph.Vertex(enterNode.getAstNode());
                                CallSCR procRegion = cSCRs.getRegion(procVertex);
                                Set<IntraSCR> procIntraSCRset = transitiveMap.get(procRegion);
                                toBeMerged.addAll(procIntraSCRset);
                                IntraSCR iSCRtarget = intraSCRs.vertexSet().stream()
                                        .filter(iSCR -> iSCR.containsVertex(enterNode))
                                        .findFirst().orElseThrow();
@@ -264,9 +260,7 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
            // 2. Borrar del ICFG todos los arcos que aparecen en cSCRs
            if (callGraph.vertexSet().size() * callGraph.vertexSet().size() < callGraph.edgeSet().size())
                for (CallGraph.Edge<?> e : callGraph.edgeSet()) {
                    CallableDeclaration<?> src = callGraph.getEdgeSource(e).getDeclaration();
                    CallableDeclaration<?> tgt = callGraph.getEdgeTarget(e).getDeclaration();
                    if (cSCRsMap.get(src) != cSCRsMap.get(tgt)) {
                    if (cSCRs.getRegion(callGraph.getEdgeSource(e)) != cSCRs.getRegion(callGraph.getEdgeTarget(e))) {
                        int callsDeleted = 0;
                        for (ControlFlowArc arc : callGraphEdge2ICFGArcMap.get(e)) {
                            if (simpleICFG.removeEdge(arc)) {
@@ -313,10 +307,6 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<

        protected void computeCallSCRs() {
            cSCRs = new CallSCRGraph(deleteDuplicatedEdges(callGraph));
            cSCRsMap = new HashMap<>(callGraph.vertexSet().size());
            for (CallSCR cSCR : cSCRs.vertexSet())
                for (CallGraph.Vertex vertex : cSCR.vertexSet())
                    cSCRsMap.put(vertex.getDeclaration(), cSCR);
        }

        public static <V, E> DefaultDirectedGraph<V, E> deleteDuplicatedEdges(Graph<V, E> baseGraph) {
+5 −1
Original line number Diff line number Diff line
@@ -34,8 +34,10 @@ public abstract class AbstractSCRAlgorithm<V, E, R extends AbstractSCR<V, E>> ex
    /**
     * Reimplementation of {@link org.jgrapht.alg.connectivity.AbstractStrongConnectivityInspector#getCondensation()} to wrap each strongly
     * connected component into a class with constant {@code hashCode} and {@code equals} implementation.
     *
     * @return A map, connecting each vertex in the original map to its location (region) in the condensation.
     */
    public void copySCRs(Graph<R, DefaultEdge> condensation) {
    public Map<V, R> copySCRs(Graph<R, DefaultEdge> condensation) {
        List<Set<V>> sets = stronglyConnectedSets();

        Map<V, R> vertexToComponent = new HashMap<>();
@@ -60,5 +62,7 @@ public abstract class AbstractSCRAlgorithm<V, E, R extends AbstractSCR<V, E>> ex
                condensation.addEdge(sComponent, tComponent);
            }
        }

        return vertexToComponent;
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@ package es.upv.mist.slicing.graphs.scrs;
import es.upv.mist.slicing.graphs.CallGraph;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleDirectedGraph;

import java.util.Set;

@@ -12,10 +11,10 @@ import java.util.Set;
 * @see AbstractSCRAlgorithm
 * @see CallSCR CallSCR: The component members of this graph.
 */
public class CallSCRGraph extends SimpleDirectedGraph<CallSCR, DefaultEdge> {
public class CallSCRGraph extends CondensedGraph<CallGraph.Vertex, CallGraph.Edge<?>, CallSCR> {
    public CallSCRGraph(Graph<CallGraph.Vertex, CallGraph.Edge<?>> graph) {
        super(DefaultEdge.class);
        new AbstractSCRAlgorithm<CallGraph.Vertex, CallGraph.Edge<?>, CallSCR>(graph) {
        regionMap = new AbstractSCRAlgorithm<CallGraph.Vertex, CallGraph.Edge<?>, CallSCR>(graph) {
            @Override
            public CallSCR newSCR(Graph<CallGraph.Vertex, CallGraph.Edge<?>> graph, Set<CallGraph.Vertex> nodeSet, Set<CallGraph.Edge<?>> edgeSet) {
                return new CallSCR(graph, nodeSet, edgeSet);
+34 −0
Original line number Diff line number Diff line
package es.upv.mist.slicing.graphs.scrs;

import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleDirectedGraph;

import java.util.Map;
import java.util.function.Supplier;

/**
 * An abstract class for condensed graphs.
 * @param <V> The type of the original graph's vertices.
 * @param <E> The type of the original graph's edges.
 * @param <R> The type of this graph's strongly connected regions.
 * @see AbstractSCRAlgorithm
 */
public abstract class CondensedGraph<V, E, R extends AbstractSCR<V, E>> extends SimpleDirectedGraph<R, DefaultEdge> {
    protected Map<V, R> regionMap;

    public CondensedGraph(Class<? extends DefaultEdge> edgeClass) {
        super(edgeClass);
    }

    public CondensedGraph(Supplier<R> vertexSupplier, Supplier<DefaultEdge> edgeSupplier, boolean weighted) {
        super(vertexSupplier, edgeSupplier, weighted);
    }

    /**
     * Obtains the strongly connected region in which a given vertex is located.
     * Only return {@code null} when the given vertex did not belong to the original graph.
     */
    public R getRegion(V v) {
        return regionMap.get(v);
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@ import es.upv.mist.slicing.graphs.icfg.ICFG;
import es.upv.mist.slicing.nodes.GraphNode;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.SimpleDirectedGraph;

import java.util.Set;

@@ -14,10 +13,10 @@ import java.util.Set;
 * @see AbstractSCRAlgorithm
 * @see IntraSCR IntraSCR: The component members of this graph.
 */
public class IntraSCRGraph extends SimpleDirectedGraph<IntraSCR, DefaultEdge> {
public class IntraSCRGraph extends CondensedGraph<GraphNode<?>, Arc, IntraSCR> {
    public IntraSCRGraph(Graph<GraphNode<?>, Arc> graph) {
        super(DefaultEdge.class);
        new AbstractSCRAlgorithm<GraphNode<?>, Arc, IntraSCR>(graph) {
        this.regionMap = new AbstractSCRAlgorithm<GraphNode<?>, Arc, IntraSCR>(graph) {
            @Override
            public IntraSCR newSCR(Graph<GraphNode<?>, Arc> graph, Set<GraphNode<?>> nodeSet, Set<Arc> edgeSet) {
                return new IntraSCR(graph, nodeSet, edgeSet);