Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index b353cdb2cc514acd7f31bc1752c92faff3f10ff7..d6dcf34e627d1397a520c01b1adcc7c2ecb81725 100644 |
--- a/src/hydrogen-instructions.cc |
+++ b/src/hydrogen-instructions.cc |
@@ -405,9 +405,10 @@ bool HValue::TestDominanceUsingProcessedFlag(HValue* dominator, |
if (dominator->block() != dominated->block()) { |
return dominator->block()->Dominates(dominated->block()); |
} else { |
- // If both arguments are in the same block we check if "dominator" has |
- // already been processed or if it is a phi: if yes it dominates the other. |
- return dominator->CheckFlag(kIDefsProcessingDone) || dominator->IsPhi(); |
+ // If both arguments are in the same block we check if dominator is a phi |
+ // or if dominated has not already been processed: in either case we know |
+ // that dominator precedes dominated. |
+ return dominator->IsPhi() || !dominated->CheckFlag(kIDefsProcessingDone); |
} |
} |
@@ -524,6 +525,16 @@ const char* HValue::Mnemonic() const { |
} |
+bool HValue::IsInteger32Constant() { |
+ return IsConstant() && HConstant::cast(this)->HasInteger32Value(); |
+} |
+ |
+ |
+int32_t HValue::GetInteger32Constant() { |
+ return HConstant::cast(this)->Integer32Value(); |
+} |
+ |
+ |
void HValue::SetOperandAt(int index, HValue* value) { |
RegisterUse(index, value); |
InternalSetOperandAt(index, value); |
@@ -794,6 +805,37 @@ void HInstruction::Verify() { |
#endif |
+HNumericConstraint* HNumericConstraint::AddToGraph( |
+ HValue* constrained_value, |
+ NumericRelation relation, |
+ HValue* related_value, |
+ HInstruction* insertion_point) { |
+ if (insertion_point == NULL) { |
+ if (constrained_value->IsInstruction()) { |
+ insertion_point = HInstruction::cast(constrained_value); |
+ } else if (constrained_value->IsPhi()) { |
+ insertion_point = constrained_value->block()->first(); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ } |
+ HNumericConstraint* result = |
+ new(insertion_point->block()->zone()) HNumericConstraint( |
+ constrained_value, relation, related_value); |
+ 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,10 +857,38 @@ void HBinaryCall::PrintDataTo(StringStream* stream) { |
} |
+void HBoundsCheck::AddInformativeDefinitions() { |
+ // TODO(mmassi): Executing this code during AddInformativeDefinitions |
+ // is a hack. Move it to some other HPhase. |
+ if (index()->IsRelationTrue(NumericRelation::Ge(), |
+ block()->graph()->GetConstant0()) && |
+ index()->IsRelationTrue(NumericRelation::Lt(), length())) { |
+ set_skip_check(true); |
+ } |
+} |
+ |
+ |
+bool HBoundsCheck::IsRelationTrueInternal(NumericRelation relation, |
+ HValue* related_value) { |
+ if (related_value == length()) { |
+ // A HBoundsCheck is smaller than the length it compared against. |
+ return NumericRelation::Lt().Implies(relation); |
+ } else if (related_value == block()->graph()->GetConstant0()) { |
+ // A HBoundsCheck is greater than or equal to zero. |
+ return NumericRelation::Ge().Implies(relation); |
+ } else { |
+ return false; |
+ } |
+} |
+ |
+ |
void HBoundsCheck::PrintDataTo(StringStream* stream) { |
index()->PrintNameTo(stream); |
stream->Add(" "); |
length()->PrintNameTo(stream); |
+ if (skip_check()) { |
+ stream->Add(" [DISABLED]"); |
+ } |
} |
@@ -1475,6 +1545,38 @@ Range* HMod::InferRange(Zone* zone) { |
} |
+void HPhi::AddInformativeDefinitions() { |
+ if (OperandCount() == 2) { |
+ for (int operand_index = 0; operand_index < 2; operand_index++) { |
+ int other_operand_index = (operand_index + 1) % 2; |
+ |
+ // Add an idef that "discards" the OSR entry block branch. |
+ if (OperandAt(operand_index)->block()->is_osr_entry()) { |
+ HNumericConstraint::AddToGraph( |
+ this, NumericRelation::Eq(), OperandAt(other_operand_index)); |
+ } |
+ |
+ static NumericRelation relations[] = { |
+ NumericRelation::Ge(), |
+ NumericRelation::Le() |
+ }; |
+ |
+ // Check if this phi is an induction variable. If, e.g., we know that |
+ // its first input is greater than the phi itself, then that must be |
+ // the back edge, and the phi is always greater than its second input. |
+ for (int relation_index = 0; relation_index < 2; relation_index++) { |
+ if (OperandAt(operand_index)->IsRelationTrue(relations[relation_index], |
+ this)) { |
+ HNumericConstraint::AddToGraph(this, |
+ relations[relation_index], |
+ OperandAt(other_operand_index)); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+ |
Range* HMathMinMax::InferRange(Zone* zone) { |
if (representation().IsInteger32()) { |
Range* a = left()->range(); |
@@ -1936,6 +2038,16 @@ void HStringCompareAndBranch::PrintDataTo(StringStream* stream) { |
} |
+void HCompareIDAndBranch::AddInformativeDefinitions() { |
+ NumericRelation r = NumericRelation::FromToken(token()); |
+ if (r.IsNone()) return; |
+ |
+ HNumericConstraint::AddToGraph(left(), r, right(), SuccessorAt(0)->first()); |
+ HNumericConstraint::AddToGraph( |
+ left(), r.Negated(), right(), SuccessorAt(1)->first()); |
+} |
+ |
+ |
void HCompareIDAndBranch::PrintDataTo(StringStream* stream) { |
stream->Add(Token::Name(token())); |
stream->Add(" "); |