| 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'; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 import '../../cps_ir/optimizers.dart'; | 32 import '../../cps_ir/optimizers.dart'; |
| 33 import '../../cps_ir/optimizers.dart' as cps_opt; | 33 import '../../cps_ir/optimizers.dart' as cps_opt; |
| 34 import '../../tracer.dart'; | 34 import '../../tracer.dart'; |
| 35 import '../../js_backend/codegen/codegen.dart'; | 35 import '../../js_backend/codegen/codegen.dart'; |
| 36 import '../../ssa/ssa.dart' as ssa; | 36 import '../../ssa/ssa.dart' as ssa; |
| 37 import '../../tree_ir/optimization/optimization.dart'; | 37 import '../../tree_ir/optimization/optimization.dart'; |
| 38 import '../../tree_ir/optimization/optimization.dart' as tree_opt; | 38 import '../../tree_ir/optimization/optimization.dart' as tree_opt; |
| 39 import '../../tree_ir/tree_ir_integrity.dart'; | 39 import '../../tree_ir/tree_ir_integrity.dart'; |
| 40 import '../../cps_ir/cps_ir_nodes_sexpr.dart'; | 40 import '../../cps_ir/cps_ir_nodes_sexpr.dart'; |
| 41 import '../../cps_ir/type_mask_system.dart'; | 41 import '../../cps_ir/type_mask_system.dart'; |
| 42 import '../../common/tasks.dart'; |
| 42 | 43 |
| 43 class CpsFunctionCompiler implements FunctionCompiler { | 44 class CpsFunctionCompiler implements FunctionCompiler { |
| 44 final ConstantSystem constantSystem; | 45 final ConstantSystem constantSystem; |
| 45 // TODO(karlklose): remove the compiler. | 46 // TODO(karlklose): remove the compiler. |
| 46 final Compiler compiler; | 47 final Compiler compiler; |
| 47 final Glue glue; | 48 final Glue glue; |
| 48 final SourceInformationStrategy sourceInformationFactory; | 49 final SourceInformationStrategy sourceInformationFactory; |
| 49 | 50 |
| 50 // TODO(karlklose,sigurdm): remove and update dart-doc of [compile]. | 51 // TODO(karlklose,sigurdm): remove and update dart-doc of [compile]. |
| 51 final FunctionCompiler fallbackCompiler; | 52 final FunctionCompiler fallbackCompiler; |
| 52 TypeMaskSystem typeSystem; | 53 TypeMaskSystem typeSystem; |
| 53 | 54 |
| 54 Tracer get tracer => compiler.tracer; | 55 Tracer get tracer => compiler.tracer; |
| 55 | 56 |
| 56 IrBuilderTask get irBuilderTask => compiler.irBuilder; | 57 final IrBuilderTask cpsBuilderTask; |
| 58 final GenericTask cpsOptimizationTask; |
| 59 final GenericTask treeBuilderTask; |
| 60 final GenericTask treeOptimizationTask; |
| 57 | 61 |
| 58 CpsFunctionCompiler(Compiler compiler, JavaScriptBackend backend, | 62 CpsFunctionCompiler(Compiler compiler, JavaScriptBackend backend, |
| 59 SourceInformationStrategy sourceInformationFactory) | 63 SourceInformationStrategy sourceInformationFactory) |
| 60 : fallbackCompiler = | 64 : fallbackCompiler = |
| 61 new ssa.SsaFunctionCompiler(backend, sourceInformationFactory), | 65 new ssa.SsaFunctionCompiler(backend, sourceInformationFactory), |
| 66 cpsBuilderTask = new IrBuilderTask(compiler, sourceInformationFactory), |
| 62 this.sourceInformationFactory = sourceInformationFactory, | 67 this.sourceInformationFactory = sourceInformationFactory, |
| 63 constantSystem = backend.constantSystem, | 68 constantSystem = backend.constantSystem, |
| 64 compiler = compiler, | 69 compiler = compiler, |
| 65 glue = new Glue(compiler); | 70 glue = new Glue(compiler), |
| 71 cpsOptimizationTask = new GenericTask('CPS optimization', compiler), |
| 72 treeBuilderTask = new GenericTask('Tree builder', compiler), |
| 73 treeOptimizationTask = new GenericTask('Tree optimization', compiler); |
| 66 | 74 |
| 67 String get name => 'CPS Ir pipeline'; | 75 String get name => 'CPS Ir pipeline'; |
| 68 | 76 |
| 69 JavaScriptBackend get backend => compiler.backend; | 77 JavaScriptBackend get backend => compiler.backend; |
| 70 | 78 |
| 71 /// Generates JavaScript code for `work.element`. | 79 /// Generates JavaScript code for `work.element`. |
| 72 js.Fun compile(CodegenWorkItem work) { | 80 js.Fun compile(CodegenWorkItem work) { |
| 73 AstElement element = work.element; | 81 AstElement element = work.element; |
| 74 return compiler.withCurrentElement(element, () { | 82 return compiler.withCurrentElement(element, () { |
| 75 typeSystem = new TypeMaskSystem(compiler); | 83 typeSystem = new TypeMaskSystem(compiler); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 101 throw new CodegenBailout(null, reason); | 109 throw new CodegenBailout(null, reason); |
| 102 } | 110 } |
| 103 | 111 |
| 104 void traceGraph(String title, var irObject) { | 112 void traceGraph(String title, var irObject) { |
| 105 if (tracer != null) { | 113 if (tracer != null) { |
| 106 tracer.traceGraph(title, irObject); | 114 tracer.traceGraph(title, irObject); |
| 107 } | 115 } |
| 108 } | 116 } |
| 109 | 117 |
| 110 void applyCpsPass(cps_opt.Pass pass, cps.FunctionDefinition cpsFunction) { | 118 void applyCpsPass(cps_opt.Pass pass, cps.FunctionDefinition cpsFunction) { |
| 111 pass.rewrite(cpsFunction); | 119 cpsOptimizationTask.measureSubtask(pass.passName, () { |
| 120 pass.rewrite(cpsFunction); |
| 121 }); |
| 112 traceGraph(pass.passName, cpsFunction); | 122 traceGraph(pass.passName, cpsFunction); |
| 113 dumpTypedIr(pass.passName, cpsFunction); | 123 dumpTypedIr(pass.passName, cpsFunction); |
| 114 assert(checkCpsIntegrity(cpsFunction)); | 124 assert(checkCpsIntegrity(cpsFunction)); |
| 115 } | 125 } |
| 116 | 126 |
| 117 cps.FunctionDefinition compileToCpsIr(AstElement element) { | 127 cps.FunctionDefinition compileToCpsIr(AstElement element) { |
| 118 cps.FunctionDefinition cpsFunction = irBuilderTask.buildNode(element); | 128 cps.FunctionDefinition cpsFunction = cpsBuilderTask.buildNode(element); |
| 119 if (cpsFunction == null) { | 129 if (cpsFunction == null) { |
| 120 if (irBuilderTask.bailoutMessage == null) { | 130 if (cpsBuilderTask.bailoutMessage == null) { |
| 121 giveUp('unable to build cps definition of $element'); | 131 giveUp('unable to build cps definition of $element'); |
| 122 } else { | 132 } else { |
| 123 giveUp(irBuilderTask.bailoutMessage); | 133 giveUp(cpsBuilderTask.bailoutMessage); |
| 124 } | 134 } |
| 125 } | 135 } |
| 126 traceGraph('IR Builder', cpsFunction); | 136 traceGraph('IR Builder', cpsFunction); |
| 127 dumpTypedIr('IR Builder', cpsFunction); | 137 dumpTypedIr('IR Builder', cpsFunction); |
| 128 // Eliminating redundant phis before the unsugaring pass will make it | 138 // Eliminating redundant phis before the unsugaring pass will make it |
| 129 // insert fewer getInterceptor calls. | 139 // insert fewer getInterceptor calls. |
| 130 applyCpsPass(new RedundantPhiEliminator(), cpsFunction); | 140 applyCpsPass(new RedundantPhiEliminator(), cpsFunction); |
| 131 applyCpsPass(new UnsugarVisitor(glue), cpsFunction); | 141 applyCpsPass(new UnsugarVisitor(glue), cpsFunction); |
| 132 return cpsFunction; | 142 return cpsFunction; |
| 133 } | 143 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 applyCpsPass(new LoopInvariantCodeMotion(), cpsFunction); | 198 applyCpsPass(new LoopInvariantCodeMotion(), cpsFunction); |
| 189 applyCpsPass(new ShareInterceptors(), cpsFunction); | 199 applyCpsPass(new ShareInterceptors(), cpsFunction); |
| 190 applyCpsPass(new ShrinkingReducer(), cpsFunction); | 200 applyCpsPass(new ShrinkingReducer(), cpsFunction); |
| 191 | 201 |
| 192 return cpsFunction; | 202 return cpsFunction; |
| 193 } | 203 } |
| 194 | 204 |
| 195 tree_ir.FunctionDefinition compileToTreeIr(cps.FunctionDefinition cpsNode) { | 205 tree_ir.FunctionDefinition compileToTreeIr(cps.FunctionDefinition cpsNode) { |
| 196 tree_builder.Builder builder = new tree_builder.Builder( | 206 tree_builder.Builder builder = new tree_builder.Builder( |
| 197 compiler.internalError); | 207 compiler.internalError); |
| 198 tree_ir.FunctionDefinition treeNode = builder.buildFunction(cpsNode); | 208 tree_ir.FunctionDefinition treeNode = |
| 209 treeBuilderTask.measure(() => builder.buildFunction(cpsNode)); |
| 199 assert(treeNode != null); | 210 assert(treeNode != null); |
| 200 traceGraph('Tree builder', treeNode); | 211 traceGraph('Tree builder', treeNode); |
| 201 assert(checkTreeIntegrity(treeNode)); | 212 assert(checkTreeIntegrity(treeNode)); |
| 202 return treeNode; | 213 return treeNode; |
| 203 } | 214 } |
| 204 | 215 |
| 205 static bool checkTreeIntegrity(tree_ir.FunctionDefinition node) { | 216 static bool checkTreeIntegrity(tree_ir.FunctionDefinition node) { |
| 206 new CheckTreeIntegrity().check(node); | 217 new CheckTreeIntegrity().check(node); |
| 207 return true; // So this can be used from assert(). | 218 return true; // So this can be used from assert(). |
| 208 } | 219 } |
| 209 | 220 |
| 210 tree_ir.FunctionDefinition optimizeTreeIr(tree_ir.FunctionDefinition node) { | 221 tree_ir.FunctionDefinition optimizeTreeIr(tree_ir.FunctionDefinition node) { |
| 211 void applyTreePass(tree_opt.Pass pass) { | 222 void applyTreePass(tree_opt.Pass pass) { |
| 212 pass.rewrite(node); | 223 treeOptimizationTask.measureSubtask(pass.passName, () { |
| 224 pass.rewrite(node); |
| 225 }); |
| 213 traceGraph(pass.passName, node); | 226 traceGraph(pass.passName, node); |
| 214 assert(checkTreeIntegrity(node)); | 227 assert(checkTreeIntegrity(node)); |
| 215 } | 228 } |
| 216 | 229 |
| 217 applyTreePass(new StatementRewriter()); | 230 applyTreePass(new StatementRewriter()); |
| 218 applyTreePass(new VariableMerger()); | 231 applyTreePass(new VariableMerger()); |
| 219 applyTreePass(new LoopRewriter()); | 232 applyTreePass(new LoopRewriter()); |
| 220 applyTreePass(new LogicalRewriter()); | 233 applyTreePass(new LogicalRewriter()); |
| 221 applyTreePass(new PullIntoInitializers()); | 234 applyTreePass(new PullIntoInitializers()); |
| 222 | 235 |
| 223 return node; | 236 return node; |
| 224 } | 237 } |
| 225 | 238 |
| 226 js.Fun compileToJavaScript(CodegenWorkItem work, | 239 js.Fun compileToJavaScript(CodegenWorkItem work, |
| 227 tree_ir.FunctionDefinition definition) { | 240 tree_ir.FunctionDefinition definition) { |
| 228 CodeGenerator codeGen = new CodeGenerator(glue, work.registry); | 241 CodeGenerator codeGen = new CodeGenerator(glue, work.registry); |
| 229 Element element = work.element; | 242 Element element = work.element; |
| 230 js.Fun code = codeGen.buildFunction(definition); | 243 js.Fun code = codeGen.buildFunction(definition); |
| 231 if (element is FunctionElement && element.asyncMarker != AsyncMarker.SYNC) { | 244 if (element is FunctionElement && element.asyncMarker != AsyncMarker.SYNC) { |
| 232 code = backend.rewriteAsync(element, code); | 245 code = backend.rewriteAsync(element, code); |
| 233 work.registry.registerAsyncMarker(element); | 246 work.registry.registerAsyncMarker(element); |
| 234 } | 247 } |
| 235 return attachPosition(code, element); | 248 return attachPosition(code, element); |
| 236 } | 249 } |
| 237 | 250 |
| 238 Iterable<CompilerTask> get tasks { | 251 Iterable<CompilerTask> get tasks { |
| 239 // TODO(sigurdm): Make a better list of tasks. | 252 return <CompilerTask>[ |
| 240 return <CompilerTask>[irBuilderTask]..addAll(fallbackCompiler.tasks); | 253 cpsBuilderTask, |
| 254 cpsOptimizationTask, |
| 255 treeBuilderTask, |
| 256 treeOptimizationTask] |
| 257 ..addAll(fallbackCompiler.tasks); |
| 241 } | 258 } |
| 242 | 259 |
| 243 js.Node attachPosition(js.Node node, AstElement element) { | 260 js.Node attachPosition(js.Node node, AstElement element) { |
| 244 return node.withSourceInformation( | 261 return node.withSourceInformation( |
| 245 sourceInformationFactory.createBuilderForContext(element) | 262 sourceInformationFactory.createBuilderForContext(element) |
| 246 .buildDeclaration(element)); | 263 .buildDeclaration(element)); |
| 247 } | 264 } |
| 248 } | 265 } |
| OLD | NEW |