diff --git a/.gitignore b/.gitignore index 5ad0476..a2f359a 100644 --- a/.gitignore +++ b/.gitignore @@ -175,6 +175,7 @@ vm/shared/xic *.typed *.ir *.s +*.dot ## Misc ignores # Platform-specific and editor temporaries diff --git a/src/main/java/edu/cornell/cs/cs4120/xic/ir/visit/CopyPropagationVisitor.java b/src/main/java/edu/cornell/cs/cs4120/xic/ir/visit/CopyPropagationVisitor.java index a60f3e4..c81fced 100644 --- a/src/main/java/edu/cornell/cs/cs4120/xic/ir/visit/CopyPropagationVisitor.java +++ b/src/main/java/edu/cornell/cs/cs4120/xic/ir/visit/CopyPropagationVisitor.java @@ -4,6 +4,7 @@ import edu.cornell.cs.cs4120.xic.ir.dfa.IRGraph; import edu.cornell.cs.cs4120.xic.ir.dfa.ReachingDefnsDFA; import kc875.cfg.Graph; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -22,7 +23,7 @@ public CopyPropagationVisitor() { } public IRCompUnit propagateCopies(IRCompUnit irnode) { IRCompUnit optimizedCompUnit = new IRCompUnit(irnode.name()); for (IRFuncDecl funcDecl : irnode.functions().values()) { - irGraph = IRGraph.buildCFG(funcDecl); + irGraph = new IRGraph(funcDecl); //TODO: is reaching definitions analysis necessary here? ReachingDefnsDFA reachingDefnsDFA = new ReachingDefnsDFA(irGraph); reachingDefnsDFA.runWorklistAlgo(); diff --git a/src/main/java/kc875/asm/ASMExprName.java b/src/main/java/kc875/asm/ASMExprName.java index b0780a6..e341355 100644 --- a/src/main/java/kc875/asm/ASMExprName.java +++ b/src/main/java/kc875/asm/ASMExprName.java @@ -34,4 +34,11 @@ public boolean equals(Object obj) { public Set vars() { return new HashSet<>(); } + + /** + * Returns true if this is for a function, false otherwise. + */ + public boolean isFunction() { + return name.startsWith("_I"); // based on the ABI spec + } } diff --git a/src/main/java/kc875/asm/dfa/ASMGraph.java b/src/main/java/kc875/asm/dfa/ASMGraph.java index a178864..30ce5bc 100644 --- a/src/main/java/kc875/asm/dfa/ASMGraph.java +++ b/src/main/java/kc875/asm/dfa/ASMGraph.java @@ -23,10 +23,8 @@ public class ASMGraph extends Graph { ASMOpCode.JGE, ASMOpCode.JL, ASMOpCode.JLE, - ASMOpCode.JNE, - ASMOpCode.RET, - ASMOpCode.CALL - ) // TODO + ASMOpCode.JNE + ) ); /** @@ -45,11 +43,12 @@ public ASMGraph(List instrs) { // set the start node Iterator iter = instrs.iterator(); Node previous = new Node(iter.next()); + setStartNode(previous); while (iter.hasNext()) { ASMInstr instr = iter.next(); Node node = new Node(instr); - this.addOtherNode(node); + addOtherNode(node); nodeInstrMap.put(node, instr); if (instr instanceof ASMInstrLabel) { @@ -58,29 +57,33 @@ public ASMGraph(List instrs) { // add an edge from the previous instruction's node if we need to if (hasEdgeToNextInstr(previous.getT())) { - this.addEdge(previous, node); + addEdge(previous, node); } previous = node; } // SECOND PASS: add CFG edges for jumps to labelled nodes - for (Node node : this.getAllNodes()) { + for (Node node : getAllNodes()) { ASMInstr instr = node.getT(); if (!jumps.contains(instr.getOpCode())) { - // this instr is not a jump node, continue to next node + // instr is not a jump node, continue to next node continue; } // we need to add another edge to the jumped-to node! if (instr instanceof ASMInstr_1Arg) { // TODO: change for A7 since we'll be able to jump to non-labels - ASMExprName label = (ASMExprName) ((ASMInstr_1Arg) instr).getArg(); + ASMExprName arg = (ASMExprName) ((ASMInstr_1Arg) instr).getArg(); + // If the arg is not for a function, then we can jump to it + // inside this function // get the node we jump to and add an edge to it - Node to = labelToNodeMap.get(label.getName()); - this.addEdge(node, to); + if (!arg.isFunction()) { + Node to = labelToNodeMap.get(arg.getName()); + addEdge(node, to); + } } else { throw new InternalCompilerError("Jmp instructions can't be " + "2Arg"); diff --git a/src/main/java/kc875/cfg/Graph.java b/src/main/java/kc875/cfg/Graph.java index 26315d7..db8b1c5 100644 --- a/src/main/java/kc875/cfg/Graph.java +++ b/src/main/java/kc875/cfg/Graph.java @@ -3,6 +3,7 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.Sets; +import org.apache.commons.io.FilenameUtils; import java.io.FileWriter; import java.io.IOException; @@ -87,6 +88,15 @@ public boolean comesFrom(Node n) { public boolean isAdj(Node n) { return in.contains(n) || out.contains(n); } + + @Override + public String toString() { + return "Node{" + + "t=" + t + + ", in=" + in + + ", out=" + out + + '}'; + } } private Node startNode; @@ -163,9 +173,12 @@ public void show(String path) throws IOException { } // Write prologue - String INDENT_TAB = " "; + String INDENT_TAB = "\t"; FileWriter f = new FileWriter(path); - f.write("digraph " + path + "\n"); + String rawPath = FilenameUtils.getName( + FilenameUtils.removeExtension(path) + ); + f.write("digraph " + rawPath + " {\n"); f.write(INDENT_TAB + "node [shape=record];\n"); f.write("\n"); @@ -188,8 +201,6 @@ public void show(String path) throws IOException { } f.write("\n"); - BiMap idNodeMap = nodeIDMap.inverse(); - Set visited = new HashSet<>(); Stack unvisited = new Stack<>(); unvisited.push(startNode); diff --git a/src/main/java/kc875/cli/CLIUtils.java b/src/main/java/kc875/cli/CLIUtils.java index 72530b7..44a5010 100644 --- a/src/main/java/kc875/cli/CLIUtils.java +++ b/src/main/java/kc875/cli/CLIUtils.java @@ -45,7 +45,7 @@ static void fileoutError(String outputFilePath, String errMessage) { static void fileoutIRPhase(IRNode ir, OptimPhases p, String path) throws Exception { // Get output file name and write the IR - String fName = path + "_initial.ir"; + String fName = path + "_" + p.toString().toLowerCase() + ".ir"; FileWriter writer = new FileWriter(fName); OptimalCodeWriter cw = new OptimalCodeWriter(writer, 80); CodeWriterSExpPrinter printer = new CodeWriterSExpPrinter(cw);