A64: Port recent ARM optimizations in LCodeGen::DoAccessArgumentsAt.
authorbaptiste.afsa@arm.com <baptiste.afsa@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Feb 2014 11:22:33 +0000 (11:22 +0000)
committerbaptiste.afsa@arm.com <baptiste.afsa@arm.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 20 Feb 2014 11:22:33 +0000 (11:22 +0000)
R=jochen@chromium.org

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

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

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

index 3857ca7..d9f51e2 100644 (file)
@@ -812,12 +812,10 @@ LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
 
 
 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
-  // TODO(all): Try to improve this, like ARM r17925.
   info()->MarkAsRequiresFrame();
   LOperand* args = NULL;
   LOperand* length = NULL;
   LOperand* index = NULL;
-  LOperand* temp = NULL;
 
   if (instr->length()->IsConstant() && instr->index()->IsConstant()) {
     args = UseRegisterAtStart(instr->arguments());
@@ -827,11 +825,9 @@ LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
     args = UseRegister(instr->arguments());
     length = UseRegisterAtStart(instr->length());
     index = UseRegisterOrConstantAtStart(instr->index());
-    temp = TempRegister();
   }
 
-  return DefineAsRegister(
-      new(zone()) LAccessArgumentsAt(args, length, index, temp));
+  return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index));
 }
 
 
index 59ae9be..26234e9 100644 (file)
@@ -541,16 +541,14 @@ class LOsrEntry V8_FINAL : public LTemplateInstruction<0, 0, 0> {
 };
 
 
-class LAccessArgumentsAt V8_FINAL : public LTemplateInstruction<1, 3, 1> {
+class LAccessArgumentsAt V8_FINAL : public LTemplateInstruction<1, 3, 0> {
  public:
   LAccessArgumentsAt(LOperand* arguments,
                      LOperand* length,
-                     LOperand* index,
-                     LOperand* temp) {
+                     LOperand* index) {
     inputs_[0] = arguments;
     inputs_[1] = length;
     inputs_[2] = index;
-    temps_[0] = temp;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
@@ -558,7 +556,6 @@ class LAccessArgumentsAt V8_FINAL : public LTemplateInstruction<1, 3, 1> {
   LOperand* arguments() { return inputs_[0]; }
   LOperand* length() { return inputs_[1]; }
   LOperand* index() { return inputs_[2]; }
-  LOperand* temp() { return temps_[0]; }
 
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
 };
index 2052a27..c983ac8 100644 (file)
@@ -1404,27 +1404,36 @@ void LCodeGen::DoGap(LGap* gap) {
 
 
 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
-  // TODO(all): Try to improve this, like ARM r17925.
   Register arguments = ToRegister(instr->arguments());
   Register result = ToRegister(instr->result());
 
+  // The pointer to the arguments array come from DoArgumentsElements.
+  // It does not point directly to the arguments and there is an offest of
+  // two words that we must take into account when accessing an argument.
+  // Subtracting the index from length accounts for one, so we add one more.
+
   if (instr->length()->IsConstantOperand() &&
       instr->index()->IsConstantOperand()) {
-    ASSERT(instr->temp() == NULL);
     int index = ToInteger32(LConstantOperand::cast(instr->index()));
     int length = ToInteger32(LConstantOperand::cast(instr->length()));
     int offset = ((length - index) + 1) * kPointerSize;
     __ Ldr(result, MemOperand(arguments, offset));
+  } else if (instr->index()->IsConstantOperand()) {
+    Register length = ToRegister32(instr->length());
+    int index = ToInteger32(LConstantOperand::cast(instr->index()));
+    int loc = index - 1;
+    if (loc != 0) {
+      __ Sub(result.W(), length, loc);
+      __ Ldr(result, MemOperand(arguments, result, UXTW, kPointerSizeLog2));
+    } else {
+      __ Ldr(result, MemOperand(arguments, length, UXTW, kPointerSizeLog2));
+    }
   } else {
-    ASSERT(instr->temp() != NULL);
-    Register temp = ToRegister32(instr->temp());
     Register length = ToRegister32(instr->length());
     Operand index = ToOperand32I(instr->index());
-    // There are two words between the frame pointer and the last arguments.
-    // Subtracting from length accounts for only one, so we add one more.
-    __ Sub(temp, length, index);
-    __ Add(temp, temp, 1);
-    __ Ldr(result, MemOperand(arguments, temp, UXTW, kPointerSizeLog2));
+    __ Sub(result.W(), length, index);
+    __ Add(result.W(), result.W(), 1);
+    __ Ldr(result, MemOperand(arguments, result, UXTW, kPointerSizeLog2));
   }
 }