Reviewers: Sven Panne,

Description:
Merged r12283 into 3.12 branch.

MIPS: Improve constant element index access code generation
Original CL: https://chromiumcodereview.appspot.com/10825263/

[email protected]
BUG=


Please review this at https://chromiumcodereview.appspot.com/10830305/

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

Affected files:
  M src/mips/lithium-codegen-mips.cc
  M src/mips/lithium-mips.cc
  M src/version.cc


Index: src/mips/lithium-codegen-mips.cc
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index d48a9e595c97628609cdada03427b350b17386da..38e75b5dc474b4c86c12a38fe263e4f014263a19 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -2525,21 +2525,32 @@ 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()) {
-    __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
-    __ addu(scratch, elements, scratch);
+  if (instr->key()->IsConstantOperand()) {
+    LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+    int offset =
+ (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
+        + FixedArray::kHeaderSize;
+    __ lw(result, FieldMemOperand(elements, offset));
   } else {
-    __ sll(scratch, key, kPointerSizeLog2);
-    __ addu(scratch, elements, scratch);
+    Register key = EmitLoadRegister(instr->key(), scratch);
+    // Even though the HLoadKeyedFastElement instruction forces the input
+    // representation for the key to be an integer, the input gets replaced
+    // during bound check elimination with the index argument to the bounds
+    // check, which can be tagged, so that case must be handled here, too.
+    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));
   }
-  uint32_t offset = FixedArray::kHeaderSize +
-                    (instr->additional_index() << kPointerSizeLog2);
-  __ lw(result, FieldMemOperand(scratch, offset));

   // Check for the hole value.
   if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3585,10 +3596,24 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {


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


@@ -3607,6 +3632,10 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
         + FixedArray::kHeaderSize;
     __ sw(value, FieldMemOperand(elements, offset));
   } else {
+    // Even though the HLoadKeyedFastElement instruction forces the input
+    // representation for the key to be an integer, the input gets replaced
+    // during bound check elimination with the index argument to the bounds
+    // check, which can be tagged, so that case must be handled here, too.
     if (instr->hydrogen()->key()->representation().IsTagged()) {
       __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
       __ addu(scratch, elements, scratch);
@@ -3614,12 +3643,9 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
       __ 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));
+    uint32_t offset = FixedArray::kHeaderSize +
+        (instr->additional_index() << kPointerSizeLog2);
+    __ sw(value, FieldMemOperand(scratch, offset));
   }

   if (instr->hydrogen()->NeedsWriteBarrier()) {
Index: src/mips/lithium-mips.cc
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index f2fbb270683929f68be305715b1a29900f7433f3..ee6d9dd6fd4af21efce84915d4816e2c11f15379 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -1483,7 +1483,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));
 }
@@ -1776,7 +1776,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/version.cc
diff --git a/src/version.cc b/src/version.cc
index 8b744a207f384a7ea7107f882757530885ddf496..acd92d4b380626ed19464175a3eaca0418040878 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     12
 #define BUILD_NUMBER      19
-#define PATCH_LEVEL       2
+#define PATCH_LEVEL       3
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0


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

Reply via email to