| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Generate code using the cps-based IR pipeline. | 5 /// Generate code using the cps-based IR pipeline. |
| 6 library code_generator_task; | 6 library code_generator_task; |
| 7 | 7 |
| 8 import 'glue.dart'; | 8 import 'glue.dart'; |
| 9 import 'codegen.dart'; | 9 import 'codegen.dart'; |
| 10 import 'unsugar.dart'; | 10 import 'unsugar.dart'; |
| 11 | 11 |
| 12 import '../js_backend.dart'; | 12 import '../js_backend.dart'; |
| 13 import '../../dart2jslib.dart'; | 13 import '../../dart2jslib.dart'; |
| 14 import '../../source_file.dart'; | 14 import '../../source_file.dart'; |
| 15 import '../../cps_ir/cps_ir_nodes.dart' as cps; | 15 import '../../cps_ir/cps_ir_nodes.dart' as cps; |
| 16 import '../../cps_ir/cps_ir_builder.dart'; | 16 import '../../cps_ir/cps_ir_builder.dart'; |
| 17 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; | 17 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; |
| 18 import '../../tree/tree.dart' as ast; | 18 import '../../tree/tree.dart' as ast; |
| 19 import '../../types/types.dart' show TypeMask; | 19 import '../../types/types.dart' show TypeMask, UnionTypeMask, FlatTypeMask, |
| 20 ForwardingTypeMask; |
| 20 import '../../scanner/scannerlib.dart' as scanner; | 21 import '../../scanner/scannerlib.dart' as scanner; |
| 21 import '../../elements/elements.dart'; | 22 import '../../elements/elements.dart'; |
| 22 import '../../closure.dart'; | 23 import '../../closure.dart'; |
| 23 import '../../js/js.dart' as js; | 24 import '../../js/js.dart' as js; |
| 24 import '../../source_map_builder.dart'; | 25 import '../../source_map_builder.dart'; |
| 25 import '../../tree_ir/tree_ir_builder.dart' as tree_builder; | 26 import '../../tree_ir/tree_ir_builder.dart' as tree_builder; |
| 26 import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter; | 27 import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter; |
| 27 import '../../cps_ir/optimizers.dart'; | 28 import '../../cps_ir/optimizers.dart'; |
| 28 import '../../tracer.dart'; | 29 import '../../tracer.dart'; |
| 29 import '../../js_backend/codegen/codegen.dart'; | 30 import '../../js_backend/codegen/codegen.dart'; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 element.enclosingClass is ClosureClassElement || | 102 element.enclosingClass is ClosureClassElement || |
| 102 element.isNative || | 103 element.isNative || |
| 103 element.isField) { | 104 element.isField) { |
| 104 giveUp('unsupported element kind: ${element.name}:${element.kind}'); | 105 giveUp('unsupported element kind: ${element.name}:${element.kind}'); |
| 105 } | 106 } |
| 106 | 107 |
| 107 cps.FunctionDefinition cpsNode = irBuilderTask.buildNode(element); | 108 cps.FunctionDefinition cpsNode = irBuilderTask.buildNode(element); |
| 108 if (cpsNode == null) { | 109 if (cpsNode == null) { |
| 109 giveUp('unable to build cps definition of $element'); | 110 giveUp('unable to build cps definition of $element'); |
| 110 } | 111 } |
| 111 const UnsugarVisitor().rewrite(cpsNode); | 112 new UnsugarVisitor(glue).rewrite(cpsNode); |
| 112 return cpsNode; | 113 return cpsNode; |
| 113 } | 114 } |
| 114 | 115 |
| 115 static const Pattern PRINT_TYPED_IR_FILTER = null; | 116 static const Pattern PRINT_TYPED_IR_FILTER = null; |
| 116 | 117 |
| 118 String formatTypeMask(TypeMask type) { |
| 119 if (type is UnionTypeMask) { |
| 120 return '[${type.disjointMasks.map(formatTypeMask).join(', ')}]'; |
| 121 } else if (type is FlatTypeMask) { |
| 122 if (type.isEmpty) { |
| 123 return "null"; |
| 124 } |
| 125 String suffix = (type.isExact ? "" : "+") + (type.isNullable ? "?" : "!"); |
| 126 return '${type.base.name}$suffix'; |
| 127 } else if (type is ForwardingTypeMask) { |
| 128 return formatTypeMask(type.forwardTo); |
| 129 } |
| 130 throw 'unsupported: $type'; |
| 131 } |
| 132 |
| 117 cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) { | 133 cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) { |
| 118 // Transformations on the CPS IR. | 134 // Transformations on the CPS IR. |
| 119 traceGraph("IR Builder", cpsNode); | 135 traceGraph("IR Builder", cpsNode); |
| 120 | 136 |
| 121 TypePropagator typePropagator = new TypePropagator<TypeMask>(compiler, | 137 TypePropagator typePropagator = new TypePropagator<TypeMask>(compiler, |
| 122 constantSystem, new TypeMaskSystem(compiler), compiler.internalError); | 138 constantSystem, new TypeMaskSystem(compiler), compiler.internalError); |
| 123 typePropagator.rewrite(cpsNode); | 139 typePropagator.rewrite(cpsNode); |
| 124 traceGraph("Sparse constant propagation", cpsNode); | 140 traceGraph("Sparse constant propagation", cpsNode); |
| 125 | 141 |
| 126 if (PRINT_TYPED_IR_FILTER != null && | 142 if (PRINT_TYPED_IR_FILTER != null && |
| 127 PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsNode.element.name) != null) { | 143 PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsNode.element.name) != null) { |
| 128 String printType(cps.Node node, String s) { | 144 String printType(cps.Node node, String s) { |
| 129 var type = typePropagator.getType(node); | 145 var type = typePropagator.getType(node); |
| 130 return type == null ? s : "<$type: $s>"; | 146 return type == null ? s : "$s:${formatTypeMask(type.type)}"; |
| 131 } | 147 } |
| 132 DEBUG_MODE = true; | 148 DEBUG_MODE = true; |
| 133 print(new SExpressionStringifier(printType).visit(cpsNode)); | 149 print(new SExpressionStringifier(printType).visit(cpsNode)); |
| 134 } | 150 } |
| 135 | 151 |
| 136 new RedundantPhiEliminator().rewrite(cpsNode); | 152 new RedundantPhiEliminator().rewrite(cpsNode); |
| 137 traceGraph("Redundant phi elimination", cpsNode); | 153 traceGraph("Redundant phi elimination", cpsNode); |
| 138 new ShrinkingReducer().rewrite(cpsNode); | 154 new ShrinkingReducer().rewrite(cpsNode); |
| 139 traceGraph("Shrinking reductions", cpsNode); | 155 traceGraph("Shrinking reductions", cpsNode); |
| 140 | 156 |
| 141 // Do not rewrite the IR after variable allocation. Allocation | 157 // Do not rewrite the IR after variable allocation. Allocation |
| 142 // makes decisions based on an approximation of IR variable live | 158 // makes decisions based on an approximation of IR variable live |
| 143 // ranges that can be invalidated by transforming the IR. | 159 // ranges that can be invalidated by transforming the IR. |
| 144 new cps.RegisterAllocator().visit(cpsNode); | 160 new cps.RegisterAllocator().visit(cpsNode); |
| 145 return cpsNode; | 161 return cpsNode; |
| 146 } | 162 } |
| 147 | 163 |
| 148 tree_ir.FunctionDefinition compileToTreeIR(cps.FunctionDefinition cpsNode) { | 164 tree_ir.FunctionDefinition compileToTreeIR(cps.FunctionDefinition cpsNode) { |
| 149 tree_builder.Builder builder = new tree_builder.Builder(compiler); | 165 tree_builder.Builder builder = new tree_builder.Builder(glue, compiler); |
| 150 tree_ir.FunctionDefinition treeNode = builder.buildFunction(cpsNode); | 166 tree_ir.FunctionDefinition treeNode = builder.buildFunction(cpsNode); |
| 151 assert(treeNode != null); | 167 assert(treeNode != null); |
| 152 traceGraph('Tree builder', treeNode); | 168 traceGraph('Tree builder', treeNode); |
| 153 return treeNode; | 169 return treeNode; |
| 154 } | 170 } |
| 155 | 171 |
| 156 tree_ir.FunctionDefinition optimizeTreeIR( | 172 tree_ir.FunctionDefinition optimizeTreeIR( |
| 157 tree_ir.FunctionDefinition treeNode) { | 173 tree_ir.FunctionDefinition treeNode) { |
| 158 // Transformations on the Tree IR. | 174 // Transformations on the Tree IR. |
| 159 new StatementRewriter().rewrite(treeNode); | 175 new StatementRewriter().rewrite(treeNode); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 new TokenSourceFileLocation(sourceFile, endToken, name); | 225 new TokenSourceFileLocation(sourceFile, endToken, name); |
| 210 } | 226 } |
| 211 return node.withPosition(sourcePosition, endSourcePosition); | 227 return node.withPosition(sourcePosition, endSourcePosition); |
| 212 } | 228 } |
| 213 | 229 |
| 214 SourceFile sourceFileOfElement(Element element) { | 230 SourceFile sourceFileOfElement(Element element) { |
| 215 return element.implementation.compilationUnit.script.file; | 231 return element.implementation.compilationUnit.script.file; |
| 216 } | 232 } |
| 217 | 233 |
| 218 } | 234 } |
| OLD | NEW |