Add Smi support to Shl
R=mvstanton@chromium.org Review URL: https://chromiumcodereview.appspot.com/20323002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15910 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
630999d1a2
commit
7471ae893e
@ -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);
|
||||
|
@ -1742,7 +1742,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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user