From ec23d0b8151ec6ee89d3720e4c9131152005d551 Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Mon, 19 May 2014 07:47:09 +0000 Subject: [PATCH] Allow comparison in UINT32 mode. Shamelessly based on parts of https://codereview.chromium.org/288853003/. :-) R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/288383002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21355 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-codegen-arm.cc | 3 ++- src/arm64/lithium-codegen-arm64.cc | 3 ++- src/hydrogen-uint32-analysis.cc | 27 +++++++++++++++++++++++++++ src/ia32/lithium-codegen-ia32.cc | 10 ++++++---- src/mips/lithium-codegen-mips.cc | 3 ++- src/x64/lithium-codegen-x64.cc | 10 ++++++---- 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 1fd4405..623a9dc 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -2361,7 +2361,8 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - Condition cond = TokenToCondition(instr->op(), false); + bool is_unsigned = instr->hydrogen()->CheckFlag(HInstruction::kUint32); + Condition cond = TokenToCondition(instr->op(), is_unsigned); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 5be55d7..dab60e5 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -2429,7 +2429,8 @@ void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - Condition cond = TokenToCondition(instr->op(), false); + bool is_unsigned = instr->hydrogen()->CheckFlag(HInstruction::kUint32); + Condition cond = TokenToCondition(instr->op(), is_unsigned); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. diff --git a/src/hydrogen-uint32-analysis.cc b/src/hydrogen-uint32-analysis.cc index 21fbec9..24c256b 100644 --- a/src/hydrogen-uint32-analysis.cc +++ b/src/hydrogen-uint32-analysis.cc @@ -8,6 +8,30 @@ namespace v8 { namespace internal { +static bool IsUnsignedLoad(HLoadKeyed* instr) { + switch (instr->elements_kind()) { + case EXTERNAL_UINT8_ELEMENTS: + case EXTERNAL_UINT16_ELEMENTS: + case EXTERNAL_UINT32_ELEMENTS: + case EXTERNAL_UINT8_CLAMPED_ELEMENTS: + case UINT8_ELEMENTS: + case UINT16_ELEMENTS: + case UINT32_ELEMENTS: + case UINT8_CLAMPED_ELEMENTS: + return true; + default: + return false; + } +} + + +static bool IsUint32Operation(HValue* instr) { + return instr->IsShr() || + (instr->IsLoadKeyed() && IsUnsignedLoad(HLoadKeyed::cast(instr))) || + (instr->IsInteger32Constant() && instr->GetInteger32Constant() >= 0); +} + + bool HUint32AnalysisPhase::IsSafeUint32Use(HValue* val, HValue* use) { // Operations that operate on bits are safe. if (use->IsBitwise() || use->IsShl() || use->IsSar() || use->IsShr()) { @@ -37,6 +61,9 @@ bool HUint32AnalysisPhase::IsSafeUint32Use(HValue* val, HValue* use) { return true; } } + } else if (use->IsCompareNumericAndBranch()) { + HCompareNumericAndBranch* c = HCompareNumericAndBranch::cast(use); + return IsUint32Operation(c->left()) && IsUint32Operation(c->right()); } return false; diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index f4bf601..906ee3e 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -1645,11 +1645,11 @@ void LCodeGen::DoShiftI(LShiftI* instr) { } break; case Token::SHR: - if (shift_count == 0 && instr->can_deopt()) { + if (shift_count != 0) { + __ shr(ToRegister(left), shift_count); + } else if (instr->can_deopt()) { __ test(ToRegister(left), ToRegister(left)); DeoptimizeIf(sign, instr->environment()); - } else { - __ shr(ToRegister(left), shift_count); } break; case Token::SHL: @@ -2236,7 +2236,9 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - Condition cc = TokenToCondition(instr->op(), instr->is_double()); + bool is_unsigned = + instr->is_double() || instr->hydrogen()->CheckFlag(HInstruction::kUint32); + Condition cc = TokenToCondition(instr->op(), is_unsigned); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index ba03e16..3419ad0 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -2270,7 +2270,8 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - Condition cond = TokenToCondition(instr->op(), false); + bool is_unsigned = instr->hydrogen()->CheckFlag(HInstruction::kUint32); + Condition cc = TokenToCondition(instr->op(), is_unsigned); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 2d34056..1d1da3d 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -1605,11 +1605,11 @@ void LCodeGen::DoShiftI(LShiftI* instr) { } break; case Token::SHR: - if (shift_count == 0 && instr->can_deopt()) { + if (shift_count != 0) { + __ shrl(ToRegister(left), Immediate(shift_count)); + } else if (instr->can_deopt()) { __ testl(ToRegister(left), ToRegister(left)); DeoptimizeIf(negative, instr->environment()); - } else { - __ shrl(ToRegister(left), Immediate(shift_count)); } break; case Token::SHL: @@ -2227,7 +2227,9 @@ inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - Condition cc = TokenToCondition(instr->op(), instr->is_double()); + bool is_unsigned = + instr->is_double() || instr->hydrogen()->CheckFlag(HInstruction::kUint32); + Condition cc = TokenToCondition(instr->op(), is_unsigned); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. -- 2.7.4