Skip to content
Snippets Groups Projects
Commit 17af8cad authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Small fixes

* Tests creates the root node of the PDG
* Data dependency ignores nonexecutable edges
* Non-executable edges are displayed as dashed
* Small bug in the implementation of `CFGBuilder`
parent 07fe208e
No related branches found
No related tags found
1 merge request!16Add more graphs and generalize CFG and control dependence creation
...@@ -12,10 +12,6 @@ import java.util.Map; ...@@ -12,10 +12,6 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
public abstract class Arc extends DefaultEdge { public abstract class Arc extends DefaultEdge {
public Arc() {
}
/** @see tfm.arcs.cfg.ControlFlowArc */ /** @see tfm.arcs.cfg.ControlFlowArc */
public final boolean isControlFlowArc() { public final boolean isControlFlowArc() {
return this instanceof ControlFlowArc; return this instanceof ControlFlowArc;
......
package tfm.arcs.cfg; package tfm.arcs.cfg;
import org.jgrapht.io.Attribute;
import org.jgrapht.io.DefaultAttribute;
import tfm.arcs.Arc; import tfm.arcs.Arc;
import tfm.graphs.augmented.ACFG; import tfm.graphs.augmented.ACFG;
import java.util.Map;
/** /**
* An edge of the {@link tfm.graphs.CFG}, representing the direct * An edge of the {@link tfm.graphs.CFG}, representing the direct
* flow of control. It connects two instructions if, when the source * flow of control. It connects two instructions if, when the source
* is executed, one of the possible next instructions is the destination. * is executed, one of the possible next instructions is the destination.
*/ */
public class ControlFlowArc extends Arc { public class ControlFlowArc extends Arc {
public ControlFlowArc() {
}
/** /**
* Represents a non-executable control flow arc, used within the {@link ACFG ACFG}. * Represents a non-executable control flow arc, used within the {@link ACFG ACFG}.
* Initially it had the following meaning: connecting a statement with * Initially it had the following meaning: connecting a statement with
...@@ -20,8 +21,12 @@ public class ControlFlowArc extends Arc { ...@@ -20,8 +21,12 @@ public class ControlFlowArc extends Arc {
* It is used to improve control dependence, and it should be skipped when * It is used to improve control dependence, and it should be skipped when
* computing data dependence and other analyses. * computing data dependence and other analyses.
*/ */
public final static class NonExecutable extends ControlFlowArc { public static final class NonExecutable extends ControlFlowArc {
public NonExecutable() { @Override
public Map<String, Attribute> getDotAttributes() {
Map<String, Attribute> map = super.getDotAttributes();
map.put("style", DefaultAttribute.createAttribute("dashed"));
return map;
} }
} }
} }
...@@ -9,6 +9,4 @@ import tfm.arcs.Arc; ...@@ -9,6 +9,4 @@ import tfm.arcs.Arc;
* {@code b} if and only if {@code b} alters the number of times {@code a} is executed. * {@code b} if and only if {@code b} alters the number of times {@code a} is executed.
*/ */
public class ControlDependencyArc extends Arc { public class ControlDependencyArc extends Arc {
public ControlDependencyArc() {
}
} }
...@@ -44,9 +44,9 @@ public class CFG extends GraphWithRootNode<MethodDeclaration> { ...@@ -44,9 +44,9 @@ public class CFG extends GraphWithRootNode<MethodDeclaration> {
Set<GraphNode<?>> res = new HashSet<>(); Set<GraphNode<?>> res = new HashSet<>();
for (Arc arc : incomingEdgesOf(currentNode)) { for (Arc arc : incomingEdgesOf(currentNode)) {
ControlFlowArc controlFlowArc = arc.asControlFlowArc(); if (!arc.isExecutableControlFlowArc())
continue;
GraphNode<?> from = this.getEdgeSource(controlFlowArc); GraphNode<?> from = getEdgeSource(arc);
if (!Objects.equals(startNode, from) && visited.contains(from.getId())) { if (!Objects.equals(startNode, from) && visited.contains(from.getId())) {
continue; continue;
......
...@@ -108,7 +108,7 @@ public class CFGBuilder extends VoidVisitorAdapter<Void> { ...@@ -108,7 +108,7 @@ public class CFGBuilder extends VoidVisitorAdapter<Void> {
hangingNodes.addAll(breakMap.remove(n.getLabel())); hangingNodes.addAll(breakMap.remove(n.getLabel()));
// Remove the label from the continue map; the list should have been emptied // Remove the label from the continue map; the list should have been emptied
// in the corresponding loop. // in the corresponding loop.
if (continueMap.remove(n.getLabel()).isEmpty()) if (!continueMap.remove(n.getLabel()).isEmpty())
throw new IllegalStateException("Labeled loop has not cleared its list of continue statements!"); throw new IllegalStateException("Labeled loop has not cleared its list of continue statements!");
} }
......
...@@ -82,6 +82,7 @@ public class PDGTests { ...@@ -82,6 +82,7 @@ public class PDGTests {
CFG cfg = new CFG(); CFG cfg = new CFG();
cfg.build(root); cfg.build(root);
PDG pdg = new PDG(cfg); PDG pdg = new PDG(cfg);
pdg.buildRootNode("ENTER " + methodName, root);
ctrlDepBuilder = new ControlDependencyBuilder(pdg, cfg); ctrlDepBuilder = new ControlDependencyBuilder(pdg, cfg);
ctrlDepBuilder.analyze(); ctrlDepBuilder.analyze();
...@@ -89,11 +90,13 @@ public class PDGTests { ...@@ -89,11 +90,13 @@ public class PDGTests {
ACFG acfg = new ACFG(); ACFG acfg = new ACFG();
acfg.build(root); acfg.build(root);
APDG apdg = new APDG(acfg); APDG apdg = new APDG(acfg);
apdg.buildRootNode("ENTER " + methodName, root);
ctrlDepBuilder = new ControlDependencyBuilder(apdg, acfg); ctrlDepBuilder = new ControlDependencyBuilder(apdg, acfg);
ctrlDepBuilder.analyze(); ctrlDepBuilder.analyze();
// Create PPDG // Create PPDG
PPDG ppdg = new PPDG(acfg); PPDG ppdg = new PPDG(acfg);
ppdg.buildRootNode("ENTER " + methodName, root);
ctrlDepBuilder = new ControlDependencyBuilder(ppdg, acfg); ctrlDepBuilder = new ControlDependencyBuilder(ppdg, acfg);
ctrlDepBuilder.analyze(); ctrlDepBuilder.analyze();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment