| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_allocator.h" | 10 #include "vm/flow_graph_allocator.h" |
| 11 #include "vm/flow_graph_builder.h" | 11 #include "vm/flow_graph_builder.h" |
| 12 #include "vm/flow_graph_compiler.h" | 12 #include "vm/flow_graph_compiler.h" |
| 13 #include "vm/flow_graph_optimizer.h" | 13 #include "vm/flow_graph_optimizer.h" |
| 14 #include "vm/locations.h" | 14 #include "vm/locations.h" |
| 15 #include "vm/object.h" | 15 #include "vm/object.h" |
| 16 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
| 17 #include "vm/os.h" | 17 #include "vm/os.h" |
| 18 #include "vm/resolver.h" | 18 #include "vm/resolver.h" |
| 19 #include "vm/scopes.h" | 19 #include "vm/scopes.h" |
| 20 #include "vm/stub_code.h" | 20 #include "vm/stub_code.h" |
| 21 #include "vm/symbols.h" | 21 #include "vm/symbols.h" |
| 22 | 22 |
| 23 #include "vm/il_printer.h" | 23 #include "vm/il_printer.h" |
| 24 | 24 |
| 25 namespace dart { | 25 namespace dart { |
| 26 | 26 |
| 27 DEFINE_FLAG(bool, propagate_ic_data, true, | 27 DEFINE_FLAG(bool, propagate_ic_data, true, |
| 28 "Propagate IC data from unoptimized to optimized IC calls."); | 28 "Propagate IC data from unoptimized to optimized IC calls."); |
| 29 DEFINE_FLAG(bool, unbox_double_fields, true, "Support unboxed double fields."); |
| 29 DECLARE_FLAG(bool, enable_type_checks); | 30 DECLARE_FLAG(bool, enable_type_checks); |
| 30 DECLARE_FLAG(bool, eliminate_type_checks); | 31 DECLARE_FLAG(bool, eliminate_type_checks); |
| 31 DECLARE_FLAG(bool, trace_optimization); | 32 DECLARE_FLAG(bool, trace_optimization); |
| 32 DECLARE_FLAG(bool, trace_constant_propagation); | 33 DECLARE_FLAG(bool, trace_constant_propagation); |
| 33 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 34 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 34 | 35 |
| 35 Definition::Definition() | 36 Definition::Definition() |
| 36 : range_(NULL), | 37 : range_(NULL), |
| 37 type_(NULL), | 38 type_(NULL), |
| 38 temp_index_(-1), | 39 temp_index_(-1), |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 return false; | 130 return false; |
| 130 } | 131 } |
| 131 CompileType* in_type = value()->Type(); | 132 CompileType* in_type = value()->Type(); |
| 132 const intptr_t cid = unary_checks().GetCidAt(0); | 133 const intptr_t cid = unary_checks().GetCidAt(0); |
| 133 // Performance check: use CheckSmiInstr instead. | 134 // Performance check: use CheckSmiInstr instead. |
| 134 ASSERT(cid != kSmiCid); | 135 ASSERT(cid != kSmiCid); |
| 135 return in_type->is_nullable() && (in_type->ToNullableCid() == cid); | 136 return in_type->is_nullable() && (in_type->ToNullableCid() == cid); |
| 136 } | 137 } |
| 137 | 138 |
| 138 | 139 |
| 140 bool LoadFieldInstr::IsUnboxedLoad() const { |
| 141 return FLAG_unbox_double_fields |
| 142 && (field() != NULL) |
| 143 && field()->IsUnboxedField(); |
| 144 } |
| 145 |
| 146 |
| 147 bool LoadFieldInstr::IsPotentialUnboxedLoad() const { |
| 148 return FLAG_unbox_double_fields |
| 149 && (field() != NULL) |
| 150 && field()->IsPotentialUnboxedField(); |
| 151 } |
| 152 |
| 153 |
| 154 bool StoreInstanceFieldInstr::IsUnboxedStore() const { |
| 155 return FLAG_unbox_double_fields && field().IsUnboxedField(); |
| 156 } |
| 157 |
| 158 |
| 159 bool StoreInstanceFieldInstr::IsPotentialUnboxedStore() const { |
| 160 return FLAG_unbox_double_fields && field().IsPotentialUnboxedField(); |
| 161 } |
| 162 |
| 163 |
| 139 bool GuardFieldInstr::AttributesEqual(Instruction* other) const { | 164 bool GuardFieldInstr::AttributesEqual(Instruction* other) const { |
| 140 return field().raw() == other->AsGuardField()->field().raw(); | 165 return field().raw() == other->AsGuardField()->field().raw(); |
| 141 } | 166 } |
| 142 | 167 |
| 143 | 168 |
| 144 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const { | 169 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const { |
| 145 AssertAssignableInstr* other_assert = other->AsAssertAssignable(); | 170 AssertAssignableInstr* other_assert = other->AsAssertAssignable(); |
| 146 ASSERT(other_assert != NULL); | 171 ASSERT(other_assert != NULL); |
| 147 // This predicate has to be commutative for DominatorBasedCSE to work. | 172 // This predicate has to be commutative for DominatorBasedCSE to work. |
| 148 // TODO(fschneider): Eliminate more asserts with subtype relation. | 173 // TODO(fschneider): Eliminate more asserts with subtype relation. |
| (...skipping 1601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1750 } | 1775 } |
| 1751 | 1776 |
| 1752 | 1777 |
| 1753 // Shared code generation methods (EmitNativeCode and | 1778 // Shared code generation methods (EmitNativeCode and |
| 1754 // MakeLocationSummary). Only assembly code that can be shared across all | 1779 // MakeLocationSummary). Only assembly code that can be shared across all |
| 1755 // architectures can be used. Machine specific register allocation and code | 1780 // architectures can be used. Machine specific register allocation and code |
| 1756 // generation is located in intermediate_language_<arch>.cc | 1781 // generation is located in intermediate_language_<arch>.cc |
| 1757 | 1782 |
| 1758 #define __ compiler->assembler()-> | 1783 #define __ compiler->assembler()-> |
| 1759 | 1784 |
| 1760 LocationSummary* GraphEntryInstr::MakeLocationSummary() const { | 1785 LocationSummary* GraphEntryInstr::MakeLocationSummary(bool optimizing) const { |
| 1761 UNREACHABLE(); | 1786 UNREACHABLE(); |
| 1762 return NULL; | 1787 return NULL; |
| 1763 } | 1788 } |
| 1764 | 1789 |
| 1765 | 1790 |
| 1766 LocationSummary* JoinEntryInstr::MakeLocationSummary() const { | 1791 LocationSummary* JoinEntryInstr::MakeLocationSummary(bool optimizing) const { |
| 1767 UNREACHABLE(); | 1792 UNREACHABLE(); |
| 1768 return NULL; | 1793 return NULL; |
| 1769 } | 1794 } |
| 1770 | 1795 |
| 1771 | 1796 |
| 1772 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1797 void JoinEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1773 __ Bind(compiler->GetJumpLabel(this)); | 1798 __ Bind(compiler->GetJumpLabel(this)); |
| 1774 if (!compiler->is_optimizing()) { | 1799 if (!compiler->is_optimizing()) { |
| 1775 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 1800 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 1776 deopt_id_, | 1801 deopt_id_, |
| 1777 Scanner::kDummyTokenIndex); | 1802 Scanner::kDummyTokenIndex); |
| 1778 } | 1803 } |
| 1779 if (HasParallelMove()) { | 1804 if (HasParallelMove()) { |
| 1780 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 1805 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
| 1781 } | 1806 } |
| 1782 } | 1807 } |
| 1783 | 1808 |
| 1784 | 1809 |
| 1785 LocationSummary* TargetEntryInstr::MakeLocationSummary() const { | 1810 LocationSummary* TargetEntryInstr::MakeLocationSummary(bool optimizing) const { |
| 1786 // FlowGraphCompiler::EmitInstructionPrologue is not called for block | 1811 // FlowGraphCompiler::EmitInstructionPrologue is not called for block |
| 1787 // entry instructions, so this function is unused. If it becomes | 1812 // entry instructions, so this function is unused. If it becomes |
| 1788 // reachable, note that the deoptimization descriptor in unoptimized code | 1813 // reachable, note that the deoptimization descriptor in unoptimized code |
| 1789 // comes after the point of local register allocation due to pattern | 1814 // comes after the point of local register allocation due to pattern |
| 1790 // matching the edge counter code backwards (as a code reuse convenience | 1815 // matching the edge counter code backwards (as a code reuse convenience |
| 1791 // on some platforms). | 1816 // on some platforms). |
| 1792 UNREACHABLE(); | 1817 UNREACHABLE(); |
| 1793 return NULL; | 1818 return NULL; |
| 1794 } | 1819 } |
| 1795 | 1820 |
| 1796 | 1821 |
| 1797 LocationSummary* PhiInstr::MakeLocationSummary() const { | 1822 LocationSummary* PhiInstr::MakeLocationSummary(bool optimizing) const { |
| 1798 UNREACHABLE(); | 1823 UNREACHABLE(); |
| 1799 return NULL; | 1824 return NULL; |
| 1800 } | 1825 } |
| 1801 | 1826 |
| 1802 | 1827 |
| 1803 void PhiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1828 void PhiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1804 UNREACHABLE(); | 1829 UNREACHABLE(); |
| 1805 } | 1830 } |
| 1806 | 1831 |
| 1807 | 1832 |
| 1808 LocationSummary* RedefinitionInstr::MakeLocationSummary() const { | 1833 LocationSummary* RedefinitionInstr::MakeLocationSummary(bool optimizing) const { |
| 1809 UNREACHABLE(); | 1834 UNREACHABLE(); |
| 1810 return NULL; | 1835 return NULL; |
| 1811 } | 1836 } |
| 1812 | 1837 |
| 1813 | 1838 |
| 1814 void RedefinitionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1839 void RedefinitionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1815 UNREACHABLE(); | 1840 UNREACHABLE(); |
| 1816 } | 1841 } |
| 1817 | 1842 |
| 1818 | 1843 |
| 1819 LocationSummary* ParameterInstr::MakeLocationSummary() const { | 1844 LocationSummary* ParameterInstr::MakeLocationSummary(bool optimizing) const { |
| 1820 UNREACHABLE(); | 1845 UNREACHABLE(); |
| 1821 return NULL; | 1846 return NULL; |
| 1822 } | 1847 } |
| 1823 | 1848 |
| 1824 | 1849 |
| 1825 void ParameterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1850 void ParameterInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1826 UNREACHABLE(); | 1851 UNREACHABLE(); |
| 1827 } | 1852 } |
| 1828 | 1853 |
| 1829 | 1854 |
| 1830 LocationSummary* ParallelMoveInstr::MakeLocationSummary() const { | 1855 LocationSummary* ParallelMoveInstr::MakeLocationSummary(bool optimizing) const { |
| 1831 return NULL; | 1856 return NULL; |
| 1832 } | 1857 } |
| 1833 | 1858 |
| 1834 | 1859 |
| 1835 void ParallelMoveInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1860 void ParallelMoveInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1836 UNREACHABLE(); | 1861 UNREACHABLE(); |
| 1837 } | 1862 } |
| 1838 | 1863 |
| 1839 | 1864 |
| 1840 LocationSummary* ConstraintInstr::MakeLocationSummary() const { | 1865 LocationSummary* ConstraintInstr::MakeLocationSummary(bool optimizing) const { |
| 1841 UNREACHABLE(); | 1866 UNREACHABLE(); |
| 1842 return NULL; | 1867 return NULL; |
| 1843 } | 1868 } |
| 1844 | 1869 |
| 1845 | 1870 |
| 1846 void ConstraintInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1871 void ConstraintInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1847 UNREACHABLE(); | 1872 UNREACHABLE(); |
| 1848 } | 1873 } |
| 1849 | 1874 |
| 1850 | 1875 |
| 1851 LocationSummary* MaterializeObjectInstr::MakeLocationSummary() const { | 1876 LocationSummary* MaterializeObjectInstr::MakeLocationSummary( |
| 1877 bool optimizing) const { |
| 1852 UNREACHABLE(); | 1878 UNREACHABLE(); |
| 1853 return NULL; | 1879 return NULL; |
| 1854 } | 1880 } |
| 1855 | 1881 |
| 1856 | 1882 |
| 1857 void MaterializeObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1883 void MaterializeObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1858 UNREACHABLE(); | 1884 UNREACHABLE(); |
| 1859 } | 1885 } |
| 1860 | 1886 |
| 1861 | 1887 |
| 1862 LocationSummary* StoreContextInstr::MakeLocationSummary() const { | 1888 LocationSummary* StoreContextInstr::MakeLocationSummary(bool optimizing) const { |
| 1863 const intptr_t kNumInputs = 1; | 1889 const intptr_t kNumInputs = 1; |
| 1864 const intptr_t kNumTemps = 0; | 1890 const intptr_t kNumTemps = 0; |
| 1865 LocationSummary* summary = | 1891 LocationSummary* summary = |
| 1866 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1892 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1867 summary->set_in(0, Location::RegisterLocation(CTX)); | 1893 summary->set_in(0, Location::RegisterLocation(CTX)); |
| 1868 return summary; | 1894 return summary; |
| 1869 } | 1895 } |
| 1870 | 1896 |
| 1871 | 1897 |
| 1872 LocationSummary* PushTempInstr::MakeLocationSummary() const { | 1898 LocationSummary* PushTempInstr::MakeLocationSummary(bool optimizing) const { |
| 1873 return LocationSummary::Make(1, | 1899 return LocationSummary::Make(1, |
| 1874 Location::NoLocation(), | 1900 Location::NoLocation(), |
| 1875 LocationSummary::kNoCall); | 1901 LocationSummary::kNoCall); |
| 1876 } | 1902 } |
| 1877 | 1903 |
| 1878 | 1904 |
| 1879 void PushTempInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1905 void PushTempInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1880 ASSERT(!compiler->is_optimizing()); | 1906 ASSERT(!compiler->is_optimizing()); |
| 1881 // Nothing to do. | 1907 // Nothing to do. |
| 1882 } | 1908 } |
| 1883 | 1909 |
| 1884 | 1910 |
| 1885 LocationSummary* DropTempsInstr::MakeLocationSummary() const { | 1911 LocationSummary* DropTempsInstr::MakeLocationSummary(bool optimizing) const { |
| 1886 return LocationSummary::Make(1, | 1912 return LocationSummary::Make(1, |
| 1887 Location::SameAsFirstInput(), | 1913 Location::SameAsFirstInput(), |
| 1888 LocationSummary::kNoCall); | 1914 LocationSummary::kNoCall); |
| 1889 } | 1915 } |
| 1890 | 1916 |
| 1891 | 1917 |
| 1892 void DropTempsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1918 void DropTempsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1893 ASSERT(!compiler->is_optimizing()); | 1919 ASSERT(!compiler->is_optimizing()); |
| 1894 Register value = locs()->in(0).reg(); | 1920 Register value = locs()->in(0).reg(); |
| 1895 Register result = locs()->out().reg(); | 1921 Register result = locs()->out().reg(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1908 Token::Kind kind, | 1934 Token::Kind kind, |
| 1909 Value* left, | 1935 Value* left, |
| 1910 Value* right, | 1936 Value* right, |
| 1911 bool needs_number_check) | 1937 bool needs_number_check) |
| 1912 : ComparisonInstr(token_pos, kind, left, right), | 1938 : ComparisonInstr(token_pos, kind, left, right), |
| 1913 needs_number_check_(needs_number_check) { | 1939 needs_number_check_(needs_number_check) { |
| 1914 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); | 1940 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); |
| 1915 } | 1941 } |
| 1916 | 1942 |
| 1917 | 1943 |
| 1918 LocationSummary* InstanceCallInstr::MakeLocationSummary() const { | 1944 LocationSummary* InstanceCallInstr::MakeLocationSummary(bool optimizing) const { |
| 1919 return MakeCallSummary(); | 1945 return MakeCallSummary(); |
| 1920 } | 1946 } |
| 1921 | 1947 |
| 1922 | 1948 |
| 1923 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1949 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1924 ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw()); | 1950 ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw()); |
| 1925 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { | 1951 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { |
| 1926 const Array& arguments_descriptor = | 1952 const Array& arguments_descriptor = |
| 1927 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(), | 1953 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(), |
| 1928 argument_names())); | 1954 argument_names())); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1969 | 1995 |
| 1970 | 1996 |
| 1971 bool PolymorphicInstanceCallInstr::HasRecognizedTarget() const { | 1997 bool PolymorphicInstanceCallInstr::HasRecognizedTarget() const { |
| 1972 return ic_data().HasOneTarget() && | 1998 return ic_data().HasOneTarget() && |
| 1973 (MethodRecognizer::RecognizeKind( | 1999 (MethodRecognizer::RecognizeKind( |
| 1974 Function::Handle(ic_data().GetTargetAt(0))) != | 2000 Function::Handle(ic_data().GetTargetAt(0))) != |
| 1975 MethodRecognizer::kUnknown); | 2001 MethodRecognizer::kUnknown); |
| 1976 } | 2002 } |
| 1977 | 2003 |
| 1978 | 2004 |
| 1979 LocationSummary* StaticCallInstr::MakeLocationSummary() const { | 2005 LocationSummary* StaticCallInstr::MakeLocationSummary(bool optimizing) const { |
| 1980 return MakeCallSummary(); | 2006 return MakeCallSummary(); |
| 1981 } | 2007 } |
| 1982 | 2008 |
| 1983 | 2009 |
| 1984 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2010 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1985 if (!compiler->is_optimizing()) { | 2011 if (!compiler->is_optimizing()) { |
| 1986 // Some static calls can be optimized by the optimizing compiler (e.g. sqrt) | 2012 // Some static calls can be optimized by the optimizing compiler (e.g. sqrt) |
| 1987 // and therefore need a deoptimization descriptor. | 2013 // and therefore need a deoptimization descriptor. |
| 1988 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 2014 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 1989 deopt_id(), | 2015 deopt_id(), |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2863 concatenated = Symbols::New(concatenated); | 2889 concatenated = Symbols::New(concatenated); |
| 2864 return flow_graph->GetConstant(concatenated); | 2890 return flow_graph->GetConstant(concatenated); |
| 2865 } | 2891 } |
| 2866 | 2892 |
| 2867 | 2893 |
| 2868 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( | 2894 InvokeMathCFunctionInstr::InvokeMathCFunctionInstr( |
| 2869 ZoneGrowableArray<Value*>* inputs, | 2895 ZoneGrowableArray<Value*>* inputs, |
| 2870 intptr_t original_deopt_id, | 2896 intptr_t original_deopt_id, |
| 2871 MethodRecognizer::Kind recognized_kind) | 2897 MethodRecognizer::Kind recognized_kind) |
| 2872 : inputs_(inputs), | 2898 : inputs_(inputs), |
| 2873 locs_(NULL), | |
| 2874 recognized_kind_(recognized_kind) { | 2899 recognized_kind_(recognized_kind) { |
| 2875 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); | 2900 ASSERT(inputs_->length() == ArgumentCountFor(recognized_kind_)); |
| 2876 for (intptr_t i = 0; i < inputs_->length(); ++i) { | 2901 for (intptr_t i = 0; i < inputs_->length(); ++i) { |
| 2877 ASSERT((*inputs)[i] != NULL); | 2902 ASSERT((*inputs)[i] != NULL); |
| 2878 (*inputs)[i]->set_instruction(this); | 2903 (*inputs)[i]->set_instruction(this); |
| 2879 (*inputs)[i]->set_use_index(i); | 2904 (*inputs)[i]->set_use_index(i); |
| 2880 } | 2905 } |
| 2881 deopt_id_ = original_deopt_id; | 2906 deopt_id_ = original_deopt_id; |
| 2882 } | 2907 } |
| 2883 | 2908 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2971 UNREACHABLE(); | 2996 UNREACHABLE(); |
| 2972 } | 2997 } |
| 2973 return kSinRuntimeEntry; | 2998 return kSinRuntimeEntry; |
| 2974 } | 2999 } |
| 2975 | 3000 |
| 2976 | 3001 |
| 2977 MergedMathInstr::MergedMathInstr(ZoneGrowableArray<Value*>* inputs, | 3002 MergedMathInstr::MergedMathInstr(ZoneGrowableArray<Value*>* inputs, |
| 2978 intptr_t original_deopt_id, | 3003 intptr_t original_deopt_id, |
| 2979 MergedMathInstr::Kind kind) | 3004 MergedMathInstr::Kind kind) |
| 2980 : inputs_(inputs), | 3005 : inputs_(inputs), |
| 2981 locs_(NULL), | |
| 2982 kind_(kind) { | 3006 kind_(kind) { |
| 2983 ASSERT(inputs_->length() == InputCountFor(kind_)); | 3007 ASSERT(inputs_->length() == InputCountFor(kind_)); |
| 2984 for (intptr_t i = 0; i < inputs_->length(); ++i) { | 3008 for (intptr_t i = 0; i < inputs_->length(); ++i) { |
| 2985 ASSERT((*inputs)[i] != NULL); | 3009 ASSERT((*inputs)[i] != NULL); |
| 2986 (*inputs)[i]->set_instruction(this); | 3010 (*inputs)[i]->set_instruction(this); |
| 2987 (*inputs)[i]->set_use_index(i); | 3011 (*inputs)[i]->set_use_index(i); |
| 2988 } | 3012 } |
| 2989 deopt_id_ = original_deopt_id; | 3013 deopt_id_ = original_deopt_id; |
| 2990 } | 3014 } |
| 2991 | 3015 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3004 case Token::kTRUNCDIV: return 0; | 3028 case Token::kTRUNCDIV: return 0; |
| 3005 case Token::kMOD: return 1; | 3029 case Token::kMOD: return 1; |
| 3006 default: UNIMPLEMENTED(); return -1; | 3030 default: UNIMPLEMENTED(); return -1; |
| 3007 } | 3031 } |
| 3008 } | 3032 } |
| 3009 | 3033 |
| 3010 | 3034 |
| 3011 #undef __ | 3035 #undef __ |
| 3012 | 3036 |
| 3013 } // namespace dart | 3037 } // namespace dart |
| OLD | NEW |