Reviewers: danno,
Description:
Skip canonicalization check in LStoreKeyedFastDoubleElement when it is not
needed:
- if value is a result of integer32 to double conversion (can't be NaN);
- if value was loaded from fast double backing store (already
canonicalized).
[email protected]
Please review this at https://chromiumcodereview.appspot.com/10054009/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/arm/lithium-arm.h
M src/arm/lithium-codegen-arm.cc
M src/hydrogen-instructions.h
M src/hydrogen-instructions.cc
M src/ia32/lithium-codegen-ia32.cc
M src/ia32/lithium-ia32.h
M src/x64/lithium-codegen-x64.cc
M src/x64/lithium-x64.h
Index: src/arm/lithium-arm.h
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index
a919a1d3bec6adf39acd0dac337cf32c869a3f99..8ee626a955c696ff95ce2826c867dd557c2a86cb
100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -1739,6 +1739,8 @@ class LStoreKeyedFastDoubleElement: public
LTemplateInstruction<0, 3, 0> {
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+
+ bool NeedsCanonicalization() { return
hydrogen()->NeedsCanonicalization(); }
};
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
7c37e8ee8b2214ae6f9d901f3613c9e6101c86d7..8be544425698c15cb67c91de4a8b3d4652624e4e
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -3615,7 +3615,6 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
Register scratch = scratch0();
bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0;
- Label not_nan;
// Calculate the effective address of the slot in the array to store the
// double value.
@@ -3638,13 +3637,15 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
}
- // Check for NaN. All NaNs must be canonicalized.
- __ VFPCompareAndSetFlags(value, value);
-
- // Only load canonical NaN if the comparison above set the overflow.
- __ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
vs);
+ if (instr->NeedsCanonicalization()) {
+ // Check for NaN. All NaNs must be canonicalized.
+ __ VFPCompareAndSetFlags(value, value);
+ // Only load canonical NaN if the comparison above set the overflow.
+ __ Vmov(value,
+ FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
+ vs);
+ }
- __ bind(¬_nan);
__ vstr(value, scratch, 0);
}
Index: src/hydrogen-instructions.cc
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index
3bb4ebc99407c337f0651eddfe2c4ea68f13c121..f02fd10a55a22d113ff466a87b25151fb7085a6a
100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -2090,6 +2090,17 @@ HValue*
HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) {
}
+bool HStoreKeyedFastDoubleElement::NeedsCanonicalization() {
+ // If value was loaded from unboxed double backing store or
+ // converted from an integer then we don't have to canonicalize it.
+ if (value()->IsLoadKeyedFastDoubleElement() ||
+ (value()->IsChange() &&
HChange::cast(value())->from().IsInteger32())) {
+ return false;
+ }
+ return true;
+}
+
+
#define
H_CONSTANT_INT32(val) \
new(zone) HConstant(FACTORY->NewNumberFromInt(val,
TENURED), \
Representation::Integer32())
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
f634a4488f36ef4593f8fc99a2818be563676fb1..dabb4fb58160d8758752592c77a1b8f83cfc4bf1
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -4210,6 +4210,8 @@ class HStoreKeyedFastDoubleElement: public
HTemplateInstruction<3> {
return StoringValueNeedsWriteBarrier(value());
}
+ bool NeedsCanonicalization();
+
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc
b/src/ia32/lithium-codegen-ia32.cc
index
72f59d09c46ad50bec4d3135dd043fe043866d14..85c2b829f2b399e2175f34ac64734dc2a83ed8ed
100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3460,15 +3460,18 @@ void
LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) {
XMMRegister value = ToDoubleRegister(instr->value());
- Label have_value;
- __ ucomisd(value, value);
- __ j(parity_odd, &have_value); // NaN.
+ if (instr->NeedsCanonicalization()) {
+ Label have_value;
- ExternalReference canonical_nan_reference =
- ExternalReference::address_of_canonical_non_hole_nan();
- __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
- __ bind(&have_value);
+ __ ucomisd(value, value);
+ __ j(parity_odd, &have_value); // NaN.
+
+ ExternalReference canonical_nan_reference =
+ ExternalReference::address_of_canonical_non_hole_nan();
+ __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
+ __ bind(&have_value);
+ }
Operand double_store_operand = BuildFastArrayOperand(
instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
Index: src/ia32/lithium-ia32.h
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index
0cfed121b6f3905fdef8b473cdcf92f578e236d0..1ebf432dc24433d75b741f2e279879690e9d5fe6
100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -1787,6 +1787,8 @@ class LStoreKeyedFastDoubleElement: public
LTemplateInstruction<0, 3, 0> {
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+
+ bool NeedsCanonicalization() { return
hydrogen()->NeedsCanonicalization(); }
};
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index
56ba6f34585179df27e6b419809857e74b2b1981..d545a6de5901c2e7e8cfd563adee14e12178efec
100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3421,16 +3421,20 @@ void
LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) {
XMMRegister value = ToDoubleRegister(instr->value());
- Label have_value;
- __ ucomisd(value, value);
- __ j(parity_odd, &have_value); // NaN.
+ if (instr->NeedsCanonicalization()) {
+ Label have_value;
- __ Set(kScratchRegister, BitCast<uint64_t>(
- FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
- __ movq(value, kScratchRegister);
+ __ ucomisd(value, value);
+ __ j(parity_odd, &have_value); // NaN.
+
+ __ Set(kScratchRegister, BitCast<uint64_t>(
+ FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
+ __ movq(value, kScratchRegister);
+
+ __ bind(&have_value);
+ }
- __ bind(&have_value);
Operand double_store_operand = BuildFastArrayOperand(
instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag);
Index: src/x64/lithium-x64.h
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index
99f28f0b692a115487b42f02a63d7ff847eef78a..feb3fa90f033a307eff48e30acb59d046e6af3bb
100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -1707,6 +1707,8 @@ class LStoreKeyedFastDoubleElement: public
LTemplateInstruction<0, 3, 0> {
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+
+ bool NeedsCanonicalization() { return
hydrogen()->NeedsCanonicalization(); }
};
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev