| 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 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 new InstanceOfInstr(call->token_pos(), | 1828 new InstanceOfInstr(call->token_pos(), |
| 1829 new Value(left), | 1829 new Value(left), |
| 1830 new Value(instantiator), | 1830 new Value(instantiator), |
| 1831 new Value(type_args), | 1831 new Value(type_args), |
| 1832 type, | 1832 type, |
| 1833 negate); | 1833 negate); |
| 1834 ReplaceCall(call, instance_of); | 1834 ReplaceCall(call, instance_of); |
| 1835 } | 1835 } |
| 1836 | 1836 |
| 1837 | 1837 |
| 1838 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
| 1839 ASSERT(Token::IsTypeCastOperator(call->token_kind())); |
| 1840 Definition* left = call->ArgumentAt(0); |
| 1841 Definition* instantiator = call->ArgumentAt(1); |
| 1842 Definition* type_args = call->ArgumentAt(2); |
| 1843 const AbstractType& type = |
| 1844 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); |
| 1845 ASSERT(!type.IsMalformed()); |
| 1846 const ICData& unary_checks = |
| 1847 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); |
| 1848 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
| 1849 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); |
| 1850 if (as_bool.raw() == Bool::True().raw()) { |
| 1851 AddReceiverCheck(call); |
| 1852 // Remove the original push arguments. |
| 1853 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 1854 PushArgumentInstr* push = call->PushArgumentAt(i); |
| 1855 push->ReplaceUsesWith(push->value()->definition()); |
| 1856 push->RemoveFromGraph(); |
| 1857 } |
| 1858 // Remove call, replace it with 'left'. |
| 1859 call->ReplaceUsesWith(left); |
| 1860 call->RemoveFromGraph(); |
| 1861 return; |
| 1862 } |
| 1863 } |
| 1864 const String& dst_name = String::ZoneHandle( |
| 1865 Symbols::New(Exceptions::kCastErrorDstName)); |
| 1866 AssertAssignableInstr* assert_as = |
| 1867 new AssertAssignableInstr(call->token_pos(), |
| 1868 new Value(left), |
| 1869 new Value(instantiator), |
| 1870 new Value(type_args), |
| 1871 type, |
| 1872 dst_name); |
| 1873 ReplaceCall(call, assert_as); |
| 1874 } |
| 1875 |
| 1876 |
| 1838 // Tries to optimize instance call by replacing it with a faster instruction | 1877 // Tries to optimize instance call by replacing it with a faster instruction |
| 1839 // (e.g, binary op, field load, ..). | 1878 // (e.g, binary op, field load, ..). |
| 1840 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { | 1879 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| 1841 if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) { | 1880 if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) { |
| 1842 return; | 1881 return; |
| 1843 } | 1882 } |
| 1844 | 1883 |
| 1845 const Token::Kind op_kind = instr->token_kind(); | 1884 const Token::Kind op_kind = instr->token_kind(); |
| 1846 // Type test is special as it always gets converted into inlined code. | 1885 // Type test is special as it always gets converted into inlined code. |
| 1847 if (Token::IsTypeTestOperator(op_kind)) { | 1886 if (Token::IsTypeTestOperator(op_kind)) { |
| 1848 ReplaceWithInstanceOf(instr); | 1887 ReplaceWithInstanceOf(instr); |
| 1849 return; | 1888 return; |
| 1850 } | 1889 } |
| 1851 | 1890 |
| 1891 if (Token::IsTypeCastOperator(op_kind)) { |
| 1892 ReplaceWithTypeCast(instr); |
| 1893 return; |
| 1894 } |
| 1895 |
| 1852 const ICData& unary_checks = | 1896 const ICData& unary_checks = |
| 1853 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks()); | 1897 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks()); |
| 1854 | 1898 |
| 1855 if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) && | 1899 if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) && |
| 1856 InstanceCallNeedsClassCheck(instr)) { | 1900 InstanceCallNeedsClassCheck(instr)) { |
| 1857 // Too many checks, it will be megamorphic which needs unary checks. | 1901 // Too many checks, it will be megamorphic which needs unary checks. |
| 1858 instr->set_ic_data(&unary_checks); | 1902 instr->set_ic_data(&unary_checks); |
| 1859 return; | 1903 return; |
| 1860 } | 1904 } |
| 1861 | 1905 |
| (...skipping 2763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4625 if (changed) { | 4669 if (changed) { |
| 4626 // We may have changed the block order and the dominator tree. | 4670 // We may have changed the block order and the dominator tree. |
| 4627 flow_graph->DiscoverBlocks(); | 4671 flow_graph->DiscoverBlocks(); |
| 4628 GrowableArray<BitVector*> dominance_frontier; | 4672 GrowableArray<BitVector*> dominance_frontier; |
| 4629 flow_graph->ComputeDominators(&dominance_frontier); | 4673 flow_graph->ComputeDominators(&dominance_frontier); |
| 4630 } | 4674 } |
| 4631 } | 4675 } |
| 4632 | 4676 |
| 4633 | 4677 |
| 4634 } // namespace dart | 4678 } // namespace dart |
| OLD | NEW |