Homework B (benchmarks)

This commit is contained in:
Carlos Galindo 2020-01-15 22:38:07 +01:00
commit 76fbabdf53
Signed by: kauron
GPG key ID: 83E68706DEE119A3
141 changed files with 7540 additions and 2032 deletions

View file

@ -0,0 +1,60 @@
package cd.util;
import cd.ir.BasicBlock;
import cd.ir.ControlFlowGraph;
import java.util.*;
/**
* A potentially handy iterator which yields the blocks in a control-flow
* graph. The order is pre-order, depth-first. Pre-order means that a
* node is visited before its successors.
*/
public class DepthFirstSearchPreOrder implements Iterable<BasicBlock> {
public final ControlFlowGraph cfg;
public DepthFirstSearchPreOrder(ControlFlowGraph cfg) {
this.cfg = cfg;
}
public Iterator<BasicBlock> iterator() {
return new Iterator<BasicBlock>() {
/** Blocks we still need to visit */
private final Stack<BasicBlock> stack = new Stack<BasicBlock>();
/** Blocks we pushed thus far */
private final Set<BasicBlock> pushed = new HashSet<BasicBlock>();
{
stack.add(cfg.start);
pushed.add(cfg.start);
}
public boolean hasNext() {
return !stack.isEmpty();
}
public BasicBlock next() {
if (stack.isEmpty())
throw new NoSuchElementException();
BasicBlock res = stack.pop();
for (BasicBlock s : res.successors)
if (!pushed.contains(s)) {
pushed.add(s);
stack.add(s);
}
return res;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}

View file

@ -9,12 +9,12 @@ public class FileUtil {
public static String readAll(Reader ubReader) throws IOException {
try (BufferedReader bReader = new BufferedReader(ubReader)) {
StringBuilder sb = new StringBuilder();
while (true) {
int ch = bReader.read();
if (ch == -1)
break;
sb.append((char) ch);
}
return sb.toString();
@ -32,7 +32,7 @@ public class FileUtil {
}
public static String runCommand(File dir, String[] command,
String[] substs, String input, boolean detectError)
String[] substs, String input, boolean detectError)
throws IOException {
// Substitute the substitution strings $0, $1, etc
String newCommand[] = new String[command.length];
@ -53,12 +53,12 @@ public class FileUtil {
osw.write(input);
}
}
try {
final StringBuffer result = new StringBuffer();
// thread to read stdout from child so that p.waitFor() is interruptible
// by JUnit's timeout mechanism. Otherwise it would block in readAll()
Thread t = new Thread () {
Thread t = new Thread() {
public void run() {
try {
result.append(readAll(new InputStreamReader(p.getInputStream())));
@ -67,7 +67,7 @@ public class FileUtil {
}
};
t.start();
if (detectError) {
int err = p.waitFor();
@ -76,7 +76,7 @@ public class FileUtil {
if (err != 0)
return "Error: " + err + "\n";
}
t.join();
return result.toString();
} catch (InterruptedException e) {
@ -94,13 +94,15 @@ public class FileUtil {
public static void findJavaliFiles(File testDir, List<Object[]> result) {
for (File testFile : testDir.listFiles()) {
if (testFile.getName().endsWith(".javali"))
result.add(new Object[] { testFile });
result.add(new Object[]{testFile});
else if (testFile.isDirectory())
findJavaliFiles(testFile, result);
}
}
/** Finds all .javali under directory {@code testDir} and returns them. */
/**
* Finds all .javali under directory {@code testDir} and returns them.
*/
public static List<File> findJavaliFiles(File testDir) {
List<File> result = new ArrayList<File>();
for (File testFile : testDir.listFiles()) {

View file

@ -3,16 +3,18 @@ package cd.util;
import java.util.ArrayList;
import java.util.List;
/** Simple class for joining two objects of the same type */
/**
* Simple class for joining two objects of the same type
*/
public class Pair<T> {
public T a;
public T b;
public Pair(T a, T b) {
this.a = a;
this.b = b;
}
public static <T> List<Pair<T>> zip(List<T> listA, List<T> listB) {
List<Pair<T>> res = new ArrayList<Pair<T>>();
for (int i = 0; i < Math.min(listA.size(), listB.size()); i++) {
@ -20,24 +22,24 @@ public class Pair<T> {
}
return res;
}
public static <T> List<T> unzipA(List<Pair<T>> list) {
List<T> res = new ArrayList<T>();
for (Pair<T> p : list)
res.add(p.a);
return res;
}
public static <T> List<T> unzipB(List<Pair<T>> list) {
List<T> res = new ArrayList<T>();
for (Pair<T> p : list)
res.add(p.b);
return res;
}
public static String join(
List<Pair<?>> pairs,
String itemSep,
List<Pair<?>> pairs,
String itemSep,
String pairSep) {
StringBuilder sb = new StringBuilder();
boolean first = true;

View file

@ -1,15 +1,17 @@
package cd.util;
/** Simple class for joining two objects of different type */
public class Tuple<A,B> {
/**
* Simple class for joining two objects of different type
*/
public class Tuple<A, B> {
public A a;
public B b;
public Tuple(A a, B b) {
this.a = a;
this.b = b;
}
public String toString() {
return "(" + a.toString() + ", " + b.toString() + ")";
}

View file

@ -8,11 +8,11 @@ import java.lang.reflect.Field;
import java.util.*;
public class AstDump {
public static String toString(Ast ast) {
return toString(ast, "");
}
public static String toString(List<? extends Ast> astRoots) {
StringBuilder sb = new StringBuilder();
for (Ast a : astRoots) {
@ -26,22 +26,22 @@ public class AstDump {
ad.dump(ast, indent);
return ad.sb.toString();
}
public static String toStringFlat(Ast ast) {
AstDump ad = new AstDump();
ad.dumpFlat(ast);
return ad.sb.toString();
}
private StringBuilder sb = new StringBuilder();
private Visitor vis = new Visitor();
protected void dump(Ast ast, String indent) {
// print out the overall class structure
sb.append(indent);
String nodeName = ast.getClass().getSimpleName();
List<Pair<?>> flds = vis.visit(ast, null);
sb.append(String.format("%s (%s)\n",
sb.append(String.format("%s (%s)\n",
nodeName,
Pair.join(flds, ": ", ", ")));
@ -51,11 +51,11 @@ public class AstDump {
dump(child, newIndent);
}
}
protected void dumpFlat(Ast ast) {
String nodeName = ast.getClass().getSimpleName();
List<Pair<?>> flds = vis.visit(ast, null);
sb.append(String.format("%s(%s)[",
sb.append(String.format("%s(%s)[",
nodeName,
Pair.join(flds, ":", ",")));
@ -68,39 +68,39 @@ public class AstDump {
sb.append("]");
}
protected class Visitor extends AstVisitor<List<Pair<?>>, Void> {
@Override
protected List<Pair<?>> dflt(Ast ast, Void arg) {
ArrayList<Pair<?>> res = new ArrayList<Pair<?>>();
// Get the list of fields and sort them by name:
java.lang.Class<? extends Ast> rclass = ast.getClass();
List<java.lang.reflect.Field> rflds =
Arrays.asList(rclass.getFields());
Collections.sort(rflds, new Comparator<java.lang.reflect.Field> () {
List<java.lang.reflect.Field> rflds =
Arrays.asList(rclass.getFields());
Collections.sort(rflds, new Comparator<java.lang.reflect.Field>() {
public int compare(Field o1, Field o2) {
return o1.getName().compareTo(o2.getName());
}
});
// Create pairs for each one that is not of type Ast:
for (java.lang.reflect.Field rfld : rflds) {
rfld.setAccessible(true);
// ignore various weird fields that show up from
// time to time:
if (rfld.getName().startsWith("$"))
continue;
// ignore fields of AST type, and rwChildren (they should be
// uncovered using the normal tree walk)
if (rfld.getType().isAssignableFrom(Ast.class))
continue;
if (rfld.getName().equals("rwChildren"))
continue;
// ignore NULL fields, but add others to our list of pairs
try {
Object value = rfld.get(ast);
@ -110,12 +110,12 @@ public class AstDump {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
return res;
}
}
}

View file

@ -5,13 +5,13 @@ import cd.ir.Ast.*;
import cd.ir.AstVisitor;
public class AstOneLine {
public static String toString(Ast ast) {
return new Visitor().visit(ast, null);
}
protected static class Visitor extends AstVisitor<String, Void> {
public String str(Ast ast) {
return ast.accept(this, null);
}
@ -23,7 +23,7 @@ public class AstOneLine {
@Override
public String binaryOp(BinaryOp ast, Void arg) {
return String.format("(%s %s %s)",
return String.format("(%s %s %s)",
str(ast.left()), ast.operator.repr, str(ast.right()));
}
@ -36,12 +36,12 @@ public class AstOneLine {
public String builtInRead(BuiltInRead ast, Void arg) {
return String.format("read()");
}
@Override
public String builtInWrite(BuiltInWrite ast, Void arg) {
return String.format("write(%s)", str(ast.arg()));
}
@Override
public String builtInWriteln(BuiltInWriteln ast, Void arg) {
return String.format("writeln()");
@ -81,12 +81,12 @@ public class AstOneLine {
public String methodCall(MethodCall ast, Void arg) {
return str(ast.getMethodCallExpr());
}
@Override
public String methodCall(MethodCallExpr ast, Void arg) {
return String.format("%s.%s(...)", str(ast.receiver()), ast.methodName);
}
@Override
public String methodDecl(MethodDecl ast, Void arg) {
return String.format("%s %s(...) {...}", ast.returnType, ast.name);
@ -121,7 +121,7 @@ public class AstOneLine {
public String thisRef(ThisRef ast, Void arg) {
return "this";
}
@Override
public String returnStmt(ReturnStmt ast, Void arg) {
return ast.arg() != null ? String.format("return %s", str(ast.arg())) : "return";
@ -136,10 +136,10 @@ public class AstOneLine {
public String var(Var ast, Void arg) {
{
if (ast.sym != null) {
String symName = ast.sym.toString();
String symName = ast.sym.toString();
if (ast.name == null || ast.name.equals(symName))
return symName;
// Return something strange to warn about the mismatch here:
return String.format("(%s!=%s)", symName, ast.name);
} else
@ -156,6 +156,6 @@ public class AstOneLine {
public String whileLoop(WhileLoop ast, Void arg) {
return String.format("while (%s) {...}", str(ast.condition()));
}
}
}

View file

@ -0,0 +1,156 @@
package cd.util.debug;
import cd.ir.Ast.ClassDecl;
import cd.ir.Ast.MethodDecl;
import cd.ir.Ast.Stmt;
import cd.ir.BasicBlock;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class CfgDump {
public static void toString(
MethodDecl mdecl,
String phase,
File filename,
boolean dumpDominators) {
if (filename == null) return;
FileWriter fw;
try {
fw = new FileWriter(new File(filename.getAbsolutePath() + phase + ".dot"));
fw.write(toString(mdecl, dumpDominators));
fw.close();
} catch (IOException e) {
}
}
public static void toString(
List<? extends ClassDecl> astRoots,
String phase,
File filename,
boolean dumpDominators) {
if (filename == null) return;
FileWriter fw;
try {
fw = new FileWriter(new File(filename.getAbsolutePath() + phase + ".dot"));
fw.write(toString(astRoots, dumpDominators));
fw.close();
} catch (IOException e) {
}
}
public static String toString(
List<? extends ClassDecl> astRoots,
boolean dumpDominators) {
return new CfgDump().dump(astRoots, dumpDominators);
}
public static String toString(
MethodDecl mdecl,
boolean dumpDominators) {
return new CfgDump().dump(mdecl, dumpDominators);
}
private int indent = 0;
private final StringBuilder sb = new StringBuilder();
private void append(String format, Object... args) {
String out = String.format(format, args);
if (out.startsWith("}") || out.startsWith("]")) indent -= 2;
for (int i = 0; i < indent; i++) sb.append(" ");
if (out.endsWith("{") || out.endsWith("[")) indent += 2;
sb.append(String.format(format, args));
sb.append("\n");
}
private String dump(
MethodDecl mdecl,
boolean dumpDominators) {
sb.setLength(0);
append("digraph G {");
append("graph [ rankdir = \"LR\" ];");
dumpBlocks(dumpDominators, mdecl, "");
append("}");
return sb.toString();
}
private String dump(
List<? extends ClassDecl> astRoots,
boolean dumpDominators) {
sb.setLength(0);
append("digraph G {");
append("graph [ rankdir = \"LR\" ];");
int sgcntr = 0, mcntr = 0;
for (ClassDecl cdecl : astRoots) {
//append("subgraph cluster_%d {", sgcntr++);
//append("label = \"%s\";", cdecl.name);
for (MethodDecl mdecl : cdecl.methods()) {
append("subgraph cluster_%d {", sgcntr++);
append("label = \"%s.%s\"", cdecl.name, mdecl.name);
String m = String.format("M%d_", mcntr++);
dumpBlocks(dumpDominators, mdecl, m);
append("}");
}
//append("}");
}
append("}");
return sb.toString();
}
private void dumpBlocks(boolean dumpDominators, MethodDecl mdecl, String m) {
for (BasicBlock blk : mdecl.cfg.allBlocks) {
append("%sBB%d [", m, blk.index);
append("shape=\"record\"");
// If we are not just dumping dominators, then build up
// a label with all the instructions in the block.
StringBuilder blklbl = new StringBuilder();
blklbl.append(String.format("BB%d", blk.index));
if (!dumpDominators || true) {
for (Stmt stmt : blk.stmts)
blklbl.append("|").append(AstOneLine.toString(stmt));
if (blk.condition != null)
blklbl.append("|If: " + AstOneLine.toString(blk.condition));
}
String[] replacements = new String[]{
"<", "\\<",
">", "\\>",
"@", "\\@",
"||", "\\|\\|",
};
String blklbls = blklbl.toString();
for (int i = 0; i < replacements.length; i += 2)
blklbls = blklbls.replace(replacements[i], replacements[i + 1]);
append("label=\"%s\"", blklbls);
append("];");
for (int idx = 0; idx < blk.successors.size(); idx++) {
BasicBlock sblk = blk.successors.get(idx);
String edgelbl = (idx == 0 ? "" : " [label=\"False\"]");
append("%sBB%d -> %sBB%d%s;",
m, blk.index, m, sblk.index, edgelbl);
}
{
if (dumpDominators && blk.dominatorTreeParent != null) {
append("%sBB%d -> %sBB%d [color=\"red\" label=\"dom\"];",
m, blk.index, m, blk.dominatorTreeParent.index);
}
}
}
}
}

View file

@ -11,13 +11,13 @@ import java.util.Set;
import static java.util.Collections.sort;
class DumpUtils {
static final Comparator<ClassDecl> classComparator = new Comparator<ClassDecl>() {
public int compare(ClassDecl left, ClassDecl right) {
return left.name.compareTo(right.name);
}
};
static final Comparator<MethodDecl> methodComparator = new Comparator<MethodDecl>() {
public int compare(MethodDecl left, MethodDecl right) {
return left.name.compareTo(right.name);
@ -26,7 +26,7 @@ class DumpUtils {
static List<String> sortedStrings(Set<?> set) {
List<String> strings = new ArrayList<String>();
for(Object element : set)
for (Object element : set)
strings.add(element.toString());
sort(strings);
return strings;