| 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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 final JavaScriptBackend backend; | 6 final JavaScriptBackend backend; |
| 7 SsaCodeGeneratorTask(JavaScriptBackend backend) | 7 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 8 : this.backend = backend, | 8 : this.backend = backend, |
| 9 super(backend.compiler); | 9 super(backend.compiler); |
| 10 String get name() => 'SSA code generator'; | 10 String get name() => 'SSA code generator'; |
| (...skipping 1827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1838 } | 1838 } |
| 1839 | 1839 |
| 1840 visitFieldGet(HFieldGet node) { | 1840 visitFieldGet(HFieldGet node) { |
| 1841 String name = | 1841 String name = |
| 1842 compiler.namer.instanceFieldName(node.library, node.fieldName); | 1842 compiler.namer.instanceFieldName(node.library, node.fieldName); |
| 1843 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); | 1843 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); |
| 1844 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); | 1844 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); |
| 1845 buffer.add('.'); | 1845 buffer.add('.'); |
| 1846 buffer.add(name); | 1846 buffer.add(name); |
| 1847 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); | 1847 beginExpression(JSPrecedence.MEMBER_PRECEDENCE); |
| 1848 Type type = node.receiver.propagatedType.computeType(compiler); | 1848 if (node.element == null) { |
| 1849 if (type != null) { | 1849 // If we don't have an element we register a dynamic field getter. |
| 1850 world.registerFieldGetter(node.element.name, type); | 1850 // This might lead to unnecessary getters, but these cases should be |
| 1851 // rare. |
| 1852 world.registerDynamicGetter(node.fieldName, Selector.GETTER); |
| 1853 } else { |
| 1854 Type type = node.receiver.propagatedType.computeType(compiler); |
| 1855 if (type != null) { |
| 1856 world.registerFieldGetter(node.element.name, type); |
| 1857 } |
| 1851 } | 1858 } |
| 1852 } | 1859 } |
| 1853 | 1860 |
| 1854 // Determine if an instruction is a simple number computation | 1861 // Determine if an instruction is a simple number computation |
| 1855 // involving only things with guaranteed number types and a given | 1862 // involving only things with guaranteed number types and a given |
| 1856 // field. | 1863 // field. |
| 1857 bool isSimpleFieldNumberComputation(HInstruction value, HFieldSet node) { | 1864 bool isSimpleFieldNumberComputation(HInstruction value, HFieldSet node) { |
| 1858 if (value.guaranteedType.union(HType.NUMBER) == HType.NUMBER) return true; | 1865 if (value.guaranteedType.union(HType.NUMBER) == HType.NUMBER) return true; |
| 1859 if (value is HBinaryArithmetic) { | 1866 if (value is HBinaryArithmetic) { |
| 1860 return (isSimpleFieldNumberComputation(value.left, node) && | 1867 return (isSimpleFieldNumberComputation(value.left, node) && |
| 1861 isSimpleFieldNumberComputation(value.right, node)); | 1868 isSimpleFieldNumberComputation(value.right, node)); |
| 1862 } | 1869 } |
| 1863 if (value is HFieldGet) return value.element == node.element; | 1870 if (value is HFieldGet) return value.element == node.element; |
| 1864 return false; | 1871 return false; |
| 1865 } | 1872 } |
| 1866 | 1873 |
| 1867 visitFieldSet(HFieldSet node) { | 1874 visitFieldSet(HFieldSet node) { |
| 1868 if (work.element.isGenerativeConstructorBody() && | 1875 if (node.element != null && |
| 1876 work.element.isGenerativeConstructorBody() && |
| 1869 node.element.enclosingElement.isClass() && | 1877 node.element.enclosingElement.isClass() && |
| 1870 node.value.hasGuaranteedType() && | 1878 node.value.hasGuaranteedType() && |
| 1871 node.block.dominates(currentGraph.exit)) { | 1879 node.block.dominates(currentGraph.exit)) { |
| 1872 backend.updateFieldConstructorSetters(node.element, | 1880 backend.updateFieldConstructorSetters(node.element, |
| 1873 node.value.guaranteedType); | 1881 node.value.guaranteedType); |
| 1874 } | 1882 } |
| 1875 String name = | 1883 String name = |
| 1876 compiler.namer.instanceFieldName(node.library, node.fieldName); | 1884 compiler.namer.instanceFieldName(node.library, node.fieldName); |
| 1877 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); | 1885 beginExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 1878 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); | 1886 use(node.receiver, JSPrecedence.MEMBER_PRECEDENCE); |
| 1879 buffer.add('.'); | 1887 buffer.add('.'); |
| 1880 buffer.add(name); | 1888 buffer.add(name); |
| 1881 Type type = node.receiver.propagatedType.computeType(compiler); | 1889 if (node.element == null) { |
| 1882 if (type != null) { | 1890 // If we don't have an element we register a dynamic field setter. |
| 1883 if (!work.element.isGenerativeConstructorBody()) { | 1891 // This might lead to unnecessary setters, but these cases should be |
| 1884 world.registerFieldSetter(node.element.name, type); | 1892 // rare. |
| 1885 } | 1893 world.registerDynamicSetter(node.fieldName, Selector.SETTER); |
| 1886 // Determine the types seen so far for the field. If only number | 1894 } else { |
| 1887 // types have been seen and the value of the field set is a | 1895 Type type = node.receiver.propagatedType.computeType(compiler); |
| 1888 // simple number computation only depending on that field, we | 1896 if (type != null) { |
| 1889 // can safely keep the number type for the field. | 1897 if (!work.element.isGenerativeConstructorBody()) { |
| 1890 HType fieldSettersType = backend.fieldSettersTypeSoFar(node.element); | 1898 world.registerFieldSetter(node.element.name, type); |
| 1891 HType initializersType = backend.typeFromInitializersSoFar(node.element); | 1899 } |
| 1892 HType fieldType = fieldSettersType.union(initializersType); | 1900 // Determine the types seen so far for the field. If only number |
| 1893 if (HType.NUMBER.union(fieldType) == HType.NUMBER && | 1901 // types have been seen and the value of the field set is a |
| 1894 isSimpleFieldNumberComputation(node.value, node)) { | 1902 // simple number computation only depending on that field, we |
| 1895 backend.updateFieldSetters(node.element, HType.NUMBER); | 1903 // can safely keep the number type for the field. |
| 1896 } else { | 1904 HType fieldSettersType = backend.fieldSettersTypeSoFar(node.element); |
| 1897 backend.updateFieldSetters(node.element, | 1905 HType initializersType = |
| 1898 node.value.propagatedType); | 1906 backend.typeFromInitializersSoFar(node.element); |
| 1907 HType fieldType = fieldSettersType.union(initializersType); |
| 1908 if (HType.NUMBER.union(fieldType) == HType.NUMBER && |
| 1909 isSimpleFieldNumberComputation(node.value, node)) { |
| 1910 backend.updateFieldSetters(node.element, HType.NUMBER); |
| 1911 } else { |
| 1912 backend.updateFieldSetters(node.element, |
| 1913 node.value.propagatedType); |
| 1914 } |
| 1899 } | 1915 } |
| 1900 } | 1916 } |
| 1901 buffer.add(' = '); | 1917 buffer.add(' = '); |
| 1902 use(node.value, JSPrecedence.ASSIGNMENT_PRECEDENCE); | 1918 use(node.value, JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 1903 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); | 1919 endExpression(JSPrecedence.ASSIGNMENT_PRECEDENCE); |
| 1904 } | 1920 } |
| 1905 | 1921 |
| 1906 visitLocalGet(HLocalGet node) { | 1922 visitLocalGet(HLocalGet node) { |
| 1907 use(node.receiver, JSPrecedence.EXPRESSION_PRECEDENCE); | 1923 use(node.receiver, JSPrecedence.EXPRESSION_PRECEDENCE); |
| 1908 } | 1924 } |
| (...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3192 if (leftType.canBeNull() && rightType.canBeNull()) { | 3208 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 3193 if (left.isConstantNull() || right.isConstantNull() || | 3209 if (left.isConstantNull() || right.isConstantNull() || |
| 3194 (leftType.isPrimitive() && leftType == rightType)) { | 3210 (leftType.isPrimitive() && leftType == rightType)) { |
| 3195 return '=='; | 3211 return '=='; |
| 3196 } | 3212 } |
| 3197 return null; | 3213 return null; |
| 3198 } else { | 3214 } else { |
| 3199 return '==='; | 3215 return '==='; |
| 3200 } | 3216 } |
| 3201 } | 3217 } |
| OLD | NEW |