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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 13878017: Convert EqualityCompare to StrictCompare if reciever is either null or guaranteed to have default e… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comments Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index d472575b40e1fe628e6edecdcded5cf7c0202320..a0213884b4657d42d88cb9d361926481944e29a1 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -70,6 +70,9 @@ void FlowGraphOptimizer::ApplyClassIds() {
ComparisonInstr* compare = instr->AsBranch()->comparison();
if (compare->IsStrictCompare()) {
VisitStrictCompare(compare->AsStrictCompare());
+ } else if (compare->IsEqualityCompare()) {
+ StrictifyEqualityCompare(compare->AsEqualityCompare(),
+ instr->AsBranch());
}
}
}
@@ -2184,24 +2187,78 @@ void FlowGraphOptimizer::VisitRelationalOp(RelationalOpInstr* instr) {
}
+bool FlowGraphOptimizer::CanStrictifyEqualityCompare(
+ EqualityCompareInstr* compare) {
+ // If one of the inputs is null this is a strict comparison.
+ if (compare->left()->BindsToConstantNull() ||
+ compare->right()->BindsToConstantNull()) {
+ return true;
+ }
+
+ if (compare->left()->Type()->IsNone()) {
+ return false; // We might be running prior to any type propagation passes.
+ }
+
+ // Try resolving target function using propagated cid for the receiver.
+ // If receiver is either null or has default equality operator then
+ // we can convert such comparison to a strict one.
+ const intptr_t receiver_cid =
+ compare->left()->Type()->ToNullableCid();
+
+ if (receiver_cid == kDynamicCid) {
+ return false;
+ }
+
+ const Class& receiver_class = Class::Handle(
+ Isolate::Current()->class_table()->At(receiver_cid));
+
+ // Resolve equality operator.
+ const Function& function = Function::Handle(
+ Resolver::ResolveDynamicForReceiverClass(
+ receiver_class,
+ Symbols::EqualOperator(),
+ 2,
+ 0));
+
+ if (function.IsNull()) {
+ return false;
+ }
+
+ // Default equality operator declared on the Object class just calls
+ // identical.
+ return (Class::Handle(function.Owner()).id() == kInstanceCid);
+}
+
+
template <typename T>
-void FlowGraphOptimizer::HandleEqualityCompare(EqualityCompareInstr* comp,
- T current_instruction) {
- // If one of the inputs is null, no ICdata will be collected.
- if (comp->left()->BindsToConstantNull() ||
- comp->right()->BindsToConstantNull()) {
- Token::Kind strict_kind = (comp->kind() == Token::kEQ) ?
+bool FlowGraphOptimizer::StrictifyEqualityCompare(
+ EqualityCompareInstr* compare,
+ T current_instruction) const {
+ if (CanStrictifyEqualityCompare(compare)) {
+ Token::Kind strict_kind = (compare->kind() == Token::kEQ) ?
Token::kEQ_STRICT : Token::kNE_STRICT;
StrictCompareInstr* strict_comp =
new StrictCompareInstr(strict_kind,
- comp->left()->Copy(),
- comp->right()->Copy());
+ compare->left()->CopyWithType(),
+ compare->right()->CopyWithType());
current_instruction->ReplaceWith(strict_comp, current_iterator());
+ return true;
+ }
+ return false;
+}
+
+
+template <typename T>
+void FlowGraphOptimizer::HandleEqualityCompare(EqualityCompareInstr* comp,
+ T current_instruction) {
+ if (StrictifyEqualityCompare(comp, current_instruction)) {
return;
}
+
if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) {
return;
}
+
ASSERT(comp->ic_data()->num_args_tested() == 2);
if (comp->ic_data()->NumberOfChecks() == 1) {
GrowableArray<intptr_t> class_ids;
@@ -2267,6 +2324,8 @@ void FlowGraphOptimizer::HandleEqualityCompare(EqualityCompareInstr* comp,
}
+
+
void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) {
HandleEqualityCompare(instr, instr);
}
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698