| 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 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 import '../../cps_ir/optimizers.dart'; | 25 import '../../cps_ir/optimizers.dart'; |
| 26 import '../../tracer.dart'; | 26 import '../../tracer.dart'; |
| 27 import '../../js_backend/codegen/codegen.dart'; | 27 import '../../js_backend/codegen/codegen.dart'; |
| 28 import '../../ssa/ssa.dart' as ssa; | 28 import '../../ssa/ssa.dart' as ssa; |
| 29 import '../../tree_ir/optimization/optimization.dart'; | 29 import '../../tree_ir/optimization/optimization.dart'; |
| 30 import '../../common.dart' show SelectorKind; | 30 import '../../common.dart' show SelectorKind; |
| 31 import '../../constants/expressions.dart'; | 31 import '../../constants/expressions.dart'; |
| 32 import '../../constants/values.dart'; | 32 import '../../constants/values.dart'; |
| 33 | 33 |
| 34 class JsBackendTreeBuilder extends tree_builder.Builder { | 34 class JsBackendTreeBuilder extends tree_builder.Builder { |
| 35 JsBackendTreeBuilder(Compiler compiler) : super(compiler); | 35 final Glue glue; |
| 36 |
| 37 JsBackendTreeBuilder(Compiler compiler, this.glue) : super(compiler); |
| 36 | 38 |
| 37 Selector get identicalSelector { | 39 Selector get identicalSelector { |
| 38 return new Selector(SelectorKind.CALL, 'identical', null, 2); | 40 return new Selector(SelectorKind.CALL, 'identical', null, 2); |
| 39 } | 41 } |
| 40 | 42 |
| 41 /// TOOD(karlklose): cache this? | 43 /// TOOD(karlklose): cache this? |
| 42 tree_ir.Constant get constantTrue { | 44 tree_ir.Constant get constantTrue { |
| 43 ConstantExpression trueValue = | 45 ConstantExpression trueValue = |
| 44 new PrimitiveConstantExpression(new TrueConstantValue()); | 46 new PrimitiveConstantExpression(new TrueConstantValue()); |
| 45 return new tree_ir.Constant(trueValue); | 47 return new tree_ir.Constant(trueValue); |
| 46 } | 48 } |
| 47 | 49 |
| 48 /** | 50 /** |
| 49 * Boolean conversion maps any object o into a boolean. Boolean conversion is | 51 * Boolean conversion maps any object o into a boolean. Boolean conversion is |
| 50 * defined by the function application | 52 * defined by the function application |
| 51 * (bool v){ | 53 * (bool v){ |
| 52 * assert(v != null); | 54 * assert(v != null); |
| 53 * return identical(v, true); | 55 * return identical(v, true); |
| 54 * }(o) | 56 * }(o) |
| 55 */ | 57 */ |
| 56 tree_ir.Expression visitIsTrue(cps.IsTrue node) { | 58 tree_ir.Expression visitIsTrue(cps.IsTrue node) { |
| 57 tree_ir.Expression value = getVariableReference(node.value); | 59 tree_ir.Expression value = getVariableReference(node.value); |
| 58 /// TODO(karlklose): implement the assert(v != null) check. | 60 /// TODO(karlklose): implement the assert(v != null) check. |
| 59 return new tree_ir.InvokeStatic( | 61 return new tree_ir.InvokeStatic( |
| 60 compiler.identicalFunction, | 62 glue.identicalFunction, |
| 61 identicalSelector, | 63 identicalSelector, |
| 62 <tree_ir.Expression>[value, constantTrue]); | 64 <tree_ir.Expression>[value, constantTrue]); |
| 63 } | 65 } |
| 64 | 66 |
| 65 } | 67 } |
| 66 | 68 |
| 67 class CspFunctionCompiler implements FunctionCompiler { | 69 class CspFunctionCompiler implements FunctionCompiler { |
| 68 final IrBuilderTask irBuilderTask; | 70 final IrBuilderTask irBuilderTask; |
| 69 final ConstantSystem constantSystem; | 71 final ConstantSystem constantSystem; |
| 70 final Compiler compiler; | 72 final Compiler compiler; |
| 73 final Glue glue; |
| 71 | 74 |
| 72 // TODO(karlklose,sigurm): remove and update dart-doc of [compile]. | 75 // TODO(karlklose,sigurm): remove and update dart-doc of [compile]. |
| 73 final FunctionCompiler fallbackCompiler; | 76 final FunctionCompiler fallbackCompiler; |
| 74 | 77 |
| 75 // TODO(sigurdm): Assign this. | 78 // TODO(sigurdm): Assign this. |
| 76 Tracer tracer; | 79 Tracer tracer; |
| 77 | 80 |
| 78 CspFunctionCompiler(Compiler compiler, JavaScriptBackend backend) | 81 CspFunctionCompiler(Compiler compiler, JavaScriptBackend backend) |
| 79 : irBuilderTask = new IrBuilderTask(compiler), | 82 : irBuilderTask = new IrBuilderTask(compiler), |
| 80 fallbackCompiler = new ssa.SsaFunctionCompiler(backend, true), | 83 fallbackCompiler = new ssa.SsaFunctionCompiler(backend, true), |
| 81 constantSystem = backend.constantSystem, | 84 constantSystem = backend.constantSystem, |
| 82 compiler = compiler; | 85 compiler = compiler, |
| 86 glue = new Glue(compiler); |
| 83 | 87 |
| 84 String get name => 'CPS Ir pipeline'; | 88 String get name => 'CPS Ir pipeline'; |
| 85 | 89 |
| 86 /// Generates JavaScript code for `work.element`. First tries to use the | 90 /// Generates JavaScript code for `work.element`. First tries to use the |
| 87 /// Cps Ir -> tree ir -> js pipeline, and if that fails due to language | 91 /// Cps Ir -> tree ir -> js pipeline, and if that fails due to language |
| 88 /// features not implemented it will fall back to the ssa pipeline (for | 92 /// features not implemented it will fall back to the ssa pipeline (for |
| 89 /// platform code) or will cancel compilation (for user code). | 93 /// platform code) or will cancel compilation (for user code). |
| 90 js.Fun compile(CodegenWorkItem work) { | 94 js.Fun compile(CodegenWorkItem work) { |
| 91 AstElement element = work.element; | 95 AstElement element = work.element; |
| 92 return compiler.withCurrentElement(element, () { | 96 return compiler.withCurrentElement(element, () { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 traceGraph("Shrinking reductions", cpsNode); | 154 traceGraph("Shrinking reductions", cpsNode); |
| 151 | 155 |
| 152 // Do not rewrite the IR after variable allocation. Allocation | 156 // Do not rewrite the IR after variable allocation. Allocation |
| 153 // makes decisions based on an approximation of IR variable live | 157 // makes decisions based on an approximation of IR variable live |
| 154 // ranges that can be invalidated by transforming the IR. | 158 // ranges that can be invalidated by transforming the IR. |
| 155 new cps.RegisterAllocator().visit(cpsNode); | 159 new cps.RegisterAllocator().visit(cpsNode); |
| 156 return cpsNode; | 160 return cpsNode; |
| 157 } | 161 } |
| 158 | 162 |
| 159 tree_ir.FunctionDefinition compileToTreeIR(cps.FunctionDefinition cpsNode) { | 163 tree_ir.FunctionDefinition compileToTreeIR(cps.FunctionDefinition cpsNode) { |
| 160 tree_builder.Builder builder = new JsBackendTreeBuilder(compiler); | 164 tree_builder.Builder builder = new JsBackendTreeBuilder(compiler, glue); |
| 161 tree_ir.FunctionDefinition treeNode = builder.build(cpsNode); | 165 tree_ir.FunctionDefinition treeNode = builder.build(cpsNode); |
| 162 assert(treeNode != null); | 166 assert(treeNode != null); |
| 163 traceGraph('Tree builder', treeNode); | 167 traceGraph('Tree builder', treeNode); |
| 164 return treeNode; | 168 return treeNode; |
| 165 } | 169 } |
| 166 | 170 |
| 167 tree_ir.FunctionDefinition optimizeTreeIR( | 171 tree_ir.FunctionDefinition optimizeTreeIR( |
| 168 tree_ir.FunctionDefinition treeNode) { | 172 tree_ir.FunctionDefinition treeNode) { |
| 169 // Transformations on the Tree IR. | 173 // Transformations on the Tree IR. |
| 170 new StatementRewriter().rewrite(treeNode); | 174 new StatementRewriter().rewrite(treeNode); |
| 171 traceGraph('Statement rewriter', treeNode); | 175 traceGraph('Statement rewriter', treeNode); |
| 172 new CopyPropagator().rewrite(treeNode); | 176 new CopyPropagator().rewrite(treeNode); |
| 173 traceGraph('Copy propagation', treeNode); | 177 traceGraph('Copy propagation', treeNode); |
| 174 new LoopRewriter().rewrite(treeNode); | 178 new LoopRewriter().rewrite(treeNode); |
| 175 traceGraph('Loop rewriter', treeNode); | 179 traceGraph('Loop rewriter', treeNode); |
| 176 new LogicalRewriter().rewrite(treeNode); | 180 new LogicalRewriter().rewrite(treeNode); |
| 177 traceGraph('Logical rewriter', treeNode); | 181 traceGraph('Logical rewriter', treeNode); |
| 178 new backend_ast_emitter.UnshadowParameters().unshadow(treeNode); | 182 new backend_ast_emitter.UnshadowParameters().unshadow(treeNode); |
| 179 traceGraph('Unshadow parameters', treeNode); | 183 traceGraph('Unshadow parameters', treeNode); |
| 180 return treeNode; | 184 return treeNode; |
| 181 } | 185 } |
| 182 | 186 |
| 183 js.Fun compileToJavaScript(CodegenWorkItem work, | 187 js.Fun compileToJavaScript(CodegenWorkItem work, |
| 184 tree_ir.FunctionDefinition definition) { | 188 tree_ir.FunctionDefinition definition) { |
| 185 CodeGenerator codeGen = | 189 CodeGenerator codeGen = new CodeGenerator(glue, work.registry); |
| 186 new CodeGenerator(new Glue(compiler), work.registry); | |
| 187 | 190 |
| 188 codeGen.buildFunction(definition); | 191 codeGen.buildFunction(definition); |
| 189 return buildJavaScriptFunction(work.element, | 192 return buildJavaScriptFunction(work.element, |
| 190 codeGen.parameters, | 193 codeGen.parameters, |
| 191 codeGen.body); | 194 codeGen.body); |
| 192 } | 195 } |
| 193 | 196 |
| 194 Iterable<CompilerTask> get tasks { | 197 Iterable<CompilerTask> get tasks { |
| 195 // TODO(sigurdm): Make a better list of tasks. | 198 // TODO(sigurdm): Make a better list of tasks. |
| 196 return <CompilerTask>[irBuilderTask]..addAll(fallbackCompiler.tasks); | 199 return <CompilerTask>[irBuilderTask]..addAll(fallbackCompiler.tasks); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 SourceFile sourceFileOfElement(Element element) { | 232 SourceFile sourceFileOfElement(Element element) { |
| 230 return element.implementation.compilationUnit.script.file; | 233 return element.implementation.compilationUnit.script.file; |
| 231 } | 234 } |
| 232 | 235 |
| 233 js.Fun buildJavaScriptFunction(FunctionElement element, | 236 js.Fun buildJavaScriptFunction(FunctionElement element, |
| 234 List<js.Parameter> parameters, | 237 List<js.Parameter> parameters, |
| 235 js.Block body) { | 238 js.Block body) { |
| 236 return attachPosition(new js.Fun(parameters, body), element); | 239 return attachPosition(new js.Fun(parameters, body), element); |
| 237 } | 240 } |
| 238 } | 241 } |
| OLD | NEW |