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

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

Issue 1867913004: Specialize instance calls when the call receiver is the method receiver and the method class has a … (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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 | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.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/flow_graph_inliner.h" 5 #include "vm/flow_graph_inliner.h"
6 6
7 #include "vm/aot_optimizer.h" 7 #include "vm/aot_optimizer.h"
8 #include "vm/block_scheduler.h" 8 #include "vm/block_scheduler.h"
9 #include "vm/branch_optimizer.h" 9 #include "vm/branch_optimizer.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 1209
1210 void InlineInstanceCalls() { 1210 void InlineInstanceCalls() {
1211 const GrowableArray<CallSites::InstanceCallInfo>& call_info = 1211 const GrowableArray<CallSites::InstanceCallInfo>& call_info =
1212 inlining_call_sites_->instance_calls(); 1212 inlining_call_sites_->instance_calls();
1213 TRACE_INLINING(THR_Print(" Polymorphic Instance Calls (%" Pd ")\n", 1213 TRACE_INLINING(THR_Print(" Polymorphic Instance Calls (%" Pd ")\n",
1214 call_info.length())); 1214 call_info.length()));
1215 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) { 1215 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) {
1216 PolymorphicInstanceCallInstr* call = call_info[call_idx].call; 1216 PolymorphicInstanceCallInstr* call = call_info[call_idx].call;
1217 if (call->with_checks()) { 1217 if (call->with_checks()) {
1218 // PolymorphicInliner introduces deoptimization paths. 1218 // PolymorphicInliner introduces deoptimization paths.
1219 if (!FLAG_polymorphic_with_deopt) { 1219 if (!call->complete() && !FLAG_polymorphic_with_deopt) {
1220 TRACE_INLINING(THR_Print( 1220 TRACE_INLINING(THR_Print(
1221 " => %s\n Bailout: call with checks\n", 1221 " => %s\n Bailout: call with checks\n",
1222 call->instance_call()->function_name().ToCString())); 1222 call->instance_call()->function_name().ToCString()));
1223 continue; 1223 continue;
1224 } 1224 }
1225 const Function& cl = call_info[call_idx].caller(); 1225 const Function& cl = call_info[call_idx].caller();
1226 intptr_t caller_inlining_id = 1226 intptr_t caller_inlining_id =
1227 call_info[call_idx].caller_graph->inlining_id(); 1227 call_info[call_idx].caller_graph->inlining_id();
1228 PolymorphicInliner inliner(this, call, cl, caller_inlining_id); 1228 PolymorphicInliner inliner(this, call, cl, caller_inlining_id);
1229 inliner.Inline(); 1229 inliner.Inline();
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1626 // at least one branch on the class id. 1626 // at least one branch on the class id.
1627 LoadClassIdInstr* load_cid = 1627 LoadClassIdInstr* load_cid =
1628 new(Z) LoadClassIdInstr(new(Z) Value(receiver)); 1628 new(Z) LoadClassIdInstr(new(Z) Value(receiver));
1629 load_cid->set_ssa_temp_index(owner_->caller_graph()->alloc_ssa_temp_index()); 1629 load_cid->set_ssa_temp_index(owner_->caller_graph()->alloc_ssa_temp_index());
1630 cursor = AppendInstruction(cursor, load_cid); 1630 cursor = AppendInstruction(cursor, load_cid);
1631 for (intptr_t i = 0; i < inlined_variants_.length(); ++i) { 1631 for (intptr_t i = 0; i < inlined_variants_.length(); ++i) {
1632 // 1. Guard the body with a class id check. 1632 // 1. Guard the body with a class id check.
1633 if ((i == (inlined_variants_.length() - 1)) && 1633 if ((i == (inlined_variants_.length() - 1)) &&
1634 non_inlined_variants_.is_empty()) { 1634 non_inlined_variants_.is_empty()) {
1635 // If it is the last variant use a check class id instruction which can 1635 // If it is the last variant use a check class id instruction which can
1636 // deoptimize, followed unconditionally by the body. 1636 // deoptimize, followed unconditionally by the body. Omit the check if
1637 RedefinitionInstr* cid_redefinition = 1637 // we know that we have covered all possible classes.
1638 new RedefinitionInstr(new(Z) Value(load_cid)); 1638 if (!call_->complete()) {
1639 cid_redefinition->set_ssa_temp_index( 1639 RedefinitionInstr* cid_redefinition =
1640 owner_->caller_graph()->alloc_ssa_temp_index()); 1640 new RedefinitionInstr(new(Z) Value(load_cid));
1641 cursor = AppendInstruction(cursor, cid_redefinition); 1641 cid_redefinition->set_ssa_temp_index(
1642 CheckClassIdInstr* check_class_id = new(Z) CheckClassIdInstr( 1642 owner_->caller_graph()->alloc_ssa_temp_index());
1643 new(Z) Value(cid_redefinition), 1643 cursor = AppendInstruction(cursor, cid_redefinition);
1644 inlined_variants_[i].cid, 1644 CheckClassIdInstr* check_class_id = new(Z) CheckClassIdInstr(
1645 call_->deopt_id()); 1645 new(Z) Value(cid_redefinition),
1646 check_class_id->InheritDeoptTarget(zone(), call_); 1646 inlined_variants_[i].cid,
1647 cursor = AppendInstruction(cursor, check_class_id); 1647 call_->deopt_id());
1648 check_class_id->InheritDeoptTarget(zone(), call_);
1649 cursor = AppendInstruction(cursor, check_class_id);
1650 }
1648 1651
1649 // The next instruction is the first instruction of the inlined body. 1652 // The next instruction is the first instruction of the inlined body.
1650 // Handle the two possible cases (unshared and shared subsequent 1653 // Handle the two possible cases (unshared and shared subsequent
1651 // predecessors) separately. 1654 // predecessors) separately.
1652 BlockEntryInstr* callee_entry = inlined_entries_[i]; 1655 BlockEntryInstr* callee_entry = inlined_entries_[i];
1653 if (callee_entry->IsGraphEntry()) { 1656 if (callee_entry->IsGraphEntry()) {
1654 // Unshared. Graft the normal entry on after the check class 1657 // Unshared. Graft the normal entry on after the check class
1655 // instruction. 1658 // instruction.
1656 TargetEntryInstr* target = 1659 TargetEntryInstr* target =
1657 callee_entry->AsGraphEntry()->normal_entry(); 1660 callee_entry->AsGraphEntry()->normal_entry();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 old_checks.deopt_id(), 1773 old_checks.deopt_id(),
1771 1)); // Number of args tested. 1774 1)); // Number of args tested.
1772 for (intptr_t i = 0; i < non_inlined_variants_.length(); ++i) { 1775 for (intptr_t i = 0; i < non_inlined_variants_.length(); ++i) {
1773 new_checks.AddReceiverCheck(non_inlined_variants_[i].cid, 1776 new_checks.AddReceiverCheck(non_inlined_variants_[i].cid,
1774 *non_inlined_variants_[i].target, 1777 *non_inlined_variants_[i].target,
1775 non_inlined_variants_[i].count); 1778 non_inlined_variants_[i].count);
1776 } 1779 }
1777 PolymorphicInstanceCallInstr* fallback_call = 1780 PolymorphicInstanceCallInstr* fallback_call =
1778 new PolymorphicInstanceCallInstr(call_->instance_call(), 1781 new PolymorphicInstanceCallInstr(call_->instance_call(),
1779 new_checks, 1782 new_checks,
1780 true); // With checks. 1783 /* with_checks = */ true,
1784 call_->complete());
1781 fallback_call->set_ssa_temp_index( 1785 fallback_call->set_ssa_temp_index(
1782 owner_->caller_graph()->alloc_ssa_temp_index()); 1786 owner_->caller_graph()->alloc_ssa_temp_index());
1783 fallback_call->InheritDeoptTarget(zone(), call_); 1787 fallback_call->InheritDeoptTarget(zone(), call_);
1784 ReturnInstr* fallback_return = 1788 ReturnInstr* fallback_return =
1785 new ReturnInstr(call_->instance_call()->token_pos(), 1789 new ReturnInstr(call_->instance_call()->token_pos(),
1786 new Value(fallback_call)); 1790 new Value(fallback_call));
1787 fallback_return->InheritDeoptTargetAfter( 1791 fallback_return->InheritDeoptTargetAfter(
1788 owner_->caller_graph(), 1792 owner_->caller_graph(),
1789 call_, 1793 call_,
1790 fallback_call); 1794 fallback_call);
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
2866 2870
2867 bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph, 2871 bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph,
2868 intptr_t receiver_cid, 2872 intptr_t receiver_cid,
2869 const Function& target, 2873 const Function& target,
2870 Instruction* call, 2874 Instruction* call,
2871 Definition* receiver, 2875 Definition* receiver,
2872 TokenPosition token_pos, 2876 TokenPosition token_pos,
2873 const ICData& ic_data, 2877 const ICData& ic_data,
2874 TargetEntryInstr** entry, 2878 TargetEntryInstr** entry,
2875 Definition** last) { 2879 Definition** last) {
2880 if (FLAG_precompiled_mode) {
2881 // The graphs generated below include deopts.
2882 return false;
2883 }
2884
2876 ICData& value_check = ICData::ZoneHandle(Z); 2885 ICData& value_check = ICData::ZoneHandle(Z);
2877 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target); 2886 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target);
2878 switch (kind) { 2887 switch (kind) {
2879 // Recognized [] operators. 2888 // Recognized [] operators.
2880 case MethodRecognizer::kImmutableArrayGetIndexed: 2889 case MethodRecognizer::kImmutableArrayGetIndexed:
2881 case MethodRecognizer::kObjectArrayGetIndexed: 2890 case MethodRecognizer::kObjectArrayGetIndexed:
2882 case MethodRecognizer::kGrowableArrayGetIndexed: 2891 case MethodRecognizer::kGrowableArrayGetIndexed:
2883 case MethodRecognizer::kInt8ArrayGetIndexed: 2892 case MethodRecognizer::kInt8ArrayGetIndexed:
2884 case MethodRecognizer::kUint8ArrayGetIndexed: 2893 case MethodRecognizer::kUint8ArrayGetIndexed:
2885 case MethodRecognizer::kUint8ClampedArrayGetIndexed: 2894 case MethodRecognizer::kUint8ClampedArrayGetIndexed:
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 return InlineDoubleOp(flow_graph, Token::kMUL, call, entry, last); 3109 return InlineDoubleOp(flow_graph, Token::kMUL, call, entry, last);
3101 case MethodRecognizer::kDoubleDiv: 3110 case MethodRecognizer::kDoubleDiv:
3102 return InlineDoubleOp(flow_graph, Token::kDIV, call, entry, last); 3111 return InlineDoubleOp(flow_graph, Token::kDIV, call, entry, last);
3103 default: 3112 default:
3104 return false; 3113 return false;
3105 } 3114 }
3106 } 3115 }
3107 3116
3108 3117
3109 } // namespace dart 3118 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698