Commit 8b40a41d authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Remove caching in slicing algorithms and SummaryTable.

- Previously, tabular slicing algorithms cached summary edges between runs (no longer necessary).
- SummaryTable is no longer in use, because tabular slicing is implemented without it.
parent c5d717b1
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
/*
 * EDG, a library to generate and slice Expression Dependence Graphs.
 * Copyright (c) 2021. David Insa, Sergio Pérez, Josep Silva, Salvador Tamarit.
 * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
@@ -29,13 +29,11 @@ public final class Config extends misc.Config
	public static final int MAX_PRODUCTION_DEPTH = 5;
	public static final int MAX_STACK_SIZE = Integer.parseInt(System.getProperty("maxStackSize", "20"));
	public static final LAST.Direction SLICE_DIRECTION = LAST.Direction.Backwards;
	public static final boolean GLOBAL_VARIABLES = false;
	public static final boolean PDG = true;
	public static final boolean APDG = false;
	public static final boolean PPDG = false;
	public static final boolean summaries = false;
	public static final boolean tabulatedSlicing = true;
	public static boolean programIsRecursive = false;

	public static Config getConfig()
	{
		return Config.config;
+18 −16
Original line number Diff line number Diff line
/*
 * EDG, a library to generate and slice Expression Dependence Graphs.
 * Copyright (c) 2021-2023. David Insa, Carlos Galindo, Sergio Pérez, Josep Silva, Salvador Tamarit.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package edg.graph;

import edg.constraint.GrammarConstraint;
import edg.slicing.SlicingCriterion;
import edg.slicing.SummaryTable;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

public class EDG extends LAST {

	protected final SummaryTable summaryTable = new SummaryTable(this);

	/** Create an empty EDG with an empty AST. */
	public EDG()
	{
@@ -32,18 +46,6 @@ public class EDG extends LAST {
		this.getGenerationTime().setCompositeTime(last.getCompositeStructureTime());
	}

	public SummaryTable getSummaryTable() {
		return summaryTable;
	}

	/**
	 * Clears any modifications made by slicing traversals over this graph.
	 * This method is mainly used for benchmarking.
	 */
	public void clearState() {
		summaryTable.clearTable();
	}

	// ================================================= //
	// ===================== NODES ===================== //
	// ================================================= //
+1 −22
Original line number Diff line number Diff line
@@ -83,17 +83,6 @@ public class ConstrainedAlgorithm implements SlicingAlgorithm
									edge.getType() == Edge.Type.Call);
		}

		if (Config.tabulatedSlicing && isArgumentOut(currentNode)) {
			edges.removeIf(e -> e.getType() == Edge.Type.Summary);
			List<SummaryTable.Value> values;
			if (phase == Phase.SummaryGeneration && Config.programIsRecursive)
				values = edg.getSummaryTable().getOrQueue(currentNode, constraints);
			else
				values = edg.getSummaryTable().getOrCompute(currentNode, constraints);
			for (SummaryTable.Value v : values)
				newWorks.add(v.createWork(initialNode, work.getTraversedEdges()));
		}

		// TRAVERSAL RESTRICTION TODO: Change this restriction to construction time removing structural arcs
		// GENERATOR NODES CONTAIN VALUE EDGES THAT MUST BE TRAVERSED ONLY IF THE GENERATOR NODE IS INCLUDED BY CONTROL
		if (currentNode.getType() == Node.Type.Generator && work.getPreviousEdgeType() != Edge.Type.Control)
@@ -143,7 +132,7 @@ public class ConstrainedAlgorithm implements SlicingAlgorithm
			final List<Constraints> newConstraintsList = constraint.resolve(phase, edg, currentEdge, constraintsClone, topConstraint, 0);

			for (Constraints newConstraints : newConstraintsList)
				if (phase == Phase.SummaryGeneration && Config.programIsRecursive)
				if (phase == Phase.SummaryGeneration)
					newWorks.add(new NodeWork(initialNode, nextNode, new EdgeList(work.getTraversedEdges(), currentEdge), newConstraints, edgeType));
				else
					newWorks.add(new NodeWork(initialNode, nextNode, newConstraints, edgeType));
@@ -160,14 +149,4 @@ public class ConstrainedAlgorithm implements SlicingAlgorithm
		return newWorks;
	}

	private boolean isArgumentOut(Node node) {
		if (node.getType() == Node.Type.Result
				&& edg.getNodeFromRes(node).getType() == Node.Type.Call) {
			List<Node> nodes = edg.getNodes(node, Direction.Backwards, Edge.Type.Value);
			for (Node n : nodes)
				if (n.equals(edg.getNodeFromRes(node)))
					return true;
		}
		return false;
	}
}
+4 −4
Original line number Diff line number Diff line
@@ -8,14 +8,15 @@ import java.util.*;
/**
 * Constraind tabular algorithm with subsumption.
 * It uses stack ordering to disallow insertion into pathEdge and workList if a subsuming
 * stack is included in them already.
 * stack is included in them already. Additionally, it implements pathEdge using a priority
 * queue based on stack size, which reduces unnecessary traversals with later-subsumed works.
 * @see ConstrainedTabularAlgorithm
 */
public class ConstrainedSubsumedTabularAlgorithm extends ConstrainedTabularAlgorithm {

    /** Lookup map for subsumption, to be able to search by
     *  context-current.node-lastEdgeType (current.stack=null in all keys). */
    protected Map<Work, Set<Work>> subLookupMap;
    protected final Map<Work, Set<Work>> subLookupMap = new HashMap<>();

    public ConstrainedSubsumedTabularAlgorithm(EDG edg) {
        super(edg);
@@ -23,8 +24,7 @@ public class ConstrainedSubsumedTabularAlgorithm extends ConstrainedTabularAlgor

    @Override
    public Set<Node> slice(Node node) {
        subLookupMap = new HashMap<>();
        current2worksMap = new HashMap<>();
        subLookupMap.clear();
        return super.slice(node);
    }

+7 −14
Original line number Diff line number Diff line
@@ -34,10 +34,10 @@ public class ConstrainedTabularAlgorithm implements SlicingAlgorithm {
    protected final EDG edg;

    /** Works that haven't been processed yet, always a subset of {@link #pathEdge}. */
    protected PriorityQueue<Work> workList;
    protected final PriorityQueue<Work> workList = new PriorityQueue<>();
    /** Works that have been reached throughout the traversal. */
    protected Set<Work> pathEdge;
    protected Map<State, Set<Work>> current2worksMap;
    protected final Set<Work> pathEdge = new HashSet<>();
    protected final Map<State, Set<Work>> current2worksMap = new HashMap<>();

    public ConstrainedTabularAlgorithm(EDG edg) {
        this.edg = edg;
@@ -45,22 +45,15 @@ public class ConstrainedTabularAlgorithm implements SlicingAlgorithm {

    @Override
    public Set<Node> slice(Node node) {
        workList = new PriorityQueue<>();
        pathEdge = new HashSet<>();
        current2worksMap = new HashMap<>();
        summaryEdges.clear();
        workList.clear();
        pathEdge.clear();
        current2worksMap.clear();
        propagate(new Work(new State(node, new Constraints())));
        workTheList();
        return pathEdge.stream().map(w -> w.current.node).collect(Collectors.toSet());
    }

    /**
     * If you run this algorithm multiple times, some summaries will be precomputed.
     * You can create new objects of this class or run this method.
     */
    public void clearState() {
        summaryEdges.clear();
    }

    /**
     * Add a new Work to be processed, only if it hasn't been visited before.
     */
Loading