From 561d0cf2282988383e456692503fe1a32d4ecc2c Mon Sep 17 00:00:00 2001 From: "fschneider@chromium.org" Date: Mon, 25 Jul 2011 13:28:35 +0000 Subject: [PATCH] Better range information for logical shift right >>>. If the input range is positive and the shift count is constant we can replace >>> with >> to compute the output range. For negative inputs, we can only compute a range if the result always fits into a signed int32. BUG=v8:1510 Review URL: http://codereview.chromium.org/7489043 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8735 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-instructions.cc | 24 ++++++++++++++++++++++++ src/hydrogen-instructions.h | 1 + 2 files changed, 25 insertions(+) diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 6c316cdd7d..2be2a03257 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1230,6 +1230,30 @@ Range* HSar::InferRange() { } +Range* HShr::InferRange() { + if (right()->IsConstant()) { + HConstant* c = HConstant::cast(right()); + if (c->HasInteger32Value()) { + int shift_count = c->Integer32Value() & 0x1f; + if (left()->range()->CanBeNegative()) { + // Only compute bounds if the result always fits into an int32. + return (shift_count >= 1) + ? new Range(0, static_cast(0xffffffff) >> shift_count) + : new Range(); + } else { + // For positive inputs we can use the >> operator. + Range* result = (left()->range() != NULL) + ? left()->range()->Copy() + : new Range(); + result->Sar(c->Integer32Value()); + return result; + } + } + } + return HValue::InferRange(); +} + + Range* HShl::InferRange() { if (right()->IsConstant()) { HConstant* c = HConstant::cast(right()); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 9b7a95b2f0..bd6763f140 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -3060,6 +3060,7 @@ class HShr: public HBitwiseBinaryOperation { HShr(HValue* context, HValue* left, HValue* right) : HBitwiseBinaryOperation(context, left, right) { } + virtual Range* InferRange(); virtual HType CalculateInferredType(); DECLARE_CONCRETE_INSTRUCTION(Shr)