Reviewers: mvstanton,
Message:
PTAL
Description:
Add Smi support to Shl
Please review this at https://chromiumcodereview.appspot.com/20323002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/arm/lithium-arm.cc
M src/arm/lithium-codegen-arm.cc
M src/hydrogen-instructions.h
M src/ia32/lithium-codegen-ia32.cc
M src/ia32/lithium-ia32.cc
M src/x64/lithium-codegen-x64.cc
M src/x64/lithium-x64.cc
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index
65abecaf1879caf3a59d6b7ff2e3309aa4f7656c..ae0b874fc68c4cc1421cbbe42be9b97d743fc629
100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -708,9 +708,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize*
instr) {
LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) {
- if (instr->representation().IsSmiOrTagged()) {
- ASSERT(instr->left()->representation().IsSmiOrTagged());
- ASSERT(instr->right()->representation().IsSmiOrTagged());
+ if (instr->representation().IsTagged()) {
+ ASSERT(instr->left()->representation().IsTagged());
+ ASSERT(instr->right()->representation().IsTagged());
LOperand* left = UseFixed(instr->left(), r1);
LOperand* right = UseFixed(instr->right(), r0);
@@ -718,25 +718,35 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
return MarkAsCall(DefineFixed(result, r0), instr);
}
- ASSERT(instr->representation().IsInteger32());
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ ASSERT(instr->representation().IsSmiOrInteger32());
+ ASSERT(instr->left()->representation().Equals(instr->representation()));
+ ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->left());
HValue* right_value = instr->right();
LOperand* right = NULL;
int constant_value = 0;
+ bool does_deopt = false;
if (right_value->IsConstant()) {
HConstant* constant = HConstant::cast(right_value);
right = chunk_->DefineConstantOperand(constant);
constant_value = constant->Integer32Value() & 0x1f;
+ // Left shifts can deoptimize if we shift by > 0 and the result cannot
be
+ // truncated to smi.
+ if (instr->representation().IsSmi() && constant_value > 0) {
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
+ does_deopt = true;
+ break;
+ }
+ }
+ }
} else {
right = UseRegisterAtStart(right_value);
}
// Shift operations can only deoptimize if we do a logical shift
// by 0 and the result cannot be truncated to int32.
- bool does_deopt = false;
if (op == Token::SHR && constant_value == 0) {
if (FLAG_opt_safe_uint32_operations) {
does_deopt = !instr->CheckFlag(HInstruction::kUint32);
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
8f28651e326da89bb99e9cb17393c374eb099bd8..d7d3c5eab40481aa1c153053e8b873f914948eb6
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -1744,7 +1744,14 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
break;
case Token::SHL:
if (shift_count != 0) {
- __ mov(result, Operand(left, LSL, shift_count));
+ if (instr->hydrogen_value()->representation().IsSmi() &&
+ instr->can_deopt()) {
+ __ mov(result, Operand(left, LSL, shift_count - 1));
+ __ SmiTag(result, result, SetCC);
+ DeoptimizeIf(vs, instr->environment());
+ } else {
+ __ mov(result, Operand(left, LSL, shift_count));
+ }
} else {
__ Move(result, left);
}
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
bf59159164c53b4e41ae52ee2d48d76625017a1b..c36388ee6abd359898fe1f57134b8e9f19311d81
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -4890,7 +4890,11 @@ class HShl: public HBitwiseBinaryOperation {
virtual void UpdateRepresentation(Representation new_rep,
HInferRepresentationPhase* h_infer,
const char* reason) {
- if (new_rep.IsSmi()) new_rep = Representation::Integer32();
+ if (new_rep.IsSmi() &&
+ !(right()->IsInteger32Constant() &&
+ right()->GetInteger32Constant() >= 0)) {
+ new_rep = Representation::Integer32();
+ }
HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer,
reason);
}
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc
b/src/ia32/lithium-codegen-ia32.cc
index
d022a82f4df540d5078dcdebc184eb3bba1566fd..de936b4a18edd79fd8371f1af201e6436389f952
100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1762,7 +1762,14 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
break;
case Token::SHL:
if (shift_count != 0) {
- __ shl(ToRegister(left), shift_count);
+ if (instr->hydrogen_value()->representation().IsSmi() &&
+ instr->can_deopt()) {
+ __ shl(ToRegister(left), shift_count - 1);
+ __ SmiTag(ToRegister(left));
+ DeoptimizeIf(overflow, instr->environment());
+ } else {
+ __ shl(ToRegister(left), shift_count);
+ }
}
break;
default:
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index
f03cd72becf934e44ade1ae8b10274adb33aa05b..2806b662661c41c768e75e8fd14fa96677a9e78d
100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -761,7 +761,7 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize*
instr) {
LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) {
- if (instr->representation().IsSmiOrTagged()) {
+ if (instr->representation().IsTagged()) {
ASSERT(instr->left()->representation().IsSmiOrTagged());
ASSERT(instr->right()->representation().IsSmiOrTagged());
@@ -772,25 +772,35 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
return MarkAsCall(DefineFixed(result, eax), instr);
}
- ASSERT(instr->representation().IsInteger32());
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ ASSERT(instr->representation().IsSmiOrInteger32());
+ ASSERT(instr->left()->representation().Equals(instr->representation()));
+ ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->left());
HValue* right_value = instr->right();
LOperand* right = NULL;
int constant_value = 0;
+ bool does_deopt = false;
if (right_value->IsConstant()) {
HConstant* constant = HConstant::cast(right_value);
right = chunk_->DefineConstantOperand(constant);
constant_value = constant->Integer32Value() & 0x1f;
+ // Left shifts can deoptimize if we shift by > 0 and the result cannot
be
+ // truncated to smi.
+ if (instr->representation().IsSmi() && constant_value > 0) {
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
+ does_deopt = true;
+ break;
+ }
+ }
+ }
} else {
right = UseFixed(right_value, ecx);
}
// Shift operations can only deoptimize if we do a logical shift by 0 and
// the result cannot be truncated to int32.
- bool does_deopt = false;
if (op == Token::SHR && constant_value == 0) {
if (FLAG_opt_safe_uint32_operations) {
does_deopt = !instr->CheckFlag(HInstruction::kUint32);
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index
364c3a1824ef671ee44dcd8f984d4be0363da993..ffe1ae8cadb819ec5e8489deb228b5f81e18ad83
100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1453,7 +1453,11 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
break;
case Token::SHL:
if (shift_count != 0) {
- __ shll(ToRegister(left), Immediate(shift_count));
+ if (instr->hydrogen_value()->representation().IsSmi()) {
+ __ shl(ToRegister(left), Immediate(shift_count));
+ } else {
+ __ shll(ToRegister(left), Immediate(shift_count));
+ }
}
break;
default:
Index: src/x64/lithium-x64.cc
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index
d6f05c0a2df80bf90531fda2ed89aae021f9c442..094d2c60bd7c8c54f60a9011444150c7ab9bb074
100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -717,9 +717,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize*
instr) {
LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) {
- if (instr->representation().IsSmiOrTagged()) {
- ASSERT(instr->left()->representation().IsSmiOrTagged());
- ASSERT(instr->right()->representation().IsSmiOrTagged());
+ if (instr->representation().IsTagged()) {
+ ASSERT(instr->left()->representation().IsTagged());
+ ASSERT(instr->right()->representation().IsTagged());
LOperand* left = UseFixed(instr->left(), rdx);
LOperand* right = UseFixed(instr->right(), rax);
@@ -727,9 +727,9 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
return MarkAsCall(DefineFixed(result, rax), instr);
}
- ASSERT(instr->representation().IsInteger32());
- ASSERT(instr->left()->representation().IsInteger32());
- ASSERT(instr->right()->representation().IsInteger32());
+ ASSERT(instr->representation().IsSmiOrInteger32());
+ ASSERT(instr->left()->representation().Equals(instr->representation()));
+ ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->left());
HValue* right_value = instr->right();
--
--
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.