Reviewers: ulan,
Description:
Crankshaft: Recognize (i >>> 0) === i for integer32 inputs and replace
with i >= 0, with no bailout.
Please review this at https://codereview.chromium.org/14211009/
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/
Affected files:
M src/hydrogen-instructions.h
M src/hydrogen.h
M src/hydrogen.cc
M src/ia32/lithium-codegen-ia32.cc
M src/token.h
M src/x64/lithium-codegen-x64.cc
Index: src/hydrogen-instructions.h
===================================================================
--- src/hydrogen-instructions.h (revision 14364)
+++ src/hydrogen-instructions.h (working copy)
@@ -4613,7 +4613,7 @@
if (right()->IsInteger32Constant()) {
if (decomposition->Apply(left(), 0,
right()->GetInteger32Constant())) {
// This is intended to look for HAdd and HSub, to handle compounds
- // like ((base + offset) >> scale) with one single decomposition.
+ // like ((base + offset) >>> scale) with one single decomposition.
left()->TryDecompose(decomposition);
return true;
}
Index: src/hydrogen.cc
===================================================================
--- src/hydrogen.cc (revision 14364)
+++ src/hydrogen.cc (working copy)
@@ -10041,6 +10041,21 @@
}
+void HOptimizedGraphBuilder::HandleTripleShiftZeroCompare(
+ CompareOperation* expr,
+ HValue* input) {
+ // (i >>> 0) === i is transformed to i >= 0.
+ // (i >>> 0) !== i is transformed to i < 0.
+ Token::Value op = (expr->op() == Token::EQ_STRICT) ? Token::GTE :
Token::LT;
+ HCompareIDAndBranch* compare =
+ new(zone()) HCompareIDAndBranch(input, graph()->GetConstant0(), op);
+ compare->set_observed_input_representation(Representation::Integer32(),
+ Representation::Integer32());
+ compare->set_position(expr->position());
+ return ast_context()->ReturnControl(compare, expr->id());
+}
+
+
void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation*
expr,
HTypeof*
typeof_expr,
Handle<String>
check) {
@@ -10067,6 +10082,34 @@
}
+// Recognize the pattern (i >>> 0) !== i.
+static bool MatchTripleShiftZeroCompare(HValue* left,
+ Token::Value op,
+ HValue* right,
+ HValue** input) {
+ if (!right->representation().IsInteger32()) return false;
+ if (!left->IsShr()) return false;
+ HShr* shr = HShr::cast(left);
+ if (right != shr->left()) return false;
+ if (!shr->right()->IsConstant()) return false;
+ HConstant* shiftOperand = HConstant::cast(shr->right());
+ if (*(shiftOperand->handle()) != Smi::FromInt(0)) return false;
+ *input = right;
+ return true;
+}
+
+
+static bool IsTripleShiftZeroCompare(HValue* left,
+ Token::Value op,
+ HValue* right,
+ HValue** input) {
+ if (!Token::IsStrictOp(op)) return false;
+ return MatchTripleShiftZeroCompare(left, op, right, input) ||
+ MatchTripleShiftZeroCompare(right, op, left, input);
+}
+
+
+
static bool MatchLiteralCompareTypeof(HValue* left,
Token::Value op,
HValue* right,
@@ -10156,6 +10199,9 @@
return HandleLiteralCompareTypeof(expr, typeof_expr, check);
}
HValue* sub_expr = NULL;
+ if (IsTripleShiftZeroCompare(left, op, right, &sub_expr)) {
+ return HandleTripleShiftZeroCompare(expr, sub_expr);
+ }
Factory* f = isolate()->factory();
if (IsLiteralCompareNil(left, op, right, f->undefined_value(),
&sub_expr)) {
return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
Index: src/hydrogen.h
===================================================================
--- src/hydrogen.h (revision 14364)
+++ src/hydrogen.h (working copy)
@@ -1559,6 +1559,7 @@
void HandleLiteralCompareNil(CompareOperation* expr,
HValue* value,
NilValue nil);
+ void HandleTripleShiftZeroCompare(CompareOperation* expr, HValue* input);
HInstruction* BuildStringCharCodeAt(HValue* context,
HValue* string,
Index: src/ia32/lithium-codegen-ia32.cc
===================================================================
--- src/ia32/lithium-codegen-ia32.cc (revision 14364)
+++ src/ia32/lithium-codegen-ia32.cc (working copy)
@@ -1692,11 +1692,11 @@
uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
switch (instr->op()) {
case Token::ROR:
- if (shift_count == 0 && instr->can_deopt()) {
+ if (shift_count != 0) {
+ __ ror(ToRegister(left), shift_count);
+ } else if (instr->can_deopt()) {
__ test(ToRegister(left), Immediate(0x80000000));
DeoptimizeIf(not_zero, instr->environment());
- } else {
- __ ror(ToRegister(left), shift_count);
}
break;
case Token::SAR:
@@ -1705,11 +1705,11 @@
}
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), Immediate(0x80000000));
DeoptimizeIf(not_zero, instr->environment());
- } else {
- __ shr(ToRegister(left), shift_count);
}
break;
case Token::SHL:
Index: src/token.h
===================================================================
--- src/token.h (revision 14364)
+++ src/token.h (working copy)
@@ -225,6 +225,10 @@
return op == EQ || op == EQ_STRICT;
}
+ static bool IsStrictOp(Value op) {
+ return op == EQ_STRICT || op == NE_STRICT;
+ }
+
static Value NegateCompareOp(Value op) {
ASSERT(IsCompareOp(op));
switch (op) {
Index: src/x64/lithium-codegen-x64.cc
===================================================================
--- src/x64/lithium-codegen-x64.cc (revision 14364)
+++ src/x64/lithium-codegen-x64.cc (working copy)
@@ -1498,11 +1498,15 @@
}
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));
+ // Even if the shift is zero, we have to zero out the high bits
with
+ // a movl for negative inputs.
+ __ movl(ToRegister(left), ToRegister(left));
}
break;
case Token::SHL:
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.