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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 21013005: Optimize equuality operation for two Boolean arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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') | tests/language/equality_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 25632)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -592,21 +592,11 @@
}
-static bool HasOnlyTwoSmis(const ICData& ic_data) {
+static bool HasOnlyTwoOf(const ICData& ic_data, intptr_t cid) {
return (ic_data.NumberOfChecks() == 1) &&
- ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid);
+ ICDataHasReceiverArgumentClassIds(ic_data, cid, cid);
}
-static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) {
- return (ic_data.NumberOfChecks() == 1) &&
- ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid);
-}
-
-static bool HasOnlyTwoUint32x4s(const ICData& ic_data) {
- return (ic_data.NumberOfChecks() == 1) &&
- ICDataHasReceiverArgumentClassIds(ic_data, kUint32x4Cid, kUint32x4Cid);
-}
-
// Returns false if the ICData contains anything other than the 4 combinations
// of Mint and Smi for the receiver and argument classes.
static bool HasTwoMintOrSmi(const ICData& ic_data) {
@@ -1030,7 +1020,7 @@
switch (op_kind) {
case Token::kADD:
case Token::kSUB:
- if (HasOnlyTwoSmis(ic_data)) {
+ if (HasOnlyTwoOf(ic_data, kSmiCid)) {
// Don't generate smi code if the IC data is marked because
// of an overflow.
operands_type = (ic_data.deopt_reason() == kDeoptBinarySmiOp)
@@ -1044,14 +1034,14 @@
operands_type = kMintCid;
} else if (ShouldSpecializeForDouble(ic_data)) {
operands_type = kDoubleCid;
- } else if (HasOnlyTwoFloat32x4s(ic_data)) {
+ } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
operands_type = kFloat32x4Cid;
} else {
return false;
}
break;
case Token::kMUL:
- if (HasOnlyTwoSmis(ic_data)) {
+ if (HasOnlyTwoOf(ic_data, kSmiCid)) {
// Don't generate smi code if the IC data is marked because of an
// overflow.
// TODO(fschneider): Add unboxed mint multiplication.
@@ -1059,23 +1049,24 @@
operands_type = kSmiCid;
} else if (ShouldSpecializeForDouble(ic_data)) {
operands_type = kDoubleCid;
- } else if (HasOnlyTwoFloat32x4s(ic_data)) {
+ } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
operands_type = kFloat32x4Cid;
} else {
return false;
}
break;
case Token::kDIV:
- if (ShouldSpecializeForDouble(ic_data) || HasOnlyTwoSmis(ic_data)) {
+ if (ShouldSpecializeForDouble(ic_data) ||
+ HasOnlyTwoOf(ic_data, kSmiCid)) {
operands_type = kDoubleCid;
- } else if (HasOnlyTwoFloat32x4s(ic_data)) {
+ } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
operands_type = kFloat32x4Cid;
} else {
return false;
}
break;
case Token::kMOD:
- if (HasOnlyTwoSmis(ic_data)) {
+ if (HasOnlyTwoOf(ic_data, kSmiCid)) {
operands_type = kSmiCid;
} else {
return false;
@@ -1084,11 +1075,11 @@
case Token::kBIT_AND:
case Token::kBIT_OR:
case Token::kBIT_XOR:
- if (HasOnlyTwoSmis(ic_data)) {
+ if (HasOnlyTwoOf(ic_data, kSmiCid)) {
operands_type = kSmiCid;
} else if (HasTwoMintOrSmi(ic_data)) {
operands_type = kMintCid;
- } else if (HasOnlyTwoUint32x4s(ic_data)) {
+ } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) {
operands_type = kUint32x4Cid;
} else {
return false;
@@ -1096,7 +1087,7 @@
break;
case Token::kSHR:
case Token::kSHL:
- if (HasOnlyTwoSmis(ic_data)) {
+ if (HasOnlyTwoOf(ic_data, kSmiCid)) {
// Left shift may overflow from smi into mint or big ints.
// Don't generate smi code if the IC data is marked because
// of an overflow.
@@ -1117,7 +1108,7 @@
}
break;
case Token::kTRUNCDIV:
- if (HasOnlyTwoSmis(ic_data)) {
+ if (HasOnlyTwoOf(ic_data, kSmiCid)) {
if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false;
operands_type = kSmiCid;
} else {
@@ -2777,7 +2768,7 @@
Instruction* current_instruction) {
ASSERT(ic_data.num_args_tested() == 2);
ASSERT(comp->operation_cid() == kIllegalCid);
- if (HasOnlyTwoSmis(ic_data)) {
+ if (HasOnlyTwoOf(ic_data, kSmiCid)) {
InsertBefore(current_instruction,
new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
current_instruction->env(),
@@ -2891,10 +2882,51 @@
}
+// Returns true if we converted EqualityCompare to StrictCompare.
template <typename T>
+bool FlowGraphOptimizer::StrictifyEqualityCompareWithICData(
+ EqualityCompareInstr* compare,
+ const ICData& unary_ic_data,
+ T current_instruction) {
+ ASSERT(unary_ic_data.num_args_tested() == 1);
+ if (unary_ic_data.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
+ // If possible classes do not override Object's equality then replace
+ // with strict equality.
+ Function& target = Function::Handle();
+ Class& targets_class = Class::Handle();
+ for (intptr_t i = 0; i < unary_ic_data.NumberOfChecks(); i++) {
+ intptr_t cid = kIllegalCid;
+ unary_ic_data.GetOneClassCheckAt(i, &cid, &target);
+ targets_class = target.Owner();
+ if (targets_class.id() != kInstanceCid) {
+ // Overriden equality operator.
+ return false;
+ }
+ }
+ AddCheckClass(compare->left()->definition(),
+ unary_ic_data,
+ compare->deopt_id(),
+ current_instruction->env(),
+ current_instruction);
+ Token::Kind strict_kind = (compare->kind() == Token::kEQ) ?
Cutch 2013/07/30 20:22:30 Maybe add: ASSERT((compare->kind() == Token::kEQ)
srdjan 2013/07/30 20:26:50 Done.
+ Token::kEQ_STRICT : Token::kNE_STRICT;
+ StrictCompareInstr* strict_comp =
+ new StrictCompareInstr(compare->token_pos(),
+ strict_kind,
+ compare->left()->Copy(),
+ compare->right()->Copy());
+ 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)) {
+ // Based on input types, equality converted to strict-equality.
return;
}
@@ -2910,6 +2942,14 @@
return;
}
+ const ICData& unary_checks_0 =
+ ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
+ if (StrictifyEqualityCompareWithICData(
+ comp, unary_checks_0, current_instruction)) {
+ // Based on ICData, equality converted to strict-equality.
+ return;
+ }
+
// Check if ICDData contains checks with Smi/Null combinations. In that case
// we can still emit the optimized Smi equality operation but need to add
// checks for null or Smi.
@@ -2920,8 +2960,6 @@
if (ICDataHasOnlyReceiverArgumentClassIds(ic_data,
smi_or_null,
smi_or_null)) {
- const ICData& unary_checks_0 =
- ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
AddCheckClass(comp->left()->definition(),
unary_checks_0,
comp->deopt_id(),
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | tests/language/equality_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698