Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index 52612acf0e44e463c5fa0de38de230d2c7c5b578..2ef39b7c09f5a3f5d9701143d8b56d509d2c36a5 100644 |
--- a/src/hydrogen-instructions.cc |
+++ b/src/hydrogen-instructions.cc |
@@ -84,9 +84,9 @@ void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) { |
UpdateRepresentation(new_rep, h_infer, "inputs"); |
new_rep = RepresentationFromUses(); |
UpdateRepresentation(new_rep, h_infer, "uses"); |
- new_rep = RepresentationFromUseRequirements(); |
- if (new_rep.fits_into(Representation::Integer32())) { |
- UpdateRepresentation(new_rep, h_infer, "use requirements"); |
+ if (representation().IsSmi() && HasNonSmiUse()) { |
+ UpdateRepresentation( |
+ Representation::Integer32(), h_infer, "use requirements"); |
} |
} |
@@ -259,34 +259,56 @@ HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { |
} |
-static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { |
- if (result > kMaxInt) { |
- *overflow = true; |
- return kMaxInt; |
- } |
- if (result < kMinInt) { |
- *overflow = true; |
- return kMinInt; |
+static int32_t ConvertAndSetOverflow(Representation r, |
+ int64_t result, |
+ bool* overflow) { |
+ if (r.IsSmi()) { |
+ if (result > Smi::kMaxValue) { |
+ *overflow = true; |
+ return Smi::kMaxValue; |
+ } |
+ if (result < Smi::kMinValue) { |
+ *overflow = true; |
+ return Smi::kMinValue; |
+ } |
+ } else { |
+ if (result > kMaxInt) { |
+ *overflow = true; |
+ return kMaxInt; |
+ } |
+ if (result < kMinInt) { |
+ *overflow = true; |
+ return kMinInt; |
+ } |
} |
return static_cast<int32_t>(result); |
} |
-static int32_t AddWithoutOverflow(int32_t a, int32_t b, bool* overflow) { |
+static int32_t AddWithoutOverflow(Representation r, |
+ int32_t a, |
+ int32_t b, |
+ bool* overflow) { |
int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b); |
- return ConvertAndSetOverflow(result, overflow); |
+ return ConvertAndSetOverflow(r, result, overflow); |
} |
-static int32_t SubWithoutOverflow(int32_t a, int32_t b, bool* overflow) { |
+static int32_t SubWithoutOverflow(Representation r, |
+ int32_t a, |
+ int32_t b, |
+ bool* overflow) { |
int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b); |
- return ConvertAndSetOverflow(result, overflow); |
+ return ConvertAndSetOverflow(r, result, overflow); |
} |
-static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { |
+static int32_t MulWithoutOverflow(const Representation& r, |
+ int32_t a, |
+ int32_t b, |
+ bool* overflow) { |
int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); |
- return ConvertAndSetOverflow(result, overflow); |
+ return ConvertAndSetOverflow(r, result, overflow); |
} |
@@ -306,8 +328,9 @@ int32_t Range::Mask() const { |
void Range::AddConstant(int32_t value) { |
if (value == 0) return; |
bool may_overflow = false; // Overflow is ignored here. |
- lower_ = AddWithoutOverflow(lower_, value, &may_overflow); |
- upper_ = AddWithoutOverflow(upper_, value, &may_overflow); |
+ Representation r = Representation::Integer32(); |
+ lower_ = AddWithoutOverflow(r, lower_, value, &may_overflow); |
+ upper_ = AddWithoutOverflow(r, upper_, value, &may_overflow); |
#ifdef DEBUG |
Verify(); |
#endif |
@@ -366,10 +389,10 @@ void Range::Shl(int32_t value) { |
} |
-bool Range::AddAndCheckOverflow(Range* other) { |
+bool Range::AddAndCheckOverflow(const Representation& r, Range* other) { |
bool may_overflow = false; |
- lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); |
- upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); |
+ lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow); |
+ upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow); |
KeepOrder(); |
#ifdef DEBUG |
Verify(); |
@@ -378,10 +401,10 @@ bool Range::AddAndCheckOverflow(Range* other) { |
} |
-bool Range::SubAndCheckOverflow(Range* other) { |
+bool Range::SubAndCheckOverflow(const Representation& r, Range* other) { |
bool may_overflow = false; |
- lower_ = SubWithoutOverflow(lower_, other->upper(), &may_overflow); |
- upper_ = SubWithoutOverflow(upper_, other->lower(), &may_overflow); |
+ lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow); |
+ upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow); |
KeepOrder(); |
#ifdef DEBUG |
Verify(); |
@@ -406,12 +429,12 @@ void Range::Verify() const { |
#endif |
-bool Range::MulAndCheckOverflow(Range* other) { |
+bool Range::MulAndCheckOverflow(const Representation& r, Range* other) { |
bool may_overflow = false; |
- int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); |
- int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); |
- int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); |
- int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); |
+ int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow); |
+ int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow); |
+ int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow); |
+ int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow); |
lower_ = Min(Min(v1, v2), Min(v3, v4)); |
upper_ = Max(Max(v1, v2), Max(v3, v4)); |
#ifdef DEBUG |
@@ -1429,7 +1452,7 @@ void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { |
HValue* HBitwise::Canonicalize() { |
- if (!representation().IsInteger32()) return this; |
+ if (!representation().IsSmiOrInteger32()) return this; |
// If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. |
int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; |
if (left()->EqualsInteger32Constant(nop_constant) && |
@@ -1549,7 +1572,7 @@ HValue* HUnaryMathOperation::Canonicalize() { |
// If the input is integer32 then we replace the floor instruction |
// with its input. |
- if (val->representation().IsInteger32()) return val; |
+ if (val->representation().IsSmiOrInteger32()) return val; |
if (val->IsDiv() && (val->UseCount() == 1)) { |
HDiv* hdiv = HDiv::cast(val); |
@@ -1559,8 +1582,8 @@ HValue* HUnaryMathOperation::Canonicalize() { |
HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left); |
if (new_left == NULL && |
hdiv->observed_input_representation(1).IsSmiOrInteger32()) { |
- new_left = new(block()->zone()) |
- HChange(left, Representation::Integer32(), false, false); |
+ new_left = new(block()->zone()) HChange( |
+ left, Representation::Integer32(), false, false, false); |
HChange::cast(new_left)->InsertBefore(this); |
} |
HValue* new_right = |
@@ -1570,8 +1593,8 @@ HValue* HUnaryMathOperation::Canonicalize() { |
CpuFeatures::IsSupported(SUDIV) && |
#endif |
hdiv->observed_input_representation(2).IsSmiOrInteger32()) { |
- new_right = new(block()->zone()) |
- HChange(right, Representation::Integer32(), false, false); |
+ new_right = new(block()->zone()) HChange( |
+ right, Representation::Integer32(), false, false, false); |
HChange::cast(new_right)->InsertBefore(this); |
} |
@@ -1741,7 +1764,7 @@ void HInstanceOf::PrintDataTo(StringStream* stream) { |
Range* HValue::InferRange(Zone* zone) { |
Range* result; |
- if (type().IsSmi()) { |
+ if (representation().IsSmi() || type().IsSmi()) { |
result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); |
result->set_can_be_minus_zero(false); |
} else { |
@@ -1756,10 +1779,11 @@ Range* HValue::InferRange(Zone* zone) { |
Range* HChange::InferRange(Zone* zone) { |
Range* input_range = value()->range(); |
- if (from().IsInteger32() && |
- to().IsSmiOrTagged() && |
- !value()->CheckFlag(HInstruction::kUint32) && |
- input_range != NULL && input_range->IsInSmiRange()) { |
+ if (from().IsInteger32() && !value()->CheckFlag(HInstruction::kUint32) && |
+ (to().IsSmi() || |
+ (to().IsTagged() && |
+ input_range != NULL && |
+ input_range->IsInSmiRange()))) { |
set_type(HType::Smi()); |
ClearGVNFlag(kChangesNewSpacePromotion); |
} |
@@ -1767,7 +1791,9 @@ Range* HChange::InferRange(Zone* zone) { |
? input_range->Copy(zone) |
: HValue::InferRange(zone); |
result->set_can_be_minus_zero(!to().IsSmiOrInteger32() || |
- !CheckFlag(kAllUsesTruncatingToInt32)); |
+ !(CheckFlag(kAllUsesTruncatingToInt32) || |
+ CheckFlag(kAllUsesTruncatingToSmi))); |
+ if (to().IsSmi()) result->ClampToSmi(); |
return result; |
} |
@@ -1804,15 +1830,18 @@ Range* HPhi::InferRange(Zone* zone) { |
Range* HAdd::InferRange(Zone* zone) { |
- if (representation().IsInteger32()) { |
+ Representation r = representation(); |
+ if (r.IsSmiOrInteger32()) { |
Range* a = left()->range(); |
Range* b = right()->range(); |
Range* res = a->Copy(zone); |
- if (!res->AddAndCheckOverflow(b) || |
- CheckFlag(kAllUsesTruncatingToInt32)) { |
+ if (!res->AddAndCheckOverflow(r, b) || |
+ (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) || |
+ (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) { |
ClearFlag(kCanOverflow); |
} |
- res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
+ res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && |
+ !CheckFlag(kAllUsesTruncatingToInt32) && |
a->CanBeMinusZero() && b->CanBeMinusZero()); |
return res; |
} else { |
@@ -1822,15 +1851,18 @@ Range* HAdd::InferRange(Zone* zone) { |
Range* HSub::InferRange(Zone* zone) { |
- if (representation().IsInteger32()) { |
+ Representation r = representation(); |
+ if (r.IsSmiOrInteger32()) { |
Range* a = left()->range(); |
Range* b = right()->range(); |
Range* res = a->Copy(zone); |
- if (!res->SubAndCheckOverflow(b) || |
- CheckFlag(kAllUsesTruncatingToInt32)) { |
+ if (!res->SubAndCheckOverflow(r, b) || |
+ (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) || |
+ (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) { |
ClearFlag(kCanOverflow); |
} |
- res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
+ res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && |
+ !CheckFlag(kAllUsesTruncatingToInt32) && |
a->CanBeMinusZero() && b->CanBeZero()); |
return res; |
} else { |
@@ -1840,17 +1872,19 @@ Range* HSub::InferRange(Zone* zone) { |
Range* HMul::InferRange(Zone* zone) { |
- if (representation().IsInteger32()) { |
+ Representation r = representation(); |
+ if (r.IsSmiOrInteger32()) { |
Range* a = left()->range(); |
Range* b = right()->range(); |
Range* res = a->Copy(zone); |
- if (!res->MulAndCheckOverflow(b)) { |
+ if (!res->MulAndCheckOverflow(r, b)) { |
// Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 |
// would be wrong, because truncated integer multiplication is too |
// precise and therefore not the same as converting to Double and back. |
ClearFlag(kCanOverflow); |
} |
- res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
+ res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) && |
+ !CheckFlag(kAllUsesTruncatingToInt32) && |
((a->CanBeZero() && b->CanBeNegative()) || |
(a->CanBeNegative() && b->CanBeZero()))); |
return res; |
@@ -1969,7 +2003,7 @@ bool HPhi::IsRelationTrueInternal(NumericRelation relation, |
Range* HMathMinMax::InferRange(Zone* zone) { |
- if (representation().IsInteger32()) { |
+ if (representation().IsSmiOrInteger32()) { |
Range* a = left()->range(); |
Range* b = right()->range(); |
Range* res = a->Copy(zone); |
@@ -2054,6 +2088,7 @@ void HPhi::InitRealUses(int phi_id) { |
// Compute a conservative approximation of truncating uses before inferring |
// representations. The proper, exact computation will be done later, when |
// inserting representation changes. |
+ SetFlag(kTruncatingToSmi); |
SetFlag(kTruncatingToInt32); |
for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
HValue* value = it.value(); |
@@ -2064,8 +2099,13 @@ void HPhi::InitRealUses(int phi_id) { |
PrintF("#%d Phi is used by real #%d %s as %s\n", |
id(), value->id(), value->Mnemonic(), rep.Mnemonic()); |
} |
- if (!value->IsSimulate() && !value->CheckFlag(kTruncatingToInt32)) { |
- ClearFlag(kTruncatingToInt32); |
+ if (!value->IsSimulate()) { |
+ if (!value->CheckFlag(kTruncatingToSmi)) { |
+ ClearFlag(kTruncatingToSmi); |
+ } |
+ if (!value->CheckFlag(kTruncatingToInt32)) { |
+ ClearFlag(kTruncatingToInt32); |
+ } |
} |
} |
} |
@@ -2252,7 +2292,7 @@ HConstant::HConstant(double double_value, |
void HConstant::Initialize(Representation r) { |
if (r.IsNone()) { |
- if (has_smi_value_) { |
+ if (has_smi_value_ && kSmiValueSize == 31) { |
r = Representation::Smi(); |
} else if (has_int32_value_) { |
r = Representation::Integer32(); |
@@ -2359,25 +2399,18 @@ void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
ASSERT(CheckFlag(kFlexibleRepresentation)); |
Representation new_rep = RepresentationFromInputs(); |
UpdateRepresentation(new_rep, h_infer, "inputs"); |
- // When the operation has information about its own output type, don't look |
- // at uses. |
- if (!observed_output_representation_.IsNone()) return; |
- new_rep = RepresentationFromUses(); |
- UpdateRepresentation(new_rep, h_infer, "uses"); |
- new_rep = RepresentationFromUseRequirements(); |
- if (new_rep.fits_into(Representation::Integer32())) { |
- UpdateRepresentation(new_rep, h_infer, "use requirements"); |
+ if (observed_output_representation_.IsNone()) { |
+ new_rep = RepresentationFromUses(); |
+ UpdateRepresentation(new_rep, h_infer, "uses"); |
+ } else { |
+ new_rep = RepresentationFromOutput(); |
+ UpdateRepresentation(new_rep, h_infer, "output"); |
} |
-} |
- |
-bool HBinaryOperation::IgnoreObservedOutputRepresentation( |
- Representation current_rep) { |
- return observed_output_representation_.IsDouble() && |
- current_rep.IsInteger32() && |
- // Mul in Integer32 mode would be too precise. |
- !this->IsMul() && |
- CheckUsesForFlag(kTruncatingToInt32); |
+ if (representation().IsSmi() && HasNonSmiUse()) { |
+ UpdateRepresentation( |
+ Representation::Integer32(), h_infer, "use requirements"); |
+ } |
} |
@@ -2386,28 +2419,38 @@ Representation HBinaryOperation::RepresentationFromInputs() { |
// the currently assumed output representation. |
Representation rep = representation(); |
for (int i = 1; i <= 2; ++i) { |
- Representation input_rep = observed_input_representation(i); |
- if (input_rep.is_more_general_than(rep)) rep = input_rep; |
+ rep = rep.generalize(observed_input_representation(i)); |
} |
// If any of the actual input representation is more general than what we |
// have so far but not Tagged, use that representation instead. |
Representation left_rep = left()->representation(); |
Representation right_rep = right()->representation(); |
+ if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); |
+ if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); |
- if (left_rep.is_more_general_than(rep) && !left_rep.IsTagged()) { |
- rep = left_rep; |
- } |
- if (right_rep.is_more_general_than(rep) && !right_rep.IsTagged()) { |
- rep = right_rep; |
- } |
+ return rep; |
+} |
+ |
+ |
+bool HBinaryOperation::IgnoreObservedOutputRepresentation( |
+ Representation current_rep) { |
+ return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) || |
+ (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) && |
+ // Mul in Integer32 mode would be too precise. |
+ !this->IsMul(); |
+} |
+ |
+ |
+Representation HBinaryOperation::RepresentationFromOutput() { |
+ Representation rep = representation(); |
// Consider observed output representation, but ignore it if it's Double, |
// this instruction is not a division, and all its uses are truncating |
// to Integer32. |
if (observed_output_representation_.is_more_general_than(rep) && |
!IgnoreObservedOutputRepresentation(rep)) { |
- rep = observed_output_representation_; |
+ return observed_output_representation_; |
} |
- return rep; |
+ return Representation::None(); |
} |
@@ -3344,29 +3387,28 @@ HType HFunctionLiteral::CalculateInferredType() { |
HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( |
BitVector* visited) { |
visited->Add(id()); |
- if (representation().IsInteger32() && |
- !value()->representation().IsInteger32()) { |
+ if (representation().IsSmiOrInteger32() && |
+ !value()->representation().Equals(representation())) { |
if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
SetFlag(kBailoutOnMinusZero); |
} |
} |
- if (RequiredInputRepresentation(0).IsInteger32() && |
- representation().IsInteger32()) { |
+ if (RequiredInputRepresentation(0).IsSmiOrInteger32() && |
+ representation().Equals(RequiredInputRepresentation(0))) { |
return value(); |
} |
return NULL; |
} |
- |
HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { |
visited->Add(id()); |
- if (from().IsInteger32()) return NULL; |
+ if (from().IsSmiOrInteger32()) return NULL; |
if (CanTruncateToInt32()) return NULL; |
if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
SetFlag(kBailoutOnMinusZero); |
} |
- ASSERT(!from().IsInteger32() || !to().IsInteger32()); |
+ ASSERT(!from().IsSmiOrInteger32() || !to().IsSmiOrInteger32()); |
return NULL; |
} |
@@ -3453,7 +3495,7 @@ bool HStoreKeyed::NeedsCanonicalization() { |
} |
if (value()->IsChange()) { |
- if (HChange::cast(value())->from().IsInteger32()) { |
+ if (HChange::cast(value())->from().IsSmiOrInteger32()) { |
return false; |
} |
if (HChange::cast(value())->value()->type().IsSmi()) { |
@@ -3464,8 +3506,8 @@ bool HStoreKeyed::NeedsCanonicalization() { |
} |
-#define H_CONSTANT_INT32(val) \ |
-new(zone) HConstant(static_cast<int32_t>(val), Representation::Integer32()) |
+#define H_CONSTANT_INT(val) \ |
+new(zone) HConstant(static_cast<int32_t>(val)) |
#define H_CONSTANT_DOUBLE(val) \ |
new(zone) HConstant(static_cast<double>(val), Representation::Double()) |
@@ -3478,7 +3520,7 @@ HInstruction* HInstr::New( \ |
if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ |
if (TypeInfo::IsInt32Double(double_res)) { \ |
- return H_CONSTANT_INT32(double_res); \ |
+ return H_CONSTANT_INT(double_res); \ |
} \ |
return H_CONSTANT_DOUBLE(double_res); \ |
} \ |
@@ -3677,7 +3719,7 @@ HInstruction* HMod::New(Zone* zone, |
if ((res == 0) && (dividend < 0)) { |
return H_CONSTANT_DOUBLE(-0.0); |
} |
- return H_CONSTANT_INT32(res); |
+ return H_CONSTANT_INT(res); |
} |
} |
} |
@@ -3695,7 +3737,7 @@ HInstruction* HDiv::New( |
if (c_right->DoubleValue() != 0) { |
double double_res = c_left->DoubleValue() / c_right->DoubleValue(); |
if (TypeInfo::IsInt32Double(double_res)) { |
- return H_CONSTANT_INT32(double_res); |
+ return H_CONSTANT_INT(double_res); |
} |
return H_CONSTANT_DOUBLE(double_res); |
} else { |
@@ -3732,7 +3774,7 @@ HInstruction* HBitwise::New( |
result = 0; // Please the compiler. |
UNREACHABLE(); |
} |
- return H_CONSTANT_INT32(result); |
+ return H_CONSTANT_INT(result); |
} |
} |
return new(zone) HBitwise(op, context, left, right); |
@@ -3746,7 +3788,7 @@ HInstruction* HInstr::New( \ |
HConstant* c_left = HConstant::cast(left); \ |
HConstant* c_right = HConstant::cast(right); \ |
if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
- return H_CONSTANT_INT32(result); \ |
+ return H_CONSTANT_INT(result); \ |
} \ |
} \ |
return new(zone) HInstr(context, left, right); \ |
@@ -3772,14 +3814,14 @@ HInstruction* HShr::New( |
if ((right_val == 0) && (left_val < 0)) { |
return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val)); |
} |
- return H_CONSTANT_INT32(static_cast<uint32_t>(left_val) >> right_val); |
+ return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val); |
} |
} |
return new(zone) HShr(context, left, right); |
} |
-#undef H_CONSTANT_INT32 |
+#undef H_CONSTANT_INT |
#undef H_CONSTANT_DOUBLE |
@@ -3804,8 +3846,7 @@ void HPhi::SimplifyConstantInputs() { |
continue; |
} else if (operand->HasDoubleValue()) { |
HConstant* integer_input = |
- new(graph->zone()) HConstant(DoubleToInt32(operand->DoubleValue()), |
- Representation::Integer32()); |
+ new(graph->zone()) HConstant(DoubleToInt32(operand->DoubleValue())); |
integer_input->InsertAfter(operand); |
SetOperandAt(i, integer_input); |
} else if (operand == graph->GetConstantTrue()) { |
@@ -3820,7 +3861,7 @@ void HPhi::SimplifyConstantInputs() { |
HValue* use = it.value(); |
if (use->IsBinaryOperation()) { |
HBinaryOperation::cast(use)->set_observed_input_representation( |
- it.index(), Representation::Integer32()); |
+ it.index(), Representation::Smi()); |
} |
} |
} |
@@ -3869,6 +3910,17 @@ Representation HValue::RepresentationFromUseRequirements() { |
} |
+bool HValue::HasNonSmiUse() { |
+ for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
+ // We check for observed_input_representation elsewhere. |
+ Representation use_rep = |
+ it.value()->RequiredInputRepresentation(it.index()); |
+ if (!use_rep.IsNone() && !use_rep.IsSmi()) return true; |
+ } |
+ return false; |
+} |
+ |
+ |
// Node-specific verification code is only included in debug mode. |
#ifdef DEBUG |