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

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

Issue 562203005: Inline toDouble calls on mints (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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/assembler_ia32_test.cc ('k') | runtime/vm/flow_graph_type_propagator.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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 static bool ShouldInlineSimd() { 56 static bool ShouldInlineSimd() {
57 return FlowGraphCompiler::SupportsUnboxedSimd128(); 57 return FlowGraphCompiler::SupportsUnboxedSimd128();
58 } 58 }
59 59
60 60
61 static bool CanUnboxDouble() { 61 static bool CanUnboxDouble() {
62 return FlowGraphCompiler::SupportsUnboxedDoubles(); 62 return FlowGraphCompiler::SupportsUnboxedDoubles();
63 } 63 }
64 64
65 65
66 static bool CanConvertUnboxedMintToDouble() {
67 #if defined(TARGET_ARCH_IA32)
68 return true;
69 #else
Florian Schneider 2014/09/19 09:49:00 I think there should be a TODO for the other platf
Cutch 2014/09/19 16:17:41 Added a note about ARM and a TODO to check for MIP
70 return false;
71 #endif
72 }
73
66 // Optimize instance calls using ICData. 74 // Optimize instance calls using ICData.
67 void FlowGraphOptimizer::ApplyICData() { 75 void FlowGraphOptimizer::ApplyICData() {
68 VisitBlocks(); 76 VisitBlocks();
69 } 77 }
70 78
71 79
72 // Optimize instance calls using cid. This is called after optimizer 80 // Optimize instance calls using cid. This is called after optimizer
73 // converted instance calls to instructions. Any remaining 81 // converted instance calls to instructions. Any remaining
74 // instance calls are either megamorphic calls, cannot be optimized or 82 // instance calls are either megamorphic calls, cannot be optimized or
75 // have no runtime type feedback collected. 83 // have no runtime type feedback collected.
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 638 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
631 converted = new UnboxInt32Instr(use->CopyWithType(), deopt_id); 639 converted = new UnboxInt32Instr(use->CopyWithType(), deopt_id);
632 } else if ((from == kUnboxedInt32) && (to == kTagged)) { 640 } else if ((from == kUnboxedInt32) && (to == kTagged)) {
633 converted = new BoxInt32Instr(use->CopyWithType()); 641 converted = new BoxInt32Instr(use->CopyWithType());
634 } else if ((from == kTagged) && (to == kUnboxedUint32)) { 642 } else if ((from == kTagged) && (to == kUnboxedUint32)) {
635 const intptr_t deopt_id = (deopt_target != NULL) ? 643 const intptr_t deopt_id = (deopt_target != NULL) ?
636 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 644 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
637 converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id); 645 converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id);
638 } else if (from == kUnboxedMint && to == kUnboxedDouble) { 646 } else if (from == kUnboxedMint && to == kUnboxedDouble) {
639 ASSERT(CanUnboxDouble()); 647 ASSERT(CanUnboxDouble());
640 // Convert by boxing/unboxing.
641 // TODO(fschneider): Implement direct unboxed mint-to-double conversion.
642 BoxIntegerInstr* boxed =
643 new(I) BoxIntegerInstr(use->CopyWithType());
644 use->BindTo(boxed);
645 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
646
647 const intptr_t deopt_id = (deopt_target != NULL) ? 648 const intptr_t deopt_id = (deopt_target != NULL) ?
648 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 649 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
649 converted = new(I) UnboxDoubleInstr(new(I) Value(boxed), deopt_id); 650 if (CanConvertUnboxedMintToDouble()) {
650 651 // Fast path.
652 converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id);
653 } else {
654 // Slow path.
655 BoxIntegerInstr* boxed = new(I) BoxIntegerInstr(use->CopyWithType());
656 use->BindTo(boxed);
657 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
658 converted = new(I) UnboxDoubleInstr(new(I) Value(boxed), deopt_id);
659 }
651 } else if ((from == kUnboxedDouble) && (to == kTagged)) { 660 } else if ((from == kUnboxedDouble) && (to == kTagged)) {
652 ASSERT(CanUnboxDouble()); 661 ASSERT(CanUnboxDouble());
653 converted = new(I) BoxDoubleInstr(use->CopyWithType()); 662 converted = new(I) BoxDoubleInstr(use->CopyWithType());
654
655 } else if ((from == kTagged) && (to == kUnboxedDouble)) { 663 } else if ((from == kTagged) && (to == kUnboxedDouble)) {
656 ASSERT(CanUnboxDouble()); 664 ASSERT(CanUnboxDouble());
657 ASSERT((deopt_target != NULL) || 665 ASSERT((deopt_target != NULL) ||
658 (use->Type()->ToCid() == kDoubleCid)); 666 (use->Type()->ToCid() == kDoubleCid));
659 const intptr_t deopt_id = (deopt_target != NULL) ? 667 const intptr_t deopt_id = (deopt_target != NULL) ?
660 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 668 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
661 ConstantInstr* constant = use->definition()->AsConstant(); 669 ConstantInstr* constant = use->definition()->AsConstant();
662 if ((constant != NULL) && constant->value().IsSmi()) { 670 if ((constant != NULL) && constant->value().IsSmi()) {
663 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); 671 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue();
664 const Double& dbl_obj = 672 const Double& dbl_obj =
(...skipping 2379 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 call->deopt_id(), 3052 call->deopt_id(),
3045 call->token_pos()); 3053 call->token_pos());
3046 ReplaceCall(call, store_op); 3054 ReplaceCall(call, store_op);
3047 return true; 3055 return true;
3048 } 3056 }
3049 return false; 3057 return false;
3050 } 3058 }
3051 3059
3052 if (CanUnboxDouble() && 3060 if (CanUnboxDouble() &&
3053 (recognized_kind == MethodRecognizer::kIntegerToDouble) && 3061 (recognized_kind == MethodRecognizer::kIntegerToDouble) &&
3054 (ic_data.NumberOfChecks() == 1) && 3062 (ic_data.NumberOfChecks() == 1)) {
3055 (class_ids[0] == kSmiCid)) { 3063 if (class_ids[0] == kSmiCid) {
3056 AddReceiverCheck(call); 3064 AddReceiverCheck(call);
3057 ReplaceCall(call, 3065 ReplaceCall(call,
3058 new(I) SmiToDoubleInstr( 3066 new(I) SmiToDoubleInstr(
3059 new(I) Value(call->ArgumentAt(0)), 3067 new(I) Value(call->ArgumentAt(0)),
3060 call->token_pos())); 3068 call->token_pos()));
3061 return true; 3069 return true;
3070 } else if ((class_ids[0] == kMintCid) && CanConvertUnboxedMintToDouble()) {
3071 AddReceiverCheck(call);
3072 ReplaceCall(call,
3073 new(I) MintToDoubleInstr(new(I) Value(call->ArgumentAt(0)),
3074 call->deopt_id()));
3075 return true;
3076 }
3062 } 3077 }
3063 3078
3064 if (class_ids[0] == kDoubleCid) { 3079 if (class_ids[0] == kDoubleCid) {
3065 if (!CanUnboxDouble()) { 3080 if (!CanUnboxDouble()) {
3066 return false; 3081 return false;
3067 } 3082 }
3068 switch (recognized_kind) { 3083 switch (recognized_kind) {
3069 case MethodRecognizer::kDoubleToInteger: { 3084 case MethodRecognizer::kDoubleToInteger: {
3070 AddReceiverCheck(call); 3085 AddReceiverCheck(call);
3071 ASSERT(call->HasICData()); 3086 ASSERT(call->HasICData());
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
4497 } 4512 }
4498 InvokeMathCFunctionInstr* invoke = 4513 InvokeMathCFunctionInstr* invoke =
4499 new(I) InvokeMathCFunctionInstr(args, 4514 new(I) InvokeMathCFunctionInstr(args,
4500 call->deopt_id(), 4515 call->deopt_id(),
4501 recognized_kind, 4516 recognized_kind,
4502 call->token_pos()); 4517 call->token_pos());
4503 ReplaceCall(call, invoke); 4518 ReplaceCall(call, invoke);
4504 } else if (recognized_kind == MethodRecognizer::kDoubleFromInteger) { 4519 } else if (recognized_kind == MethodRecognizer::kDoubleFromInteger) {
4505 if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) { 4520 if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) {
4506 const ICData& ic_data = *call->ic_data(); 4521 const ICData& ic_data = *call->ic_data();
4507 if (CanUnboxDouble() && ArgIsAlways(kSmiCid, ic_data, 0)) { 4522 if (CanUnboxDouble()) {
4508 Definition* arg = call->ArgumentAt(0); 4523 if (ArgIsAlways(kSmiCid, ic_data, 1)) {
4509 InsertBefore(call, 4524 Definition* arg = call->ArgumentAt(1);
4510 new(I) CheckSmiInstr( 4525 AddCheckSmi(arg, call->deopt_id(), call->env(), call);
4511 new(I) Value(arg), 4526 ReplaceCall(call,
4512 call->deopt_id(), 4527 new(I) SmiToDoubleInstr(new(I) Value(arg),
4513 call->token_pos()), 4528 call->token_pos()));
4514 call->env(), 4529 } else if (ArgIsAlways(kMintCid, ic_data, 1) &&
4515 FlowGraph::kEffect); 4530 CanConvertUnboxedMintToDouble()) {
4516 ReplaceCall(call, 4531 Definition* arg = call->ArgumentAt(1);
4517 new(I) SmiToDoubleInstr(new(I) Value(arg), 4532 ReplaceCall(call,
4518 call->token_pos())); 4533 new(I) MintToDoubleInstr(new(I) Value(arg),
4534 call->deopt_id()));
4535 }
4519 } 4536 }
4520 } 4537 }
4521 } else if (call->function().IsFactory()) { 4538 } else if (call->function().IsFactory()) {
4522 const Class& function_class = 4539 const Class& function_class =
4523 Class::Handle(I, call->function().Owner()); 4540 Class::Handle(I, call->function().Owner());
4524 if ((function_class.library() == Library::CoreLibrary()) || 4541 if ((function_class.library() == Library::CoreLibrary()) ||
4525 (function_class.library() == Library::TypedDataLibrary())) { 4542 (function_class.library() == Library::TypedDataLibrary())) {
4526 intptr_t cid = FactoryRecognizer::ResultCid(call->function()); 4543 intptr_t cid = FactoryRecognizer::ResultCid(call->function());
4527 switch (cid) { 4544 switch (cid) {
4528 case kArrayCid: { 4545 case kArrayCid: {
(...skipping 3888 matching lines...) Expand 10 before | Expand all | Expand 10 after
8417 const Object& value = instr->value()->definition()->constant_value(); 8434 const Object& value = instr->value()->definition()->constant_value();
8418 if (IsConstant(value) && value.IsInteger()) { 8435 if (IsConstant(value) && value.IsInteger()) {
8419 SetValue(instr, Double::Handle(I, 8436 SetValue(instr, Double::Handle(I,
8420 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); 8437 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld)));
8421 } else if (IsNonConstant(value)) { 8438 } else if (IsNonConstant(value)) {
8422 SetValue(instr, non_constant_); 8439 SetValue(instr, non_constant_);
8423 } 8440 }
8424 } 8441 }
8425 8442
8426 8443
8444 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) {
8445 const Object& value = instr->value()->definition()->constant_value();
8446 if (IsConstant(value) && value.IsInteger()) {
8447 SetValue(instr, Double::Handle(I,
8448 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld)));
8449 } else if (IsNonConstant(value)) {
8450 SetValue(instr, non_constant_);
8451 }
8452 }
8453
8454
8427 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { 8455 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) {
8428 const Object& value = instr->value()->definition()->constant_value(); 8456 const Object& value = instr->value()->definition()->constant_value();
8429 if (IsConstant(value) && value.IsInteger()) { 8457 if (IsConstant(value) && value.IsInteger()) {
8430 SetValue(instr, Double::Handle(I, 8458 SetValue(instr, Double::Handle(I,
8431 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); 8459 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld)));
8432 } else if (IsNonConstant(value)) { 8460 } else if (IsNonConstant(value)) {
8433 SetValue(instr, non_constant_); 8461 SetValue(instr, non_constant_);
8434 } 8462 }
8435 } 8463 }
8436 8464
(...skipping 1647 matching lines...) Expand 10 before | Expand all | Expand 10 after
10084 10112
10085 // Insert materializations at environment uses. 10113 // Insert materializations at environment uses.
10086 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 10114 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
10087 CreateMaterializationAt( 10115 CreateMaterializationAt(
10088 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 10116 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
10089 } 10117 }
10090 } 10118 }
10091 10119
10092 10120
10093 } // namespace dart 10121 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/assembler_ia32_test.cc ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698