Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 631 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 632 converted = new UnboxInt32Instr(use->CopyWithType(), deopt_id); | 632 converted = new UnboxInt32Instr(use->CopyWithType(), deopt_id); |
| 633 } else if ((from == kUnboxedInt32) && (to == kTagged)) { | 633 } else if ((from == kUnboxedInt32) && (to == kTagged)) { |
| 634 converted = new BoxInt32Instr(use->CopyWithType()); | 634 converted = new BoxInt32Instr(use->CopyWithType()); |
| 635 } else if ((from == kTagged) && (to == kUnboxedUint32)) { | 635 } else if ((from == kTagged) && (to == kUnboxedUint32)) { |
| 636 const intptr_t deopt_id = (deopt_target != NULL) ? | 636 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 637 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 637 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 638 converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id); | 638 converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id); |
| 639 } else if (from == kUnboxedMint && to == kUnboxedDouble) { | 639 } else if (from == kUnboxedMint && to == kUnboxedDouble) { |
| 640 ASSERT(CanUnboxDouble()); | 640 ASSERT(CanUnboxDouble()); |
| 641 // Convert by boxing/unboxing. | |
| 642 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. | |
| 643 BoxIntegerInstr* boxed = | |
| 644 new(I) BoxIntegerInstr(use->CopyWithType()); | |
| 645 use->BindTo(boxed); | |
| 646 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue); | |
| 647 | |
| 648 const intptr_t deopt_id = (deopt_target != NULL) ? | 641 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 649 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 642 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 650 converted = new(I) UnboxDoubleInstr(new(I) Value(boxed), deopt_id); | 643 converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id); |
| 651 | |
| 652 } else if ((from == kUnboxedDouble) && (to == kTagged)) { | 644 } else if ((from == kUnboxedDouble) && (to == kTagged)) { |
| 653 ASSERT(CanUnboxDouble()); | 645 ASSERT(CanUnboxDouble()); |
| 654 converted = new(I) BoxDoubleInstr(use->CopyWithType()); | 646 converted = new(I) BoxDoubleInstr(use->CopyWithType()); |
| 655 | |
| 656 } else if ((from == kTagged) && (to == kUnboxedDouble)) { | 647 } else if ((from == kTagged) && (to == kUnboxedDouble)) { |
| 657 ASSERT(CanUnboxDouble()); | 648 ASSERT(CanUnboxDouble()); |
| 658 ASSERT((deopt_target != NULL) || | 649 ASSERT((deopt_target != NULL) || |
| 659 (use->Type()->ToCid() == kDoubleCid)); | 650 (use->Type()->ToCid() == kDoubleCid)); |
| 660 const intptr_t deopt_id = (deopt_target != NULL) ? | 651 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 661 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 652 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 662 ConstantInstr* constant = use->definition()->AsConstant(); | 653 ConstantInstr* constant = use->definition()->AsConstant(); |
| 663 if ((constant != NULL) && constant->value().IsSmi()) { | 654 if ((constant != NULL) && constant->value().IsSmi()) { |
| 664 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); | 655 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); |
| 665 const Double& dbl_obj = | 656 const Double& dbl_obj = |
| (...skipping 2378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3044 call->deopt_id(), | 3035 call->deopt_id(), |
| 3045 call->token_pos()); | 3036 call->token_pos()); |
| 3046 ReplaceCall(call, store_op); | 3037 ReplaceCall(call, store_op); |
| 3047 return true; | 3038 return true; |
| 3048 } | 3039 } |
| 3049 return false; | 3040 return false; |
| 3050 } | 3041 } |
| 3051 | 3042 |
| 3052 if (CanUnboxDouble() && | 3043 if (CanUnboxDouble() && |
| 3053 (recognized_kind == MethodRecognizer::kIntegerToDouble) && | 3044 (recognized_kind == MethodRecognizer::kIntegerToDouble) && |
| 3054 (ic_data.NumberOfChecks() == 1) && | 3045 (ic_data.NumberOfChecks() == 1)) { |
| 3055 (class_ids[0] == kSmiCid)) { | 3046 if (class_ids[0] == kSmiCid) { |
| 3056 AddReceiverCheck(call); | 3047 AddReceiverCheck(call); |
| 3057 ReplaceCall(call, | 3048 ReplaceCall(call, |
| 3058 new(I) SmiToDoubleInstr( | 3049 new(I) SmiToDoubleInstr( |
| 3059 new(I) Value(call->ArgumentAt(0)), | 3050 new(I) Value(call->ArgumentAt(0)), |
| 3060 call->token_pos())); | 3051 call->token_pos())); |
| 3061 return true; | 3052 return true; |
| 3053 } else if (class_ids[0] == kMintCid) { | |
| 3054 AddReceiverCheck(call); | |
| 3055 ReplaceCall(call, | |
| 3056 new(I) MintToDoubleInstr(new(I) Value(call->ArgumentAt(0)), | |
| 3057 call->deopt_id())); | |
| 3058 return true; | |
| 3059 } | |
| 3062 } | 3060 } |
| 3063 | 3061 |
| 3064 if (class_ids[0] == kDoubleCid) { | 3062 if (class_ids[0] == kDoubleCid) { |
| 3065 if (!CanUnboxDouble()) { | 3063 if (!CanUnboxDouble()) { |
| 3066 return false; | 3064 return false; |
| 3067 } | 3065 } |
| 3068 switch (recognized_kind) { | 3066 switch (recognized_kind) { |
| 3069 case MethodRecognizer::kDoubleToInteger: { | 3067 case MethodRecognizer::kDoubleToInteger: { |
| 3070 AddReceiverCheck(call); | 3068 AddReceiverCheck(call); |
| 3071 ASSERT(call->HasICData()); | 3069 ASSERT(call->HasICData()); |
| (...skipping 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4495 new(I) ZoneGrowableArray<Value*>(call->ArgumentCount()); | 4493 new(I) ZoneGrowableArray<Value*>(call->ArgumentCount()); |
| 4496 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { | 4494 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { |
| 4497 args->Add(new(I) Value(call->ArgumentAt(i))); | 4495 args->Add(new(I) Value(call->ArgumentAt(i))); |
| 4498 } | 4496 } |
| 4499 InvokeMathCFunctionInstr* invoke = | 4497 InvokeMathCFunctionInstr* invoke = |
| 4500 new(I) InvokeMathCFunctionInstr(args, | 4498 new(I) InvokeMathCFunctionInstr(args, |
| 4501 call->deopt_id(), | 4499 call->deopt_id(), |
| 4502 recognized_kind, | 4500 recognized_kind, |
| 4503 call->token_pos()); | 4501 call->token_pos()); |
| 4504 ReplaceCall(call, invoke); | 4502 ReplaceCall(call, invoke); |
| 4505 } else if (recognized_kind == MethodRecognizer::kDoubleFromInteger) { | |
| 4506 if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) { | |
|
Cutch
2014/09/16 16:04:11
This code had two problems:
1) DoubleFromInteger
Florian Schneider
2014/09/17 11:15:32
Good catch. Double.fromInteger is called in a lot
Cutch
2014/09/18 16:39:49
Done.
| |
| 4507 const ICData& ic_data = *call->ic_data(); | |
| 4508 if (CanUnboxDouble() && ArgIsAlways(kSmiCid, ic_data, 0)) { | |
| 4509 Definition* arg = call->ArgumentAt(0); | |
| 4510 InsertBefore(call, | |
| 4511 new(I) CheckSmiInstr( | |
| 4512 new(I) Value(arg), | |
| 4513 call->deopt_id(), | |
| 4514 call->token_pos()), | |
| 4515 call->env(), | |
| 4516 FlowGraph::kEffect); | |
| 4517 ReplaceCall(call, | |
| 4518 new(I) SmiToDoubleInstr(new(I) Value(arg), | |
| 4519 call->token_pos())); | |
| 4520 } | |
| 4521 } | |
| 4522 } else if (call->function().IsFactory()) { | 4503 } else if (call->function().IsFactory()) { |
| 4523 const Class& function_class = | 4504 const Class& function_class = |
| 4524 Class::Handle(I, call->function().Owner()); | 4505 Class::Handle(I, call->function().Owner()); |
| 4525 if ((function_class.library() == Library::CoreLibrary()) || | 4506 if ((function_class.library() == Library::CoreLibrary()) || |
| 4526 (function_class.library() == Library::TypedDataLibrary())) { | 4507 (function_class.library() == Library::TypedDataLibrary())) { |
| 4527 intptr_t cid = FactoryRecognizer::ResultCid(call->function()); | 4508 intptr_t cid = FactoryRecognizer::ResultCid(call->function()); |
| 4528 switch (cid) { | 4509 switch (cid) { |
| 4529 case kArrayCid: { | 4510 case kArrayCid: { |
| 4530 Value* type = new(I) Value(call->ArgumentAt(0)); | 4511 Value* type = new(I) Value(call->ArgumentAt(0)); |
| 4531 Value* num_elements = new(I) Value(call->ArgumentAt(1)); | 4512 Value* num_elements = new(I) Value(call->ArgumentAt(1)); |
| (...skipping 3944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8476 const Object& value = instr->value()->definition()->constant_value(); | 8457 const Object& value = instr->value()->definition()->constant_value(); |
| 8477 if (IsConstant(value) && value.IsInteger()) { | 8458 if (IsConstant(value) && value.IsInteger()) { |
| 8478 SetValue(instr, Double::Handle(I, | 8459 SetValue(instr, Double::Handle(I, |
| 8479 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); | 8460 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); |
| 8480 } else if (IsNonConstant(value)) { | 8461 } else if (IsNonConstant(value)) { |
| 8481 SetValue(instr, non_constant_); | 8462 SetValue(instr, non_constant_); |
| 8482 } | 8463 } |
| 8483 } | 8464 } |
| 8484 | 8465 |
| 8485 | 8466 |
| 8467 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) { | |
| 8468 const Object& value = instr->value()->definition()->constant_value(); | |
| 8469 if (IsConstant(value) && value.IsInteger()) { | |
| 8470 SetValue(instr, Double::Handle(I, | |
| 8471 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); | |
| 8472 } else if (IsNonConstant(value)) { | |
| 8473 SetValue(instr, non_constant_); | |
| 8474 } | |
| 8475 } | |
| 8476 | |
| 8477 | |
| 8486 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { | 8478 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { |
| 8487 const Object& value = instr->value()->definition()->constant_value(); | 8479 const Object& value = instr->value()->definition()->constant_value(); |
| 8488 if (IsConstant(value) && value.IsInteger()) { | 8480 if (IsConstant(value) && value.IsInteger()) { |
| 8489 SetValue(instr, Double::Handle(I, | 8481 SetValue(instr, Double::Handle(I, |
| 8490 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); | 8482 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); |
| 8491 } else if (IsNonConstant(value)) { | 8483 } else if (IsNonConstant(value)) { |
| 8492 SetValue(instr, non_constant_); | 8484 SetValue(instr, non_constant_); |
| 8493 } | 8485 } |
| 8494 } | 8486 } |
| 8495 | 8487 |
| (...skipping 1650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10146 | 10138 |
| 10147 // Insert materializations at environment uses. | 10139 // Insert materializations at environment uses. |
| 10148 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10140 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 10149 CreateMaterializationAt( | 10141 CreateMaterializationAt( |
| 10150 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); | 10142 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); |
| 10151 } | 10143 } |
| 10152 } | 10144 } |
| 10153 | 10145 |
| 10154 | 10146 |
| 10155 } // namespace dart | 10147 } // namespace dart |
| OLD | NEW |