From 4db29c52b227e025ec7c48f5edd4c8ec41959861 Mon Sep 17 00:00:00 2001 From: "baptiste.afsa@arm.com" Date: Thu, 20 Feb 2014 11:22:33 +0000 Subject: [PATCH] A64: Port recent ARM optimizations in LCodeGen::DoAccessArgumentsAt. 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 | 6 +----- src/a64/lithium-a64.h | 7 ++----- src/a64/lithium-codegen-a64.cc | 27 ++++++++++++++++++--------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/a64/lithium-a64.cc b/src/a64/lithium-a64.cc index 3857ca7..d9f51e2 100644 --- a/src/a64/lithium-a64.cc +++ b/src/a64/lithium-a64.cc @@ -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)); } diff --git a/src/a64/lithium-a64.h b/src/a64/lithium-a64.h index 59ae9be..26234e9 100644 --- a/src/a64/lithium-a64.h +++ b/src/a64/lithium-a64.h @@ -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; }; diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc index 2052a27..c983ac8 100644 --- a/src/a64/lithium-codegen-a64.cc +++ b/src/a64/lithium-codegen-a64.cc @@ -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)); } } -- 2.7.4