Improvements in lithium code generation. Recognizing if some operands are constants...
authormvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 22 Apr 2013 07:47:25 +0000 (07:47 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 22 Apr 2013 07:47:25 +0000 (07:47 +0000)
BUG=

Review URL: https://codereview.chromium.org/14022011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14364 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/lithium-arm.cc
src/arm/lithium-codegen-arm.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-ia32.cc
src/x64/lithium-codegen-x64.cc
src/x64/lithium-x64.cc

index 1314e78..618ac10 100644 (file)
@@ -2460,8 +2460,15 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
   info()->MarkAsRequiresFrame();
   LOperand* args = UseRegister(instr->arguments());
-  LOperand* length = UseTempRegister(instr->length());
-  LOperand* index = UseRegister(instr->index());
+  LOperand* length;
+  LOperand* index;
+  if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
+    length = UseRegisterOrConstant(instr->length());
+    index = UseOrConstant(instr->index());
+  } else {
+    length = UseTempRegister(instr->length());
+    index = Use(instr->index());
+  }
   return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
 }
 
index f47e7e8..5c15d49 100644 (file)
@@ -3277,14 +3277,22 @@ void LCodeGen::DoLoadExternalArrayPointer(
 
 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
   Register arguments = ToRegister(instr->arguments());
-  Register length = ToRegister(instr->length());
-  Register index = ToRegister(instr->index());
   Register result = ToRegister(instr->result());
-  // There are two words between the frame pointer and the last argument.
-  // Subtracting from length accounts for one of them add one more.
-  __ sub(length, length, index);
-  __ add(length, length, Operand(1));
-  __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
+  if (instr->length()->IsConstantOperand() &&
+      instr->index()->IsConstantOperand()) {
+    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+    int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
+    int index = (const_length - const_index) + 1;
+    __ ldr(result, MemOperand(arguments, index * kPointerSize));
+  } else {
+    Register length = ToRegister(instr->length());
+    Register index = ToRegister(instr->index());
+    // There are two words between the frame pointer and the last argument.
+    // Subtracting from length accounts for one of them add one more.
+    __ sub(length, length, index);
+    __ add(length, length, Operand(1));
+    __ ldr(result, MemOperand(arguments, length, LSL, kPointerSizeLog2));
+  }
 }
 
 
index 221882c..de62e1f 100644 (file)
@@ -3196,13 +3196,21 @@ void LCodeGen::DoLoadExternalArrayPointer(
 
 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
   Register arguments = ToRegister(instr->arguments());
-  Register length = ToRegister(instr->length());
-  Operand index = ToOperand(instr->index());
   Register result = ToRegister(instr->result());
-  // There are two words between the frame pointer and the last argument.
-  // Subtracting from length accounts for one of them add one more.
-  __ sub(length, index);
-  __ mov(result, Operand(arguments, length, times_4, kPointerSize));
+  if (instr->length()->IsConstantOperand() &&
+      instr->index()->IsConstantOperand()) {
+    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+    int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
+    int index = (const_length - const_index) + 1;
+    __ mov(result, Operand(arguments, index * kPointerSize));
+  } else {
+    Register length = ToRegister(instr->length());
+    Operand index = ToOperand(instr->index());
+    // There are two words between the frame pointer and the last argument.
+    // Subtracting from length accounts for one of them add one more.
+    __ sub(length, index);
+    __ mov(result, Operand(arguments, length, times_4, kPointerSize));
+  }
 }
 
 
@@ -4220,7 +4228,6 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
 
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Register object = ToRegister(instr->object());
-  Register value = ToRegister(instr->value());
   int offset = instr->offset();
 
   if (!instr->transition().is_null()) {
@@ -4246,34 +4253,42 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   HType type = instr->hydrogen()->value()->type();
   SmiCheck check_needed =
       type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
-  if (instr->is_in_object()) {
-    __ mov(FieldOperand(object, offset), value);
-    if (instr->hydrogen()->NeedsWriteBarrier()) {
-      Register temp = ToRegister(instr->temp());
-      // Update the write barrier for the object for in-object properties.
-      __ RecordWriteField(object,
-                          offset,
-                          value,
-                          temp,
-                          GetSaveFPRegsMode(),
-                          EMIT_REMEMBERED_SET,
-                          check_needed);
+
+  Register write_register = object;
+  if (!instr->is_in_object()) {
+    write_register = ToRegister(instr->temp());
+    __ mov(write_register,
+           FieldOperand(object, JSObject::kPropertiesOffset));
+  }
+
+  if (instr->value()->IsConstantOperand()) {
+    LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+    if (IsInteger32(operand_value)) {
+      int const_value = ToInteger32(operand_value);
+      __ mov(FieldOperand(write_register, offset), Immediate(const_value));
+    } else {
+      if (operand_value->IsRegister()) {
+        __ mov(FieldOperand(write_register, offset), ToRegister(operand_value));
+      } else {
+        Handle<Object> handle_value = ToHandle(operand_value);
+        __ mov(FieldOperand(write_register, offset), handle_value);
+      }
     }
   } else {
-    Register temp = ToRegister(instr->temp());
-    __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
-    __ mov(FieldOperand(temp, offset), value);
-    if (instr->hydrogen()->NeedsWriteBarrier()) {
-      // Update the write barrier for the properties array.
-      // object is used as a scratch register.
-      __ RecordWriteField(temp,
-                          offset,
-                          value,
-                          object,
-                          GetSaveFPRegsMode(),
-                          EMIT_REMEMBERED_SET,
-                          check_needed);
-    }
+    __ mov(FieldOperand(write_register, offset), ToRegister(instr->value()));
+  }
+
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    Register value = ToRegister(instr->value());
+    Register temp = instr->is_in_object() ? ToRegister(instr->temp()) : object;
+    // Update the write barrier for the object for in-object properties.
+    __ RecordWriteField(write_register,
+                        offset,
+                        value,
+                        temp,
+                        GetSaveFPRegsMode(),
+                        EMIT_REMEMBERED_SET,
+                        check_needed);
   }
 }
 
@@ -4451,7 +4466,6 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
 
 
 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
-  Register value = ToRegister(instr->value());
   Register elements = ToRegister(instr->elements());
   Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
 
@@ -4462,9 +4476,22 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
       FAST_ELEMENTS,
       FixedArray::kHeaderSize - kHeapObjectTag,
       instr->additional_index());
-  __ mov(operand, value);
+  if (instr->value()->IsRegister()) {
+    __ mov(operand, ToRegister(instr->value()));
+  } else {
+    LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+    if (IsInteger32(operand_value)) {
+      Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
+      __ mov(operand, Immediate(smi_value));
+    } else {
+      Handle<Object> handle_value = ToHandle(operand_value);
+      __ mov(operand, handle_value);
+    }
+  }
 
   if (instr->hydrogen()->NeedsWriteBarrier()) {
+    ASSERT(instr->value()->IsRegister());
+    Register value = ToRegister(instr->value());
     ASSERT(!instr->key()->IsConstantOperand());
     HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
index 523673a..4daf309 100644 (file)
@@ -2297,19 +2297,21 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
         val = UseX87TopOfStack(instr->value());
       }
       LOperand* key = UseRegisterOrConstantAtStart(instr->key());
-
       return new(zone()) LStoreKeyed(object, key, val);
     } else {
       ASSERT(instr->value()->representation().IsTagged());
       bool needs_write_barrier = instr->NeedsWriteBarrier();
 
       LOperand* obj = UseRegister(instr->elements());
-      LOperand* val = needs_write_barrier
-          ? UseTempRegister(instr->value())
-          : UseRegisterAtStart(instr->value());
-      LOperand* key = needs_write_barrier
-          ? UseTempRegister(instr->key())
-          : UseRegisterOrConstantAtStart(instr->key());
+      LOperand* val;
+      LOperand* key;
+      if (needs_write_barrier) {
+        val = UseTempRegister(instr->value());
+        key = UseTempRegister(instr->key());
+      } else {
+        val = UseRegisterOrConstantAtStart(instr->value());
+        key = UseRegisterOrConstantAtStart(instr->key());
+      }
       return new(zone()) LStoreKeyed(obj, key, val);
     }
   }
@@ -2409,9 +2411,22 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
         : UseRegisterAtStart(instr->object());
   }
 
-  LOperand* val = needs_write_barrier
-      ? UseTempRegister(instr->value())
-      : UseRegister(instr->value());
+  bool register_or_constant = false;
+  if (instr->value()->IsConstant()) {
+    HConstant* constant_value = HConstant::cast(instr->value());
+    register_or_constant = constant_value->HasInteger32Value()
+        || constant_value->HasDoubleValue()
+        || constant_value->ImmortalImmovable();
+  }
+
+  LOperand* val;
+  if (needs_write_barrier) {
+    val = UseTempRegister(instr->value());
+  } else if (register_or_constant) {
+    val = UseRegisterOrConstant(instr->value());
+  } else {
+    val = UseRegister(instr->value());
+  }
 
   // We only need a scratch register if we have a write barrier or we
   // have a store into the properties array (not in-object-property).
@@ -2579,8 +2594,15 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
   info()->MarkAsRequiresFrame();
   LOperand* args = UseRegister(instr->arguments());
-  LOperand* length = UseTempRegister(instr->length());
-  LOperand* index = Use(instr->index());
+  LOperand* length;
+  LOperand* index;
+  if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
+    length = UseRegisterOrConstant(instr->length());
+    index = UseOrConstant(instr->index());
+  } else {
+    length = UseTempRegister(instr->length());
+    index = Use(instr->index());
+  }
   return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
 }
 
index 21b0fcd..fa12270 100644 (file)
@@ -2899,16 +2899,26 @@ void LCodeGen::DoLoadExternalArrayPointer(
 
 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
   Register arguments = ToRegister(instr->arguments());
-  Register length = ToRegister(instr->length());
   Register result = ToRegister(instr->result());
-  // There are two words between the frame pointer and the last argument.
-  // Subtracting from length accounts for one of them add one more.
-  if (instr->index()->IsRegister()) {
-    __ subl(length, ToRegister(instr->index()));
+
+  if (instr->length()->IsConstantOperand() &&
+      instr->index()->IsConstantOperand()) {
+    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+    int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
+    int index = (const_length - const_index) + 1;
+    __ movq(result, Operand(arguments, index * kPointerSize));
   } else {
-    __ subl(length, ToOperand(instr->index()));
+    Register length = ToRegister(instr->length());
+    // There are two words between the frame pointer and the last argument.
+    // Subtracting from length accounts for one of them add one more.
+    if (instr->index()->IsRegister()) {
+      __ subl(length, ToRegister(instr->index()));
+    } else {
+      __ subl(length, ToOperand(instr->index()));
+    }
+    __ movq(result,
+            Operand(arguments, length, times_pointer_size, kPointerSize));
   }
-  __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
 }
 
 
@@ -3916,7 +3926,6 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
 
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Register object = ToRegister(instr->object());
-  Register value = ToRegister(instr->value());
   int offset = instr->offset();
 
   if (!instr->transition().is_null()) {
@@ -3942,34 +3951,42 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   HType type = instr->hydrogen()->value()->type();
   SmiCheck check_needed =
       type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
-  if (instr->is_in_object()) {
-    __ movq(FieldOperand(object, offset), value);
-    if (instr->hydrogen()->NeedsWriteBarrier()) {
-      Register temp = ToRegister(instr->temp());
-      // Update the write barrier for the object for in-object properties.
-      __ RecordWriteField(object,
-                          offset,
-                          value,
-                          temp,
-                          kSaveFPRegs,
-                          EMIT_REMEMBERED_SET,
-                          check_needed);
+
+  Register write_register = object;
+  if (!instr->is_in_object()) {
+    write_register = ToRegister(instr->temp());
+    __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
+  }
+
+  if (instr->value()->IsConstantOperand()) {
+    LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+    if (IsInteger32Constant(operand_value)) {
+      int const_value = ToInteger32(operand_value);
+      __ movq(FieldOperand(write_register, offset), Immediate(const_value));
+    } else {
+      if (operand_value->IsRegister()) {
+        __ movq(FieldOperand(write_register, offset),
+                ToRegister(operand_value));
+      } else {
+        Handle<Object> handle_value = ToHandle(operand_value);
+        __ Move(FieldOperand(write_register, offset), handle_value);
+      }
     }
   } else {
-    Register temp = ToRegister(instr->temp());
-    __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset));
-    __ movq(FieldOperand(temp, offset), value);
-    if (instr->hydrogen()->NeedsWriteBarrier()) {
-      // Update the write barrier for the properties array.
-      // object is used as a scratch register.
-      __ RecordWriteField(temp,
-                          offset,
-                          value,
-                          object,
-                          kSaveFPRegs,
-                          EMIT_REMEMBERED_SET,
-                          check_needed);
-    }
+    __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
+  }
+
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    Register value = ToRegister(instr->value());
+    Register temp = instr->is_in_object() ? ToRegister(instr->temp()) : object;
+    // Update the write barrier for the object for in-object properties.
+    __ RecordWriteField(write_register,
+                        offset,
+                        value,
+                        temp,
+                        kSaveFPRegs,
+                        EMIT_REMEMBERED_SET,
+                        check_needed);
   }
 }
 
@@ -4135,7 +4152,6 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
 
 
 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
-  Register value = ToRegister(instr->value());
   Register elements = ToRegister(instr->elements());
   LOperand* key = instr->key();
   if (!key->IsConstantOperand()) {
@@ -4160,8 +4176,22 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
                             FAST_ELEMENTS,
                             FixedArray::kHeaderSize - kHeapObjectTag,
                             instr->additional_index());
+  if (instr->value()->IsRegister()) {
+    __ movq(operand, ToRegister(instr->value()));
+  } else {
+    LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+    if (IsInteger32Constant(operand_value)) {
+      Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
+      __ Move(operand, smi_value);
+    } else {
+      Handle<Object> handle_value = ToHandle(operand_value);
+      __ Move(operand, handle_value);
+    }
+  }
 
   if (instr->hydrogen()->NeedsWriteBarrier()) {
+    ASSERT(instr->value()->IsRegister());
+    Register value = ToRegister(instr->value());
     ASSERT(!instr->key()->IsConstantOperand());
     HType type = instr->hydrogen()->value()->type();
     SmiCheck check_needed =
@@ -4169,15 +4199,12 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
     // Compute address of modified element and store it into key register.
     Register key_reg(ToRegister(key));
     __ lea(key_reg, operand);
-    __ movq(Operand(key_reg, 0), value);
     __ RecordWrite(elements,
                    key_reg,
                    value,
                    kSaveFPRegs,
                    EMIT_REMEMBERED_SET,
                    check_needed);
-  } else {
-    __ movq(operand, value);
   }
 }
 
index d365174..e78cee4 100644 (file)
@@ -2139,7 +2139,7 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
       ASSERT(instr->value()->representation().IsTagged());
       object = UseTempRegister(instr->elements());
       val = needs_write_barrier ? UseTempRegister(instr->value())
-          : UseRegisterAtStart(instr->value());
+          : UseRegisterOrConstantAtStart(instr->value());
       key = (clobbers_key || needs_write_barrier)
           ? UseTempRegister(instr->key())
           : UseRegisterOrConstantAtStart(instr->key());
@@ -2236,9 +2236,22 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
         : UseRegisterAtStart(instr->object());
   }
 
-  LOperand* val = needs_write_barrier
-      ? UseTempRegister(instr->value())
-      : UseRegister(instr->value());
+  bool register_or_constant = false;
+  if (instr->value()->IsConstant()) {
+    HConstant* constant_value = HConstant::cast(instr->value());
+    register_or_constant = constant_value->HasInteger32Value()
+        || constant_value->HasDoubleValue()
+        || constant_value->ImmortalImmovable();
+  }
+
+  LOperand* val;
+  if (needs_write_barrier) {
+    val = UseTempRegister(instr->value());
+  } else if (register_or_constant) {
+    val = UseRegisterOrConstant(instr->value());
+  } else {
+    val = UseRegister(instr->value());
+  }
 
   // We only need a scratch register if we have a write barrier or we
   // have a store into the properties array (not in-object-property).
@@ -2382,8 +2395,15 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
   info()->MarkAsRequiresFrame();
   LOperand* args = UseRegister(instr->arguments());
-  LOperand* length = UseTempRegister(instr->length());
-  LOperand* index = Use(instr->index());
+  LOperand* length;
+  LOperand* index;
+  if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
+    length = UseRegisterOrConstant(instr->length());
+    index = UseOrConstant(instr->index());
+  } else {
+    length = UseTempRegister(instr->length());
+    index = Use(instr->index());
+  }
   return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
 }