Support Smi in CompareIDAndBranch

BUG=
R=jkummerow@chromium.org

Review URL: https://chromiumcodereview.appspot.com/16134003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14842 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-05-28 09:24:39 +00:00
parent 0aaed2bba7
commit cf9b1170d1
8 changed files with 69 additions and 31 deletions

View File

@ -1681,9 +1681,10 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
LInstruction* LChunkBuilder::DoCompareIDAndBranch(
HCompareIDAndBranch* instr) {
Representation r = instr->representation();
if (r.IsInteger32()) {
ASSERT(instr->left()->representation().IsInteger32());
ASSERT(instr->right()->representation().IsInteger32());
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(
instr->right()->representation()));
LOperand* left = UseRegisterOrConstantAtStart(instr->left());
LOperand* right = UseRegisterOrConstantAtStart(instr->right());
return new(zone()) LCmpIDAndBranch(left, right);

View File

@ -2414,11 +2414,19 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
__ b(vs, chunk_->GetAssemblyLabel(false_block));
} else {
if (right->IsConstantOperand()) {
__ cmp(ToRegister(left),
Operand(ToInteger32(LConstantOperand::cast(right))));
int32_t value = ToInteger32(LConstantOperand::cast(right));
if (instr->hydrogen_value()->representation().IsSmi()) {
__ cmp(ToRegister(left), Operand(Smi::FromInt(value)));
} else {
__ cmp(ToRegister(left), Operand(value));
}
} else if (left->IsConstantOperand()) {
__ cmp(ToRegister(right),
Operand(ToInteger32(LConstantOperand::cast(left))));
int32_t value = ToInteger32(LConstantOperand::cast(left));
if (instr->hydrogen_value()->representation().IsSmi()) {
__ cmp(ToRegister(right), Operand(Smi::FromInt(value)));
} else {
__ cmp(ToRegister(right), Operand(value));
}
// We transposed the operands. Reverse the condition.
cond = ReverseCondition(cond);
} else {

View File

@ -2454,18 +2454,18 @@ void HGoto::PrintDataTo(StringStream* stream) {
void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) {
Representation rep = Representation::None();
Representation left_rep = left()->representation();
Representation right_rep = right()->representation();
bool observed_integers =
observed_input_representation(0).IsInteger32() &&
observed_input_representation(1).IsInteger32();
bool inputs_are_not_doubles =
!left_rep.IsDouble() && !right_rep.IsDouble();
if (observed_integers && inputs_are_not_doubles) {
rep = Representation::Integer32();
} else {
rep = Representation::Double();
Representation observed_left = observed_input_representation(0);
Representation observed_right = observed_input_representation(1);
Representation rep = Representation::Smi();
if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
if (!observed_left.IsTagged()) rep = rep.generalize(observed_left);
if (!observed_right.IsTagged()) rep = rep.generalize(observed_right);
if (rep.IsDouble()) {
// According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, ===
// and !=) have special handling of undefined, e.g. undefined == undefined
// is 'true'. Relational comparisons have a different semantic, first

View File

@ -1128,7 +1128,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
Zone* zone = this->zone();
IfBuilder length_checker(this);
length_checker.IfCompare(length, key, Token::EQ);
length_checker.IfCompare(length, key, Token::EQ, Representation::Smi());
length_checker.Then();
HValue* current_capacity =
@ -1136,7 +1136,8 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
IfBuilder capacity_checker(this);
capacity_checker.IfCompare(length, current_capacity, Token::EQ);
capacity_checker.IfCompare(
length, current_capacity, Token::EQ, Representation::Smi());
capacity_checker.Then();
HValue* context = environment()->LookupContext();
@ -1258,11 +1259,11 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
new(zone) HLoadExternalArrayPointer(elements);
AddInstruction(external_elements);
IfBuilder length_checker(this);
length_checker.IfCompare(key, length, Token::LT);
length_checker.IfCompare(key, length, Token::LT, Representation::Smi());
length_checker.Then();
IfBuilder negative_checker(this);
HValue* bounds_check = negative_checker.IfCompare(
key, graph()->GetConstant0(), Token::GTE);
key, graph()->GetConstant0(), Token::GTE, Representation::Smi());
negative_checker.Then();
HInstruction* result = BuildExternalArrayElementAccess(
external_elements, key, val, bounds_check,

View File

@ -2305,9 +2305,19 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
__ j(parity_even, chunk_->GetAssemblyLabel(false_block));
} else {
if (right->IsConstantOperand()) {
__ cmp(ToRegister(left), ToInteger32Immediate(right));
int32_t const_value = ToInteger32(LConstantOperand::cast(right));
if (instr->hydrogen_value()->representation().IsSmi()) {
__ cmp(ToOperand(left), Immediate(Smi::FromInt(const_value)));
} else {
__ cmp(ToOperand(left), Immediate(const_value));
}
} else if (left->IsConstantOperand()) {
__ cmp(ToOperand(right), ToInteger32Immediate(left));
int32_t const_value = ToInteger32(LConstantOperand::cast(left));
if (instr->hydrogen_value()->representation().IsSmi()) {
__ cmp(ToOperand(right), Immediate(Smi::FromInt(const_value)));
} else {
__ cmp(ToOperand(right), Immediate(const_value));
}
// We transposed the operands. Reverse the condition.
cc = ReverseCondition(cc);
} else {

View File

@ -1689,9 +1689,10 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
LInstruction* LChunkBuilder::DoCompareIDAndBranch(
HCompareIDAndBranch* instr) {
Representation r = instr->representation();
if (r.IsInteger32()) {
ASSERT(instr->left()->representation().IsInteger32());
ASSERT(instr->right()->representation().IsInteger32());
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(
instr->right()->representation()));
LOperand* left = UseRegisterOrConstantAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());
return new(zone()) LCmpIDAndBranch(left, right);

View File

@ -2074,16 +2074,32 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
int32_t value;
if (right->IsConstantOperand()) {
value = ToInteger32(LConstantOperand::cast(right));
__ cmpl(ToRegister(left), Immediate(value));
if (instr->hydrogen_value()->representation().IsSmi()) {
__ Cmp(ToRegister(left), Smi::FromInt(value));
} else {
__ cmpl(ToRegister(left), Immediate(value));
}
} else if (left->IsConstantOperand()) {
value = ToInteger32(LConstantOperand::cast(left));
if (right->IsRegister()) {
if (instr->hydrogen_value()->representation().IsSmi()) {
if (right->IsRegister()) {
__ Cmp(ToRegister(right), Smi::FromInt(value));
} else {
__ Cmp(ToOperand(right), Smi::FromInt(value));
}
} else if (right->IsRegister()) {
__ cmpl(ToRegister(right), Immediate(value));
} else {
__ cmpl(ToOperand(right), Immediate(value));
}
// We transposed the operands. Reverse the condition.
cc = ReverseCondition(cc);
} else if (instr->hydrogen_value()->representation().IsSmi()) {
if (right->IsRegister()) {
__ cmpq(ToRegister(left), ToRegister(right));
} else {
__ cmpq(ToRegister(left), ToOperand(right));
}
} else {
if (right->IsRegister()) {
__ cmpl(ToRegister(left), ToRegister(right));

View File

@ -1597,9 +1597,10 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
LInstruction* LChunkBuilder::DoCompareIDAndBranch(
HCompareIDAndBranch* instr) {
Representation r = instr->representation();
if (r.IsInteger32()) {
ASSERT(instr->left()->representation().IsInteger32());
ASSERT(instr->right()->representation().IsInteger32());
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().Equals(
instr->right()->representation()));
LOperand* left = UseRegisterOrConstantAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());
return new(zone()) LCmpIDAndBranch(left, right);