Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #include "vm/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1731 case MethodRecognizer::kByteArrayBaseSetFloat32x4: | 1731 case MethodRecognizer::kByteArrayBaseSetFloat32x4: |
| 1732 return BuildByteArrayViewStore( | 1732 return BuildByteArrayViewStore( |
| 1733 call, class_ids[0], kTypedDataFloat32x4ArrayCid); | 1733 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1734 default: | 1734 default: |
| 1735 // Unsupported method. | 1735 // Unsupported method. |
| 1736 return false; | 1736 return false; |
| 1737 } | 1737 } |
| 1738 } | 1738 } |
| 1739 | 1739 |
| 1740 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 1740 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| 1741 switch (recognized_kind) { | 1741 return TryInlineFloat32x4Method(call, recognized_kind); |
| 1742 case MethodRecognizer::kFloat32x4Equal: | |
| 1743 case MethodRecognizer::kFloat32x4GreaterThan: | |
| 1744 case MethodRecognizer::kFloat32x4GreaterThanOrEqual: | |
| 1745 case MethodRecognizer::kFloat32x4LessThan: | |
| 1746 case MethodRecognizer::kFloat32x4LessThanOrEqual: | |
| 1747 case MethodRecognizer::kFloat32x4NotEqual: { | |
| 1748 Definition* left = call->ArgumentAt(0); | |
| 1749 Definition* right = call->ArgumentAt(1); | |
| 1750 // Type check left. | |
| 1751 AddCheckClass(left, | |
| 1752 ICData::ZoneHandle( | |
| 1753 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1754 call->deopt_id(), | |
| 1755 call->env(), | |
| 1756 call); | |
| 1757 // Replace call. | |
| 1758 Float32x4ComparisonInstr* cmp = | |
| 1759 new Float32x4ComparisonInstr(recognized_kind, new Value(left), | |
| 1760 new Value(right), call); | |
| 1761 ReplaceCall(call, cmp); | |
| 1762 return true; | |
| 1763 } | |
| 1764 case MethodRecognizer::kFloat32x4Min: | |
| 1765 case MethodRecognizer::kFloat32x4Max: { | |
| 1766 Definition* left = call->ArgumentAt(0); | |
| 1767 Definition* right = call->ArgumentAt(1); | |
| 1768 // Type check left. | |
| 1769 AddCheckClass(left, | |
| 1770 ICData::ZoneHandle( | |
| 1771 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1772 call->deopt_id(), | |
| 1773 call->env(), | |
| 1774 call); | |
| 1775 Float32x4MinMaxInstr* minmax = | |
| 1776 new Float32x4MinMaxInstr(recognized_kind, new Value(left), | |
| 1777 new Value(right), call); | |
| 1778 ReplaceCall(call, minmax); | |
| 1779 return true; | |
| 1780 } | |
| 1781 case MethodRecognizer::kFloat32x4Scale: { | |
| 1782 Definition* left = call->ArgumentAt(0); | |
| 1783 Definition* right = call->ArgumentAt(1); | |
| 1784 // Type check left. | |
| 1785 AddCheckClass(left, | |
| 1786 ICData::ZoneHandle( | |
| 1787 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1788 call->deopt_id(), | |
| 1789 call->env(), | |
| 1790 call); | |
| 1791 // Left and right values are swapped when handed to the instruction, | |
| 1792 // this is done so that the double value is loaded into the output | |
| 1793 // register and can be destroyed. | |
| 1794 Float32x4ScaleInstr* scale = | |
| 1795 new Float32x4ScaleInstr(recognized_kind, new Value(right), | |
| 1796 new Value(left), call); | |
| 1797 ReplaceCall(call, scale); | |
| 1798 return true; | |
| 1799 } | |
| 1800 case MethodRecognizer::kFloat32x4Sqrt: | |
| 1801 case MethodRecognizer::kFloat32x4ReciprocalSqrt: | |
| 1802 case MethodRecognizer::kFloat32x4Reciprocal: { | |
| 1803 Definition* left = call->ArgumentAt(0); | |
| 1804 AddCheckClass(left, | |
| 1805 ICData::ZoneHandle( | |
| 1806 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1807 call->deopt_id(), | |
| 1808 call->env(), | |
| 1809 call); | |
| 1810 Float32x4SqrtInstr* sqrt = | |
| 1811 new Float32x4SqrtInstr(recognized_kind, new Value(left), call); | |
| 1812 ReplaceCall(call, sqrt); | |
| 1813 return true; | |
| 1814 } | |
| 1815 default: | |
| 1816 return false; | |
| 1817 } | |
| 1818 } | 1742 } |
| 1819 return false; | 1743 return false; |
| 1820 } | 1744 } |
| 1821 | 1745 |
| 1822 | 1746 |
| 1747 bool FlowGraphOptimizer::TryInlineFloat32x4Method( | |
| 1748 InstanceCallInstr* call, | |
|
srdjan
2013/05/01 20:02:24
can call be const &?
Cutch
2013/05/01 20:11:18
Not simply. ReplaceCall takes a non-const pointer
srdjan
2013/05/01 20:18:41
I see.
| |
| 1749 MethodRecognizer::Kind recognized_kind) { | |
| 1750 ASSERT(call->HasICData()); | |
| 1751 switch (recognized_kind) { | |
| 1752 case MethodRecognizer::kFloat32x4Equal: | |
| 1753 case MethodRecognizer::kFloat32x4GreaterThan: | |
| 1754 case MethodRecognizer::kFloat32x4GreaterThanOrEqual: | |
| 1755 case MethodRecognizer::kFloat32x4LessThan: | |
| 1756 case MethodRecognizer::kFloat32x4LessThanOrEqual: | |
| 1757 case MethodRecognizer::kFloat32x4NotEqual: { | |
| 1758 Definition* left = call->ArgumentAt(0); | |
| 1759 Definition* right = call->ArgumentAt(1); | |
| 1760 // Type check left. | |
| 1761 AddCheckClass(left, | |
| 1762 ICData::ZoneHandle( | |
| 1763 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1764 call->deopt_id(), | |
| 1765 call->env(), | |
| 1766 call); | |
| 1767 // Replace call. | |
| 1768 Float32x4ComparisonInstr* cmp = | |
| 1769 new Float32x4ComparisonInstr(recognized_kind, new Value(left), | |
| 1770 new Value(right), call); | |
| 1771 ReplaceCall(call, cmp); | |
| 1772 return true; | |
| 1773 } | |
| 1774 case MethodRecognizer::kFloat32x4Min: | |
| 1775 case MethodRecognizer::kFloat32x4Max: { | |
| 1776 Definition* left = call->ArgumentAt(0); | |
| 1777 Definition* right = call->ArgumentAt(1); | |
| 1778 // Type check left. | |
| 1779 AddCheckClass(left, | |
| 1780 ICData::ZoneHandle( | |
| 1781 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1782 call->deopt_id(), | |
| 1783 call->env(), | |
| 1784 call); | |
| 1785 Float32x4MinMaxInstr* minmax = | |
| 1786 new Float32x4MinMaxInstr(recognized_kind, new Value(left), | |
| 1787 new Value(right), call); | |
| 1788 ReplaceCall(call, minmax); | |
| 1789 return true; | |
| 1790 } | |
| 1791 case MethodRecognizer::kFloat32x4Scale: { | |
| 1792 Definition* left = call->ArgumentAt(0); | |
| 1793 Definition* right = call->ArgumentAt(1); | |
| 1794 // Type check left. | |
| 1795 AddCheckClass(left, | |
| 1796 ICData::ZoneHandle( | |
| 1797 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1798 call->deopt_id(), | |
| 1799 call->env(), | |
| 1800 call); | |
| 1801 // Left and right values are swapped when handed to the instruction, | |
| 1802 // this is done so that the double value is loaded into the output | |
| 1803 // register and can be destroyed. | |
| 1804 Float32x4ScaleInstr* scale = | |
| 1805 new Float32x4ScaleInstr(recognized_kind, new Value(right), | |
| 1806 new Value(left), call); | |
| 1807 ReplaceCall(call, scale); | |
| 1808 return true; | |
| 1809 } | |
| 1810 case MethodRecognizer::kFloat32x4Sqrt: | |
| 1811 case MethodRecognizer::kFloat32x4ReciprocalSqrt: | |
| 1812 case MethodRecognizer::kFloat32x4Reciprocal: { | |
| 1813 Definition* left = call->ArgumentAt(0); | |
| 1814 AddCheckClass(left, | |
| 1815 ICData::ZoneHandle( | |
| 1816 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1817 call->deopt_id(), | |
| 1818 call->env(), | |
| 1819 call); | |
| 1820 Float32x4SqrtInstr* sqrt = | |
| 1821 new Float32x4SqrtInstr(recognized_kind, new Value(left), call); | |
| 1822 ReplaceCall(call, sqrt); | |
| 1823 return true; | |
| 1824 } | |
| 1825 case MethodRecognizer::kFloat32x4WithX: | |
| 1826 case MethodRecognizer::kFloat32x4WithY: | |
| 1827 case MethodRecognizer::kFloat32x4WithZ: | |
| 1828 case MethodRecognizer::kFloat32x4WithW: { | |
| 1829 Definition* left = call->ArgumentAt(0); | |
| 1830 Definition* right = call->ArgumentAt(1); | |
| 1831 // Type check left. | |
| 1832 AddCheckClass(left, | |
| 1833 ICData::ZoneHandle( | |
| 1834 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1835 call->deopt_id(), | |
| 1836 call->env(), | |
| 1837 call); | |
| 1838 Float32x4WithInstr* with = new Float32x4WithInstr(recognized_kind, | |
| 1839 new Value(left), | |
| 1840 new Value(right), | |
| 1841 call); | |
| 1842 ReplaceCall(call, with); | |
| 1843 return true; | |
| 1844 } | |
| 1845 case MethodRecognizer::kFloat32x4Absolute: | |
| 1846 case MethodRecognizer::kFloat32x4Negate: { | |
| 1847 Definition* left = call->ArgumentAt(0); | |
| 1848 // Type check left. | |
| 1849 AddCheckClass(left, | |
| 1850 ICData::ZoneHandle( | |
| 1851 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1852 call->deopt_id(), | |
| 1853 call->env(), | |
| 1854 call); | |
| 1855 Float32x4ZeroArgInstr* zeroArg = | |
| 1856 new Float32x4ZeroArgInstr(recognized_kind, new Value(left), call); | |
| 1857 ReplaceCall(call, zeroArg); | |
| 1858 return true; | |
| 1859 } | |
| 1860 case MethodRecognizer::kFloat32x4Clamp: { | |
| 1861 Definition* left = call->ArgumentAt(0); | |
| 1862 Definition* lower = call->ArgumentAt(1); | |
| 1863 Definition* upper = call->ArgumentAt(2); | |
| 1864 // Type check left. | |
| 1865 AddCheckClass(left, | |
| 1866 ICData::ZoneHandle( | |
| 1867 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1868 call->deopt_id(), | |
| 1869 call->env(), | |
| 1870 call); | |
| 1871 Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left), | |
| 1872 new Value(lower), | |
| 1873 new Value(upper), | |
| 1874 call); | |
| 1875 ReplaceCall(call, clamp); | |
| 1876 return true; | |
| 1877 } | |
| 1878 case MethodRecognizer::kFloat32x4ToUint32x4: { | |
| 1879 Definition* left = call->ArgumentAt(0); | |
| 1880 // Type check left. | |
| 1881 AddCheckClass(left, | |
| 1882 ICData::ZoneHandle( | |
| 1883 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1884 call->deopt_id(), | |
| 1885 call->env(), | |
| 1886 call); | |
| 1887 Float32x4ToUint32x4Instr* cast = | |
| 1888 new Float32x4ToUint32x4Instr(new Value(left), call); | |
| 1889 ReplaceCall(call, cast); | |
| 1890 return true; | |
| 1891 } | |
| 1892 default: | |
| 1893 return false; | |
| 1894 } | |
| 1895 } | |
| 1896 | |
| 1897 | |
| 1823 bool FlowGraphOptimizer::BuildByteArrayViewLoad( | 1898 bool FlowGraphOptimizer::BuildByteArrayViewLoad( |
| 1824 InstanceCallInstr* call, | 1899 InstanceCallInstr* call, |
| 1825 intptr_t receiver_cid, | 1900 intptr_t receiver_cid, |
| 1826 intptr_t view_cid) { | 1901 intptr_t view_cid) { |
| 1827 Definition* array = call->ArgumentAt(0); | 1902 Definition* array = call->ArgumentAt(0); |
| 1828 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); | 1903 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); |
| 1829 | 1904 |
| 1830 // Optimistically build a smi-checked load for Int32 and Uint32 | 1905 // Optimistically build a smi-checked load for Int32 and Uint32 |
| 1831 // loads on ia32 like we do for normal array loads, and only revert to | 1906 // loads on ia32 like we do for normal array loads, and only revert to |
| 1832 // mint case after deoptimizing here. | 1907 // mint case after deoptimizing here. |
| (...skipping 3097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4930 void ConstantPropagator::VisitFloat32x4Scale(Float32x4ScaleInstr* instr) { | 5005 void ConstantPropagator::VisitFloat32x4Scale(Float32x4ScaleInstr* instr) { |
| 4931 SetValue(instr, non_constant_); | 5006 SetValue(instr, non_constant_); |
| 4932 } | 5007 } |
| 4933 | 5008 |
| 4934 | 5009 |
| 4935 void ConstantPropagator::VisitFloat32x4Sqrt(Float32x4SqrtInstr* instr) { | 5010 void ConstantPropagator::VisitFloat32x4Sqrt(Float32x4SqrtInstr* instr) { |
| 4936 SetValue(instr, non_constant_); | 5011 SetValue(instr, non_constant_); |
| 4937 } | 5012 } |
| 4938 | 5013 |
| 4939 | 5014 |
| 5015 void ConstantPropagator::VisitFloat32x4ZeroArg(Float32x4ZeroArgInstr* instr) { | |
| 5016 SetValue(instr, non_constant_); | |
| 5017 } | |
| 5018 | |
| 5019 | |
| 5020 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) { | |
| 5021 SetValue(instr, non_constant_); | |
| 5022 } | |
| 5023 | |
| 5024 | |
| 5025 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) { | |
| 5026 SetValue(instr, non_constant_); | |
| 5027 } | |
| 5028 | |
| 5029 | |
| 5030 void ConstantPropagator::VisitFloat32x4ToUint32x4( | |
| 5031 Float32x4ToUint32x4Instr* instr) { | |
| 5032 SetValue(instr, non_constant_); | |
| 5033 } | |
| 5034 | |
| 5035 | |
| 4940 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) { | 5036 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) { |
| 4941 const Object& value = instr->value()->definition()->constant_value(); | 5037 const Object& value = instr->value()->definition()->constant_value(); |
| 4942 if (IsNonConstant(value)) { | 5038 if (IsNonConstant(value)) { |
| 4943 SetValue(instr, non_constant_); | 5039 SetValue(instr, non_constant_); |
| 4944 } else if (IsConstant(value)) { | 5040 } else if (IsConstant(value)) { |
| 4945 // TODO(kmillikin): Handle sqrt. | 5041 // TODO(kmillikin): Handle sqrt. |
| 4946 SetValue(instr, non_constant_); | 5042 SetValue(instr, non_constant_); |
| 4947 } | 5043 } |
| 4948 } | 5044 } |
| 4949 | 5045 |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5576 if (changed) { | 5672 if (changed) { |
| 5577 // We may have changed the block order and the dominator tree. | 5673 // We may have changed the block order and the dominator tree. |
| 5578 flow_graph->DiscoverBlocks(); | 5674 flow_graph->DiscoverBlocks(); |
| 5579 GrowableArray<BitVector*> dominance_frontier; | 5675 GrowableArray<BitVector*> dominance_frontier; |
| 5580 flow_graph->ComputeDominators(&dominance_frontier); | 5676 flow_graph->ComputeDominators(&dominance_frontier); |
| 5581 } | 5677 } |
| 5582 } | 5678 } |
| 5583 | 5679 |
| 5584 | 5680 |
| 5585 } // namespace dart | 5681 } // namespace dart |
| OLD | NEW |