| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 7 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 8 import '../common/tasks.dart' show CompilerTask; | 8 import '../common/tasks.dart' show CompilerTask; |
| 9 import '../compiler.dart'; | 9 import '../compiler.dart'; |
| 10 import '../diagnostics/spannable.dart'; | 10 import '../diagnostics/spannable.dart'; |
| 11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import '../io/source_information.dart'; | 12 import '../io/source_information.dart'; |
| 13 import '../js_backend/backend.dart' show JavaScriptBackend; | 13 import '../js_backend/backend.dart' show JavaScriptBackend; |
| 14 import '../kernel/kernel.dart'; | 14 import '../kernel/kernel.dart'; |
| 15 import '../kernel/kernel_visitor.dart'; | 15 import '../kernel/kernel_visitor.dart'; |
| 16 import '../resolution/tree_elements.dart'; | 16 import '../resolution/tree_elements.dart'; |
| 17 import '../tree/dartstring.dart'; | 17 import '../tree/dartstring.dart'; |
| 18 import '../types/masks.dart'; | 18 import '../types/masks.dart'; |
| 19 | 19 |
| 20 import 'graph_builder.dart'; | 20 import 'graph_builder.dart'; |
| 21 import 'kernel_ast_adapter.dart'; | 21 import 'kernel_ast_adapter.dart'; |
| 22 import 'locals_handler.dart'; | 22 import 'locals_handler.dart'; |
| 23 import 'nodes.dart'; | 23 import 'nodes.dart'; |
| 24 import 'ssa_branch_builder.dart'; |
| 24 | 25 |
| 25 class SsaKernelBuilderTask extends CompilerTask { | 26 class SsaKernelBuilderTask extends CompilerTask { |
| 26 final JavaScriptBackend backend; | 27 final JavaScriptBackend backend; |
| 27 final SourceInformationStrategy sourceInformationFactory; | 28 final SourceInformationStrategy sourceInformationFactory; |
| 28 | 29 |
| 29 String get name => 'SSA kernel builder'; | 30 String get name => 'SSA kernel builder'; |
| 30 | 31 |
| 31 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) | 32 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) |
| 32 : backend = backend, | 33 : backend = backend, |
| 33 super(backend.compiler.measurer); | 34 super(backend.compiler.measurer); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 60 | 61 |
| 61 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { | 62 class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
| 62 final IrFunction function; | 63 final IrFunction function; |
| 63 final FunctionElement functionElement; | 64 final FunctionElement functionElement; |
| 64 final ResolvedAst resolvedAst; | 65 final ResolvedAst resolvedAst; |
| 65 final Compiler compiler; | 66 final Compiler compiler; |
| 66 final CodegenRegistry registry; | 67 final CodegenRegistry registry; |
| 67 | 68 |
| 68 JavaScriptBackend get backend => compiler.backend; | 69 JavaScriptBackend get backend => compiler.backend; |
| 69 | 70 |
| 70 LocalsHandler localsHandler; | |
| 71 SourceInformationBuilder sourceInformationBuilder; | 71 SourceInformationBuilder sourceInformationBuilder; |
| 72 KernelAstAdapter astAdapter; | 72 KernelAstAdapter astAdapter; |
| 73 | 73 |
| 74 KernelSsaBuilder( | 74 KernelSsaBuilder( |
| 75 this.function, | 75 this.function, |
| 76 this.functionElement, | 76 this.functionElement, |
| 77 this.resolvedAst, | 77 this.resolvedAst, |
| 78 this.compiler, | 78 this.compiler, |
| 79 this.registry, | 79 this.registry, |
| 80 SourceInformationStrategy sourceInformationFactory, | 80 SourceInformationStrategy sourceInformationFactory, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 106 } else { | 106 } else { |
| 107 compiler.reporter.internalError( | 107 compiler.reporter.internalError( |
| 108 functionElement, | 108 functionElement, |
| 109 "Unable to convert this kind of Kernel " | 109 "Unable to convert this kind of Kernel " |
| 110 "procedure to SSA: ${function.kind}"); | 110 "procedure to SSA: ${function.kind}"); |
| 111 } | 111 } |
| 112 assert(graph.isValid()); | 112 assert(graph.isValid()); |
| 113 return graph; | 113 return graph; |
| 114 } | 114 } |
| 115 | 115 |
| 116 @override |
| 117 HInstruction popBoolified() { |
| 118 HInstruction value = pop(); |
| 119 // TODO(het): add boolean conversion type check |
| 120 HInstruction result = new HBoolify(value, backend.boolType); |
| 121 add(result); |
| 122 return result; |
| 123 } |
| 124 |
| 125 // TODO(het): This implementation is shared with [SsaBuilder]. Should we just |
| 126 // allow [GraphBuilder] to access `compiler`? |
| 127 @override |
| 128 pushCheckNull(HInstruction expression) { |
| 129 push(new HIdentity( |
| 130 expression, graph.addConstantNull(compiler), null, backend.boolType)); |
| 131 } |
| 132 |
| 116 /// Builds a SSA graph for [method]. | 133 /// Builds a SSA graph for [method]. |
| 117 void buildMethod(IrFunction method, FunctionElement functionElement) { | 134 void buildMethod(IrFunction method, FunctionElement functionElement) { |
| 118 openFunction(method, functionElement); | 135 openFunction(method, functionElement); |
| 119 method.node.body.accept(this); | 136 method.node.body.accept(this); |
| 120 closeFunction(); | 137 closeFunction(); |
| 121 } | 138 } |
| 122 | 139 |
| 123 void openFunction(IrFunction method, FunctionElement functionElement) { | 140 void openFunction(IrFunction method, FunctionElement functionElement) { |
| 124 HBasicBlock block = graph.addNewBlock(); | 141 HBasicBlock block = graph.addNewBlock(); |
| 125 open(graph.entry); | 142 open(graph.entry); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 149 } | 166 } |
| 150 } | 167 } |
| 151 assert(!current.isClosed()); | 168 assert(!current.isClosed()); |
| 152 if (stack.isNotEmpty) { | 169 if (stack.isNotEmpty) { |
| 153 compiler.reporter | 170 compiler.reporter |
| 154 .internalError(NO_LOCATION_SPANNABLE, 'Non-empty instruction stack'); | 171 .internalError(NO_LOCATION_SPANNABLE, 'Non-empty instruction stack'); |
| 155 } | 172 } |
| 156 } | 173 } |
| 157 | 174 |
| 158 @override | 175 @override |
| 176 visitExpressionStatement(ir.ExpressionStatement exprStatement) { |
| 177 exprStatement.expression.accept(this); |
| 178 pop(); |
| 179 } |
| 180 |
| 181 @override |
| 159 void visitReturnStatement(ir.ReturnStatement returnStatement) { | 182 void visitReturnStatement(ir.ReturnStatement returnStatement) { |
| 160 HInstruction value; | 183 HInstruction value; |
| 161 if (returnStatement.expression == null) { | 184 if (returnStatement.expression == null) { |
| 162 value = graph.addConstantNull(compiler); | 185 value = graph.addConstantNull(compiler); |
| 163 } else { | 186 } else { |
| 164 returnStatement.expression.accept(this); | 187 returnStatement.expression.accept(this); |
| 165 value = pop(); | 188 value = pop(); |
| 166 // TODO(het): Check or trust the type of value | 189 // TODO(het): Check or trust the type of value |
| 167 } | 190 } |
| 168 // TODO(het): Add source information | 191 // TODO(het): Add source information |
| 169 // TODO(het): Set a return value instead of closing the function when we | 192 // TODO(het): Set a return value instead of closing the function when we |
| 170 // support inlining. | 193 // support inlining. |
| 171 closeAndGotoExit(new HReturn(value, null)); | 194 closeAndGotoExit(new HReturn(value, null)); |
| 172 } | 195 } |
| 173 | 196 |
| 174 @override | 197 @override |
| 198 void visitIfStatement(ir.IfStatement ifStatement) { |
| 199 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, compiler); |
| 200 branchBuilder.handleIf( |
| 201 () => ifStatement.condition.accept(this), |
| 202 () => ifStatement.then.accept(this), |
| 203 () => ifStatement.otherwise?.accept(this)); |
| 204 } |
| 205 |
| 206 @override |
| 175 void visitIntLiteral(ir.IntLiteral intLiteral) { | 207 void visitIntLiteral(ir.IntLiteral intLiteral) { |
| 176 stack.add(graph.addConstantInt(intLiteral.value, compiler)); | 208 stack.add(graph.addConstantInt(intLiteral.value, compiler)); |
| 177 } | 209 } |
| 178 | 210 |
| 179 @override | 211 @override |
| 180 visitDoubleLiteral(ir.DoubleLiteral doubleLiteral) { | 212 visitDoubleLiteral(ir.DoubleLiteral doubleLiteral) { |
| 181 stack.add(graph.addConstantDouble(doubleLiteral.value, compiler)); | 213 stack.add(graph.addConstantDouble(doubleLiteral.value, compiler)); |
| 182 } | 214 } |
| 183 | 215 |
| 184 @override | 216 @override |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 push(new HInvokeDynamicMethod(astAdapter.getSelector(invocation), | 300 push(new HInvokeDynamicMethod(astAdapter.getSelector(invocation), |
| 269 astAdapter.getTypeMask(invocation), inputs, type, isIntercepted)); | 301 astAdapter.getTypeMask(invocation), inputs, type, isIntercepted)); |
| 270 } | 302 } |
| 271 | 303 |
| 272 @override | 304 @override |
| 273 visitThisExpression(ir.ThisExpression thisExpression) { | 305 visitThisExpression(ir.ThisExpression thisExpression) { |
| 274 stack.add(localsHandler.readThis()); | 306 stack.add(localsHandler.readThis()); |
| 275 } | 307 } |
| 276 | 308 |
| 277 @override | 309 @override |
| 278 visitExpressionStatement(ir.ExpressionStatement exprStatement) { | 310 visitNot(ir.Not not) { |
| 279 exprStatement.expression.accept(this); | 311 not.operand.accept(this); |
| 280 pop(); | 312 push(new HNot(popBoolified(), backend.boolType)); |
| 281 } | 313 } |
| 282 } | 314 } |
| OLD | NEW |