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:
parent
8161285786
commit
5c07b5837b
@ -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(¬_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:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user