Reviewers: Jakob,

Message:
PTAL

Description:
Improve constant element index access code generation

[email protected]


Please review this at http://codereview.chromium.org/10831049/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/arm/lithium-arm.cc
  M src/arm/lithium-codegen-arm.cc
  M src/hydrogen-instructions.h
  M src/hydrogen.cc
  M src/ia32/lithium-codegen-ia32.cc
  M src/x64/lithium-codegen-x64.cc


Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 91afec53b1fa48b07f5409b671d984efc6ac2d9c..0dda5bdaa1416fae1802f457cfa91a533bb18c47 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1546,7 +1546,7 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {


 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
-  LOperand* value = UseRegisterAtStart(instr->index());
+  LOperand* value = UseRegisterOrConstantAtStart(instr->index());
   LOperand* length = UseRegister(instr->length());
   return AssignEnvironment(new(zone()) LBoundsCheck(value, length));
 }
@@ -1838,7 +1838,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
   ASSERT(instr->key()->representation().IsInteger32() ||
          instr->key()->representation().IsTagged());
   LOperand* obj = UseRegisterAtStart(instr->object());
-  LOperand* key = UseRegisterAtStart(instr->key());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key);
   if (instr->RequiresHoleCheck()) AssignEnvironment(result);
   return DefineAsRegister(result);
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index d94a1feb238c5e0abef2c1d2f670e30e2c72c6b9..90a315b2b6e360e1e6951ced76147b2ceff92f39 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2779,20 +2779,30 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {

 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
   Register elements = ToRegister(instr->elements());
-  Register key = EmitLoadRegister(instr->key(), scratch0());
   Register result = ToRegister(instr->result());
   Register scratch = scratch0();

-  // Load the result.
-  if (instr->hydrogen()->key()->representation().IsTagged()) {
-    __ add(scratch, elements,
-           Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+  if (instr->key()->IsConstantOperand()) {
+    LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+    int offset =
+ (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
+        + FixedArray::kHeaderSize;
+    __ ldr(result, FieldMemOperand(elements, offset));
   } else {
-    __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
+    Register key = EmitLoadRegister(instr->key(), scratch0());
+    if (instr->hydrogen()->key()->representation().IsTagged()) {
+      __ add(scratch, elements,
+             Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
+    } else {
+      __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
+    }
+    if (instr->additional_index() != 0) {
+      __ add(scratch,
+             scratch,
+             Operand(instr->additional_index() << kPointerSizeLog2));
+    }
+    __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize));
   }
-  uint32_t offset = FixedArray::kHeaderSize +
-                    (instr->additional_index() << kPointerSizeLog2);
-  __ ldr(result, FieldMemOperand(scratch, offset));

   // Check for the hole value.
   if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3823,7 +3833,18 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {


 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
-  __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
+  if (instr->index()->IsConstantOperand()) {
+    int constant_index =
+        ToInteger32(LConstantOperand::cast(instr->index()));
+    if (instr->hydrogen()->length()->representation().IsTagged()) {
+      __ mov(ip, Operand(Smi::FromInt(constant_index)));
+    } else {
+      __ mov(ip, Operand(constant_index));
+    }
+    __ cmp(ip, ToRegister(instr->length()));
+  } else {
+    __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
+  }
   DeoptimizeIf(hs, instr->environment());
 }

Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index c2cb271277afc0e4ccdfb9fd15f3f374aab96cb3..a4377de165ab84721cf40d20c0b9248fefbeb90d 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2776,13 +2776,25 @@ class HBoundsCheck: public HTemplateInstruction<2> {
   }

   virtual Representation RequiredInputRepresentation(int arg_index) {
-    if (index()->representation().IsTagged() &&
-        !index()->IsConstant() &&
-        key_mode_ == ALLOW_SMI_KEY) {
-      return Representation::Tagged();
-    } else {
+    if (key_mode_ == DONT_ALLOW_SMI_KEY ||
+        !length()->representation().IsTagged()) {
       return Representation::Integer32();
     }
+    // If the index is tagged and isn't constant, then allow the length
+ // to be tagged, since it is usually already tagged from loading it out of + // the length field of a JSArray. This allows for direct comparison without
+    // untagging.
+    if (index()->representation().IsTagged() && !index()->IsConstant()) {
+      return Representation::Tagged();
+    }
+    // Also allow the length to be tagged if the index is constant, because
+    // it can be tagged to allow direct comparison.
+    if (index()->IsConstant() &&
+        index()->representation().IsInteger32() &&
+        arg_index == 1) {
+      return Representation::Tagged();
+    }
+    return Representation::Integer32();
   }

   virtual void PrintDataTo(StringStream* stream);
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index df4d8fc99c650a0192a8782db7cbf302e311802e..6eece777a17fc0c141f6e3155f71375ce137390e 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5864,7 +5864,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
   } else {
     length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
   }
-  checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
+  checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length,
+                                                        ALLOW_SMI_KEY));
   return BuildFastElementAccess(elements, checked_key, val, mapcheck,
                                 map->elements_kind(), is_store);
 }
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index f3bcf1abc3fc1974af2b7bd55a8aeec35aec8269..0687e82550d37411f34fe2df806718bb84d1bfce 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3681,8 +3681,14 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {

 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
   if (instr->index()->IsConstantOperand()) {
-    __ cmp(ToOperand(instr->length()),
-           Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+    int constant_index =
+        ToInteger32(LConstantOperand::cast(instr->index()));
+    if (instr->hydrogen()->length()->representation().IsTagged()) {
+      __ cmp(ToOperand(instr->length()),
+             Immediate(Smi::FromInt(constant_index)));
+    } else {
+      __ cmp(ToOperand(instr->length()), Immediate(constant_index));
+    }
     DeoptimizeIf(below_equal, instr->environment());
   } else {
     __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 3e688dfd004c7bc4aa29dfa2637ce62ba6203bc4..0d8bf77cd1b4da9aafd093d6d039057bb25ebe26 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3617,8 +3617,13 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
       __ AbortIfNotZeroExtended(reg);
     }
     if (instr->index()->IsConstantOperand()) {
-      __ cmpq(reg,
- Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
+      int constant_index =
+          ToInteger32(LConstantOperand::cast(instr->index()));
+      if (instr->hydrogen()->length()->representation().IsTagged()) {
+        __ Cmp(reg, Smi::FromInt(constant_index));
+      } else {
+        __ cmpq(reg, Immediate(constant_index));
+      }
     } else {
       Register reg2 = ToRegister(instr->index());
       if (FLAG_debug_code &&


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to