Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(966)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/codegen.dart

Issue 16077015: Rip-off the backend type inferrer. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 new SsaLiveIntervalBuilder(compiler, generateAtUseSite); 296 new SsaLiveIntervalBuilder(compiler, generateAtUseSite);
297 intervalBuilder.visitGraph(graph); 297 intervalBuilder.visitGraph(graph);
298 SsaVariableAllocator allocator = new SsaVariableAllocator( 298 SsaVariableAllocator allocator = new SsaVariableAllocator(
299 compiler, 299 compiler,
300 intervalBuilder.liveInstructions, 300 intervalBuilder.liveInstructions,
301 intervalBuilder.liveIntervals, 301 intervalBuilder.liveIntervals,
302 generateAtUseSite); 302 generateAtUseSite);
303 allocator.visitGraph(graph); 303 allocator.visitGraph(graph);
304 variableNames = allocator.names; 304 variableNames = allocator.names;
305 shouldGroupVarDeclarations = allocator.names.numberOfVariables > 1; 305 shouldGroupVarDeclarations = allocator.names.numberOfVariables > 1;
306
307 // Don't register a return type for lazily initialized variables.
308 if (work.element is! FunctionElement) return;
309
310 // Register return types to the backend.
311 graph.exit.predecessors.forEach((HBasicBlock block) {
312 HInstruction last = block.last;
313 assert(last is HGoto || last is HReturn || last is HThrow);
314 if (last is HReturn) {
315 backend.registerReturnType(
316 work.element, last.inputs[0].instructionType);
317 } else if (last is HGoto) {
318 backend.registerReturnType(work.element, HType.NULL);
319 }
320 });
321 } 306 }
322 307
323 void handleDelayedVariableDeclarations() { 308 void handleDelayedVariableDeclarations() {
324 // If we have only one variable declaration and the first statement is an 309 // If we have only one variable declaration and the first statement is an
325 // assignment to that variable then we can merge the two. We count the 310 // assignment to that variable then we can merge the two. We count the
326 // number of variables in the variable allocator to try to avoid this issue, 311 // number of variables in the variable allocator to try to avoid this issue,
327 // but it sometimes happens that the variable allocator introduces a 312 // but it sometimes happens that the variable allocator introduces a
328 // temporary variable that it later eliminates. 313 // temporary variable that it later eliminates.
329 if (!collectedVariableDeclarations.isEmpty) { 314 if (!collectedVariableDeclarations.isEmpty) {
330 if (collectedVariableDeclarations.length == 1 && 315 if (collectedVariableDeclarations.length == 1 &&
(...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 } 1541 }
1557 1542
1558 void registerInvoke(HInvokeDynamic node, Selector selector) { 1543 void registerInvoke(HInvokeDynamic node, Selector selector) {
1559 if (node.isInterceptedCall) { 1544 if (node.isInterceptedCall) {
1560 backend.addInterceptedSelector(selector); 1545 backend.addInterceptedSelector(selector);
1561 } 1546 }
1562 } 1547 }
1563 1548
1564 void registerMethodInvoke(HInvokeDynamic node) { 1549 void registerMethodInvoke(HInvokeDynamic node) {
1565 Selector selector = getOptimizedSelectorFor(node, node.selector); 1550 Selector selector = getOptimizedSelectorFor(node, node.selector);
1566 // Register this invocation to collect the types used at all call sites.
1567 backend.registerDynamicInvocation(node, selector);
1568 1551
1569 // If we don't know what we're calling or if we are calling a getter, 1552 // If we don't know what we're calling or if we are calling a getter,
1570 // we need to register that fact that we may be calling a closure 1553 // we need to register that fact that we may be calling a closure
1571 // with the same arguments. 1554 // with the same arguments.
1572 Element target = node.element; 1555 Element target = node.element;
1573 if (target == null || target.isGetter()) { 1556 if (target == null || target.isGetter()) {
1574 // TODO(kasperl): If we have a typed selector for the call, we 1557 // TODO(kasperl): If we have a typed selector for the call, we
1575 // may know something about the types of closures that need 1558 // may know something about the types of closures that need
1576 // the specific closure call method. 1559 // the specific closure call method.
1577 Selector call = new Selector.callClosureFrom(selector); 1560 Selector call = new Selector.callClosureFrom(selector);
(...skipping 10 matching lines...) Expand all
1588 } 1571 }
1589 registerInvoke(node, selector); 1572 registerInvoke(node, selector);
1590 } 1573 }
1591 1574
1592 void registerSetter(HInvokeDynamic node) { 1575 void registerSetter(HInvokeDynamic node) {
1593 Selector selector = getOptimizedSelectorFor(node, node.selector); 1576 Selector selector = getOptimizedSelectorFor(node, node.selector);
1594 world.registerDynamicSetter(selector.name, selector); 1577 world.registerDynamicSetter(selector.name, selector);
1595 HType valueType = node.isInterceptedCall 1578 HType valueType = node.isInterceptedCall
1596 ? node.inputs[2].instructionType 1579 ? node.inputs[2].instructionType
1597 : node.inputs[1].instructionType; 1580 : node.inputs[1].instructionType;
1598 backend.addedDynamicSetter(selector, valueType);
1599 registerInvoke(node, selector); 1581 registerInvoke(node, selector);
1600 } 1582 }
1601 1583
1602 void registerGetter(HInvokeDynamic node) { 1584 void registerGetter(HInvokeDynamic node) {
1603 Selector selector = getOptimizedSelectorFor(node, node.selector); 1585 Selector selector = getOptimizedSelectorFor(node, node.selector);
1604 world.registerDynamicGetter(selector.name, selector); 1586 world.registerDynamicGetter(selector.name, selector);
1605 world.registerInstantiatedClass( 1587 world.registerInstantiatedClass(
1606 compiler.functionClass, work.resolutionTree); 1588 compiler.functionClass, work.resolutionTree);
1607 registerInvoke(node, selector); 1589 registerInvoke(node, selector);
1608 } 1590 }
(...skipping 16 matching lines...) Expand all
1625 Selector call = new Selector.callClosureFrom(node.selector); 1607 Selector call = new Selector.callClosureFrom(node.selector);
1626 use(node.receiver); 1608 use(node.receiver);
1627 push(jsPropertyCall(pop(), 1609 push(jsPropertyCall(pop(),
1628 backend.namer.invocationName(call), 1610 backend.namer.invocationName(call),
1629 visitArguments(node.inputs)), 1611 visitArguments(node.inputs)),
1630 node); 1612 node);
1631 world.registerDynamicInvocation(call.name, call); 1613 world.registerDynamicInvocation(call.name, call);
1632 } 1614 }
1633 1615
1634 visitInvokeStatic(HInvokeStatic node) { 1616 visitInvokeStatic(HInvokeStatic node) {
1635 if (node.typeCode() == HInstruction.INVOKE_STATIC_TYPECODE) {
1636 // Register this invocation to collect the types used at all call sites.
1637 backend.registerStaticInvocation(node);
1638 }
1639 Element element = node.element; 1617 Element element = node.element;
1640 world.registerStaticUse(element); 1618 world.registerStaticUse(element);
1641 ClassElement cls = element.getEnclosingClass(); 1619 ClassElement cls = element.getEnclosingClass();
1642 if (element.isGenerativeConstructor() 1620 if (element.isGenerativeConstructor()
1643 || (element.isFactoryConstructor() && cls == compiler.listClass)) { 1621 || (element.isFactoryConstructor() && cls == compiler.listClass)) {
1644 world.registerInstantiatedClass(cls, work.resolutionTree); 1622 world.registerInstantiatedClass(cls, work.resolutionTree);
1645 } 1623 }
1646 push(new js.VariableUse(backend.namer.isolateAccess(node.element))); 1624 push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
1647 push(new js.Call(pop(), visitArguments(node.inputs, start: 0)), node); 1625 push(new js.Call(pop(), visitArguments(node.inputs, start: 0)), node);
1648 } 1626 }
(...skipping 18 matching lines...) Expand all
1667 } else { 1645 } else {
1668 String methodName = backend.namer.getName(superMethod); 1646 String methodName = backend.namer.getName(superMethod);
1669 String className = backend.namer.isolateAccess(superClass); 1647 String className = backend.namer.isolateAccess(superClass);
1670 js.VariableUse classReference = new js.VariableUse(className); 1648 js.VariableUse classReference = new js.VariableUse(className);
1671 js.PropertyAccess prototype = 1649 js.PropertyAccess prototype =
1672 new js.PropertyAccess.field(classReference, "prototype"); 1650 new js.PropertyAccess.field(classReference, "prototype");
1673 js.PropertyAccess method = 1651 js.PropertyAccess method =
1674 new js.PropertyAccess.field(prototype, methodName); 1652 new js.PropertyAccess.field(prototype, methodName);
1675 push(jsPropertyCall( 1653 push(jsPropertyCall(
1676 method, "call", visitArguments(node.inputs, start: 0)), node); 1654 method, "call", visitArguments(node.inputs, start: 0)), node);
1677 // Register this invocation to collect the types used at all call sites.
1678 backend.registerDynamicInvocation(node, node.selector);
1679 } 1655 }
1680 } 1656 }
1681 1657
1682 visitFieldGet(HFieldGet node) { 1658 visitFieldGet(HFieldGet node) {
1683 use(node.receiver); 1659 use(node.receiver);
1684 Element element = node.element; 1660 Element element = node.element;
1685 if (element == backend.jsIndexableLength) { 1661 if (element == backend.jsIndexableLength) {
1686 // We're accessing a native JavaScript property called 'length' 1662 // We're accessing a native JavaScript property called 'length'
1687 // on a JS String or a JS array. Therefore, the name of that 1663 // on a JS String or a JS array. Therefore, the name of that
1688 // property should not be mangled. 1664 // property should not be mangled.
1689 push(new js.PropertyAccess.field(pop(), 'length'), node); 1665 push(new js.PropertyAccess.field(pop(), 'length'), node);
1690 } else { 1666 } else {
1691 String name = _fieldPropertyName(element); 1667 String name = _fieldPropertyName(element);
1692 push(new js.PropertyAccess.field(pop(), name), node); 1668 push(new js.PropertyAccess.field(pop(), name), node);
1693 world.registerFieldGetter(element); 1669 world.registerFieldGetter(element);
1694 } 1670 }
1695 } 1671 }
1696 1672
1697 visitFieldSet(HFieldSet node) { 1673 visitFieldSet(HFieldSet node) {
1698 Element element = node.element; 1674 Element element = node.element;
1675 world.registerFieldSetter(element);
1699 String name = _fieldPropertyName(element); 1676 String name = _fieldPropertyName(element);
1700 if (!node.receiver.instructionType.isUnknown()) {
1701 // Field setters in the generative constructor body are handled in a
1702 // step "SsaConstructionFieldTypes" in the ssa optimizer.
1703 if (!work.element.isGenerativeConstructorBody()) {
1704 world.registerFieldSetter(element);
1705 backend.registerFieldSetter(
1706 work.element, element, node.value.instructionType);
1707 }
1708 }
1709 use(node.receiver); 1677 use(node.receiver);
1710 js.Expression receiver = pop(); 1678 js.Expression receiver = pop();
1711 use(node.value); 1679 use(node.value);
1712 push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()), 1680 push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()),
1713 node); 1681 node);
1714 } 1682 }
1715 1683
1716 String _fieldPropertyName(Element element) => element.hasFixedBackendName() 1684 String _fieldPropertyName(Element element) => element.hasFixedBackendName()
1717 ? element.fixedBackendName() 1685 ? element.fixedBackendName()
1718 : backend.namer.getName(element); 1686 : backend.namer.getName(element);
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 push(value, node); 1981 push(value, node);
2014 } 1982 }
2015 1983
2016 void visitSwitch(HSwitch node) { 1984 void visitSwitch(HSwitch node) {
2017 // Switches are handled using [visitSwitchInfo]. 1985 // Switches are handled using [visitSwitchInfo].
2018 } 1986 }
2019 1987
2020 void visitStatic(HStatic node) { 1988 void visitStatic(HStatic node) {
2021 Element element = node.element; 1989 Element element = node.element;
2022 if (element.isFunction()) { 1990 if (element.isFunction()) {
2023 backend.registerNonCallStaticUse(node);
2024 world.registerInstantiatedClass( 1991 world.registerInstantiatedClass(
2025 compiler.functionClass, work.resolutionTree); 1992 compiler.functionClass, work.resolutionTree);
2026 push(new js.VariableUse( 1993 push(new js.VariableUse(
2027 backend.namer.isolateStaticClosureAccess(node.element))); 1994 backend.namer.isolateStaticClosureAccess(node.element)));
2028 } else { 1995 } else {
2029 push(new js.VariableUse(backend.namer.isolateAccess(node.element))); 1996 push(new js.VariableUse(backend.namer.isolateAccess(node.element)));
2030 } 1997 }
2031 world.registerStaticUse(element); 1998 world.registerStaticUse(element);
2032 } 1999 }
2033 2000
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after
3036 if (leftType.canBeNull() && rightType.canBeNull()) { 3003 if (leftType.canBeNull() && rightType.canBeNull()) {
3037 if (left.isConstantNull() || right.isConstantNull() || 3004 if (left.isConstantNull() || right.isConstantNull() ||
3038 (leftType.isPrimitive() && leftType == rightType)) { 3005 (leftType.isPrimitive() && leftType == rightType)) {
3039 return '=='; 3006 return '==';
3040 } 3007 }
3041 return null; 3008 return null;
3042 } else { 3009 } else {
3043 return '==='; 3010 return '===';
3044 } 3011 }
3045 } 3012 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698