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

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

Issue 616873003: Use UnboxedInt32 and UnboxedUint32 representation for LoadIndexedInstr (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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 | « no previous file | runtime/vm/intermediate_language_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/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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return true; 68 return true;
69 #else 69 #else
70 // ARM does not have a short instruction sequence for converting int64 to 70 // ARM does not have a short instruction sequence for converting int64 to
71 // double. 71 // double.
72 // TODO(johnmccutchan): Investigate possibility on MIPS once 72 // TODO(johnmccutchan): Investigate possibility on MIPS once
73 // mints are implemented there. 73 // mints are implemented there.
74 return false; 74 return false;
75 #endif 75 #endif
76 } 76 }
77 77
78
79 static bool CanConvertUnboxedInt32ToDouble() {
80 #if defined(TARGET_ARCH_IA32)
81 return true;
82 #elif defined(TARGET_ARCH_ARM)
83 return true;
84 #elif defined(TARGET_ARCH_X64)
85 return true;
86 #else
87 return false;
Vyacheslav Egorov (Google) 2014/10/02 17:14:04 How hard it is to support Int32ToDouble() on MIPS
Cutch 2014/10/02 22:41:12 Done.
88 #endif
89 }
90
91
78 // Optimize instance calls using ICData. 92 // Optimize instance calls using ICData.
79 void FlowGraphOptimizer::ApplyICData() { 93 void FlowGraphOptimizer::ApplyICData() {
80 VisitBlocks(); 94 VisitBlocks();
81 } 95 }
82 96
83 97
84 // Optimize instance calls using cid. This is called after optimizer 98 // Optimize instance calls using cid. This is called after optimizer
85 // converted instance calls to instructions. Any remaining 99 // converted instance calls to instructions. Any remaining
86 // instance calls are either megamorphic calls, cannot be optimized or 100 // instance calls are either megamorphic calls, cannot be optimized or
87 // have no runtime type feedback collected. 101 // have no runtime type feedback collected.
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 635
622 Definition* converted = NULL; 636 Definition* converted = NULL;
623 if ((from == kTagged) && (to == kUnboxedMint)) { 637 if ((from == kTagged) && (to == kUnboxedMint)) {
624 ASSERT((deopt_target != NULL) || 638 ASSERT((deopt_target != NULL) ||
625 (use->Type()->ToCid() == kUnboxedMint)); 639 (use->Type()->ToCid() == kUnboxedMint));
626 const intptr_t deopt_id = (deopt_target != NULL) ? 640 const intptr_t deopt_id = (deopt_target != NULL) ?
627 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 641 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
628 converted = new(I) UnboxIntegerInstr(use->CopyWithType(), deopt_id); 642 converted = new(I) UnboxIntegerInstr(use->CopyWithType(), deopt_id);
629 } else if ((from == kUnboxedMint) && (to == kTagged)) { 643 } else if ((from == kUnboxedMint) && (to == kTagged)) {
630 converted = new(I) BoxIntegerInstr(use->CopyWithType()); 644 converted = new(I) BoxIntegerInstr(use->CopyWithType());
645 } else if ((from == kUnboxedUint32) && (to == kTagged)) {
646 converted = new(I) BoxUint32Instr(use->CopyWithType());
631 } else if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) { 647 } else if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) {
632 const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ? 648 const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ?
633 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 649 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
634 converted = new(I) UnboxedIntConverterInstr(from, 650 converted = new(I) UnboxedIntConverterInstr(from,
635 to, 651 to,
636 use->CopyWithType(), 652 use->CopyWithType(),
637 deopt_id); 653 deopt_id);
638 } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) { 654 } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) {
639 converted = new Int32ToDoubleInstr(use->CopyWithType()); 655 const intptr_t deopt_id = (deopt_target != NULL) ?
656 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
657 if (CanConvertUnboxedInt32ToDouble()) {
658 converted = new Int32ToDoubleInstr(use->CopyWithType());
659 } else {
660 BoxInt32Instr* boxed = new(I) BoxInt32Instr(use->CopyWithType());
661 use->BindTo(boxed);
662 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
663 converted = new(I) UnboxDoubleInstr(new(I) Value(boxed), deopt_id);
664 }
640 } else if ((from == kTagged) && (to == kUnboxedInt32)) { 665 } else if ((from == kTagged) && (to == kUnboxedInt32)) {
641 const intptr_t deopt_id = (deopt_target != NULL) ? 666 const intptr_t deopt_id = (deopt_target != NULL) ?
642 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 667 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
643 converted = new UnboxInt32Instr(use->CopyWithType(), deopt_id); 668 converted = new UnboxInt32Instr(use->CopyWithType(), deopt_id);
644 } else if ((from == kUnboxedInt32) && (to == kTagged)) { 669 } else if ((from == kUnboxedInt32) && (to == kTagged)) {
645 converted = new BoxInt32Instr(use->CopyWithType()); 670 converted = new BoxInt32Instr(use->CopyWithType());
646 } else if ((from == kTagged) && (to == kUnboxedUint32)) { 671 } else if ((from == kTagged) && (to == kUnboxedUint32)) {
647 const intptr_t deopt_id = (deopt_target != NULL) ? 672 const intptr_t deopt_id = (deopt_target != NULL) ?
648 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 673 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
649 converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id); 674 converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id);
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 &array, 1373 &array,
1349 index, 1374 index,
1350 &cursor); 1375 &cursor);
1351 1376
1352 // Check if store barrier is needed. Byte arrays don't need a store barrier. 1377 // Check if store barrier is needed. Byte arrays don't need a store barrier.
1353 StoreBarrierType needs_store_barrier = 1378 StoreBarrierType needs_store_barrier =
1354 (RawObject::IsTypedDataClassId(array_cid) || 1379 (RawObject::IsTypedDataClassId(array_cid) ||
1355 RawObject::IsTypedDataViewClassId(array_cid) || 1380 RawObject::IsTypedDataViewClassId(array_cid) ||
1356 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier 1381 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier
1357 : kEmitStoreBarrier; 1382 : kEmitStoreBarrier;
1358 if (!value_check.IsNull()) { 1383
1384 // If the stored value is an integer that is already unboxed as
1385 // the StoreIndexedInstr expects, skip the class check.
1386 bool is_already_unboxed =
1387 ((array_cid == kTypedDataInt32ArrayCid) &&
1388 (stored_value->representation() == kUnboxedInt32)) ||
1389 ((array_cid == kTypedDataUint32ArrayCid) &&
1390 (stored_value->representation() == kUnboxedUint32));
1391
1392 if (!is_already_unboxed && !value_check.IsNull()) {
Vyacheslav Egorov (Google) 2014/10/02 17:14:04 I am somewhat concerned about fragility of this.
Cutch 2014/10/02 22:41:12 Done.
1359 // No store barrier needed because checked value is a smi, an unboxed mint, 1393 // No store barrier needed because checked value is a smi, an unboxed mint,
1360 // an unboxed double, an unboxed Float32x4, or unboxed Int32x4. 1394 // an unboxed double, an unboxed Float32x4, or unboxed Int32x4.
1361 needs_store_barrier = kNoStoreBarrier; 1395 needs_store_barrier = kNoStoreBarrier;
1362 Instruction* check = GetCheckClass( 1396 Instruction* check = GetCheckClass(
1363 stored_value, value_check, call->deopt_id(), call->token_pos()); 1397 stored_value, value_check, call->deopt_id(), call->token_pos());
1364 cursor = flow_graph()->AppendTo(cursor, 1398 cursor = flow_graph()->AppendTo(cursor,
1365 check, 1399 check,
1366 call->env(), 1400 call->env(),
1367 FlowGraph::kEffect); 1401 FlowGraph::kEffect);
1368 } 1402 }
1369 1403
1370 if (array_cid == kTypedDataFloat32ArrayCid) { 1404 if (array_cid == kTypedDataFloat32ArrayCid) {
1371 stored_value = 1405 stored_value =
1372 new(I) DoubleToFloatInstr( 1406 new(I) DoubleToFloatInstr(
1373 new(I) Value(stored_value), call->deopt_id()); 1407 new(I) Value(stored_value), call->deopt_id());
1374 cursor = flow_graph()->AppendTo(cursor, 1408 cursor = flow_graph()->AppendTo(cursor,
1375 stored_value, 1409 stored_value,
1376 NULL, 1410 NULL,
1377 FlowGraph::kValue); 1411 FlowGraph::kValue);
1378 } else if (array_cid == kTypedDataInt32ArrayCid) { 1412 } else if (!is_already_unboxed && (array_cid == kTypedDataInt32ArrayCid)) {
1379 stored_value = new(I) UnboxInt32Instr( 1413 stored_value = new(I) UnboxInt32Instr(
1380 new(I) Value(stored_value), 1414 new(I) Value(stored_value),
1381 call->deopt_id()); 1415 call->deopt_id());
1382 stored_value->AsUnboxIntN()->mark_truncating(); 1416 stored_value->AsUnboxIntN()->mark_truncating();
1383 cursor = flow_graph()->AppendTo(cursor, 1417 cursor = flow_graph()->AppendTo(cursor,
1384 stored_value, 1418 stored_value,
1385 call->env(), 1419 call->env(),
1386 FlowGraph::kValue); 1420 FlowGraph::kValue);
1387 } else if (array_cid == kTypedDataUint32ArrayCid) { 1421 } else if (!is_already_unboxed && (array_cid == kTypedDataUint32ArrayCid)) {
1388 stored_value = new(I) UnboxUint32Instr( 1422 stored_value = new(I) UnboxUint32Instr(
1389 new(I) Value(stored_value), 1423 new(I) Value(stored_value),
1390 call->deopt_id()); 1424 call->deopt_id());
1391 ASSERT(stored_value->AsUnboxIntN()->is_truncating()); 1425 ASSERT(stored_value->AsUnboxIntN()->is_truncating());
1392 cursor = flow_graph()->AppendTo(cursor, 1426 cursor = flow_graph()->AppendTo(cursor,
1393 stored_value, 1427 stored_value,
1394 call->env(), 1428 call->env(),
1395 FlowGraph::kValue); 1429 FlowGraph::kValue);
1396 } 1430 }
1397 1431
(...skipping 8722 matching lines...) Expand 10 before | Expand all | Expand 10 after
10120 10154
10121 // Insert materializations at environment uses. 10155 // Insert materializations at environment uses.
10122 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 10156 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
10123 CreateMaterializationAt( 10157 CreateMaterializationAt(
10124 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 10158 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
10125 } 10159 }
10126 } 10160 }
10127 10161
10128 10162
10129 } // namespace dart 10163 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698