A64: Improve constraints on StoreKeyed instructions
authorm.m.capewell@googlemail.com <m.m.capewell@googlemail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Mar 2014 17:12:47 +0000 (17:12 +0000)
committerm.m.capewell@googlemail.com <m.m.capewell@googlemail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Mar 2014 17:12:47 +0000 (17:12 +0000)
BUG=
R=ulan@chromium.org

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

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

src/a64/lithium-a64.cc
src/a64/lithium-codegen-a64.cc

index ae32e36..12812bb 100644 (file)
@@ -2124,7 +2124,7 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
   LOperand* temp = NULL;
   LOperand* elements = NULL;
   LOperand* val = NULL;
-  LOperand* key = NULL;
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
 
   if (!instr->is_typed_elements() &&
       instr->value()->representation().IsTagged() &&
@@ -2132,11 +2132,11 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
     // RecordWrite() will clobber all registers.
     elements = UseRegisterAndClobber(instr->elements());
     val = UseRegisterAndClobber(instr->value());
-    key = UseRegisterAndClobber(instr->key());
+    temp = TempRegister();
   } else {
     elements = UseRegister(instr->elements());
     val = UseRegister(instr->value());
-    key = UseRegisterOrConstantAtStart(instr->key());
+    temp = instr->key()->IsConstant() ? NULL : TempRegister();
   }
 
   if (instr->is_typed_elements()) {
@@ -2148,23 +2148,16 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
             instr->elements()->representation().IsTagged()) ||
            (instr->is_external() &&
             instr->elements()->representation().IsExternal()));
-    temp = instr->key()->IsConstant() ? NULL : TempRegister();
     return new(zone()) LStoreKeyedExternal(elements, key, val, temp);
 
   } else if (instr->value()->representation().IsDouble()) {
     ASSERT(instr->elements()->representation().IsTagged());
-
-    // The constraint used here is UseRegister, even though the StoreKeyed
-    // instruction may canonicalize the value in the register if it is a NaN.
-    temp = TempRegister();
     return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp);
 
   } else {
     ASSERT(instr->elements()->representation().IsTagged());
     ASSERT(instr->value()->representation().IsSmiOrTagged() ||
            instr->value()->representation().IsInteger32());
-
-    temp = TempRegister();
     return new(zone()) LStoreKeyedFixed(elements, key, val, temp);
   }
 }
index 3d2e6e4..8e443b9 100644 (file)
@@ -4989,7 +4989,7 @@ void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) {
 void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) {
   Register elements = ToRegister(instr->elements());
   DoubleRegister value = ToDoubleRegister(instr->value());
-  Register store_base = ToRegister(instr->temp());
+  Register store_base = no_reg;
   int offset = 0;
 
   if (instr->key()->IsConstantOperand()) {
@@ -5001,6 +5001,7 @@ void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) {
                                                  instr->additional_index());
     store_base = elements;
   } else {
+    store_base = ToRegister(instr->temp());
     Register key = ToRegister(instr->key());
     bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
     CalcKeyedArrayBaseRegister(store_base, elements, key, key_is_tagged,
@@ -5023,17 +5024,23 @@ void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) {
 void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) {
   Register value = ToRegister(instr->value());
   Register elements = ToRegister(instr->elements());
-  Register store_base = ToRegister(instr->temp());
+  Register scratch = no_reg;
+  Register store_base = no_reg;
   Register key = no_reg;
   int offset = 0;
 
+  if (!instr->key()->IsConstantOperand() ||
+      instr->hydrogen()->NeedsWriteBarrier()) {
+    scratch = ToRegister(instr->temp());
+  }
+
   if (instr->key()->IsConstantOperand()) {
-    ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
     LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
     offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
                                            instr->additional_index());
     store_base = elements;
   } else {
+    store_base = scratch;
     key = ToRegister(instr->key());
     bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi();
     CalcKeyedArrayBaseRegister(store_base, elements, key, key_is_tagged,
@@ -5052,13 +5059,16 @@ void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) {
   }
 
   if (instr->hydrogen()->NeedsWriteBarrier()) {
+    ASSERT(representation.IsTagged());
+    // This assignment may cause element_addr to alias store_base.
+    Register element_addr = scratch;
     SmiCheck check_needed =
         instr->hydrogen()->value()->IsHeapObject()
             ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
     // Compute address of modified element and store it into key register.
-    __ Add(key, store_base, offset - kHeapObjectTag);
-    __ RecordWrite(elements, key, value, GetLinkRegisterState(), kSaveFPRegs,
-                   EMIT_REMEMBERED_SET, check_needed);
+    __ Add(element_addr, store_base, offset - kHeapObjectTag);
+    __ RecordWrite(elements, element_addr, value, GetLinkRegisterState(),
+                   kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed);
   }
 }