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 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1226 ASSERT(!field.IsNull()); | 1226 ASSERT(!field.IsNull()); |
| 1227 | 1227 |
| 1228 if (InstanceCallNeedsClassCheck(call)) { | 1228 if (InstanceCallNeedsClassCheck(call)) { |
| 1229 AddReceiverCheck(call); | 1229 AddReceiverCheck(call); |
| 1230 } | 1230 } |
| 1231 LoadFieldInstr* load = new LoadFieldInstr( | 1231 LoadFieldInstr* load = new LoadFieldInstr( |
| 1232 new Value(call->ArgumentAt(0)), | 1232 new Value(call->ArgumentAt(0)), |
| 1233 field.Offset(), | 1233 field.Offset(), |
| 1234 AbstractType::ZoneHandle(field.type()), | 1234 AbstractType::ZoneHandle(field.type()), |
| 1235 field.is_final()); | 1235 field.is_final()); |
| 1236 if (field.guarded_cid() != kIllegalCid) { | |
| 1237 load->set_result_cid(field.GuardedCid()); | |
| 1238 load->set_field(&Field::ZoneHandle(field.raw())); | |
| 1239 } | |
| 1240 load->set_field_name(String::Handle(field.name()).ToCString()); | |
| 1241 | |
| 1236 // Discard the environment from the original instruction because the load | 1242 // Discard the environment from the original instruction because the load |
| 1237 // can't deoptimize. | 1243 // can't deoptimize. |
| 1238 call->RemoveEnvironment(); | 1244 call->RemoveEnvironment(); |
| 1239 ReplaceCall(call, load); | 1245 ReplaceCall(call, load); |
| 1240 } | 1246 } |
| 1241 | 1247 |
| 1242 | 1248 |
| 1243 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call, | 1249 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call, |
| 1244 intptr_t length_offset, | 1250 intptr_t length_offset, |
| 1245 bool is_immutable, | 1251 bool is_immutable, |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1869 new InstanceOfInstr(call->token_pos(), | 1875 new InstanceOfInstr(call->token_pos(), |
| 1870 new Value(left), | 1876 new Value(left), |
| 1871 new Value(instantiator), | 1877 new Value(instantiator), |
| 1872 new Value(type_args), | 1878 new Value(type_args), |
| 1873 type, | 1879 type, |
| 1874 negate); | 1880 negate); |
| 1875 ReplaceCall(call, instance_of); | 1881 ReplaceCall(call, instance_of); |
| 1876 } | 1882 } |
| 1877 | 1883 |
| 1878 | 1884 |
| 1885 void FlowGraphOptimizer::VisitStoreInstanceField( | |
| 1886 StoreInstanceFieldInstr* instr) { | |
| 1887 if (!instr->should_emit_field_guard()) return; | |
| 1888 | |
| 1889 if (instr->field().guarded_cid() != kDynamicCid) { | |
|
Kevin Millikin (Google)
2013/03/12 12:14:56
I think it's a bit better to always insert the gua
Vyacheslav Egorov (Google)
2013/03/12 16:54:40
Done. Though it requires an expression temp to pre
| |
| 1890 ASSERT(instr->env() != NULL); | |
| 1891 // TODO(vegorov) need a deopt id here! | |
| 1892 InsertBefore(instr, | |
| 1893 new GuardFieldInstr(instr->value()->Copy(), | |
| 1894 instr->field(), | |
| 1895 instr->deopt_id()), | |
| 1896 instr->env(), | |
| 1897 Definition::kEffect); | |
| 1898 } | |
| 1899 | |
| 1900 instr->detach_field_guard(); | |
| 1901 } | |
| 1902 | |
| 1903 | |
| 1879 // Tries to optimize instance call by replacing it with a faster instruction | 1904 // Tries to optimize instance call by replacing it with a faster instruction |
| 1880 // (e.g, binary op, field load, ..). | 1905 // (e.g, binary op, field load, ..). |
| 1881 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { | 1906 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| 1882 if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) { | 1907 if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) { |
| 1883 return; | 1908 return; |
| 1884 } | 1909 } |
| 1885 | 1910 |
| 1886 const Token::Kind op_kind = instr->token_kind(); | 1911 const Token::Kind op_kind = instr->token_kind(); |
| 1887 // Type test is special as it always gets converted into inlined code. | 1912 // Type test is special as it always gets converted into inlined code. |
| 1888 if (Token::IsTypeTestOperator(op_kind)) { | 1913 if (Token::IsTypeTestOperator(op_kind)) { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2009 } | 2034 } |
| 2010 StoreBarrierType needs_store_barrier = kEmitStoreBarrier; | 2035 StoreBarrierType needs_store_barrier = kEmitStoreBarrier; |
| 2011 if (ArgIsAlwaysSmi(*instr->ic_data(), 1)) { | 2036 if (ArgIsAlwaysSmi(*instr->ic_data(), 1)) { |
| 2012 InsertBefore(instr, | 2037 InsertBefore(instr, |
| 2013 new CheckSmiInstr(new Value(instr->ArgumentAt(1)), | 2038 new CheckSmiInstr(new Value(instr->ArgumentAt(1)), |
| 2014 instr->deopt_id()), | 2039 instr->deopt_id()), |
| 2015 instr->env(), | 2040 instr->env(), |
| 2016 Definition::kEffect); | 2041 Definition::kEffect); |
| 2017 needs_store_barrier = kNoStoreBarrier; | 2042 needs_store_barrier = kNoStoreBarrier; |
| 2018 } | 2043 } |
| 2044 | |
| 2045 if (field.guarded_cid() != kDynamicCid) { | |
| 2046 InsertBefore(instr, | |
| 2047 new GuardFieldInstr(new Value(instr->ArgumentAt(1)), | |
| 2048 field, | |
| 2049 instr->deopt_id()), | |
| 2050 instr->env(), | |
| 2051 Definition::kEffect); | |
| 2052 } | |
| 2053 | |
| 2054 // Field guard was detached. | |
| 2055 const bool needs_field_guard = false; | |
| 2019 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( | 2056 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( |
| 2020 field, | 2057 field, |
| 2021 new Value(instr->ArgumentAt(0)), | 2058 new Value(instr->ArgumentAt(0)), |
| 2022 new Value(instr->ArgumentAt(1)), | 2059 new Value(instr->ArgumentAt(1)), |
| 2023 needs_store_barrier); | 2060 needs_store_barrier, |
| 2061 needs_field_guard); | |
| 2024 // Discard the environment from the original instruction because the store | 2062 // Discard the environment from the original instruction because the store |
| 2025 // can't deoptimize. | 2063 // can't deoptimize. |
| 2026 instr->RemoveEnvironment(); | 2064 instr->RemoveEnvironment(); |
| 2027 ReplaceCall(instr, store); | 2065 ReplaceCall(instr, store); |
| 2028 return true; | 2066 return true; |
| 2029 } | 2067 } |
| 2030 | 2068 |
| 2031 | 2069 |
| 2032 void FlowGraphOptimizer::HandleRelationalOp(RelationalOpInstr* comp) { | 2070 void FlowGraphOptimizer::HandleRelationalOp(RelationalOpInstr* comp) { |
| 2033 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) { | 2071 if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) { |
| (...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3770 | 3808 |
| 3771 void ConstantPropagator::VisitCatchEntry(CatchEntryInstr* instr) { } | 3809 void ConstantPropagator::VisitCatchEntry(CatchEntryInstr* instr) { } |
| 3772 | 3810 |
| 3773 | 3811 |
| 3774 void ConstantPropagator::VisitCheckStackOverflow( | 3812 void ConstantPropagator::VisitCheckStackOverflow( |
| 3775 CheckStackOverflowInstr* instr) { } | 3813 CheckStackOverflowInstr* instr) { } |
| 3776 | 3814 |
| 3777 | 3815 |
| 3778 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { } | 3816 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { } |
| 3779 | 3817 |
| 3818 void ConstantPropagator::VisitGuardField(GuardFieldInstr* instr) { } | |
| 3780 | 3819 |
| 3781 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { } | 3820 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { } |
| 3782 | 3821 |
| 3783 | 3822 |
| 3784 void ConstantPropagator::VisitCheckEitherNonSmi( | 3823 void ConstantPropagator::VisitCheckEitherNonSmi( |
| 3785 CheckEitherNonSmiInstr* instr) { } | 3824 CheckEitherNonSmiInstr* instr) { } |
| 3786 | 3825 |
| 3787 | 3826 |
| 3788 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) { } | 3827 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) { } |
| 3789 | 3828 |
| (...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4659 if (changed) { | 4698 if (changed) { |
| 4660 // We may have changed the block order and the dominator tree. | 4699 // We may have changed the block order and the dominator tree. |
| 4661 flow_graph->DiscoverBlocks(); | 4700 flow_graph->DiscoverBlocks(); |
| 4662 GrowableArray<BitVector*> dominance_frontier; | 4701 GrowableArray<BitVector*> dominance_frontier; |
| 4663 flow_graph->ComputeDominators(&dominance_frontier); | 4702 flow_graph->ComputeDominators(&dominance_frontier); |
| 4664 } | 4703 } |
| 4665 } | 4704 } |
| 4666 | 4705 |
| 4667 | 4706 |
| 4668 } // namespace dart | 4707 } // namespace dart |
| OLD | NEW |