| 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 '../../scanner/scannerlib.dart' as scanner; | 20 import '../../scanner/scannerlib.dart' as scanner; |
| 20 import '../../elements/elements.dart'; | 21 import '../../elements/elements.dart'; |
| 21 import '../../closure.dart'; | 22 import '../../closure.dart'; |
| 22 import '../../js/js.dart' as js; | 23 import '../../js/js.dart' as js; |
| 23 import '../../source_map_builder.dart'; | 24 import '../../source_map_builder.dart'; |
| 24 import '../../tree_ir/tree_ir_builder.dart' as tree_builder; | 25 import '../../tree_ir/tree_ir_builder.dart' as tree_builder; |
| 25 import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter; | 26 import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter; |
| 26 import '../../cps_ir/optimizers.dart'; | 27 import '../../cps_ir/optimizers.dart'; |
| 27 import '../../tracer.dart'; | 28 import '../../tracer.dart'; |
| 28 import '../../js_backend/codegen/codegen.dart'; | 29 import '../../js_backend/codegen/codegen.dart'; |
| 29 import '../../ssa/ssa.dart' as ssa; | 30 import '../../ssa/ssa.dart' as ssa; |
| 30 import '../../tree_ir/optimization/optimization.dart'; | 31 import '../../tree_ir/optimization/optimization.dart'; |
| 32 import '../../cps_ir/cps_ir_nodes_sexpr.dart'; |
| 31 | 33 |
| 32 class CspFunctionCompiler implements FunctionCompiler { | 34 class CspFunctionCompiler implements FunctionCompiler { |
| 33 final IrBuilderTask irBuilderTask; | 35 final IrBuilderTask irBuilderTask; |
| 34 final ConstantSystem constantSystem; | 36 final ConstantSystem constantSystem; |
| 35 final Compiler compiler; | 37 final Compiler compiler; |
| 36 final Glue glue; | 38 final Glue glue; |
| 37 | 39 |
| 40 TypeSystem types; |
| 41 |
| 38 // TODO(karlklose,sigurm): remove and update dart-doc of [compile]. | 42 // TODO(karlklose,sigurm): remove and update dart-doc of [compile]. |
| 39 final FunctionCompiler fallbackCompiler; | 43 final FunctionCompiler fallbackCompiler; |
| 40 | 44 |
| 41 // TODO(sigurdm): Assign this. | 45 // TODO(sigurdm): Assign this. |
| 42 Tracer tracer; | 46 Tracer tracer; |
| 43 | 47 |
| 44 CspFunctionCompiler(Compiler compiler, JavaScriptBackend backend) | 48 CspFunctionCompiler(Compiler compiler, JavaScriptBackend backend) |
| 45 : irBuilderTask = new IrBuilderTask(compiler), | 49 : irBuilderTask = new IrBuilderTask(compiler), |
| 46 fallbackCompiler = new ssa.SsaFunctionCompiler(backend, true), | 50 fallbackCompiler = new ssa.SsaFunctionCompiler(backend, true), |
| 47 constantSystem = backend.constantSystem, | 51 constantSystem = backend.constantSystem, |
| 48 compiler = compiler, | 52 compiler = compiler, |
| 49 glue = new Glue(compiler); | 53 glue = new Glue(compiler); |
| 50 | 54 |
| 51 String get name => 'CPS Ir pipeline'; | 55 String get name => 'CPS Ir pipeline'; |
| 52 | 56 |
| 53 /// Generates JavaScript code for `work.element`. First tries to use the | 57 /// Generates JavaScript code for `work.element`. First tries to use the |
| 54 /// Cps Ir -> tree ir -> js pipeline, and if that fails due to language | 58 /// Cps Ir -> tree ir -> js pipeline, and if that fails due to language |
| 55 /// features not implemented it will fall back to the ssa pipeline (for | 59 /// features not implemented it will fall back to the ssa pipeline (for |
| 56 /// platform code) or will cancel compilation (for user code). | 60 /// platform code) or will cancel compilation (for user code). |
| 57 js.Fun compile(CodegenWorkItem work) { | 61 js.Fun compile(CodegenWorkItem work) { |
| 62 types = new TypeMaskSystem(compiler); |
| 58 AstElement element = work.element; | 63 AstElement element = work.element; |
| 59 return compiler.withCurrentElement(element, () { | 64 return compiler.withCurrentElement(element, () { |
| 60 try { | 65 try { |
| 61 if (tracer != null) { | 66 if (tracer != null) { |
| 62 tracer.traceCompilation(element.name, null); | 67 tracer.traceCompilation(element.name, null); |
| 63 } | 68 } |
| 64 cps.FunctionDefinition cpsFunction = compileToCpsIR(element); | 69 cps.FunctionDefinition cpsFunction = compileToCpsIR(element); |
| 65 cpsFunction = optimizeCpsIR(cpsFunction); | 70 cpsFunction = optimizeCpsIR(cpsFunction); |
| 66 tree_ir.FunctionDefinition treeFunction = compileToTreeIR(cpsFunction); | 71 tree_ir.FunctionDefinition treeFunction = compileToTreeIR(cpsFunction); |
| 67 treeFunction = optimizeTreeIR(treeFunction); | 72 treeFunction = optimizeTreeIR(treeFunction); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 } | 105 } |
| 101 | 106 |
| 102 cps.FunctionDefinition cpsNode = irBuilderTask.buildNode(element); | 107 cps.FunctionDefinition cpsNode = irBuilderTask.buildNode(element); |
| 103 if (cpsNode == null) { | 108 if (cpsNode == null) { |
| 104 giveUp('unable to build cps definition of $element'); | 109 giveUp('unable to build cps definition of $element'); |
| 105 } | 110 } |
| 106 const UnsugarVisitor().rewrite(cpsNode); | 111 const UnsugarVisitor().rewrite(cpsNode); |
| 107 return cpsNode; | 112 return cpsNode; |
| 108 } | 113 } |
| 109 | 114 |
| 115 static const Pattern PRINT_TYPED_IR_FILTER = null; |
| 116 |
| 110 cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) { | 117 cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) { |
| 111 // Transformations on the CPS IR. | 118 // Transformations on the CPS IR. |
| 112 traceGraph("IR Builder", cpsNode); | 119 traceGraph("IR Builder", cpsNode); |
| 113 new ConstantPropagator(compiler, constantSystem) | 120 |
| 114 .rewrite(cpsNode); | 121 TypePropagator typePropagator = new TypePropagator<TypeMask>(compiler, |
| 122 constantSystem, new TypeMaskSystem(compiler), compiler.internalError); |
| 123 typePropagator.rewrite(cpsNode); |
| 115 traceGraph("Sparse constant propagation", cpsNode); | 124 traceGraph("Sparse constant propagation", cpsNode); |
| 125 |
| 126 if (PRINT_TYPED_IR_FILTER != null && |
| 127 PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsNode.element.name) != null) { |
| 128 String printType(cps.Node node, String s) { |
| 129 var type = typePropagator.getType(node); |
| 130 return type == null ? s : "<$type: $s>"; |
| 131 } |
| 132 DEBUG_MODE = true; |
| 133 print(new SExpressionStringifier(printType).visit(cpsNode)); |
| 134 } |
| 135 |
| 116 new RedundantPhiEliminator().rewrite(cpsNode); | 136 new RedundantPhiEliminator().rewrite(cpsNode); |
| 117 traceGraph("Redundant phi elimination", cpsNode); | 137 traceGraph("Redundant phi elimination", cpsNode); |
| 118 new ShrinkingReducer().rewrite(cpsNode); | 138 new ShrinkingReducer().rewrite(cpsNode); |
| 119 traceGraph("Shrinking reductions", cpsNode); | 139 traceGraph("Shrinking reductions", cpsNode); |
| 120 | 140 |
| 121 // Do not rewrite the IR after variable allocation. Allocation | 141 // Do not rewrite the IR after variable allocation. Allocation |
| 122 // makes decisions based on an approximation of IR variable live | 142 // makes decisions based on an approximation of IR variable live |
| 123 // ranges that can be invalidated by transforming the IR. | 143 // ranges that can be invalidated by transforming the IR. |
| 124 new cps.RegisterAllocator().visit(cpsNode); | 144 new cps.RegisterAllocator().visit(cpsNode); |
| 125 return cpsNode; | 145 return cpsNode; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 new TokenSourceFileLocation(sourceFile, endToken, name); | 209 new TokenSourceFileLocation(sourceFile, endToken, name); |
| 190 } | 210 } |
| 191 return node.withPosition(sourcePosition, endSourcePosition); | 211 return node.withPosition(sourcePosition, endSourcePosition); |
| 192 } | 212 } |
| 193 | 213 |
| 194 SourceFile sourceFileOfElement(Element element) { | 214 SourceFile sourceFileOfElement(Element element) { |
| 195 return element.implementation.compilationUnit.script.file; | 215 return element.implementation.compilationUnit.script.file; |
| 196 } | 216 } |
| 197 | 217 |
| 198 } | 218 } |
| OLD | NEW |