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

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

Issue 2102663003: Refactor inlining of recognized methods. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed missing inlining, more cleanup Created 4 years, 5 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_inliner.h ('k') | runtime/vm/jit_optimizer.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 2442 matching lines...) Expand 10 before | Expand all | Expand 10 after
2453 new(Z) Value(left), 2453 new(Z) Value(left),
2454 new(Z) Value(right), 2454 new(Z) Value(right),
2455 call->deopt_id(), call->token_pos()); 2455 call->deopt_id(), call->token_pos());
2456 flow_graph->AppendTo(*entry, double_bin_op, call->env(), FlowGraph::kValue); 2456 flow_graph->AppendTo(*entry, double_bin_op, call->env(), FlowGraph::kValue);
2457 *last = double_bin_op; 2457 *last = double_bin_op;
2458 2458
2459 return true; 2459 return true;
2460 } 2460 }
2461 2461
2462 2462
2463 static bool InlineGrowableArraySetter(FlowGraph* flow_graph,
2464 intptr_t offset,
2465 StoreBarrierType store_barrier_type,
2466 Instruction* call,
2467 TargetEntryInstr** entry,
2468 Definition** last) {
2469 Definition* array = call->ArgumentAt(0);
2470 Definition* value = call->ArgumentAt(1);
2471
2472 *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2473 call->GetBlock()->try_index());
2474 (*entry)->InheritDeoptTarget(Z, call);
2475
2476 // This is an internal method, no need to check argument types.
2477 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
2478 offset,
2479 new(Z) Value(array),
2480 new(Z) Value(value),
2481 store_barrier_type,
2482 call->token_pos());
2483 flow_graph->AppendTo(*entry, store, call->env(), FlowGraph::kEffect);
2484 *last = store;
2485
2486 return true;
2487 }
2488
2489
2463 static intptr_t PrepareInlineByteArrayBaseOp( 2490 static intptr_t PrepareInlineByteArrayBaseOp(
2464 FlowGraph* flow_graph, 2491 FlowGraph* flow_graph,
2465 Instruction* call, 2492 Instruction* call,
2466 intptr_t array_cid, 2493 intptr_t array_cid,
2467 intptr_t view_cid, 2494 intptr_t view_cid,
2468 Definition** array, 2495 Definition** array,
2469 Definition* byte_index, 2496 Definition* byte_index,
2470 Instruction** cursor) { 2497 Instruction** cursor) {
2471 // Insert byte_index smi check. 2498 // Insert byte_index smi check.
2472 *cursor = flow_graph->AppendTo(*cursor, 2499 *cursor = flow_graph->AppendTo(*cursor,
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2869 return true; 2896 return true;
2870 } 2897 }
2871 2898
2872 2899
2873 static bool InlineStringCodeUnitAt( 2900 static bool InlineStringCodeUnitAt(
2874 FlowGraph* flow_graph, 2901 FlowGraph* flow_graph,
2875 Instruction* call, 2902 Instruction* call,
2876 intptr_t cid, 2903 intptr_t cid,
2877 TargetEntryInstr** entry, 2904 TargetEntryInstr** entry,
2878 Definition** last) { 2905 Definition** last) {
2906 ASSERT((cid == kOneByteStringCid) ||
2907 (cid == kTwoByteStringCid) ||
2908 (cid == kExternalOneByteStringCid) ||
2909 (cid == kExternalTwoByteStringCid));
2879 Definition* str = call->ArgumentAt(0); 2910 Definition* str = call->ArgumentAt(0);
2880 Definition* index = call->ArgumentAt(1); 2911 Definition* index = call->ArgumentAt(1);
2881 2912
2882 *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2913 *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2883 call->GetBlock()->try_index()); 2914 call->GetBlock()->try_index());
2884 (*entry)->InheritDeoptTarget(Z, call); 2915 (*entry)->InheritDeoptTarget(Z, call);
2885 2916
2886 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); 2917 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry);
2887 2918
2888 return true; 2919 return true;
2889 } 2920 }
2890 2921
2891 2922
2923 bool FlowGraphInliner::TryReplaceInstanceCallWithInline(
2924 FlowGraph* flow_graph,
2925 ForwardInstructionIterator* iterator,
2926 InstanceCallInstr* call) {
2927 Function& target = Function::Handle(Z);
2928 GrowableArray<intptr_t> class_ids;
2929 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2930 const intptr_t receiver_cid = class_ids[0];
2931
2932 TargetEntryInstr* entry;
2933 Definition* last;
2934 if (!FlowGraphInliner::TryInlineRecognizedMethod(flow_graph,
2935 receiver_cid,
2936 target,
2937 call,
2938 call->ArgumentAt(0),
2939 call->token_pos(),
2940 *call->ic_data(),
2941 &entry, &last)) {
2942 return false;
2943 }
2944
2945 // Insert receiver class check if needed.
2946 if (MethodRecognizer::PolymorphicTarget(target) ||
2947 flow_graph->InstanceCallNeedsClassCheck(call, target.kind())) {
2948 Instruction* check = GetCheckClass(
2949 flow_graph,
2950 call->ArgumentAt(0),
2951 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()),
2952 call->deopt_id(),
2953 call->token_pos());
2954 flow_graph->InsertBefore(call, check, call->env(), FlowGraph::kEffect);
2955 }
2956
2957 // Remove the original push arguments.
2958 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
2959 PushArgumentInstr* push = call->PushArgumentAt(i);
2960 push->ReplaceUsesWith(push->value()->definition());
2961 push->RemoveFromGraph();
2962 }
2963 // Replace all uses of this definition with the result.
2964 call->ReplaceUsesWith(last);
2965 // Finally insert the sequence other definition in place of this one in the
2966 // graph.
2967 call->previous()->LinkTo(entry->next());
2968 entry->UnuseAllInputs(); // Entry block is not in the graph.
2969 last->LinkTo(call);
2970 // Remove through the iterator.
2971 ASSERT(iterator->Current() == call);
2972 iterator->RemoveCurrentFromGraph();
2973 call->set_previous(NULL);
2974 call->set_next(NULL);
2975 return true;
2976 }
2977
2978
2892 bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph, 2979 bool FlowGraphInliner::TryInlineRecognizedMethod(FlowGraph* flow_graph,
2893 intptr_t receiver_cid, 2980 intptr_t receiver_cid,
2894 const Function& target, 2981 const Function& target,
2895 Instruction* call, 2982 Instruction* call,
2896 Definition* receiver, 2983 Definition* receiver,
2897 TokenPosition token_pos, 2984 TokenPosition token_pos,
2898 const ICData& ic_data, 2985 const ICData& ic_data,
2899 TargetEntryInstr** entry, 2986 TargetEntryInstr** entry,
2900 Definition** last) { 2987 Definition** last) {
2901 ICData& value_check = ICData::ZoneHandle(Z); 2988 ICData& value_check = ICData::ZoneHandle(Z);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
3121 return InlineStringBaseCharAt( 3208 return InlineStringBaseCharAt(
3122 flow_graph, call, receiver_cid, entry, last); 3209 flow_graph, call, receiver_cid, entry, last);
3123 case MethodRecognizer::kDoubleAdd: 3210 case MethodRecognizer::kDoubleAdd:
3124 return InlineDoubleOp(flow_graph, Token::kADD, call, entry, last); 3211 return InlineDoubleOp(flow_graph, Token::kADD, call, entry, last);
3125 case MethodRecognizer::kDoubleSub: 3212 case MethodRecognizer::kDoubleSub:
3126 return InlineDoubleOp(flow_graph, Token::kSUB, call, entry, last); 3213 return InlineDoubleOp(flow_graph, Token::kSUB, call, entry, last);
3127 case MethodRecognizer::kDoubleMul: 3214 case MethodRecognizer::kDoubleMul:
3128 return InlineDoubleOp(flow_graph, Token::kMUL, call, entry, last); 3215 return InlineDoubleOp(flow_graph, Token::kMUL, call, entry, last);
3129 case MethodRecognizer::kDoubleDiv: 3216 case MethodRecognizer::kDoubleDiv:
3130 return InlineDoubleOp(flow_graph, Token::kDIV, call, entry, last); 3217 return InlineDoubleOp(flow_graph, Token::kDIV, call, entry, last);
3218 case MethodRecognizer::kGrowableArraySetData:
3219 ASSERT(receiver_cid == kGrowableObjectArrayCid);
3220 ASSERT(ic_data.NumberOfChecks() == 1);
3221 return InlineGrowableArraySetter(
3222 flow_graph, GrowableObjectArray::data_offset(), kEmitStoreBarrier,
3223 call, entry, last);
3224 case MethodRecognizer::kGrowableArraySetLength:
3225 ASSERT(receiver_cid == kGrowableObjectArrayCid);
3226 ASSERT(ic_data.NumberOfChecks() == 1);
3227 return InlineGrowableArraySetter(
3228 flow_graph, GrowableObjectArray::length_offset(), kNoStoreBarrier,
3229 call, entry, last);
3131 default: 3230 default:
3132 return false; 3231 return false;
3133 } 3232 }
3134 } 3233 }
3135 3234
3136 3235
3137 } // namespace dart 3236 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_inliner.h ('k') | runtime/vm/jit_optimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698