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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 20468002: Allow equality operation on mixed double/smi 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 | « no previous file | runtime/vm/intermediate_language.h » ('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 25478)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -603,6 +603,16 @@
}
+// Returns false if the ICData contains anything other than the 4 combinations
+// of Double and Smi for the receiver and argument classes.
+static bool HasTwoDoubleOrSmi(const ICData& ic_data) {
+ GrowableArray<intptr_t> class_ids(2);
+ class_ids.Add(kSmiCid);
+ class_ids.Add(kDoubleCid);
+ return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids);
+}
+
+
static bool HasOnlyOneDouble(const ICData& ic_data) {
return (ic_data.NumberOfChecks() == 1)
&& ic_data.HasReceiverClassId(kDoubleCid);
@@ -2645,35 +2655,48 @@
}
+static bool SmiFitsInDouble() { return kSmiBits < 53; }
+
+
void FlowGraphOptimizer::HandleRelationalOp(RelationalOpInstr* comp) {
if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) {
return;
}
const ICData& ic_data = *comp->ic_data();
Cutch 2013/07/25 21:03:36 To match HandleEqualityCompare why don't you add:
srdjan 2013/07/25 22:17:02 Factored out code. Done.
Instruction* instr = current_iterator()->Current();
- if (ic_data.NumberOfChecks() == 1) {
- ASSERT(ic_data.HasOneTarget());
- if (HasOnlyTwoSmis(ic_data)) {
- InsertBefore(instr,
- new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
- instr->env(),
- Definition::kEffect);
- InsertBefore(instr,
- new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
- instr->env(),
- Definition::kEffect);
- comp->set_operands_class_id(kSmiCid);
- } else if (ShouldSpecializeForDouble(ic_data)) {
- comp->set_operands_class_id(kDoubleCid);
- } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
- FlowGraphCompiler::SupportsUnboxedMints()) {
- comp->set_operands_class_id(kMintCid);
+ if (HasOnlyTwoSmis(ic_data)) {
+ InsertBefore(instr,
+ new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
+ instr->env(),
+ Definition::kEffect);
+ InsertBefore(instr,
+ new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
+ instr->env(),
+ Definition::kEffect);
+ comp->set_operation_cid(kSmiCid);
+ } else if (HasTwoMintOrSmi(ic_data) &&
+ FlowGraphCompiler::SupportsUnboxedMints()) {
+ comp->set_operation_cid(kMintCid);
+ } else if (HasTwoDoubleOrSmi(ic_data)) {
+ // Use double comparison.
+ if (SmiFitsInDouble()) {
+ comp->set_operation_cid(kDoubleCid);
} else {
- ASSERT(comp->operands_class_id() == kIllegalCid);
+ if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
+ // We cannot use double comparison on two Smi-s.
+ ASSERT(comp->operation_cid() == kIllegalCid);
+ } else {
+ InsertBefore(instr,
+ new CheckEitherNonSmiInstr(comp->left()->Copy(),
+ comp->right()->Copy(),
+ comp->deopt_id()),
+ instr->env(),
+ Definition::kEffect);
+ comp->set_operation_cid(kDoubleCid);
+ }
}
- } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
- FlowGraphCompiler::SupportsUnboxedMints()) {
- comp->set_operands_class_id(kMintCid);
+ } else {
+ ASSERT(comp->operation_cid() == kIllegalCid);
}
}
@@ -2758,37 +2781,45 @@
return;
}
- ASSERT(comp->ic_data()->num_args_tested() == 2);
- if (comp->ic_data()->NumberOfChecks() == 1) {
- GrowableArray<intptr_t> class_ids;
- Function& target = Function::Handle();
- comp->ic_data()->GetCheckAt(0, &class_ids, &target);
- // TODO(srdjan): allow for mixed mode int/double comparison.
-
- if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
- InsertBefore(current_instruction,
- new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
- current_instruction->env(),
- Definition::kEffect);
- InsertBefore(current_instruction,
- new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
- current_instruction->env(),
- Definition::kEffect);
- comp->set_receiver_class_id(kSmiCid);
- } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) {
- comp->set_receiver_class_id(kDoubleCid);
- } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
- FlowGraphCompiler::SupportsUnboxedMints()) {
- comp->set_receiver_class_id(kMintCid);
+ const ICData& ic_data = *comp->ic_data();
+ ASSERT(ic_data.num_args_tested() == 2);
Cutch 2013/07/25 21:03:36 Can this duplicate code in HandleEqualityCompare a
srdjan 2013/07/25 22:17:02 Done.
+ ASSERT(comp->operation_cid() == kIllegalCid);
+ if (HasOnlyTwoSmis(ic_data)) {
+ InsertBefore(current_instruction,
+ new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
+ current_instruction->env(),
+ Definition::kEffect);
+ InsertBefore(current_instruction,
+ new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
+ current_instruction->env(),
+ Definition::kEffect);
+ comp->set_operation_cid(kSmiCid);
+ } else if (HasTwoMintOrSmi(ic_data) &&
+ FlowGraphCompiler::SupportsUnboxedMints()) {
+ comp->set_operation_cid(kMintCid);
+ } else if (HasTwoDoubleOrSmi(ic_data)) {
+ // Use double comparison.
+ if (SmiFitsInDouble()) {
+ comp->set_operation_cid(kDoubleCid);
} else {
- ASSERT(comp->receiver_class_id() == kIllegalCid);
+ if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
+ // We cannot use double comparison on two Smi-s.
+ ASSERT(comp->operation_cid() == kIllegalCid);
+ } else {
+ InsertBefore(current_instruction,
+ new CheckEitherNonSmiInstr(comp->left()->Copy(),
+ comp->right()->Copy(),
+ comp->deopt_id()),
+ current_instruction->env(),
+ Definition::kEffect);
+ comp->set_operation_cid(kDoubleCid);
+ }
}
- } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
- FlowGraphCompiler::SupportsUnboxedMints()) {
- comp->set_receiver_class_id(kMintCid);
+ } else {
+ ASSERT(comp->operation_cid() == kIllegalCid);
}
- if (comp->receiver_class_id() != kIllegalCid) {
+ if (comp->operation_cid() != kIllegalCid) {
// Done.
return;
}
@@ -2800,7 +2831,7 @@
GrowableArray<intptr_t> smi_or_null(2);
smi_or_null.Add(kSmiCid);
smi_or_null.Add(kNullCid);
- if (ICDataHasOnlyReceiverArgumentClassIds(*comp->ic_data(),
+ if (ICDataHasOnlyReceiverArgumentClassIds(ic_data,
smi_or_null,
smi_or_null)) {
const ICData& unary_checks_0 =
@@ -2818,7 +2849,7 @@
comp->deopt_id(),
current_instruction->env(),
current_instruction);
- comp->set_receiver_class_id(kSmiCid);
+ comp->set_operation_cid(kSmiCid);
}
}
@@ -3138,7 +3169,7 @@
void RangeAnalysis::ConstrainValueAfterBranch(Definition* defn, Value* use) {
BranchInstr* branch = use->instruction()->AsBranch();
RelationalOpInstr* rel_op = branch->comparison()->AsRelationalOp();
- if ((rel_op != NULL) && (rel_op->operands_class_id() == kSmiCid)) {
+ if ((rel_op != NULL) && (rel_op->operation_cid() == kSmiCid)) {
// Found comparison of two smis. Constrain defn at true and false
// successors using the other operand as a boundary.
Definition* boundary;
@@ -5781,7 +5812,7 @@
// Fold x == x, and x != x to true/false for numbers and checked strict
// comparisons.
if (instr->IsCheckedStrictEqual() ||
- RawObject::IsIntegerClassId(instr->receiver_class_id())) {
+ RawObject::IsIntegerClassId(instr->operation_cid())) {
return SetValue(instr,
(instr->kind() == Token::kEQ)
? Bool::True()
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698