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

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

Issue 2098643003: VM: [AOT] Make sure that we inline all resolved accessor invocations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Done. 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/aot_optimizer.h ('k') | runtime/vm/assembler_arm.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 2274 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 } 2285 }
2286 // If all of the inputs are known smis or the result of CheckedSmiOp, 2286 // If all of the inputs are known smis or the result of CheckedSmiOp,
2287 // we guess the operand to be likely smi. 2287 // we guess the operand to be likely smi.
2288 for (intptr_t i = 0; i < instr->ArgumentCount(); ++i) { 2288 for (intptr_t i = 0; i < instr->ArgumentCount(); ++i) {
2289 if (!instr->ArgumentAt(i)->IsCheckedSmiOp()) return false; 2289 if (!instr->ArgumentAt(i)->IsCheckedSmiOp()) return false;
2290 } 2290 }
2291 return true; 2291 return true;
2292 } 2292 }
2293 2293
2294 2294
2295 bool AotOptimizer::TryInlineFieldAccess(InstanceCallInstr* call) {
2296 const Token::Kind op_kind = call->token_kind();
2297 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(call)) {
2298 return true;
2299 }
2300
2301 const ICData& unary_checks =
2302 ICData::Handle(Z, call->ic_data()->AsUnaryClassChecks());
2303 if ((unary_checks.NumberOfChecks() > 0) &&
2304 (op_kind == Token::kSET) &&
2305 TryInlineInstanceSetter(call, unary_checks)) {
2306 return true;
2307 }
2308
2309 return false;
2310 }
2311
2312
2295 // Tries to optimize instance call by replacing it with a faster instruction 2313 // Tries to optimize instance call by replacing it with a faster instruction
2296 // (e.g, binary op, field load, ..). 2314 // (e.g, binary op, field load, ..).
2297 void AotOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { 2315 void AotOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
2298 ASSERT(FLAG_precompiled_mode); 2316 ASSERT(FLAG_precompiled_mode);
2299 // TODO(srdjan): Investigate other attempts, as they are not allowed to 2317 // TODO(srdjan): Investigate other attempts, as they are not allowed to
2300 // deoptimize. 2318 // deoptimize.
2301 2319
2302 // Type test is special as it always gets converted into inlined code. 2320 // Type test is special as it always gets converted into inlined code.
2303 const Token::Kind op_kind = instr->token_kind(); 2321 const Token::Kind op_kind = instr->token_kind();
2304 if (Token::IsTypeTestOperator(op_kind)) { 2322 if (Token::IsTypeTestOperator(op_kind)) {
2305 ReplaceWithInstanceOf(instr); 2323 ReplaceWithInstanceOf(instr);
2306 return; 2324 return;
2307 } 2325 }
2308 if (Token::IsTypeCastOperator(op_kind)) { 2326 if (Token::IsTypeCastOperator(op_kind)) {
2309 ReplaceWithTypeCast(instr); 2327 ReplaceWithTypeCast(instr);
2310 return; 2328 return;
2311 } 2329 }
2312 2330
2313 if ((op_kind == Token::kGET) && 2331 if (TryInlineFieldAccess(instr)) {
2314 TryInlineInstanceGetter(instr)) {
2315 return;
2316 }
2317 const ICData& unary_checks =
2318 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
2319 if ((unary_checks.NumberOfChecks() > 0) &&
2320 (op_kind == Token::kSET) &&
2321 TryInlineInstanceSetter(instr, unary_checks)) {
2322 return; 2332 return;
2323 } 2333 }
2324 2334
2335 const ICData& unary_checks =
2336 ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
2325 if (IsAllowedForInlining(instr->deopt_id()) && 2337 if (IsAllowedForInlining(instr->deopt_id()) &&
2326 (unary_checks.NumberOfChecks() > 0)) { 2338 (unary_checks.NumberOfChecks() > 0)) {
2327 if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) { 2339 if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) {
2328 return; 2340 return;
2329 } 2341 }
2330 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) { 2342 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) {
2331 return; 2343 return;
2332 } 2344 }
2333 if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) { 2345 if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) {
2334 return; 2346 return;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2506 2518
2507 single_target = Function::null(); 2519 single_target = Function::null();
2508 } 2520 }
2509 2521
2510 ASSERT(ic_data.raw() != ICData::null()); 2522 ASSERT(ic_data.raw() != ICData::null());
2511 ASSERT(single_target.raw() == Function::null()); 2523 ASSERT(single_target.raw() == Function::null());
2512 ic_data.AddReceiverCheck(cid, target); 2524 ic_data.AddReceiverCheck(cid, target);
2513 } 2525 }
2514 2526
2515 if (single_target.raw() != Function::null()) { 2527 if (single_target.raw() != Function::null()) {
2528 // If this is a getter or setter invocation try inlining it right away
2529 // instead of replacing it with a static call.
2530 if ((op_kind == Token::kGET) || (op_kind == Token::kSET)) {
2531 // Create fake IC data with the resolved target.
2532 const ICData& ic_data = ICData::Handle(
2533 ICData::New(flow_graph_->function(),
2534 instr->function_name(),
2535 args_desc_array,
2536 Thread::kNoDeoptId,
2537 /* args_tested = */ 1,
2538 false));
2539 cls = single_target.Owner();
2540 ic_data.AddReceiverCheck(cls.id(), single_target);
2541 instr->set_ic_data(&ic_data);
2542
2543 if (TryInlineFieldAccess(instr)) {
2544 return;
2545 }
2546 }
2547
2516 // We have computed that there is only a single target for this call 2548 // We have computed that there is only a single target for this call
2517 // within the whole hierarchy. Replace InstanceCall with StaticCall. 2549 // within the whole hierarchy. Replace InstanceCall with StaticCall.
2518 ZoneGrowableArray<PushArgumentInstr*>* args = 2550 ZoneGrowableArray<PushArgumentInstr*>* args =
2519 new (Z) ZoneGrowableArray<PushArgumentInstr*>( 2551 new (Z) ZoneGrowableArray<PushArgumentInstr*>(
2520 instr->ArgumentCount()); 2552 instr->ArgumentCount());
2521 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) { 2553 for (intptr_t i = 0; i < instr->ArgumentCount(); i++) {
2522 args->Add(instr->PushArgumentAt(i)); 2554 args->Add(instr->PushArgumentAt(i));
2523 } 2555 }
2524 StaticCallInstr* call = new (Z) StaticCallInstr( 2556 StaticCallInstr* call = new (Z) StaticCallInstr(
2525 instr->token_pos(), 2557 instr->token_pos(),
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
2778 2810
2779 // Discard the environment from the original instruction because the store 2811 // Discard the environment from the original instruction because the store
2780 // can't deoptimize. 2812 // can't deoptimize.
2781 instr->RemoveEnvironment(); 2813 instr->RemoveEnvironment();
2782 ReplaceCall(instr, store); 2814 ReplaceCall(instr, store);
2783 return true; 2815 return true;
2784 } 2816 }
2785 2817
2786 2818
2787 } // namespace dart 2819 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/aot_optimizer.h ('k') | runtime/vm/assembler_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698