| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of dart_backend; | 5 part of dart_backend; |
| 6 | 6 |
| 7 // TODO(ahe): This class is simply wrong. This backend should use | 7 // TODO(ahe): This class is simply wrong. This backend should use |
| 8 // elements when it can, not AST nodes. Perhaps a [Map<Element, | 8 // elements when it can, not AST nodes. Perhaps a [Map<Element, |
| 9 // TreeElements>] is what is needed. | 9 // TreeElements>] is what is needed. |
| 10 class ElementAst { | 10 class ElementAst { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 // Enqueue the methods that the VM might invoke on user objects because | 124 // Enqueue the methods that the VM might invoke on user objects because |
| 125 // we don't trust the resolution to always get these included. | 125 // we don't trust the resolution to always get these included. |
| 126 world.registerInvocation(new Selector.call("toString", null, 0)); | 126 world.registerInvocation(new Selector.call("toString", null, 0)); |
| 127 world.registerInvokedGetter(new Selector.getter("hashCode", null)); | 127 world.registerInvokedGetter(new Selector.getter("hashCode", null)); |
| 128 world.registerInvocation(new Selector.binaryOperator("==")); | 128 world.registerInvocation(new Selector.binaryOperator("==")); |
| 129 world.registerInvocation(new Selector.call("compareTo", null, 1)); | 129 world.registerInvocation(new Selector.call("compareTo", null, 1)); |
| 130 } | 130 } |
| 131 | 131 |
| 132 void codegen(CodegenWorkItem work) { } | 132 void codegen(CodegenWorkItem work) { } |
| 133 | 133 |
| 134 static bool checkTreeIntegrity(tree_ir.ExecutableDefinition node) { |
| 135 new CheckTreeIntegrity().check(node); |
| 136 return true; // So this can be used from assert(). |
| 137 } |
| 138 |
| 139 static bool checkCpsIntegrity(cps_ir.ExecutableDefinition node) { |
| 140 new CheckCpsIntegrity().check(node); |
| 141 return true; // So this can be used from assert(). |
| 142 } |
| 143 |
| 134 /// Create an [ElementAst] from the CPS IR. | 144 /// Create an [ElementAst] from the CPS IR. |
| 135 static ElementAst createElementAst( | 145 static ElementAst createElementAst( |
| 136 ElementAstCreationContext context, | 146 ElementAstCreationContext context, |
| 137 Element element, | 147 Element element, |
| 138 cps_ir.ExecutableDefinition cpsDefinition) { | 148 cps_ir.ExecutableDefinition cpsDefinition) { |
| 149 context.traceCompilation(element.name); |
| 150 context.traceGraph('CPS builder', cpsDefinition); |
| 151 assert(checkCpsIntegrity(cpsDefinition)); |
| 152 |
| 139 // Transformations on the CPS IR. | 153 // Transformations on the CPS IR. |
| 140 context.traceCompilation(element.name); | 154 void applyCpsPass(String name, cps_opt.Pass pass) { |
| 155 pass.rewrite(cpsDefinition); |
| 156 context.traceGraph(name, cpsDefinition); |
| 157 assert(checkCpsIntegrity(cpsDefinition)); |
| 158 } |
| 141 | 159 |
| 142 // TODO(karlklose): enable type propagation for dart2dart when constant | 160 // TODO(karlklose): enable type propagation for dart2dart when constant |
| 143 // types are correctly marked as instantiated (Issue 21880). | 161 // types are correctly marked as instantiated (Issue 21880). |
| 144 new TypePropagator(context.dartTypes, | 162 applyCpsPass('Sparse constant propagation', |
| 145 context.constantSystem, | 163 new TypePropagator(context.dartTypes, |
| 146 new UnitTypeSystem(), | 164 context.constantSystem, |
| 147 context.internalError) | 165 new UnitTypeSystem(), |
| 148 .rewrite(cpsDefinition); | 166 context.internalError)); |
| 149 context.traceGraph("Sparse constant propagation", cpsDefinition); | 167 applyCpsPass('Redundant phi elimination', new RedundantPhiEliminator()); |
| 150 new RedundantPhiEliminator().rewrite(cpsDefinition); | 168 applyCpsPass('Shrinking reductions', new ShrinkingReducer()); |
| 151 context.traceGraph("Redundant phi elimination", cpsDefinition); | |
| 152 new ShrinkingReducer().rewrite(cpsDefinition); | |
| 153 context.traceGraph("Shrinking reductions", cpsDefinition); | |
| 154 | 169 |
| 155 // Do not rewrite the IR after variable allocation. Allocation | 170 // Do not rewrite the IR after variable allocation. Allocation |
| 156 // makes decisions based on an approximation of IR variable live | 171 // makes decisions based on an approximation of IR variable live |
| 157 // ranges that can be invalidated by transforming the IR. | 172 // ranges that can be invalidated by transforming the IR. |
| 158 new cps_ir.RegisterAllocator().visit(cpsDefinition); | 173 new cps_ir.RegisterAllocator().visit(cpsDefinition); |
| 159 | 174 |
| 160 tree_builder.Builder builder = | 175 tree_builder.Builder builder = |
| 161 new tree_builder.Builder(context.internalError); | 176 new tree_builder.Builder(context.internalError); |
| 162 tree_ir.ExecutableDefinition treeDefinition = builder.build(cpsDefinition); | 177 tree_ir.ExecutableDefinition treeDefinition = builder.build(cpsDefinition); |
| 163 assert(treeDefinition != null); | 178 assert(treeDefinition != null); |
| 164 context.traceGraph('Tree builder', treeDefinition); | 179 context.traceGraph('Tree builder', treeDefinition); |
| 180 assert(checkTreeIntegrity(treeDefinition)); |
| 165 | 181 |
| 166 // Transformations on the Tree IR. | 182 // Transformations on the Tree IR. |
| 167 new StatementRewriter().rewrite(treeDefinition); | 183 void applyTreePass(String name, tree_opt.Pass pass) { |
| 168 context.traceGraph('Statement rewriter', treeDefinition); | 184 pass.rewrite(treeDefinition); |
| 169 new CopyPropagator().rewrite(treeDefinition); | 185 context.traceGraph(name, treeDefinition); |
| 170 context.traceGraph('Copy propagation', treeDefinition); | 186 assert(checkTreeIntegrity(treeDefinition)); |
| 171 new LoopRewriter().rewrite(treeDefinition); | 187 } |
| 172 context.traceGraph('Loop rewriter', treeDefinition); | 188 |
| 173 new LogicalRewriter().rewrite(treeDefinition); | 189 applyTreePass('Statement rewriter', new StatementRewriter()); |
| 174 context.traceGraph('Logical rewriter', treeDefinition); | 190 applyTreePass('Copy propagation', new CopyPropagator()); |
| 191 applyTreePass('Loop rewriter', new LoopRewriter()); |
| 192 applyTreePass('Logical rewriter', new LogicalRewriter()); |
| 193 |
| 194 // Backend-specific transformations. |
| 175 new backend_ast_emitter.UnshadowParameters().unshadow(treeDefinition); | 195 new backend_ast_emitter.UnshadowParameters().unshadow(treeDefinition); |
| 176 context.traceGraph('Unshadow parameters', treeDefinition); | 196 context.traceGraph('Unshadow parameters', treeDefinition); |
| 177 | 197 |
| 178 TreeElementMapping treeElements = new TreeElementMapping(element); | 198 TreeElementMapping treeElements = new TreeElementMapping(element); |
| 179 backend_ast.ExecutableDefinition backendAst = | 199 backend_ast.ExecutableDefinition backendAst = |
| 180 backend_ast_emitter.emit(treeDefinition); | 200 backend_ast_emitter.emit(treeDefinition); |
| 181 Node frontend_ast = backend2frontend.emit(treeElements, backendAst); | 201 Node frontend_ast = backend2frontend.emit(treeElements, backendAst); |
| 182 return new ElementAst(frontend_ast, treeElements); | 202 return new ElementAst(frontend_ast, treeElements); |
| 183 | 203 |
| 184 } | 204 } |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 } | 561 } |
| 542 | 562 |
| 543 void traceGraph(String title, var irObject) { | 563 void traceGraph(String title, var irObject) { |
| 544 compiler.tracer.traceGraph(title, irObject); | 564 compiler.tracer.traceGraph(title, irObject); |
| 545 } | 565 } |
| 546 | 566 |
| 547 DartTypes get dartTypes => compiler.types; | 567 DartTypes get dartTypes => compiler.types; |
| 548 | 568 |
| 549 InternalErrorFunction get internalError => compiler.internalError; | 569 InternalErrorFunction get internalError => compiler.internalError; |
| 550 } | 570 } |
| OLD | NEW |