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

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

Issue 2877713003: Eliminated with_checks variable (Closed)
Patch Set: Removed TODO Created 3 years, 7 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
« no previous file with comments | « no previous file | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/aot_optimizer.h" 5 #include "vm/aot_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/branch_optimizer.h" 8 #include "vm/branch_optimizer.h"
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 const Class& cls = Class::Handle(Z, I->object_store()->object_class()); 115 const Class& cls = Class::Handle(Z, I->object_store()->object_class());
116 const Array& args_desc_array = Array::Handle( 116 const Array& args_desc_array = Array::Handle(
117 Z, 117 Z,
118 ArgumentsDescriptor::New(call->ArgumentCount(), call->argument_names())); 118 ArgumentsDescriptor::New(call->ArgumentCount(), call->argument_names()));
119 ArgumentsDescriptor args_desc(args_desc_array); 119 ArgumentsDescriptor args_desc(args_desc_array);
120 const Function& function = 120 const Function& function =
121 Function::Handle(Z, Resolver::ResolveDynamicForReceiverClass( 121 Function::Handle(Z, Resolver::ResolveDynamicForReceiverClass(
122 cls, call->function_name(), args_desc)); 122 cls, call->function_name(), args_desc));
123 ASSERT(!function.IsNull()); 123 ASSERT(!function.IsNull());
124 124
125 ZoneGrowableArray<PushArgumentInstr*>* args = 125 const Function& target = Function::ZoneHandle(Z, function.raw());
126 new (Z) ZoneGrowableArray<PushArgumentInstr*>(call->ArgumentCount()); 126 StaticCallInstr* static_call = StaticCallInstr::FromCall(Z, call, target);
127 for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
128 args->Add(call->PushArgumentAt(i));
129 }
130 StaticCallInstr* static_call = new (Z) StaticCallInstr(
131 call->token_pos(), Function::ZoneHandle(Z, function.raw()),
132 call->argument_names(), args, call->deopt_id());
133 static_call->set_result_cid(kTypeCid); 127 static_call->set_result_cid(kTypeCid);
134 call->ReplaceWith(static_call, current_iterator()); 128 call->ReplaceWith(static_call, current_iterator());
135 return true; 129 return true;
136 } 130 }
137 131
138 132
139 // Optimize instance calls using cid. This is called after optimizer 133 // Optimize instance calls using cid. This is called after optimizer
140 // converted instance calls to instructions. Any remaining 134 // converted instance calls to instructions. Any remaining
141 // instance calls are either megamorphic calls, cannot be optimized or 135 // instance calls are either megamorphic calls, cannot be optimized or
142 // have no runtime type feedback collected. 136 // have no runtime type feedback collected.
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 PushArgumentInstr* arg = 639 PushArgumentInstr* arg =
646 new (Z) PushArgumentInstr(new (Z) Value(left->ArgumentAt(0))); 640 new (Z) PushArgumentInstr(new (Z) Value(left->ArgumentAt(0)));
647 InsertBefore(call, arg, NULL, FlowGraph::kEffect); 641 InsertBefore(call, arg, NULL, FlowGraph::kEffect);
648 args->Add(arg); 642 args->Add(arg);
649 arg = new (Z) PushArgumentInstr(new (Z) Value(right->ArgumentAt(0))); 643 arg = new (Z) PushArgumentInstr(new (Z) Value(right->ArgumentAt(0)));
650 InsertBefore(call, arg, NULL, FlowGraph::kEffect); 644 InsertBefore(call, arg, NULL, FlowGraph::kEffect);
651 args->Add(arg); 645 args->Add(arg);
652 StaticCallInstr* static_call = 646 StaticCallInstr* static_call =
653 new (Z) StaticCallInstr(call->token_pos(), have_same_runtime_type, 647 new (Z) StaticCallInstr(call->token_pos(), have_same_runtime_type,
654 Object::null_array(), // argument_names 648 Object::null_array(), // argument_names
655 args, call->deopt_id()); 649 args, call->deopt_id(), call->CallCount());
656 static_call->set_result_cid(kBoolCid); 650 static_call->set_result_cid(kBoolCid);
657 ReplaceCall(call, static_call); 651 ReplaceCall(call, static_call);
658 return true; 652 return true;
659 } 653 }
660 654
661 return false; 655 return false;
662 } 656 }
663 657
664 658
665 bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call, 659 bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 Library::Handle(Z, Library::InternalLibrary()); 1505 Library::Handle(Z, Library::InternalLibrary());
1512 const String& target_name = Symbols::_classRangeCheck(); 1506 const String& target_name = Symbols::_classRangeCheck();
1513 const Function& target = Function::ZoneHandle( 1507 const Function& target = Function::ZoneHandle(
1514 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); 1508 Z, dart_internal.LookupFunctionAllowPrivate(target_name));
1515 ASSERT(!target.IsNull()); 1509 ASSERT(!target.IsNull());
1516 ASSERT(target.IsRecognized() && target.always_inline()); 1510 ASSERT(target.IsRecognized() && target.always_inline());
1517 1511
1518 StaticCallInstr* new_call = 1512 StaticCallInstr* new_call =
1519 new (Z) StaticCallInstr(call->token_pos(), target, 1513 new (Z) StaticCallInstr(call->token_pos(), target,
1520 Object::null_array(), // argument_names 1514 Object::null_array(), // argument_names
1521 args, call->deopt_id()); 1515 args, call->deopt_id(), call->CallCount());
1522 Environment* copy = call->env()->DeepCopy( 1516 Environment* copy = call->env()->DeepCopy(
1523 Z, call->env()->Length() - call->ArgumentCount()); 1517 Z, call->env()->Length() - call->ArgumentCount());
1524 for (intptr_t i = 0; i < args->length(); ++i) { 1518 for (intptr_t i = 0; i < args->length(); ++i) {
1525 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); 1519 copy->PushValue(new (Z) Value((*args)[i]->value()->definition()));
1526 } 1520 }
1527 call->RemoveEnvironment(); 1521 call->RemoveEnvironment();
1528 ReplaceCall(call, new_call); 1522 ReplaceCall(call, new_call);
1529 copy->DeepCopyTo(Z, new_call); 1523 copy->DeepCopyTo(Z, new_call);
1530 return; 1524 return;
1531 } 1525 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 const String& target_name = Symbols::_classIdEqualsAssert(); 1597 const String& target_name = Symbols::_classIdEqualsAssert();
1604 const Function& target = Function::ZoneHandle( 1598 const Function& target = Function::ZoneHandle(
1605 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); 1599 Z, dart_internal.LookupFunctionAllowPrivate(target_name));
1606 ASSERT(!target.IsNull()); 1600 ASSERT(!target.IsNull());
1607 ASSERT(target.IsRecognized()); 1601 ASSERT(target.IsRecognized());
1608 ASSERT(target.always_inline()); 1602 ASSERT(target.always_inline());
1609 1603
1610 StaticCallInstr* new_call = 1604 StaticCallInstr* new_call =
1611 new (Z) StaticCallInstr(call->token_pos(), target, 1605 new (Z) StaticCallInstr(call->token_pos(), target,
1612 Object::null_array(), // argument_names 1606 Object::null_array(), // argument_names
1613 args, call->deopt_id()); 1607 args, call->deopt_id(), call->CallCount());
1614 Environment* copy = 1608 Environment* copy =
1615 call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount()); 1609 call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount());
1616 for (intptr_t i = 0; i < args->length(); ++i) { 1610 for (intptr_t i = 0; i < args->length(); ++i) {
1617 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); 1611 copy->PushValue(new (Z) Value((*args)[i]->value()->definition()));
1618 } 1612 }
1619 call->RemoveEnvironment(); 1613 call->RemoveEnvironment();
1620 ReplaceCall(call, new_call); 1614 ReplaceCall(call, new_call);
1621 copy->DeepCopyTo(Z, new_call); 1615 copy->DeepCopyTo(Z, new_call);
1622 return; 1616 return;
1623 } 1617 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1666 const String& target_name = Symbols::_classRangeAssert(); 1660 const String& target_name = Symbols::_classRangeAssert();
1667 const Function& target = Function::ZoneHandle( 1661 const Function& target = Function::ZoneHandle(
1668 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); 1662 Z, dart_internal.LookupFunctionAllowPrivate(target_name));
1669 ASSERT(!target.IsNull()); 1663 ASSERT(!target.IsNull());
1670 ASSERT(target.IsRecognized()); 1664 ASSERT(target.IsRecognized());
1671 ASSERT(target.always_inline()); 1665 ASSERT(target.always_inline());
1672 1666
1673 StaticCallInstr* new_call = 1667 StaticCallInstr* new_call =
1674 new (Z) StaticCallInstr(call->token_pos(), target, 1668 new (Z) StaticCallInstr(call->token_pos(), target,
1675 Object::null_array(), // argument_names 1669 Object::null_array(), // argument_names
1676 args, call->deopt_id()); 1670 args, call->deopt_id(), call->CallCount());
1677 Environment* copy = call->env()->DeepCopy( 1671 Environment* copy = call->env()->DeepCopy(
1678 Z, call->env()->Length() - call->ArgumentCount()); 1672 Z, call->env()->Length() - call->ArgumentCount());
1679 for (intptr_t i = 0; i < args->length(); ++i) { 1673 for (intptr_t i = 0; i < args->length(); ++i) {
1680 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); 1674 copy->PushValue(new (Z) Value((*args)[i]->value()->definition()));
1681 } 1675 }
1682 call->RemoveEnvironment(); 1676 call->RemoveEnvironment();
1683 ReplaceCall(call, new_call); 1677 ReplaceCall(call, new_call);
1684 copy->DeepCopyTo(Z, new_call); 1678 copy->DeepCopyTo(Z, new_call);
1685 return; 1679 return;
1686 } 1680 }
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); 1830 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0));
1837 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); 1831 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
1838 has_one_target = !polymorphic_target; 1832 has_one_target = !polymorphic_target;
1839 } 1833 }
1840 1834
1841 if (has_one_target) { 1835 if (has_one_target) {
1842 RawFunction::Kind function_kind = 1836 RawFunction::Kind function_kind =
1843 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind(); 1837 Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
1844 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) { 1838 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) {
1845 CallTargets* targets = CallTargets::Create(Z, unary_checks); 1839 CallTargets* targets = CallTargets::Create(Z, unary_checks);
1846 PolymorphicInstanceCallInstr* call = 1840 ASSERT(targets->HasSingleTarget());
1847 new (Z) PolymorphicInstanceCallInstr(instr, *targets, 1841 const Function& target = targets->FirstTarget();
1848 /* with_checks = */ false, 1842 StaticCallInstr* call = StaticCallInstr::FromCall(Z, instr, target);
1849 /* complete = */ true);
1850 instr->ReplaceWith(call, current_iterator()); 1843 instr->ReplaceWith(call, current_iterator());
1851 return; 1844 return;
1852 } 1845 }
1853 } 1846 }
1854 switch (instr->token_kind()) { 1847 switch (instr->token_kind()) {
1855 case Token::kEQ: 1848 case Token::kEQ:
1856 case Token::kLT: 1849 case Token::kLT:
1857 case Token::kLTE: 1850 case Token::kLTE:
1858 case Token::kGT: 1851 case Token::kGT:
1859 case Token::kGTE: { 1852 case Token::kGTE: {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 Class::Handle(Z, isolate()->class_table()->At(receiver_cid)); 1895 Class::Handle(Z, isolate()->class_table()->At(receiver_cid));
1903 1896
1904 const Array& args_desc_array = 1897 const Array& args_desc_array =
1905 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(), 1898 Array::Handle(Z, ArgumentsDescriptor::New(instr->ArgumentCount(),
1906 instr->argument_names())); 1899 instr->argument_names()));
1907 ArgumentsDescriptor args_desc(args_desc_array); 1900 ArgumentsDescriptor args_desc(args_desc_array);
1908 Function& function = Function::Handle( 1901 Function& function = Function::Handle(
1909 Z, Resolver::ResolveDynamicForReceiverClass( 1902 Z, Resolver::ResolveDynamicForReceiverClass(
1910 receiver_class, instr->function_name(), args_desc)); 1903 receiver_class, instr->function_name(), args_desc));
1911 if (!function.IsNull()) { 1904 if (!function.IsNull()) {
1912 CallTargets* targets = new (Z) CallTargets(); 1905 const Function& target = Function::ZoneHandle(Z, function.raw());
1913 Function& target = Function::ZoneHandle(Z, function.raw()); 1906 StaticCallInstr* call = StaticCallInstr::FromCall(Z, instr, target);
1914 targets->Add(CidRangeTarget(receiver_class.id(), receiver_class.id(),
1915 &target, /*count = */ 1));
1916 PolymorphicInstanceCallInstr* call =
1917 new (Z) PolymorphicInstanceCallInstr(instr, *targets,
1918 /* with_checks = */ false,
1919 /* complete = */ true);
1920 instr->ReplaceWith(call, current_iterator()); 1907 instr->ReplaceWith(call, current_iterator());
1921 return; 1908 return;
1922 } 1909 }
1923 } 1910 }
1924 1911
1925 Definition* callee_receiver = instr->ArgumentAt(0); 1912 Definition* callee_receiver = instr->ArgumentAt(0);
1926 const Function& function = flow_graph_->function(); 1913 const Function& function = flow_graph_->function();
1927 Class& receiver_class = Class::Handle(Z); 1914 Class& receiver_class = Class::Handle(Z);
1928 1915
1929 if (function.IsDynamicFunction() && 1916 if (function.IsDynamicFunction() &&
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 ic_data.AddReceiverCheck(cls.id(), single_target); 2005 ic_data.AddReceiverCheck(cls.id(), single_target);
2019 instr->set_ic_data(&ic_data); 2006 instr->set_ic_data(&ic_data);
2020 2007
2021 if (TryInlineFieldAccess(instr)) { 2008 if (TryInlineFieldAccess(instr)) {
2022 return; 2009 return;
2023 } 2010 }
2024 } 2011 }
2025 2012
2026 // We have computed that there is only a single target for this call 2013 // We have computed that there is only a single target for this call
2027 // within the whole hierarchy. Replace InstanceCall with StaticCall. 2014 // within the whole hierarchy. Replace InstanceCall with StaticCall.
2028 ZoneGrowableArray<PushArgumentInstr*>* args = new (Z) 2015 const Function& target = Function::ZoneHandle(Z, single_target.raw());
2029 ZoneGrowableArray<PushArgumentInstr*>(instr->ArgumentCount()); 2016 StaticCallInstr* call = StaticCallInstr::FromCall(Z, instr, target);
2030 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) {
2031 args->Add(instr->PushArgumentAt(i));
2032 }
2033 StaticCallInstr* call = new (Z) StaticCallInstr(
2034 instr->token_pos(), Function::ZoneHandle(Z, single_target.raw()),
2035 instr->argument_names(), args, instr->deopt_id());
2036 instr->ReplaceWith(call, current_iterator()); 2017 instr->ReplaceWith(call, current_iterator());
2037 return; 2018 return;
2038 } else if ((ic_data.raw() != ICData::null()) && 2019 } else if ((ic_data.raw() != ICData::null()) &&
2039 !ic_data.NumberOfChecksIs(0)) { 2020 !ic_data.NumberOfChecksIs(0)) {
2040 CallTargets* targets = CallTargets::Create(Z, ic_data); 2021 CallTargets* targets = CallTargets::Create(Z, ic_data);
2041 PolymorphicInstanceCallInstr* call = 2022 PolymorphicInstanceCallInstr* call =
2042 new (Z) PolymorphicInstanceCallInstr(instr, *targets, 2023 new (Z) PolymorphicInstanceCallInstr(instr, *targets,
2043 /* with_checks = */ true,
2044 /* complete = */ true); 2024 /* complete = */ true);
2045 instr->ReplaceWith(call, current_iterator()); 2025 instr->ReplaceWith(call, current_iterator());
2046 return; 2026 return;
2047 } 2027 }
2048 } 2028 }
2049 } 2029 }
2050 2030
2051 // More than one target. Generate generic polymorphic call without 2031 // More than one target. Generate generic polymorphic call without
2052 // deoptimization. 2032 // deoptimization.
2053 if (instr->ic_data()->NumberOfUsedChecks() > 0) { 2033 if (instr->ic_data()->NumberOfUsedChecks() > 0) {
2054 ASSERT(!FLAG_polymorphic_with_deopt); 2034 ASSERT(!FLAG_polymorphic_with_deopt);
2055 // OK to use checks with PolymorphicInstanceCallInstr since no 2035 // OK to use checks with PolymorphicInstanceCallInstr since no
2056 // deoptimization is allowed. 2036 // deoptimization is allowed.
2057 CallTargets* targets = CallTargets::Create(Z, *instr->ic_data()); 2037 CallTargets* targets = CallTargets::Create(Z, *instr->ic_data());
2058 PolymorphicInstanceCallInstr* call = 2038 PolymorphicInstanceCallInstr* call =
2059 new (Z) PolymorphicInstanceCallInstr(instr, *targets, 2039 new (Z) PolymorphicInstanceCallInstr(instr, *targets,
2060 /* with_checks = */ true,
2061 /* complete = */ false); 2040 /* complete = */ false);
2062 instr->ReplaceWith(call, current_iterator()); 2041 instr->ReplaceWith(call, current_iterator());
2063 return; 2042 return;
2064 } 2043 }
2065 } 2044 }
2066 2045
2067 2046
2068 void AotOptimizer::VisitPolymorphicInstanceCall( 2047 void AotOptimizer::VisitPolymorphicInstanceCall(
2069 PolymorphicInstanceCallInstr* call) { 2048 PolymorphicInstanceCallInstr* call) {
2070 if (call->with_checks()) { 2049 const intptr_t receiver_cid =
2071 const intptr_t receiver_cid = 2050 call->PushArgumentAt(0)->value()->Type()->ToCid();
2072 call->PushArgumentAt(0)->value()->Type()->ToCid(); 2051 if (receiver_cid != kDynamicCid) {
2073 if (receiver_cid != kDynamicCid) { 2052 const Class& receiver_class =
2074 const Class& receiver_class = 2053 Class::Handle(Z, isolate()->class_table()->At(receiver_cid));
2075 Class::Handle(Z, isolate()->class_table()->At(receiver_cid));
2076 2054
2077 const Array& args_desc_array = Array::Handle( 2055 const Array& args_desc_array = Array::Handle(
2078 Z, ArgumentsDescriptor::New(call->ArgumentCount(), 2056 Z, ArgumentsDescriptor::New(call->ArgumentCount(),
2079 call->instance_call()->argument_names())); 2057 call->instance_call()->argument_names()));
2080 ArgumentsDescriptor args_desc(args_desc_array); 2058 ArgumentsDescriptor args_desc(args_desc_array);
2081 const Function& function = Function::Handle( 2059 const Function& function = Function::Handle(
2082 Z, Resolver::ResolveDynamicForReceiverClass( 2060 Z,
2083 receiver_class, call->instance_call()->function_name(), 2061 Resolver::ResolveDynamicForReceiverClass(
2084 args_desc)); 2062 receiver_class, call->instance_call()->function_name(), args_desc));
2085 if (!function.IsNull()) { 2063 if (!function.IsNull()) {
2086 call->set_with_checks(false); 2064 // Only one target. Replace by static call.
2087 } 2065 StaticCallInstr* new_call = StaticCallInstr::FromCall(Z, call, function);
2066 call->ReplaceWith(new_call, current_iterator());
2088 } 2067 }
2089 } 2068 }
2090 } 2069 }
2091 2070
2092 2071
2093 void AotOptimizer::VisitStaticCall(StaticCallInstr* call) { 2072 void AotOptimizer::VisitStaticCall(StaticCallInstr* call) {
2094 if (!IsAllowedForInlining(call->deopt_id())) { 2073 if (!IsAllowedForInlining(call->deopt_id())) {
2095 // Inlining disabled after a speculative inlining attempt. 2074 // Inlining disabled after a speculative inlining attempt.
2096 return; 2075 return;
2097 } 2076 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 FlowGraph::kEffect); 2234 FlowGraph::kEffect);
2256 current_iterator()->RemoveCurrentFromGraph(); 2235 current_iterator()->RemoveCurrentFromGraph();
2257 } 2236 }
2258 } 2237 }
2259 } 2238 }
2260 } 2239 }
2261 2240
2262 #endif // DART_PRECOMPILER 2241 #endif // DART_PRECOMPILER
2263 2242
2264 } // namespace dart 2243 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698