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(&not_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

Reply via email to