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

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

Issue 178193020: Better inlining of type tests. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 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_compiler_x64.cc ('k') | no next file » | 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 3541 matching lines...) Expand 10 before | Expand all | Expand 10 after
3552 if (defn->IsRedefinition()) { 3552 if (defn->IsRedefinition()) {
3553 defn = defn->AsRedefinition()->value()->definition(); 3553 defn = defn->AsRedefinition()->value()->definition();
3554 } else { 3554 } else {
3555 defn = defn->AsAssertAssignable()->value()->definition(); 3555 defn = defn->AsAssertAssignable()->value()->definition();
3556 } 3556 }
3557 } 3557 }
3558 return defn; 3558 return defn;
3559 } 3559 }
3560 3560
3561 3561
3562 // Returns true if checking against this type is a direct class id comparison.
3563 static bool TypeCheckAsClassEquality(const AbstractType& type) {
3564 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
3565 // Requires CHA, which can be applied in optimized code only,
regis 2014/03/03 17:54:25 Comment ending with a comma.
Florian Schneider 2014/03/03 18:09:50 Done.
3566 if (!FLAG_use_cha) return false;
3567 if (!type.IsInstantiated()) return false;
3568 const Class& type_class = Class::Handle(type.type_class());
3569 // Signature classes have different type checking rules.
3570 if (type_class.IsSignatureClass()) return false;
3571 // Could be an interface check?
3572 if (type_class.is_implemented()) return false;
3573 const intptr_t type_cid = type_class.id();
3574 if (CHA::HasSubclasses(type_cid)) return false;
3575 const intptr_t num_type_args = type_class.NumTypeArguments();
3576 if (num_type_args > 0) {
3577 // Only raw types can be directly compared, thus disregarding type
3578 // arguments.
3579 const intptr_t num_type_params = type_class.NumTypeParameters();
3580 const intptr_t from_index = num_type_args - num_type_params;
3581 const TypeArguments& type_arguments =
3582 TypeArguments::Handle(type.arguments());
3583 const bool is_raw_type = type_arguments.IsNull() ||
3584 type_arguments.IsRaw(from_index, num_type_params);
3585 return is_raw_type;
3586 }
3587 return true;
3588 }
3589
3590
3562 // TODO(srdjan): Use ICData to check if always true or false. 3591 // TODO(srdjan): Use ICData to check if always true or false.
3563 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { 3592 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
3564 ASSERT(Token::IsTypeTestOperator(call->token_kind())); 3593 ASSERT(Token::IsTypeTestOperator(call->token_kind()));
3565 Definition* left = call->ArgumentAt(0); 3594 Definition* left = call->ArgumentAt(0);
3566 Definition* instantiator = call->ArgumentAt(1); 3595 Definition* instantiator = call->ArgumentAt(1);
3567 Definition* type_args = call->ArgumentAt(2); 3596 Definition* type_args = call->ArgumentAt(2);
3568 const AbstractType& type = 3597 const AbstractType& type =
3569 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); 3598 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value());
3570 const bool negate = Bool::Cast( 3599 const bool negate = Bool::Cast(
3571 OriginalDefinition(call->ArgumentAt(4))->AsConstant()->value()).value(); 3600 OriginalDefinition(call->ArgumentAt(4))->AsConstant()->value()).value();
(...skipping 11 matching lines...) Expand all
3583 PushArgumentInstr* push = call->PushArgumentAt(i); 3612 PushArgumentInstr* push = call->PushArgumentAt(i);
3584 push->ReplaceUsesWith(push->value()->definition()); 3613 push->ReplaceUsesWith(push->value()->definition());
3585 push->RemoveFromGraph(); 3614 push->RemoveFromGraph();
3586 } 3615 }
3587 call->ReplaceUsesWith(bool_const); 3616 call->ReplaceUsesWith(bool_const);
3588 ASSERT(current_iterator()->Current() == call); 3617 ASSERT(current_iterator()->Current() == call);
3589 current_iterator()->RemoveCurrentFromGraph(); 3618 current_iterator()->RemoveCurrentFromGraph();
3590 return; 3619 return;
3591 } 3620 }
3592 } 3621 }
3622
3623 if (TypeCheckAsClassEquality(type)) {
srdjan 2014/03/03 18:13:25 For next CL eventually: how about supporting a set
Florian Schneider 2014/03/04 10:22:52 Definitely.
3624 LoadClassIdInstr* left_cid = new LoadClassIdInstr(new Value(left));
3625 InsertBefore(call,
3626 left_cid,
3627 NULL,
3628 Definition::kValue);
3629 const intptr_t type_cid = Class::Handle(type.type_class()).id();
3630 ConstantInstr* cid =
3631 flow_graph()->GetConstant(Smi::Handle(Smi::New(type_cid)));
3632
3633 StrictCompareInstr* check_cid =
3634 new StrictCompareInstr(call->token_pos(),
3635 negate ? Token::kNE_STRICT : Token::kEQ_STRICT,
3636 new Value(left_cid),
3637 new Value(cid),
3638 false); // No number check.
3639 ReplaceCall(call, check_cid);
3640 return;
3641 }
3642
3593 InstanceOfInstr* instance_of = 3643 InstanceOfInstr* instance_of =
3594 new InstanceOfInstr(call->token_pos(), 3644 new InstanceOfInstr(call->token_pos(),
3595 new Value(left), 3645 new Value(left),
3596 new Value(instantiator), 3646 new Value(instantiator),
3597 new Value(type_args), 3647 new Value(type_args),
3598 type, 3648 type,
3599 negate, 3649 negate,
3600 call->deopt_id()); 3650 call->deopt_id());
3601 ReplaceCall(call, instance_of); 3651 ReplaceCall(call, instance_of);
3602 } 3652 }
(...skipping 5007 matching lines...) Expand 10 before | Expand all | Expand 10 after
8610 } 8660 }
8611 8661
8612 // Insert materializations at environment uses. 8662 // Insert materializations at environment uses.
8613 for (intptr_t i = 0; i < exits.length(); i++) { 8663 for (intptr_t i = 0; i < exits.length(); i++) {
8614 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8664 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8615 } 8665 }
8616 } 8666 }
8617 8667
8618 8668
8619 } // namespace dart 8669 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698