Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Unified Diff: src/hydrogen-instructions.cc

Issue 16206004: Add smi support to all binops minus shr, sar, shl, div and mod. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/hydrogen-instructions.cc
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index b8fb1757a5fa0edb9b9fec3f6acdb1c261d85724..4404a5a22c10ea67ff807e484839078d7b5b21f3 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -254,34 +254,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(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);
}
@@ -301,8 +323,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
@@ -361,10 +384,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();
@@ -373,10 +396,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();
@@ -401,12 +424,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
@@ -1371,7 +1394,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) &&
@@ -1480,10 +1503,10 @@ void HChange::PrintDataTo(StringStream* stream) {
HValue* HUnaryMathOperation::Canonicalize() {
if (op() == kMathFloor) {
- // If the input is integer32 then we replace the floor instruction
+ // If the input is smi or integer32 then we replace the floor instruction
// with its input. This happens before the representation changes are
// introduced.
- if (value()->representation().IsInteger32()) return value();
+ if (value()->representation().IsSmiOrInteger32()) return value();
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
defined(V8_TARGET_ARCH_X64)
@@ -1661,7 +1684,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 {
@@ -1685,7 +1708,7 @@ Range* HChange::InferRange(Zone* zone) {
Range* result = (input_range != NULL)
? input_range->Copy(zone)
: HValue::InferRange(zone);
- if (to().IsInteger32()) result->set_can_be_minus_zero(false);
+ if (to().IsSmiOrInteger32()) result->set_can_be_minus_zero(false);
return result;
}
@@ -1701,9 +1724,12 @@ Range* HConstant::InferRange(Zone* zone) {
Range* HPhi::InferRange(Zone* zone) {
- if (representation().IsInteger32()) {
+ Representation r = representation();
+ if (r.IsSmiOrInteger32()) {
if (block()->IsLoopHeader()) {
- Range* range = new(zone) Range(kMinInt, kMaxInt);
+ Range* range = r.IsSmi()
+ ? new(zone) Range(Smi::kMinValue, Smi::kMaxValue)
+ : new(zone) Range(kMinInt, kMaxInt);
return range;
} else {
Range* range = OperandAt(0)->range()->Copy(zone);
@@ -1719,11 +1745,12 @@ 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)) {
+ if (!res->AddAndCheckOverflow(r, b)) {
ClearFlag(kCanOverflow);
}
bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero();
@@ -1736,11 +1763,12 @@ 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)) {
+ if (!res->SubAndCheckOverflow(r, b)) {
ClearFlag(kCanOverflow);
}
res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero());
@@ -1752,11 +1780,12 @@ 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)) {
ClearFlag(kCanOverflow);
}
bool m0 = (a->CanBeZero() && b->CanBeNegative()) ||
@@ -1770,7 +1799,8 @@ Range* HMul::InferRange(Zone* zone) {
Range* HDiv::InferRange(Zone* zone) {
- if (representation().IsInteger32()) {
+ Representation r = representation();
+ if (r.IsSmiOrInteger32()) {
Range* a = left()->range();
Range* b = right()->range();
Range* result = new(zone) Range();
@@ -1782,7 +1812,9 @@ Range* HDiv::InferRange(Zone* zone) {
result->set_can_be_minus_zero(true);
}
- if (!a->Includes(kMinInt) || !b->Includes(-1)) {
+ if (!b->Includes(-1) ||
+ (r.IsSmi() && !a->Includes(Smi::kMinValue)) ||
+ (r.IsInteger32() && !a->Includes(kMinInt))) {
ClearFlag(HValue::kCanOverflow);
}
@@ -1797,7 +1829,8 @@ Range* HDiv::InferRange(Zone* zone) {
Range* HMod::InferRange(Zone* zone) {
- if (representation().IsInteger32()) {
+ Representation r = representation();
+ if (r.IsSmiOrInteger32()) {
Range* a = left()->range();
Range* b = right()->range();
@@ -1815,7 +1848,9 @@ Range* HMod::InferRange(Zone* zone) {
result->set_can_be_minus_zero(true);
}
- if (!a->Includes(kMinInt) || !b->Includes(-1)) {
+ if (!b->Includes(-1) ||
+ (r.IsSmi() && !a->Includes(Smi::kMinValue)) ||
Sven Panne 2013/06/04 09:53:56 * Re-order back to a, then b test. * Introduce 'mi
Sven Panne 2013/06/04 10:01:07 Thinking about it: We have to avoid an idiv of 0x8
Toon Verwaest 2013/06/04 15:06:40 You are right. I actually (temporarily) backed out
+ (r.IsInteger32() && !a->Includes(kMinInt))) {
ClearFlag(HValue::kCanOverflow);
}
@@ -1884,7 +1919,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);
@@ -2174,7 +2209,7 @@ void HConstant::Initialize(Representation r) {
}
set_representation(r);
SetFlag(kUseGVN);
- if (representation().IsInteger32()) {
+ if (representation().IsSmiOrInteger32()) {
ClearGVNFlag(kDependsOnOsrEntries);
}
}
@@ -2269,8 +2304,7 @@ 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.
@@ -2456,8 +2490,8 @@ void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) {
Representation observed_left = observed_input_representation(0);
Representation observed_right = observed_input_representation(1);
- Representation rep = Representation::Smi();
- if (observed_left.IsInteger32() && observed_right.IsInteger32()) {
+ Representation rep = observed_left.generalize(observed_right);
+ if (rep.IsNone() || rep.IsSmiOrInteger32()) {
if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
} else {
@@ -3053,14 +3087,14 @@ 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;
@@ -3070,12 +3104,12 @@ HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero(
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;
}
@@ -3162,7 +3196,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()) {
@@ -3538,7 +3572,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());
}
}
}

Powered by Google App Engine
This is Rietveld 408576698