| 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, UnionTypeMask, FlatTypeMask, | 19 import '../../types/types.dart' show TypeMask; |
| 20 ForwardingTypeMask; | |
| 21 import '../../scanner/scannerlib.dart' as scanner; | 20 import '../../scanner/scannerlib.dart' as scanner; |
| 22 import '../../elements/elements.dart'; | 21 import '../../elements/elements.dart'; |
| 23 import '../../closure.dart'; | 22 import '../../closure.dart'; |
| 24 import '../../js/js.dart' as js; | 23 import '../../js/js.dart' as js; |
| 25 import '../../source_map_builder.dart'; | 24 import '../../source_map_builder.dart'; |
| 26 import '../../tree_ir/tree_ir_builder.dart' as tree_builder; | 25 import '../../tree_ir/tree_ir_builder.dart' as tree_builder; |
| 27 import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter; | 26 import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter; |
| 28 import '../../cps_ir/optimizers.dart'; | 27 import '../../cps_ir/optimizers.dart'; |
| 29 import '../../tracer.dart'; | 28 import '../../tracer.dart'; |
| 30 import '../../js_backend/codegen/codegen.dart'; | 29 import '../../js_backend/codegen/codegen.dart'; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 element.enclosingClass is ClosureClassElement || | 101 element.enclosingClass is ClosureClassElement || |
| 103 element.isNative || | 102 element.isNative || |
| 104 element.isField) { | 103 element.isField) { |
| 105 giveUp('unsupported element kind: ${element.name}:${element.kind}'); | 104 giveUp('unsupported element kind: ${element.name}:${element.kind}'); |
| 106 } | 105 } |
| 107 | 106 |
| 108 cps.FunctionDefinition cpsNode = irBuilderTask.buildNode(element); | 107 cps.FunctionDefinition cpsNode = irBuilderTask.buildNode(element); |
| 109 if (cpsNode == null) { | 108 if (cpsNode == null) { |
| 110 giveUp('unable to build cps definition of $element'); | 109 giveUp('unable to build cps definition of $element'); |
| 111 } | 110 } |
| 112 new UnsugarVisitor(glue).rewrite(cpsNode); | 111 const UnsugarVisitor().rewrite(cpsNode); |
| 113 return cpsNode; | 112 return cpsNode; |
| 114 } | 113 } |
| 115 | 114 |
| 116 static const Pattern PRINT_TYPED_IR_FILTER = null; | 115 static const Pattern PRINT_TYPED_IR_FILTER = null; |
| 117 | 116 |
| 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 | |
| 133 cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) { | 117 cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) { |
| 134 // Transformations on the CPS IR. | 118 // Transformations on the CPS IR. |
| 135 traceGraph("IR Builder", cpsNode); | 119 traceGraph("IR Builder", cpsNode); |
| 136 | 120 |
| 137 TypePropagator typePropagator = new TypePropagator<TypeMask>(compiler, | 121 TypePropagator typePropagator = new TypePropagator<TypeMask>(compiler, |
| 138 constantSystem, new TypeMaskSystem(compiler), compiler.internalError); | 122 constantSystem, new TypeMaskSystem(compiler), compiler.internalError); |
| 139 typePropagator.rewrite(cpsNode); | 123 typePropagator.rewrite(cpsNode); |
| 140 traceGraph("Sparse constant propagation", cpsNode); | 124 traceGraph("Sparse constant propagation", cpsNode); |
| 141 | 125 |
| 142 if (PRINT_TYPED_IR_FILTER != null && | 126 if (PRINT_TYPED_IR_FILTER != null && |
| 143 PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsNode.element.name) != null) { | 127 PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsNode.element.name) != null) { |
| 144 String printType(cps.Node node, String s) { | 128 String printType(cps.Node node, String s) { |
| 145 var type = typePropagator.getType(node); | 129 var type = typePropagator.getType(node); |
| 146 return type == null ? s : "$s:${formatTypeMask(type.type)}"; | 130 return type == null ? s : "<$type: $s>"; |
| 147 } | 131 } |
| 148 DEBUG_MODE = true; | 132 DEBUG_MODE = true; |
| 149 print(new SExpressionStringifier(printType).visit(cpsNode)); | 133 print(new SExpressionStringifier(printType).visit(cpsNode)); |
| 150 } | 134 } |
| 151 | 135 |
| 152 new RedundantPhiEliminator().rewrite(cpsNode); | 136 new RedundantPhiEliminator().rewrite(cpsNode); |
| 153 traceGraph("Redundant phi elimination", cpsNode); | 137 traceGraph("Redundant phi elimination", cpsNode); |
| 154 new ShrinkingReducer().rewrite(cpsNode); | 138 new ShrinkingReducer().rewrite(cpsNode); |
| 155 traceGraph("Shrinking reductions", cpsNode); | 139 traceGraph("Shrinking reductions", cpsNode); |
| 156 | 140 |
| 157 // Do not rewrite the IR after variable allocation. Allocation | 141 // Do not rewrite the IR after variable allocation. Allocation |
| 158 // makes decisions based on an approximation of IR variable live | 142 // makes decisions based on an approximation of IR variable live |
| 159 // ranges that can be invalidated by transforming the IR. | 143 // ranges that can be invalidated by transforming the IR. |
| 160 new cps.RegisterAllocator().visit(cpsNode); | 144 new cps.RegisterAllocator().visit(cpsNode); |
| 161 return cpsNode; | 145 return cpsNode; |
| 162 } | 146 } |
| 163 | 147 |
| 164 tree_ir.FunctionDefinition compileToTreeIR(cps.FunctionDefinition cpsNode) { | 148 tree_ir.FunctionDefinition compileToTreeIR(cps.FunctionDefinition cpsNode) { |
| 165 tree_builder.Builder builder = new tree_builder.Builder(glue, compiler); | 149 tree_builder.Builder builder = new tree_builder.Builder(compiler); |
| 166 tree_ir.FunctionDefinition treeNode = builder.buildFunction(cpsNode); | 150 tree_ir.FunctionDefinition treeNode = builder.buildFunction(cpsNode); |
| 167 assert(treeNode != null); | 151 assert(treeNode != null); |
| 168 traceGraph('Tree builder', treeNode); | 152 traceGraph('Tree builder', treeNode); |
| 169 return treeNode; | 153 return treeNode; |
| 170 } | 154 } |
| 171 | 155 |
| 172 tree_ir.FunctionDefinition optimizeTreeIR( | 156 tree_ir.FunctionDefinition optimizeTreeIR( |
| 173 tree_ir.FunctionDefinition treeNode) { | 157 tree_ir.FunctionDefinition treeNode) { |
| 174 // Transformations on the Tree IR. | 158 // Transformations on the Tree IR. |
| 175 new StatementRewriter().rewrite(treeNode); | 159 new StatementRewriter().rewrite(treeNode); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 new TokenSourceFileLocation(sourceFile, endToken, name); | 209 new TokenSourceFileLocation(sourceFile, endToken, name); |
| 226 } | 210 } |
| 227 return node.withPosition(sourcePosition, endSourcePosition); | 211 return node.withPosition(sourcePosition, endSourcePosition); |
| 228 } | 212 } |
| 229 | 213 |
| 230 SourceFile sourceFileOfElement(Element element) { | 214 SourceFile sourceFileOfElement(Element element) { |
| 231 return element.implementation.compilationUnit.script.file; | 215 return element.implementation.compilationUnit.script.file; |
| 232 } | 216 } |
| 233 | 217 |
| 234 } | 218 } |
| OLD | NEW |