From 5c07b5837b627fe7488b3ae726273f0f72209b12 Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Wed, 25 Jul 2012 14:38:32 +0000 Subject: [PATCH] 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 . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12189 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 142 ++++++++++++++++++++++++--------------- src/mips/lithium-codegen-mips.h | 9 +++ src/mips/lithium-mips.cc | 18 +++-- src/mips/lithium-mips.h | 1 + 4 files changed, 111 insertions(+), 59 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 9fbb2da..cb39b70 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -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: diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index a2125d7..570fb07 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -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); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index da5beb6..f2fbb27 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -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 = diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index 86b8f33..7f8bdfd 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -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) }; -- 2.7.4