Revision: 18362
Author: [email protected]
Date: Wed Dec 18 18:05:10 2013 UTC
Log: HStoreKeyed for Smis optimized for x64 + related redundant moves
of elements removed
[email protected]
Review URL: https://codereview.chromium.org/108503004
http://code.google.com/p/v8/source/detail?r=18362
Modified:
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Dec 18 17:53:50
2013 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Dec 18 18:05:10
2013 UTC
@@ -6684,6 +6684,8 @@
public:
DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*,
ElementsKind);
+ DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
+ ElementsKind, StoreFieldOrKeyedMode);
virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
// kind_fast: tagged[int32] = tagged
@@ -6702,7 +6704,9 @@
if (IsDoubleOrFloatElementsKind(elements_kind())) {
return Representation::Double();
}
-
+ if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY)
{
+ return Representation::Integer32();
+ }
if (IsFastSmiElementsKind(elements_kind())) {
return Representation::Smi();
}
@@ -6720,12 +6724,15 @@
if (IsUninitialized()) {
return Representation::None();
}
- if (IsFastSmiElementsKind(elements_kind())) {
- return Representation::Smi();
- }
if (IsDoubleOrFloatElementsKind(elements_kind())) {
return Representation::Double();
}
+ if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY)
{
+ return Representation::Integer32();
+ }
+ if (IsFastSmiElementsKind(elements_kind())) {
+ return Representation::Smi();
+ }
if (is_external()) {
return Representation::Integer32();
}
@@ -6739,6 +6746,7 @@
bool value_is_smi() const {
return IsFastSmiElementsKind(elements_kind_);
}
+ StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
ElementsKind elements_kind() const { return elements_kind_; }
uint32_t index_offset() { return index_offset_; }
void SetIndexOffset(uint32_t index_offset) { index_offset_ =
index_offset; }
@@ -6784,16 +6792,21 @@
private:
HStoreKeyed(HValue* obj, HValue* key, HValue* val,
- ElementsKind elements_kind)
+ ElementsKind elements_kind,
+ StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
: elements_kind_(elements_kind),
index_offset_(0),
is_dehoisted_(false),
is_uninitialized_(false),
+ store_mode_(store_mode),
new_space_dominator_(NULL) {
SetOperandAt(0, obj);
SetOperandAt(1, key);
SetOperandAt(2, val);
+ ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
+ elements_kind == FAST_SMI_ELEMENTS);
+
if (IsFastObjectElementsKind(elements_kind)) {
SetFlag(kTrackSideEffectDominators);
SetGVNFlag(kDependsOnNewSpacePromotion);
@@ -6820,6 +6833,7 @@
uint32_t index_offset_;
bool is_dehoisted_ : 1;
bool is_uninitialized_ : 1;
+ StoreFieldOrKeyedMode store_mode_: 1;
HValue* new_space_dominator_;
};
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Wed Dec 18 17:53:50 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Wed Dec 18 18:05:10 2013 UTC
@@ -1296,7 +1296,8 @@
ElementsKind kind,
HValue* length,
HValue* key,
- bool is_js_array) {
+ bool is_js_array,
+ bool is_store) {
IfBuilder length_checker(this);
Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ;
@@ -1338,6 +1339,13 @@
Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
new_length);
}
+
+ if (is_store && kind == FAST_SMI_ELEMENTS) {
+ HValue* checked_elements = environment()->Top();
+
+ // Write zero to ensure that the new element is initialized with some
smi.
+ Add<HStoreKeyed>(checked_elements, key, graph()->GetConstant0(), kind);
+ }
length_checker.Else();
Add<HBoundsCheck>(key, length);
@@ -2102,7 +2110,7 @@
NoObservableSideEffectsScope no_effects(this);
elements = BuildCheckForCapacityGrow(checked_object, elements,
elements_kind, length, key,
- is_js_array);
+ is_js_array, is_store);
checked_key = key;
} else {
checked_key = Add<HBoundsCheck>(key, length);
@@ -2266,7 +2274,10 @@
if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
val = Add<HClampToUint8>(val);
}
- return Add<HStoreKeyed>(elements, checked_key, val, elements_kind);
+ return Add<HStoreKeyed>(elements, checked_key, val, elements_kind,
+ elements_kind == FAST_SMI_ELEMENTS
+ ? STORE_TO_INITIALIZED_ENTRY
+ : INITIALIZING_STORE);
}
ASSERT(!is_store);
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Wed Dec 18 11:58:58 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.h Wed Dec 18 18:05:10 2013 UTC
@@ -1272,7 +1272,8 @@
ElementsKind kind,
HValue* length,
HValue* key,
- bool is_js_array);
+ bool is_js_array,
+ bool is_store);
HValue* BuildCopyElementsOnWrite(HValue* object,
HValue* elements,
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Dec 18
17:53:50 2013 UTC
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Dec 18
18:05:10 2013 UTC
@@ -4241,7 +4241,7 @@
void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
- Register elements = ToRegister(instr->elements());
+ HStoreKeyed* hinstr = instr->hydrogen();
LOperand* key = instr->key();
if (!key->IsConstantOperand()) {
Register key_reg = ToRegister(key);
@@ -4250,38 +4250,56 @@
// input gets replaced during bound check elimination with the index
// argument to the bounds check, which can be tagged, so that case
// must be handled here, too.
- if (instr->hydrogen()->IsDehoisted()) {
+ if (hinstr->IsDehoisted()) {
// Sign extend key because it could be a 32 bit negative value
// and the dehoisted address computation happens in 64 bits
__ movsxlq(key_reg, key_reg);
}
}
+
+ int offset = FixedArray::kHeaderSize - kHeapObjectTag;
+ Representation representation = hinstr->value()->representation();
+
+ if (representation.IsInteger32()) {
+ ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
+ ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
+ // Store int value directly to upper half of the smi.
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+ offset += kPointerSize / 2;
+ }
Operand operand =
BuildFastArrayOperand(instr->elements(),
key,
FAST_ELEMENTS,
- FixedArray::kHeaderSize - kHeapObjectTag,
+ offset,
instr->additional_index());
+
if (instr->value()->IsRegister()) {
- __ movq(operand, ToRegister(instr->value()));
+ __ Store(operand, ToRegister(instr->value()), representation);
} else {
LConstantOperand* operand_value =
LConstantOperand::cast(instr->value());
if (IsInteger32Constant(operand_value)) {
- Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
- __ Move(operand, smi_value);
+ int32_t value = ToInteger32(operand_value);
+ if (representation.IsSmi()) {
+ __ Move(operand, Smi::FromInt(value));
+
+ } else {
+ __ movl(operand, Immediate(value));
+ }
} else {
Handle<Object> handle_value = ToHandle(operand_value);
__ Move(operand, handle_value);
}
}
- if (instr->hydrogen()->NeedsWriteBarrier()) {
+ if (hinstr->NeedsWriteBarrier()) {
+ Register elements = ToRegister(instr->elements());
ASSERT(instr->value()->IsRegister());
Register value = ToRegister(instr->value());
- ASSERT(!instr->key()->IsConstantOperand());
- SmiCheck check_needed =
- instr->hydrogen()->value()->IsHeapObject()
+ ASSERT(!key->IsConstantOperand());
+ SmiCheck check_needed = hinstr->value()->IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
Register key_reg(ToRegister(key));
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Dec 18 17:53:50 2013
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Dec 18 18:05:10 2013
UTC
@@ -506,6 +506,13 @@
LOperand* LChunkBuilder::UseTempRegister(HValue* value) {
return Use(value, new(zone())
LUnallocated(LUnallocated::WRITABLE_REGISTER));
}
+
+
+LOperand* LChunkBuilder::UseTempRegisterOrConstant(HValue* value) {
+ return value->IsConstant()
+ ? chunk_->DefineConstantOperand(HConstant::cast(value))
+ : UseTempRegister(value);
+}
LOperand* LChunkBuilder::Use(HValue* value) {
@@ -2177,17 +2184,20 @@
LOperand* key = NULL;
LOperand* val = NULL;
- if (instr->value()->representation().IsDouble()) {
+ Representation value_representation = instr->value()->representation();
+ if (value_representation.IsDouble()) {
object = UseRegisterAtStart(instr->elements());
val = UseTempRegister(instr->value());
key = UseRegisterOrConstantAtStart(instr->key());
} else {
- ASSERT(instr->value()->representation().IsSmiOrTagged());
- object = UseTempRegister(instr->elements());
+ ASSERT(value_representation.IsSmiOrTagged() ||
+ value_representation.IsInteger32());
if (needs_write_barrier) {
+ object = UseTempRegister(instr->elements());
val = UseTempRegister(instr->value());
key = UseTempRegister(instr->key());
} else {
+ object = UseRegisterAtStart(instr->elements());
val = UseRegisterOrConstantAtStart(instr->value());
key = UseRegisterOrConstantAtStart(instr->key());
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Wed Dec 18 10:40:26 2013
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Dec 18 18:05:10 2013
UTC
@@ -2710,6 +2710,9 @@
// An input operand in a register that may be trashed.
MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
+ // An input operand in a register that may be trashed or a constant
operand.
+ MUST_USE_RESULT LOperand* UseTempRegisterOrConstant(HValue* value);
+
// An input operand in a register or stack slot.
MUST_USE_RESULT LOperand* Use(HValue* value);
MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.