| 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 ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class SsaCodeGeneratorTask extends CompilerTask { | 7 class SsaCodeGeneratorTask extends CompilerTask { |
| 8 | 8 |
| 9 final JavaScriptBackend backend; | 9 final JavaScriptBackend backend; |
| 10 | 10 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 compiler.tracer.traceGraph("codegen", graph); | 73 compiler.tracer.traceGraph("codegen", graph); |
| 74 SsaCodeGenerator codegen = new SsaCodeGenerator(backend, work); | 74 SsaCodeGenerator codegen = new SsaCodeGenerator(backend, work); |
| 75 codegen.visitGraph(graph); | 75 codegen.visitGraph(graph); |
| 76 return new js.Fun(codegen.parameters, | 76 return new js.Fun(codegen.parameters, |
| 77 attachPosition(codegen.body, work.element)); | 77 attachPosition(codegen.body, work.element)); |
| 78 }); | 78 }); |
| 79 } | 79 } |
| 80 | 80 |
| 81 js.Expression generateMethod(CodegenWorkItem work, HGraph graph) { | 81 js.Expression generateMethod(CodegenWorkItem work, HGraph graph) { |
| 82 return measure(() { | 82 return measure(() { |
| 83 compiler.tracer.traceGraph("codegen", graph); | |
| 84 SsaCodeGenerator codegen = new SsaCodeGenerator(backend, work); | 83 SsaCodeGenerator codegen = new SsaCodeGenerator(backend, work); |
| 85 codegen.visitGraph(graph); | 84 codegen.visitGraph(graph); |
| 85 compiler.tracer.traceGraph("codegen", graph); |
| 86 FunctionElement element = work.element; | 86 FunctionElement element = work.element; |
| 87 return buildJavaScriptFunction(element, codegen.parameters, codegen.body); | 87 return buildJavaScriptFunction(element, codegen.parameters, codegen.body); |
| 88 }); | 88 }); |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 | 91 |
| 92 typedef void ElementAction(Element element); | 92 typedef void ElementAction(Element element); |
| 93 | 93 |
| 94 class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { | 94 class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
| 95 /** | 95 /** |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 SourceFileLocation endSourcePosition) { | 275 SourceFileLocation endSourcePosition) { |
| 276 jsNode.sourcePosition = sourcePosition; | 276 jsNode.sourcePosition = sourcePosition; |
| 277 jsNode.endSourcePosition = endSourcePosition; | 277 jsNode.endSourcePosition = endSourcePosition; |
| 278 return jsNode; | 278 return jsNode; |
| 279 } | 279 } |
| 280 | 280 |
| 281 beginGraph(HGraph graph); | 281 beginGraph(HGraph graph); |
| 282 endGraph(HGraph graph); | 282 endGraph(HGraph graph); |
| 283 | 283 |
| 284 void preGenerateMethod(HGraph graph) { | 284 void preGenerateMethod(HGraph graph) { |
| 285 new SsaTypeKnownRemover().visitGraph(graph); |
| 285 new SsaInstructionMerger(generateAtUseSite, compiler).visitGraph(graph); | 286 new SsaInstructionMerger(generateAtUseSite, compiler).visitGraph(graph); |
| 286 new SsaConditionMerger( | 287 new SsaConditionMerger( |
| 287 generateAtUseSite, controlFlowOperators).visitGraph(graph); | 288 generateAtUseSite, controlFlowOperators).visitGraph(graph); |
| 288 SsaLiveIntervalBuilder intervalBuilder = new SsaLiveIntervalBuilder( | 289 SsaLiveIntervalBuilder intervalBuilder = new SsaLiveIntervalBuilder( |
| 289 compiler, generateAtUseSite, controlFlowOperators); | 290 compiler, generateAtUseSite, controlFlowOperators); |
| 290 intervalBuilder.visitGraph(graph); | 291 intervalBuilder.visitGraph(graph); |
| 291 SsaVariableAllocator allocator = new SsaVariableAllocator( | 292 SsaVariableAllocator allocator = new SsaVariableAllocator( |
| 292 compiler, | 293 compiler, |
| 293 intervalBuilder.liveInstructions, | 294 intervalBuilder.liveInstructions, |
| 294 intervalBuilder.liveIntervals, | 295 intervalBuilder.liveIntervals, |
| (...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 // type because our optimizations might end up in a state where the | 1539 // type because our optimizations might end up in a state where the |
| 1539 // invoke dynamic knows more than the receiver. | 1540 // invoke dynamic knows more than the receiver. |
| 1540 ClassElement enclosing = node.element.getEnclosingClass(); | 1541 ClassElement enclosing = node.element.getEnclosingClass(); |
| 1541 HType receiverType = new HType.fromMask( | 1542 HType receiverType = new HType.fromMask( |
| 1542 new TypeMask.nonNullExact(enclosing.declaration), | 1543 new TypeMask.nonNullExact(enclosing.declaration), |
| 1543 compiler); | 1544 compiler); |
| 1544 return receiverType.refine(selector, compiler); | 1545 return receiverType.refine(selector, compiler); |
| 1545 } | 1546 } |
| 1546 // If [JSInvocationMirror._invokeOn] has been called, we must not create a | 1547 // If [JSInvocationMirror._invokeOn] has been called, we must not create a |
| 1547 // typed selector based on the receiver type. | 1548 // typed selector based on the receiver type. |
| 1548 if (backend.compiler.enabledInvokeOn) { | 1549 return backend.compiler.enabledInvokeOn ? selector.asUntyped : selector; |
| 1549 return selector.asUntyped; | |
| 1550 } | |
| 1551 HType receiverType = node.getDartReceiver(compiler).instructionType; | |
| 1552 return receiverType.refine(selector, compiler); | |
| 1553 } | 1550 } |
| 1554 | 1551 |
| 1555 void registerMethodInvoke(HInvokeDynamic node) { | 1552 void registerMethodInvoke(HInvokeDynamic node) { |
| 1556 Selector selector = getOptimizedSelectorFor(node, node.selector); | 1553 Selector selector = getOptimizedSelectorFor(node, node.selector); |
| 1557 | 1554 |
| 1558 // If we don't know what we're calling or if we are calling a getter, | 1555 // If we don't know what we're calling or if we are calling a getter, |
| 1559 // we need to register that fact that we may be calling a closure | 1556 // we need to register that fact that we may be calling a closure |
| 1560 // with the same arguments. | 1557 // with the same arguments. |
| 1561 Element target = node.element; | 1558 Element target = node.element; |
| 1562 if (target == null || target.isGetter()) { | 1559 if (target == null || target.isGetter()) { |
| (...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2570 const CheckedModeHelper('boolConversionCheck'); | 2567 const CheckedModeHelper('boolConversionCheck'); |
| 2571 } else { | 2568 } else { |
| 2572 helper = | 2569 helper = |
| 2573 backend.getCheckedModeHelper(type, typeCast: node.isCastTypeCheck); | 2570 backend.getCheckedModeHelper(type, typeCast: node.isCastTypeCheck); |
| 2574 } | 2571 } |
| 2575 | 2572 |
| 2576 push(helper.generateCall(this, node)); | 2573 push(helper.generateCall(this, node)); |
| 2577 } | 2574 } |
| 2578 | 2575 |
| 2579 void visitTypeKnown(HTypeKnown node) { | 2576 void visitTypeKnown(HTypeKnown node) { |
| 2580 use(node.checkedInput); | 2577 // [HTypeKnown] instructions are removed before generating code. |
| 2578 assert(false); |
| 2581 } | 2579 } |
| 2582 } | 2580 } |
| 2583 | 2581 |
| 2584 String singleIdentityComparison(HInstruction left, | 2582 String singleIdentityComparison(HInstruction left, |
| 2585 HInstruction right, | 2583 HInstruction right, |
| 2586 Compiler compiler) { | 2584 Compiler compiler) { |
| 2587 // Returns the single identity comparison (== or ===) or null if a more | 2585 // Returns the single identity comparison (== or ===) or null if a more |
| 2588 // complex expression is required. | 2586 // complex expression is required. |
| 2589 if ((left.isConstant() && left.isConstantSentinel()) || | 2587 if ((left.isConstant() && left.isConstantSentinel()) || |
| 2590 (right.isConstant() && right.isConstantSentinel())) return '==='; | 2588 (right.isConstant() && right.isConstantSentinel())) return '==='; |
| 2591 HType leftType = left.instructionType; | 2589 HType leftType = left.instructionType; |
| 2592 HType rightType = right.instructionType; | 2590 HType rightType = right.instructionType; |
| 2593 if (leftType.canBeNull() && rightType.canBeNull()) { | 2591 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 2594 if (left.isConstantNull() || right.isConstantNull() || | 2592 if (left.isConstantNull() || right.isConstantNull() || |
| 2595 (leftType.isPrimitive(compiler) && leftType == rightType)) { | 2593 (leftType.isPrimitive(compiler) && leftType == rightType)) { |
| 2596 return '=='; | 2594 return '=='; |
| 2597 } | 2595 } |
| 2598 return null; | 2596 return null; |
| 2599 } else { | 2597 } else { |
| 2600 return '==='; | 2598 return '==='; |
| 2601 } | 2599 } |
| 2602 } | 2600 } |
| OLD | NEW |