summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbd-912 <bdunahu@colostate.edu>2024-04-20 18:22:49 -0600
committerbd-912 <bdunahu@colostate.edu>2024-04-20 18:22:49 -0600
commit35eae1492c94e353ba8a1a52bfbae9313808b357 (patch)
treeeb30b12ae142a23a9837cfd097c1556828c95c44
parent38ef4ec52804876ba0a3daef3a2d1817f17bc1e5 (diff)
CFG Class cleanup/reordering
-rw-r--r--V2VM.java2
-rw-r--r--cfg/CFGNode.java73
-rw-r--r--cfg/ControlFlowGraph.java (renamed from vaporize/library/ControlFlowGraph.java)64
-rw-r--r--vaporize/library/CFGNode.java95
-rw-r--r--vaporize/library/CFGSimp.java72
5 files changed, 142 insertions, 164 deletions
diff --git a/V2VM.java b/V2VM.java
index 5d78381..3d181dd 100644
--- a/V2VM.java
+++ b/V2VM.java
@@ -13,7 +13,7 @@ import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintStream;
-import st.*;
+import cfg.*;
import misc.*;
import vaporize.library.*;
diff --git a/cfg/CFGNode.java b/cfg/CFGNode.java
new file mode 100644
index 0000000..e604753
--- /dev/null
+++ b/cfg/CFGNode.java
@@ -0,0 +1,73 @@
+package cfg;
+
+import misc.*;
+import cs132.vapor.ast.*;
+
+import java.util.*;
+
+public class CFGNode {
+
+ private Node instruction;
+ private ArrayList<CFGNode> sources;
+ private ArrayList<CFGNode> dests;
+ protected Set<String> reaching;
+ protected Set<String> liveness;
+
+ public CFGNode(Node instruction) {
+ this.instruction = instruction;
+ this.sources = new ArrayList<>();
+ this.dests = new ArrayList<>();
+ this.reaching = new HashSet<>();
+ this.liveness = new HashSet<>();
+ }
+
+ public String toString() {
+ return String.format("L%d",
+ this.instruction.sourcePos.line);
+ }
+
+ /**
+ * For if we only have a line
+ * number. (VBranch issues)
+ */
+ public boolean equals(Object other) {
+ return (other instanceof CFGNode &&
+ (((CFGNode) other).instruction ==
+ this.instruction)) ||
+ (other instanceof Node &&
+ (((Node) other).sourcePos ==
+ this.instruction.sourcePos)) ||
+ (other instanceof Integer &&
+ (((Integer) other)
+ .equals(this.instruction.sourcePos.line)));
+ }
+
+ protected void addSource(CFGNode node) {
+ this.sources.add(node);
+ }
+
+ protected void addDest(CFGNode node) {
+ this.dests.add(node);
+ }
+
+ public Node getInstruction() {
+ return this.instruction;
+ }
+
+ public List<CFGNode> getSources() {
+ return Collections.unmodifiableList(this.sources);
+ }
+
+ public List<CFGNode> getDests() {
+ return Collections.unmodifiableList(this.dests);
+ }
+
+ public Set<String> getReaching() {
+ return Collections.unmodifiableSet(this.reaching);
+ }
+
+ public Set<String> getLiveness() {
+ return Collections.unmodifiableSet(this.liveness);
+ }
+
+}
diff --git a/vaporize/library/ControlFlowGraph.java b/cfg/ControlFlowGraph.java
index 5d589fb..c8a7f16 100644
--- a/vaporize/library/ControlFlowGraph.java
+++ b/cfg/ControlFlowGraph.java
@@ -1,21 +1,22 @@
-package vaporize.library;
+package cfg;
import cs132.vapor.ast.*;
import misc.*;
import java.util.ArrayList;
+import java.util.Arrays;
public class ControlFlowGraph {
+ private VFunction f; // the function represented by this CFG
private ArrayList<CFGNode> nodes;
- private CFGNode start;
- protected ControlFlowGraph() {
+ public ControlFlowGraph(VFunction f) {
+ this.f = f;
this.nodes = new ArrayList<>();
- this.start = null;
}
- protected CFGNode getNode(Object a) {
+ public CFGNode getNode(Object a) {
CFGNode ret = null;
for (CFGNode n : this.nodes) {
if (n.equals(a)) {
@@ -33,7 +34,7 @@ public class ControlFlowGraph {
return ret;
}
- protected CFGNode getNextNode(CFGNode a) {
+ public CFGNode getNextNode(CFGNode a) {
CFGNode ret = null;
// we return null if the passed node is the last in the list
for (int i = 0; i < this.nodes.size()-1; ++i) {
@@ -51,11 +52,13 @@ public class ControlFlowGraph {
}
- protected void addNode(CFGNode node) {
- this.nodes.add(node);
+ public void addNode(CFGNode n) {
+ MinimalLogger.info(String.format("Node + %s",
+ n.toString()));
+ this.nodes.add(n);
}
- protected String addEdge(CFGNode source, CFGNode dest) {
+ public String addEdge(CFGNode source, CFGNode dest) {
/**
* Iff the CFGNodes are different, construct an edge between them.
* All variables reaching the parent also reach the children.
@@ -64,9 +67,9 @@ public class ControlFlowGraph {
*/
String ret = "";
if (!source.equals(dest)) {
- ret = String.format("%d -> %d",
- source.getInstruction().sourcePos.line,
- dest.getInstruction().sourcePos.line);
+ ret = String.format("%s -> %s",
+ source.toString(),
+ dest.toString());
MinimalLogger.info(String.format("Edge %s",
ret));
@@ -75,23 +78,48 @@ public class ControlFlowGraph {
ret += ";";
} else {
- MinimalLogger.info(String.format("Skipping duplicate edge for %d",
- source.getInstruction().sourcePos.line));
+ MinimalLogger.info(String.format("Skipping duplicate edge for %s",
+ source.toString()));
}
MinimalLogger.info(String.format("Spilling variables: %s",
source.getReaching().toString()));
- dest.getReaching().addAll(source.getReaching());
+ dest.reaching.addAll(source.reaching);
return ret;
}
- protected void setStart(CFGNode start) {
- this.start = start;
+ public void addReaching(CFGNode n, String s) {
+ MinimalLogger.info(String.format("Def \"%s\" at %s",
+ s,
+ n.toString()));
+ n.reaching.add(s);
}
- protected ArrayList<CFGNode> getNodes() {
+ public void addLiveness(CFGNode n, String s) {
+ if (this.isKnownVar(s)) {
+ MinimalLogger.info(String.format("Use \"%s\" at %s",
+ s,
+ n.toString()));
+ n.liveness.add(s);
+ } else
+ MinimalLogger.info(String.format("Use \"%s\" not a known variable!",
+ s));
+ }
+
+ public ArrayList<CFGNode> getNodes() {
return this.nodes;
}
+ protected boolean isKnownVar(String str) {
+ /**
+ * Returns true if the variable belongs to the current function.
+ * Required when matching liveness in certain instructions.
+ *
+ * Helper for addLivenessi
+ */
+ return Arrays.asList(f.vars).contains(str) ||
+ Arrays.asList(f.params).contains(str);
+ }
+
}
diff --git a/vaporize/library/CFGNode.java b/vaporize/library/CFGNode.java
deleted file mode 100644
index b23ca00..0000000
--- a/vaporize/library/CFGNode.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package vaporize.library;
-
-import misc.*;
-import cs132.vapor.ast.*;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-
-class CFGNode {
-
- private Node instruction;
- private ArrayList<CFGNode> sources;
- private ArrayList<CFGNode> dests;
- private HashSet<String> reaching;
- private HashSet<String> liveness;
- private int line;
-
- protected CFGNode(Node instruction) {
- this.instruction = instruction;
- this.sources = new ArrayList<>();
- this.dests = new ArrayList<>();
- this.reaching = new HashSet<>();
- this.liveness = new HashSet<>();
- this.line = this.instruction.sourcePos.line;
- }
-
- public String toString() {
- return this.instruction.toString();
- }
-
- /**
- * For if we only have a line
- * number. (VBranch issues)
- */
- // FIXME
- public boolean equals(Object other) {
- return (other instanceof CFGNode &&
- (((CFGNode) other).instruction ==
- this.instruction)) ||
- (other instanceof Node &&
- (((Node) other).sourcePos ==
- this.instruction.sourcePos)) ||
- (other instanceof Integer &&
- (((Integer) other)
- .equals(this.instruction.sourcePos.line)));
- }
-
- protected void addSource(CFGNode node) {
- this.sources.add(node);
- }
-
- protected void addDest(CFGNode node) {
- this.dests.add(node);
- }
-
- protected void addReaching(String add) {
- MinimalLogger.info(String.format("Def %s at %s",
- add,
- this.line));
- this.reaching.add(add);
- }
-
- protected void addLiveness(String add) {
- MinimalLogger.info(String.format("Use %s at %s",
- add,
- this.line));
- this.liveness.add(add);
- }
-
- protected Node getInstruction() {
- return this.instruction;
- }
-
- protected ArrayList<CFGNode> getSources() {
- return this.sources;
- }
-
- protected ArrayList<CFGNode> getDests() {
- return this.dests;
- }
-
- protected HashSet<String> getReaching() {
- return this.reaching;
- }
-
- protected HashSet<String> getLiveness() {
- return this.liveness;
- }
-
- protected int getLine() {
- return this.line;
- }
-
-
-}
diff --git a/vaporize/library/CFGSimp.java b/vaporize/library/CFGSimp.java
index 54ec61c..30ddc7d 100644
--- a/vaporize/library/CFGSimp.java
+++ b/vaporize/library/CFGSimp.java
@@ -2,6 +2,7 @@ package vaporize.library;
import cs132.vapor.ast.*;
import graphviz.*;
+import cfg.*;
import misc.*;
import java.io.File;
@@ -13,7 +14,6 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
private Kettle kettle;
private ArrayList<ControlFlowGraph> cfgs;
- private VFunction func; // the current function being processed
private CFGNode curr; // the current node being processed
private String dot_format; // a list of edges to be processed by graphviz
@@ -24,22 +24,15 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
for (VFunction f : vp.functions) {
- this.func = f;
- ControlFlowGraph cfg = new ControlFlowGraph();
+ ControlFlowGraph cfg = new ControlFlowGraph(f);
this.dot_format = "";
MinimalLogger.info(String.format("CFGSimp is collecting nodes for %s",
- this.kettle.parseFuncName(this.func)));
- for (VCodeLabel s : this.func.labels) {
- MinimalLogger.info(String.format("Label %d \"%s\"",
- s.sourcePos.line,
- this.kettle.get(s).trim()));
+ this.kettle.parseFuncName(f)));
+ for (VCodeLabel s : f.labels) {
cfg.addNode(new CFGNode(s));
}
- for (VInstr s : this.func.body) {
- MinimalLogger.info(String.format(" Body %d \"%s\"",
- s.sourcePos.line,
- this.kettle.get(s).trim()));
+ for (VInstr s : f.body) {
cfg.addNode(new CFGNode(s));
}
@@ -50,22 +43,21 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
// inital setup
// first visit may not find edges; cfg.addEdges will handle
this.curr = new CFGNode(f.body[0]);
- cfg.setStart(curr);
// cascades downwards --- cfg.addEdges
for (VVarRef.Local l : f.params)
- this.curr.addReaching(l.ident.toString());
- for (VInstr s : this.func.body)
+ cfg.addReaching(this.curr, l.ident.toString());
+ for (VInstr s : f.body)
s.accept(cfg, this);
MinimalLogger.info(String.format("Spitting out reaching/liveness..."));
for (CFGNode n : cfg.getNodes())
- MinimalLogger.info(String.format("%d ::: %s ::: %s",
- n.getLine(),
+ MinimalLogger.info(String.format("%s ::: %s ::: %s",
+ n.toString(),
n.getReaching(),
n.getLiveness()));
if (this.use_graphviz)
- this.createDotGraph(this.kettle.parseFuncName(this.func));
+ this.createDotGraph(this.kettle.parseFuncName(f));
this.cfgs.add(cfg);
}
@@ -92,15 +84,6 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
gv.writeGraphToFile( gv.getGraph( gv.getDotSource(), type ), out );
}
- protected boolean isKnownVar(String str) {
- /**
- * Returns true if the variable belongs to the current function.
- * Required when matching liveness in certain instructions.
- */
- return Arrays.asList(this.func.vars).contains(str) ||
- Arrays.asList(this.func.params).contains(str);
- }
-
public String visit(ControlFlowGraph cfg, VMemRead n) throws RuntimeException {
MinimalLogger.info(String.format("->%s (\"%s\":%s)",
n.getClass().getSimpleName(),
@@ -111,10 +94,8 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
this.dot_format += cfg.addEdge(this.curr, curr);
this.curr = curr;
- curr.addReaching(n.dest.toString());
- String source = ((VMemRef.Global) n.source).base.toString();
- if (isKnownVar(source))
- curr.addLiveness(source);
+ cfg.addReaching(curr, n.dest.toString());
+ cfg.addLiveness(curr, ((VMemRef.Global) n.source).base.toString());
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<-%s (\"%s\":%s)",
n.getClass().getSimpleName(),
@@ -133,9 +114,7 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
this.dot_format += cfg.addEdge(this.curr, curr);
this.curr = curr;
- String source = n.source.toString();
- if (isKnownVar(source))
- curr.addLiveness(source);
+ cfg.addLiveness(curr, n.source.toString());
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<-%s (\"%s\":%s)",
n.getClass().getSimpleName(),
@@ -154,10 +133,8 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
this.dot_format += cfg.addEdge(this.curr, curr);
this.curr = curr;
- curr.addReaching(n.dest.toString());
- String source = n.source.toString();
- if (isKnownVar(source))
- curr.addLiveness(source);
+ cfg.addReaching(curr, n.dest.toString());
+ cfg.addLiveness(curr, n.source.toString());
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<-%s (\"%s\":%s)",
n.getClass().getSimpleName(),
@@ -177,8 +154,7 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
this.dot_format += cfg.addEdge(curr, cfg.getNode(new Integer(this.kettle
.findLabelIndex(n.target.toString()))));
- this.curr = curr;
- curr.addLiveness(n.value.toString());
+ cfg.addLiveness(curr, n.value.toString());
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<-%s (\"%s\":%s)",
n.getClass().getSimpleName(),
@@ -219,11 +195,9 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
this.curr = curr;
if (n.dest != null)
- curr.addReaching(n.dest.toString());
+ cfg.addReaching(curr, n.dest.toString());
for (VOperand a : n.args) {
- String source = a.toString();
- if (isKnownVar(source))
- curr.addLiveness(source);
+ cfg.addLiveness(curr, a.toString());
}
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<-%s (\"%s\":%s)",
@@ -244,11 +218,9 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
this.curr = curr;
if (n.dest != null)
- curr.addReaching(n.dest.toString());
+ cfg.addReaching(curr, n.dest.toString());
for (VOperand a : n.args) {
- String source = a.toString();
- if (isKnownVar(source))
- curr.addLiveness(source);
+ cfg.addLiveness(curr, a.toString());
}
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<-%s (\"%s\":%s)",
@@ -268,8 +240,8 @@ public class CFGSimp extends VInstr.VisitorPR<ControlFlowGraph, String, RuntimeE
this.dot_format += cfg.addEdge(this.curr, curr);
this.curr = curr;
- if (n.value != null && isKnownVar(n.value.toString()))
- curr.addLiveness(n.value.toString());
+ if (n.value != null)
+ cfg.addLiveness(curr, n.value.toString());
///////////////////////////////////////////////////////////////
MinimalLogger.info(String.format("<-%s (\"%s\":%s)",
n.getClass().getSimpleName(),