Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index b353cdb2cc514acd7f31bc1752c92faff3f10ff7..3ef1969d1020f737a6ba4bb44f7ea034681547f3 100644 |
| --- a/src/hydrogen-instructions.cc |
| +++ b/src/hydrogen-instructions.cc |
| @@ -524,6 +524,17 @@ const char* HValue::Mnemonic() const { |
| } |
| +bool HValue::IsInteger32Constant() { |
| + return IsConstant() && HConstant::cast(this)->HasInteger32Value(); |
| +} |
| + |
| + |
| +int32_t HValue::GetInteger32Constant() { |
| + ASSERT(IsInteger32Constant()); |
| + return HConstant::cast(this)->Integer32Value(); |
| +} |
| + |
| + |
| void HValue::SetOperandAt(int index, HValue* value) { |
| RegisterUse(index, value); |
| InternalSetOperandAt(index, value); |
| @@ -690,6 +701,14 @@ void HInstruction::PrintMnemonicTo(StringStream* stream) { |
| } |
| +HValue* HValue::AddNumericConstraint(HInstruction* insertion_point, |
| + HValue* related_value, |
| + NumericRelation relation) { |
| + return HNumericConstraint::New( |
| + insertion_point, this, related_value, relation); |
| +} |
| + |
| + |
| void HInstruction::Unlink() { |
| ASSERT(IsLinked()); |
| ASSERT(!IsControlInstruction()); // Must never move control instructions. |
| @@ -794,6 +813,27 @@ void HInstruction::Verify() { |
| #endif |
| +HNumericConstraint* HNumericConstraint::New(HInstruction* insertion_point, |
| + HValue* constrained_value, |
| + HValue* related_value, |
| + NumericRelation relation) { |
| + HNumericConstraint* result = |
| + new(insertion_point->block()->zone()) HNumericConstraint( |
| + constrained_value, related_value, relation); |
| + result->InsertAfter(insertion_point); |
| + return result; |
| +} |
| + |
| + |
| +void HNumericConstraint::PrintDataTo(StringStream* stream) { |
| + stream->Add("("); |
| + constrained_value()->PrintNameTo(stream); |
| + stream->Add(" %s ", relation().Mnemonic()); |
| + related_value()->PrintNameTo(stream); |
| + stream->Add(")"); |
| +} |
| + |
| + |
| void HDummyUse::PrintDataTo(StringStream* stream) { |
| value()->PrintNameTo(stream); |
| } |
| @@ -815,6 +855,18 @@ void HBinaryCall::PrintDataTo(StringStream* stream) { |
| } |
| +bool HBoundsCheck::CheckRelation(NumericRelation relation, |
| + HValue* related_value) { |
| + if (related_value == length()) { |
| + return NumericRelation::Lt().Implies(relation); |
| + } else if (related_value == block()->graph()->GetConstant0()) { |
| + return NumericRelation::Ge().Implies(relation); |
| + } else { |
| + return false; |
| + } |
| +} |
| + |
| + |
| void HBoundsCheck::PrintDataTo(StringStream* stream) { |
| index()->PrintNameTo(stream); |
| stream->Add(" "); |
| @@ -1475,6 +1527,31 @@ Range* HMod::InferRange(Zone* zone) { |
| } |
| +void HPhi::AddInformativeDefinitions() { |
| + HValue* induction_base = NULL; |
| + NumericRelation relation = NumericRelation::None(); |
| + if (OperandCount() == 2) { |
| + if (OperandAt(0)->IsRelationTrue(NumericRelation::Ge(), this)) { |
|
Jakob Kummerow
2013/02/12 15:10:42
I don't feel strongly about it, but you *could* av
Massi
2013/02/13 11:56:42
Done.
|
| + induction_base = OperandAt(1); |
| + relation = NumericRelation::Ge(); |
| + } else if (OperandAt(0)->IsRelationTrue(NumericRelation::Le(), this)) { |
| + induction_base = OperandAt(1); |
| + relation = NumericRelation::Ge(); |
|
Jakob Kummerow
2013/02/12 15:10:42
s/Ge/Le/
Massi
2013/02/13 11:56:42
Done.
|
| + } else if (OperandAt(1)->IsRelationTrue(NumericRelation::Ge(), this)) { |
| + induction_base = OperandAt(0); |
| + relation = NumericRelation::Ge(); |
| + } else if (OperandAt(1)->IsRelationTrue(NumericRelation::Le(), this)) { |
| + induction_base = OperandAt(0); |
| + relation = NumericRelation::Ge(); |
|
Jakob Kummerow
2013/02/12 15:10:42
s/Ge/Le/
Massi
2013/02/13 11:56:42
Done.
|
| + } |
| + } |
| + |
| + if (induction_base == NULL) return; |
| + |
| + AddNumericConstraint(block()->first(), induction_base, relation); |
| +} |
| + |
| + |
| Range* HMathMinMax::InferRange(Zone* zone) { |
| if (representation().IsInteger32()) { |
| Range* a = left()->range(); |
| @@ -1888,6 +1965,23 @@ Range* HShr::InferRange(Zone* zone) { |
| } |
| +bool HShr::CheckRelation(NumericRelation relation, HValue* other) { |
| + if (right()->IsInteger32Constant()) { |
| + HValue* base = left(); |
| + int32_t bits = right()->GetInteger32Constant(); |
| + if (relation.IsExtendable(-bits) && |
| + base->IsRelationTrue(NumericRelation::Ge(), |
| + block()->graph()->GetConstant0())) { |
| + return base->IsRelationTrue(relation, other); |
| + } else { |
| + return false; |
| + } |
| + } else { |
| + return false; |
| + } |
| +} |
| + |
| + |
| Range* HShl::InferRange(Zone* zone) { |
| if (right()->IsConstant()) { |
| HConstant* c = HConstant::cast(right()); |
| @@ -1904,6 +1998,23 @@ Range* HShl::InferRange(Zone* zone) { |
| } |
| +bool HShl::CheckRelation(NumericRelation relation, HValue* other) { |
| + if (right()->IsInteger32Constant()) { |
| + HValue* base = left(); |
| + int32_t bits = right()->GetInteger32Constant(); |
| + if (relation.IsExtendable(bits) && |
| + base->IsRelationTrue(NumericRelation::Ge(), |
| + block()->graph()->GetConstant0())) { |
| + return base->IsRelationTrue(relation, other); |
| + } else { |
| + return false; |
| + } |
| + } else { |
| + return false; |
| + } |
| +} |
| + |
| + |
| Range* HLoadKeyed::InferRange(Zone* zone) { |
| switch (elements_kind()) { |
| case EXTERNAL_PIXEL_ELEMENTS: |