Index: pkg/kernel/test/type_propagation_dump.dart |
diff --git a/pkg/kernel/test/type_propagation_dump.dart b/pkg/kernel/test/type_propagation_dump.dart |
deleted file mode 100644 |
index 5af3f105a194d4b8d01ca35d21e430189ab19e47..0000000000000000000000000000000000000000 |
--- a/pkg/kernel/test/type_propagation_dump.dart |
+++ /dev/null |
@@ -1,188 +0,0 @@ |
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
-library kernel.type_propagation.dump; |
- |
-import 'package:kernel/kernel.dart'; |
-import 'package:kernel/text/ast_to_text.dart'; |
-import 'package:kernel/type_propagation/builder.dart'; |
-import 'package:kernel/type_propagation/solver.dart'; |
-import 'package:kernel/type_propagation/visualizer.dart'; |
-import 'package:kernel/type_propagation/constraints.dart'; |
-import 'package:kernel/type_propagation/type_propagation.dart'; |
-import 'package:args/args.dart'; |
-import 'dart:io'; |
- |
-ArgParser parser = new ArgParser() |
- ..addFlag('graph', help: 'Generate graphviz dot files') |
- ..addOption('graph-filter', |
- valueHelp: 'name', |
- help: 'Only print graph for members whose name contains the given string') |
- ..addFlag('text', help: 'Generate annotated kernel text files') |
- ..addFlag('escape', help: 'Dump information from escape analysis') |
- ..addFlag('stats', |
- help: 'Print times and constraint system size', defaultsTo: true) |
- ..addFlag('solve', help: 'Solve the constraint system', defaultsTo: true); |
- |
-String get usage => """ |
-Usage: dump [options] FILE.dill |
- |
-Options: |
-${parser.usage} |
-"""; |
- |
-const String outputDir = 'typegraph'; |
- |
-main(List<String> args) { |
- if (args.length == 0) { |
- print(usage); |
- exit(1); |
- } |
- ArgResults options = parser.parse(args); |
- if (options.rest.length != 1) { |
- print('Exactly one file must be given'); |
- exit(1); |
- } |
- String path = options.rest.single; |
- |
- bool printGraphviz = options['graph']; |
- bool printText = options['text']; |
- bool printEscape = options['escape']; |
- bool useVisualizer = printGraphviz || printText || printEscape; |
- |
- Program program = loadProgramFromBinary(path); |
- Stopwatch watch = new Stopwatch()..start(); |
- Visualizer visualizer = useVisualizer ? new Visualizer(program) : null; |
- Builder builder = new Builder(program, visualizer: visualizer, verbose: true); |
- int buildTime = watch.elapsedMilliseconds; |
- |
- watch.reset(); |
- var solver = new Solver(builder); |
- if (options['solve']) { |
- solver.solve(); |
- } |
- int solveTime = watch.elapsedMilliseconds; |
- visualizer?.solver = solver; |
- ConstraintSystem constraints = builder.constraints; |
- |
- if (printEscape) { |
- for (int value = 0; value <= constraints.numberOfValues; ++value) { |
- TreeNode node; |
- if (value < builder.hierarchy.classes.length) { |
- node = builder.hierarchy.classes[value]; |
- } else { |
- FunctionNode function = visualizer.getFunctionFromValue(value); |
- if (function == null || function.parent is! Member) continue; |
- node = function.parent; |
- } |
- int escape = solver.getEscapeContext(value); |
- String escapeString = (escape == constraints.latticePointOfValue[value]) |
- ? 'no escape' |
- : visualizer.getLatticePointName(escape); |
- print('$node -> $escapeString'); |
- } |
- } |
- |
- if (printText) { |
- print('Printing kernel text files...'); |
- new Directory(outputDir).createSync(); |
- StringBuffer buffer = new StringBuffer(); |
- Printer printer = |
- new Printer(buffer, annotator: visualizer.getTextAnnotator()); |
- printer.writeProgramFile(program); |
- String path = '$outputDir/program.txt'; |
- new File(path).writeAsStringSync('$buffer'); |
- } |
- |
- if (printGraphviz) { |
- print('Printing graphviz dot files...'); |
- String filter = options['graph-filter']; |
- new Directory(outputDir).createSync(); |
- void dumpMember(Member member) { |
- if (filter != null && !'$member'.contains(filter)) return; |
- String name = sanitizeFilename('$member'); |
- String path = '$outputDir/$name.dot'; |
- String dotCode = visualizer.dumpMember(member); |
- new File(path).writeAsStringSync(dotCode); |
- } |
- |
- for (var library in program.libraries) { |
- library.members.forEach(dumpMember); |
- for (var class_ in library.classes) { |
- class_.members.forEach(dumpMember); |
- } |
- } |
- } |
- |
- if (options['stats']) { |
- var constraints = solver.constraints; |
- int numberOfConstraints = constraints.numberOfAssignments + |
- constraints.numberOfLoads + |
- constraints.numberOfStores; |
- int numberOfTransfers = numberOfConstraints * solver.iterations; |
- double transfersPerSecond = |
- (numberOfConstraints * solver.iterations) / (solveTime / 1000); |
- Iterable<int> outputVariables = [ |
- builder.global.fields.values, |
- builder.global.returns.values, |
- builder.global.parameters.values |
- ].expand((x) => x); |
- int outputCount = outputVariables.length; |
- int inferredUnknown = 0; |
- int inferredNothing = 0; |
- int inferredNullable = 0; |
- int inferredNonNullable = 0; |
- int inferredOnlyNull = 0; |
- for (int variable in outputVariables) { |
- int values = solver.getVariableValue(variable); |
- int bitmask = solver.getVariableBitmask(variable); |
- if (values == Solver.bottom && bitmask == 0) { |
- ++inferredNothing; |
- } else if (values == Solver.bottom && bitmask == ValueBit.null_) { |
- ++inferredOnlyNull; |
- } else if (values == Solver.rootClass && bitmask == ValueBit.all) { |
- ++inferredUnknown; |
- } else if (bitmask & ValueBit.null_ != 0) { |
- ++inferredNullable; |
- } else { |
- ++inferredNonNullable; |
- } |
- } |
- print(""" |
-Build time: $buildTime ms |
-Solve time: $solveTime ms |
-Iterations: ${solver.iterations} |
- |
-Classes: ${builder.hierarchy.classes.length} |
-Values: ${constraints.numberOfValues} |
-Unions: ${constraints.numberOfLatticePoints} |
-Variables: ${constraints.numberOfVariables} |
-Fields: ${builder.fieldNames.length} |
-Assignments: ${constraints.numberOfAssignments} |
-Loads: ${constraints.numberOfLoads} |
-Stores: ${constraints.numberOfStores} |
- |
-Transfers: $numberOfTransfers (${(transfersPerSecond / 1000000).toStringAsFixed(1)} M/s) |
- |
-Outputs: $outputCount |
-Unknown: $inferredUnknown (${percent(inferredUnknown, outputCount)}) |
-Nullable: $inferredNullable (${percent(inferredNullable, outputCount)}) |
-Non-nullable: $inferredNonNullable (${percent(inferredNonNullable, outputCount)}) |
-Only null: $inferredOnlyNull (${percent(inferredOnlyNull, outputCount)}) |
-Nothing: $inferredNothing (${percent(inferredNothing, outputCount)}) |
- """); |
- } |
-} |
- |
-String percent(int amount, int total) { |
- if (total == 0) return '0%'; |
- return (amount / total * 100).toStringAsFixed(1) + '%'; |
-} |
- |
-String sanitizeFilename(String name) { |
- return name |
- .replaceAll('::', '.') |
- .replaceAll('/', r'$div') |
- .replaceAll('(', '') |
- .replaceAll(')', ''); |
-} |