MIPS: Optimize Smi keys for KeyedLoads

Port r12156 (e2874cdf)

Original commit message:
Allows KeyeLoad/KeyedStore operations where the key is a Smi to fold the untagging of the key into the element offset calculation.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10790143
Patch from Akos Palfi <palfia@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12189 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
danno@chromium.org 2012-07-25 14:38:32 +00:00
parent 8161285786
commit 5c07b5837b
4 changed files with 111 additions and 59 deletions

View File

@ -2530,8 +2530,13 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
Register scratch = scratch0();
// Load the result.
__ sll(scratch, key, kPointerSizeLog2); // Key indexes words.
__ addu(scratch, elements, scratch);
if (instr->hydrogen()->key()->representation().IsTagged()) {
__ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
__ addu(scratch, elements, scratch);
} else {
__ sll(scratch, key, kPointerSizeLog2);
__ addu(scratch, elements, scratch);
}
uint32_t offset = FixedArray::kHeaderSize +
(instr->additional_index() << kPointerSizeLog2);
__ lw(result, FieldMemOperand(scratch, offset));
@ -2557,8 +2562,9 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
DoubleRegister result = ToDoubleRegister(instr->result());
Register scratch = scratch0();
int shift_size =
ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
int constant_key = 0;
if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
@ -2571,14 +2577,15 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
if (key_is_constant) {
__ Addu(elements, elements,
Operand(((constant_key + instr->additional_index()) << shift_size) +
Operand(((constant_key + instr->additional_index()) <<
element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
__ Addu(elements, elements, Operand(scratch));
__ Addu(elements, elements,
Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
(instr->additional_index() << shift_size)));
(instr->additional_index() << element_size_shift)));
}
if (instr->hydrogen()->RequiresHoleCheck()) {
@ -2590,6 +2597,50 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
}
MemOperand LCodeGen::PrepareKeyedOperand(Register key,
Register base,
bool key_is_constant,
int constant_key,
int element_size,
int shift_size,
int additional_index,
int additional_offset) {
if (additional_index != 0 && !key_is_constant) {
additional_index *= 1 << (element_size - shift_size);
__ Addu(scratch0(), key, Operand(additional_index));
}
if (key_is_constant) {
return MemOperand(base,
(constant_key << element_size) + additional_offset);
}
if (additional_index == 0) {
if (shift_size >= 0) {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), base, scratch0());
return MemOperand(scratch0());
} else {
ASSERT_EQ(-1, shift_size);
__ srl(scratch0(), key, 1);
__ Addu(scratch0(), base, scratch0());
return MemOperand(scratch0());
}
}
if (shift_size >= 0) {
__ sll(scratch0(), scratch0(), shift_size);
__ Addu(scratch0(), base, scratch0());
return MemOperand(scratch0());
} else {
ASSERT_EQ(-1, shift_size);
__ srl(scratch0(), scratch0(), 1);
__ Addu(scratch0(), base, scratch0());
return MemOperand(scratch0());
}
}
void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer());
@ -2605,14 +2656,16 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
} else {
key = ToRegister(instr->key());
}
int shift_size = ElementsKindToShiftSize(elements_kind);
int additional_offset = instr->additional_index() << shift_size;
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
int additional_offset = instr->additional_index() << element_size_shift;
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 << shift_size);
__ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
@ -2626,24 +2679,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
}
} 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 << shift_size) + additional_offset);
} else {
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);
}
MemOperand mem_operand = PrepareKeyedOperand(
key, external_pointer, key_is_constant, constant_key,
element_size_shift, shift_size,
instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_BYTE_ELEMENTS:
__ lb(result, mem_operand);
@ -3574,8 +3613,13 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
+ FixedArray::kHeaderSize;
__ sw(value, FieldMemOperand(elements, offset));
} else {
__ sll(scratch, key, kPointerSizeLog2);
__ addu(scratch, elements, scratch);
if (instr->hydrogen()->key()->representation().IsTagged()) {
__ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
__ addu(scratch, elements, scratch);
} else {
__ sll(scratch, key, kPointerSizeLog2);
__ addu(scratch, elements, scratch);
}
if (instr->additional_index() != 0) {
__ Addu(scratch,
scratch,
@ -3621,9 +3665,11 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
} else {
key = ToRegister(instr->key());
}
int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
if (key_is_constant) {
__ Addu(scratch, elements, Operand((constant_key << shift_size) +
__ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} else {
__ sll(scratch, key, shift_size);
@ -3644,7 +3690,8 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
}
__ bind(&not_nan);
__ sdc1(value, MemOperand(scratch, instr->additional_index() << shift_size));
__ sdc1(value, MemOperand(scratch, instr->additional_index() <<
element_size_shift));
}
@ -3664,14 +3711,17 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
} else {
key = ToRegister(instr->key());
}
int shift_size = ElementsKindToShiftSize(elements_kind);
int additional_offset = instr->additional_index() << shift_size;
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
? (element_size_shift - kSmiTagSize) : element_size_shift;
int additional_offset = instr->additional_index() << element_size_shift;
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 << shift_size);
__ Addu(scratch0(), external_pointer, constant_key <<
element_size_shift);
} else {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), scratch0(), external_pointer);
@ -3685,24 +3735,10 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
}
} else {
Register value(ToRegister(instr->value()));
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 + instr->additional_index())
<< shift_size));
} else {
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);
}
MemOperand mem_operand = PrepareKeyedOperand(
key, external_pointer, key_is_constant, constant_key,
element_size_shift, shift_size,
instr->additional_index(), additional_offset);
switch (elements_kind) {
case EXTERNAL_PIXEL_ELEMENTS:
case EXTERNAL_BYTE_ELEMENTS:

View File

@ -128,6 +128,15 @@ class LCodeGen BASE_EMBEDDED {
void DoParallelMove(LParallelMove* move);
void DoGap(LGap* instr);
MemOperand PrepareKeyedOperand(Register key,
Register base,
bool key_is_constant,
int constant_key,
int element_size,
int shift_size,
int additional_index,
int additional_offset);
// Emit frame translation commands for an environment.
void WriteTranslation(LEnvironment* environment, Translation* translation);

View File

@ -1773,7 +1773,8 @@ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
HLoadKeyedFastElement* instr) {
ASSERT(instr->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* obj = UseRegisterAtStart(instr->object());
LOperand* key = UseRegisterAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
@ -1785,7 +1786,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
HLoadKeyedFastDoubleElement* instr) {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->key()->representation().IsInteger32());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* elements = UseTempRegister(instr->elements());
LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastDoubleElement* result =
@ -1805,7 +1807,8 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
(representation.IsDouble() &&
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->key()->representation().IsInteger32());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegisterOrConstant(instr->key());
LLoadKeyedSpecializedArrayElement* result =
@ -1833,7 +1836,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
bool needs_write_barrier = instr->NeedsWriteBarrier();
ASSERT(instr->value()->representation().IsTagged());
ASSERT(instr->object()->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* obj = UseTempRegister(instr->object());
LOperand* val = needs_write_barrier
@ -1850,7 +1854,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
HStoreKeyedFastDoubleElement* instr) {
ASSERT(instr->value()->representation().IsDouble());
ASSERT(instr->elements()->representation().IsTagged());
ASSERT(instr->key()->representation().IsInteger32());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* elements = UseRegisterAtStart(instr->elements());
LOperand* val = UseTempRegister(instr->value());
@ -1872,7 +1877,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32());
ASSERT(instr->key()->representation().IsInteger32() ||
instr->key()->representation().IsTagged());
LOperand* external_pointer = UseRegister(instr->external_pointer());
bool val_is_temp_register =

View File

@ -843,6 +843,7 @@ class LBoundsCheck: public LTemplateInstruction<0, 2, 0> {
LOperand* length() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
};