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 |