Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 12529008: Collect type feedback for fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698