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

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

Issue 161853002: Enable polymorphic inlining of StringBase [] and StringBase codeUnitAt (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('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_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/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 case MethodRecognizer::kByteArrayBaseGetFloat32x4: 1354 case MethodRecognizer::kByteArrayBaseGetFloat32x4:
1355 if (!ShouldInlineSimd()) return false; 1355 if (!ShouldInlineSimd()) return false;
1356 return InlineByteArrayViewLoad(call, receiver, receiver_cid, 1356 return InlineByteArrayViewLoad(call, receiver, receiver_cid,
1357 kTypedDataFloat32x4ArrayCid, 1357 kTypedDataFloat32x4ArrayCid,
1358 ic_data, entry, last); 1358 ic_data, entry, last);
1359 case MethodRecognizer::kByteArrayBaseGetInt32x4: 1359 case MethodRecognizer::kByteArrayBaseGetInt32x4:
1360 if (!ShouldInlineSimd()) return false; 1360 if (!ShouldInlineSimd()) return false;
1361 return InlineByteArrayViewLoad(call, receiver, receiver_cid, 1361 return InlineByteArrayViewLoad(call, receiver, receiver_cid,
1362 kTypedDataInt32x4ArrayCid, 1362 kTypedDataInt32x4ArrayCid,
1363 ic_data, entry, last); 1363 ic_data, entry, last);
1364 case MethodRecognizer::kStringBaseCodeUnitAt:
1365 return InlineStringCodeUnitAt(call, receiver_cid, entry, last);
1366 case MethodRecognizer::kStringBaseCharAt:
1367 return InlineStringBaseCharAt(call, receiver_cid, entry, last);
1364 default: 1368 default:
1365 return false; 1369 return false;
1366 } 1370 }
1367 } 1371 }
1368 1372
1369 1373
1370 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, 1374 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call,
1371 intptr_t array_cid, 1375 intptr_t array_cid,
1372 Definition** array, 1376 Definition** array,
1373 Definition* index, 1377 Definition* index,
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after
2362 if (target.kind() != RawFunction::kImplicitGetter) { 2366 if (target.kind() != RawFunction::kImplicitGetter) {
2363 // Non-implicit getters are inlined like normal methods by conventional 2367 // Non-implicit getters are inlined like normal methods by conventional
2364 // inlining in FlowGraphInliner. 2368 // inlining in FlowGraphInliner.
2365 return false; 2369 return false;
2366 } 2370 }
2367 InlineImplicitInstanceGetter(call); 2371 InlineImplicitInstanceGetter(call);
2368 return true; 2372 return true;
2369 } 2373 }
2370 2374
2371 2375
2376 // Returns the LoadIndexedInstr.
2377 Definition* FlowGraphOptimizer::PrepareInlineStringIndexOp(
2378 Instruction* call,
2379 intptr_t cid,
2380 Definition* str,
2381 Definition* index,
2382 Instruction* cursor) {
2383
2384 cursor = flow_graph()->AppendTo(cursor,
2385 new CheckSmiInstr(new Value(index),
2386 call->deopt_id()),
2387 call->env(),
2388 Definition::kEffect);
2389
2390 // If both index and string are constants, then do a compile-time check.
2391 // TODO(srdjan): Remove once constant propagation handles bounds checks.
2392 bool skip_check = false;
Florian Schneider 2014/02/13 11:57:46 I'm pretty sure that constant propagation handles
2393 if (str->IsConstant() && index->IsConstant()) {
2394 const String& constant_string =
2395 String::Cast(str->AsConstant()->value());
2396 const Object& constant_index = index->AsConstant()->value();
2397 skip_check = constant_index.IsSmi() &&
2398 (Smi::Cast(constant_index).Value() < constant_string.Length());
2399 }
2400
2401 if (!skip_check) {
2402 // Load the length of the string.
2403 LoadFieldInstr* length = BuildLoadStringLength(str);
2404 cursor = flow_graph()->AppendTo(cursor, length, NULL, Definition::kValue);
2405 // Bounds check.
2406 cursor = flow_graph()->AppendTo(cursor,
2407 new CheckArrayBoundInstr(new Value(length),
2408 new Value(index),
2409 call->deopt_id()),
2410 call->env(),
2411 Definition::kEffect);
2412 }
2413 LoadIndexedInstr* load_indexed = new LoadIndexedInstr(
2414 new Value(str),
2415 new Value(index),
2416 FlowGraphCompiler::ElementSizeFor(cid),
2417 cid,
2418 Isolate::kNoDeoptId);
2419
2420 cursor = flow_graph()->AppendTo(cursor,
2421 load_indexed,
2422 NULL,
2423 Definition::kValue);
2424 ASSERT(cursor == load_indexed);
2425 return load_indexed;
2426 }
2427
2428
2429 bool FlowGraphOptimizer::InlineStringCodeUnitAt(
2430 Instruction* call,
2431 intptr_t cid,
2432 TargetEntryInstr** entry,
2433 Definition** last) {
2434
2435 Definition* str = call->ArgumentAt(0);
2436 Definition* index = call->ArgumentAt(1);
2437
2438 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
2439 call->GetBlock()->try_index());
2440 (*entry)->InheritDeoptTarget(call);
2441
2442 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
2443
2444 return true;
2445 }
2446
2447
2448 bool FlowGraphOptimizer::InlineStringBaseCharAt(
2449 Instruction* call,
2450 intptr_t cid,
2451 TargetEntryInstr** entry,
2452 Definition** last) {
2453
2454 Definition* str = call->ArgumentAt(0);
2455 Definition* index = call->ArgumentAt(1);
2456
2457 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
2458 call->GetBlock()->try_index());
2459 (*entry)->InheritDeoptTarget(call);
2460
2461 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
2462
2463 StringFromCharCodeInstr* char_at =
2464 new StringFromCharCodeInstr(new Value(*last), cid);
2465
2466 flow_graph()->AppendTo(*last, char_at, NULL, Definition::kValue);
2467 *last = char_at;
2468
2469 return true;
2470 }
2471
2472
2372 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt( 2473 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt(
Florian Schneider 2014/02/13 11:57:46 I think you should be able to use your newly intro
2373 InstanceCallInstr* call, 2474 InstanceCallInstr* call,
2374 intptr_t cid) { 2475 intptr_t cid) {
2375 Definition* str = call->ArgumentAt(0); 2476 Definition* str = call->ArgumentAt(0);
2376 Definition* index = call->ArgumentAt(1); 2477 Definition* index = call->ArgumentAt(1);
2377 AddReceiverCheck(call); 2478 AddReceiverCheck(call);
2378 InsertBefore(call, 2479 InsertBefore(call,
2379 new CheckSmiInstr(new Value(index), call->deopt_id()), 2480 new CheckSmiInstr(new Value(index), call->deopt_id()),
2380 call->env(), 2481 call->env(),
2381 Definition::kEffect); 2482 Definition::kEffect);
2382 // If both index and string are constants, then do a compile-time check. 2483 // If both index and string are constants, then do a compile-time check.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 } 2593 }
2493 2594
2494 if ((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) && 2595 if ((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) &&
2495 (ic_data.NumberOfChecks() == 1) && 2596 (ic_data.NumberOfChecks() == 1) &&
2496 ((class_ids[0] == kOneByteStringCid) || 2597 ((class_ids[0] == kOneByteStringCid) ||
2497 (class_ids[0] == kTwoByteStringCid))) { 2598 (class_ids[0] == kTwoByteStringCid))) {
2498 LoadIndexedInstr* instr = BuildStringCodeUnitAt(call, class_ids[0]); 2599 LoadIndexedInstr* instr = BuildStringCodeUnitAt(call, class_ids[0]);
2499 ReplaceCall(call, instr); 2600 ReplaceCall(call, instr);
2500 return true; 2601 return true;
2501 } 2602 }
2502 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { 2603 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
Florian Schneider 2014/02/13 11:57:46 Here you should use the newly added builder functi
2503 if (recognized_kind == MethodRecognizer::kStringBaseCharAt) { 2604 if (recognized_kind == MethodRecognizer::kStringBaseCharAt) {
2504 // TODO(fschneider): Handle TwoByteString. 2605 // TODO(fschneider): Handle TwoByteString.
2505 LoadIndexedInstr* load_char_code = 2606 LoadIndexedInstr* load_char_code =
2506 BuildStringCodeUnitAt(call, class_ids[0]); 2607 BuildStringCodeUnitAt(call, class_ids[0]);
2507 InsertBefore(call, load_char_code, NULL, Definition::kValue); 2608 InsertBefore(call, load_char_code, NULL, Definition::kValue);
2508 StringFromCharCodeInstr* char_at = 2609 StringFromCharCodeInstr* char_at =
2509 new StringFromCharCodeInstr(new Value(load_char_code), 2610 new StringFromCharCodeInstr(new Value(load_char_code),
2510 kOneByteStringCid); 2611 kOneByteStringCid);
2511 ReplaceCall(call, char_at); 2612 ReplaceCall(call, char_at);
2512 return true; 2613 return true;
(...skipping 5983 matching lines...) Expand 10 before | Expand all | Expand 10 after
8496 } 8597 }
8497 8598
8498 // Insert materializations at environment uses. 8599 // Insert materializations at environment uses.
8499 for (intptr_t i = 0; i < exits.length(); i++) { 8600 for (intptr_t i = 0; i < exits.length(); i++) {
8500 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8601 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8501 } 8602 }
8502 } 8603 }
8503 8604
8504 8605
8505 } // namespace dart 8606 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698