Reviewers: Massi, danno, Paul Lind, kisg,
Description:
MIPS: Array index computation dehoisting.
Port r11596 (0cee9fca)
Original commit message:
Array index computation dehoisting.
When an array index (in an array access) is a simple "expression +
constant",
just embed the constant in the array access operation so that the full index
expression is (potentially) no longer used and its live range can be much
shorter.
This is effective in conjunction with array bounds check removal (otherwise
the
index is anyway used in the check).
BUG=
TEST=
Please review this at https://chromiumcodereview.appspot.com/10442003/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/mips/lithium-codegen-mips.cc
M src/mips/lithium-mips.h
Index: src/mips/lithium-codegen-mips.cc
diff --git a/src/mips/lithium-codegen-mips.cc
b/src/mips/lithium-codegen-mips.cc
index
7094b0a15e779add1d6e48fd29bd7882bd7adae0..914036bf400ab207398bb227ef7877a70c678743
100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -2504,7 +2504,9 @@ void
LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
// Load the result.
__ sll(scratch, key, kPointerSizeLog2); // Key indexes words.
__ addu(scratch, elements, scratch);
- __ lw(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
+ uint32_t offset = FixedArray::kHeaderSize +
+ (instr->additional_index() << kPointerSizeLog2);
+ __ lw(result, FieldMemOperand(scratch, offset));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2535,13 +2537,15 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
}
if (key_is_constant) {
- __ Addu(elements, elements, Operand(constant_key * (1 << shift_size) +
- FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ __ Addu(elements, elements,
+ Operand(((constant_key + instr->additional_index()) << shift_size)
+
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
__ Addu(elements, elements, Operand(scratch));
__ Addu(elements, elements,
- Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
+ (instr->additional_index() << shift_size)));
}
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -2569,32 +2573,40 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
key = ToRegister(instr->key());
}
int shift_size = ElementsKindToShiftSize(elements_kind);
+ int additional_offset = instr->additional_index() << shift_size;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
FPURegister result = ToDoubleRegister(instr->result());
if (key_is_constant) {
- __ Addu(scratch0(), external_pointer, constant_key * (1 <<
shift_size));
+ __ Addu(scratch0(), external_pointer, constant_key << shift_size);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
}
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
- __ lwc1(result, MemOperand(scratch0()));
+ __ lwc1(result, MemOperand(scratch0(), additional_offset));
__ cvt_d_s(result, result);
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
- __ ldc1(result, MemOperand(scratch0()));
+ __ ldc1(result, MemOperand(scratch0(), additional_offset));
}
} else {
Register result = ToRegister(instr->result());
Register scratch = scratch0();
+ if (instr->additional_index() != 0 && !key_is_constant) {
+ __ Addu(scratch, key, instr->additional_index());
+ }
MemOperand mem_operand(zero_reg);
if (key_is_constant) {
mem_operand = MemOperand(external_pointer,
- constant_key * (1 << shift_size));
+ (constant_key << shift_size) +
additional_offset);
} else {
- __ sll(scratch, key, shift_size);
+ if (instr->additional_index() == 0) {
+ __ sll(scratch, key, shift_size);
+ } else {
+ __ sll(scratch, scratch, shift_size);
+ }
__ Addu(scratch, scratch, external_pointer);
mem_operand = MemOperand(scratch);
}
@@ -3512,11 +3524,17 @@ void
LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
int offset =
- ToInteger32(const_operand) * kPointerSize +
FixedArray::kHeaderSize;
+ (ToInteger32(const_operand) + instr->additional_index()) *
kPointerSize
+ + FixedArray::kHeaderSize;
__ sw(value, FieldMemOperand(elements, offset));
} else {
__ sll(scratch, key, kPointerSizeLog2);
__ addu(scratch, elements, scratch);
+ if (instr->additional_index() != 0) {
+ __ Addu(scratch,
+ scratch,
+ instr->additional_index() << kPointerSizeLog2);
+ }
__ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
}
@@ -3559,7 +3577,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
}
int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
if (key_is_constant) {
- __ Addu(scratch, elements, Operand(constant_key * (1 << shift_size) +
+ __ Addu(scratch, elements, Operand((constant_key << shift_size) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
@@ -3580,7 +3598,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
}
__ bind(¬_nan);
- __ sdc1(value, MemOperand(scratch));
+ __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
shift_size));
}
@@ -3601,12 +3619,13 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
key = ToRegister(instr->key());
}
int shift_size = ElementsKindToShiftSize(elements_kind);
+ int additional_offset = instr->additional_index() << shift_size;
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
FPURegister value(ToDoubleRegister(instr->value()));
if (key_is_constant) {
- __ Addu(scratch0(), external_pointer, constant_key * (1 <<
shift_size));
+ __ Addu(scratch0(), external_pointer, constant_key << shift_size);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
@@ -3614,19 +3633,27 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ cvt_s_d(double_scratch0(), value);
- __ swc1(double_scratch0(), MemOperand(scratch0()));
+ __ swc1(double_scratch0(), MemOperand(scratch0(),
additional_offset));
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
- __ sdc1(value, MemOperand(scratch0()));
+ __ sdc1(value, MemOperand(scratch0(), additional_offset));
}
} else {
Register value(ToRegister(instr->value()));
- MemOperand mem_operand(zero_reg);
Register scratch = scratch0();
+ if (instr->additional_index() != 0 && !key_is_constant) {
+ __ Addu(scratch0(), key, instr->additional_index());
+ }
+ MemOperand mem_operand(zero_reg);
if (key_is_constant) {
mem_operand = MemOperand(external_pointer,
- constant_key * (1 << shift_size));
+ ((constant_key + instr->additional_index())
+ << shift_size));
} else {
- __ sll(scratch, key, shift_size);
+ if (instr->additional_index() == 0) {
+ __ sll(scratch, key, shift_size);
+ } else {
+ __ sll(scratch, scratch, shift_size);
+ }
__ Addu(scratch, scratch, external_pointer);
mem_operand = MemOperand(scratch);
}
Index: src/mips/lithium-mips.h
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index
a04b42961adff945edc337de9041e0d985fcaa1a..c7dc7b763a4e2ebfc4b9e9e4451250fae0a0ada8
100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -1201,6 +1201,7 @@ class LLoadKeyedFastElement: public
LTemplateInstruction<1, 2, 0> {
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1217,13 +1218,13 @@ class LLoadKeyedFastDoubleElement: public
LTemplateInstruction<1, 2, 0> {
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2,
0> {
public:
- LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
- LOperand* key) {
+ LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
LOperand* key) {
inputs_[0] = external_pointer;
inputs_[1] = key;
}
@@ -1237,6 +1238,7 @@ class LLoadKeyedSpecializedArrayElement: public
LTemplateInstruction<1, 2, 0> {
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1705,6 +1707,7 @@ class LStoreKeyedFastElement: public
LTemplateInstruction<0, 3, 0> {
LOperand* object() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
@@ -1727,6 +1730,7 @@ class LStoreKeyedFastDoubleElement: public
LTemplateInstruction<0, 3, 0> {
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
bool NeedsCanonicalization() { return
hydrogen()->NeedsCanonicalization(); }
};
@@ -1771,6 +1775,7 @@ class LStoreKeyedSpecializedArrayElement: public
LTemplateInstruction<0, 3, 0> {
ElementsKind elements_kind() const {
return hydrogen()->elements_kind();
}
+ uint32_t additional_index() const { return hydrogen()->index_offset(); }
};
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev