Eliminate overflow check after integer add and sub operation if result is truncated to int32.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10870 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c5dbc7b2
...@@ -285,6 +285,14 @@ HUseListNode* HUseListNode::tail() { ...@@ -285,6 +285,14 @@ HUseListNode* HUseListNode::tail() {
} }
bool HValue::CheckUsesForFlag(Flag f) {
for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
if (!it.value()->CheckFlag(f)) return false;
}
return true;
}
HUseIterator::HUseIterator(HUseListNode* head) : next_(head) { HUseIterator::HUseIterator(HUseListNode* head) : next_(head) {
Advance(); Advance();
} }
...@@ -831,12 +839,12 @@ void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { ...@@ -831,12 +839,12 @@ void HLoadFieldByIndex::PrintDataTo(StringStream* stream) {
HValue* HConstant::Canonicalize() { HValue* HConstant::Canonicalize() {
return HasNoUses() && !IsBlockEntry() ? NULL : this; return HasNoUses() ? NULL : this;
} }
HValue* HTypeof::Canonicalize() { HValue* HTypeof::Canonicalize() {
return HasNoUses() && !IsBlockEntry() ? NULL : this; return HasNoUses() ? NULL : this;
} }
...@@ -858,6 +866,20 @@ HValue* HBitwise::Canonicalize() { ...@@ -858,6 +866,20 @@ HValue* HBitwise::Canonicalize() {
} }
HValue* HAdd::Canonicalize() {
if (!representation().IsInteger32()) return this;
if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow);
return this;
}
HValue* HSub::Canonicalize() {
if (!representation().IsInteger32()) return this;
if (CheckUsesForFlag(kTruncatingToInt32)) ClearFlag(kCanOverflow);
return this;
}
HValue* HChange::Canonicalize() { HValue* HChange::Canonicalize() {
return (from().Equals(to())) ? value() : this; return (from().Equals(to())) ? value() : this;
} }
......
...@@ -645,6 +645,9 @@ class HValue: public ZoneObject { ...@@ -645,6 +645,9 @@ class HValue: public ZoneObject {
void ClearFlag(Flag f) { flags_ &= ~(1 << f); } void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
// Returns true if the flag specified is set for all uses, false otherwise.
bool CheckUsesForFlag(Flag f);
GVNFlagSet gvn_flags() const { return gvn_flags_; } GVNFlagSet gvn_flags() const { return gvn_flags_; }
void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); } void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); } void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
...@@ -824,6 +827,8 @@ class HInstruction: public HValue { ...@@ -824,6 +827,8 @@ class HInstruction: public HValue {
bool has_position() const { return position_ != RelocInfo::kNoPosition; } bool has_position() const { return position_ != RelocInfo::kNoPosition; }
void set_position(int position) { position_ = position; } void set_position(int position) { position_ = position; }
bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
#ifdef DEBUG #ifdef DEBUG
...@@ -1121,10 +1126,6 @@ class HUnaryOperation: public HTemplateInstruction<1> { ...@@ -1121,10 +1126,6 @@ class HUnaryOperation: public HTemplateInstruction<1> {
return reinterpret_cast<HUnaryOperation*>(value); return reinterpret_cast<HUnaryOperation*>(value);
} }
virtual bool CanTruncateToInt32() const {
return CheckFlag(kTruncatingToInt32);
}
HValue* value() { return OperandAt(0); } HValue* value() { return OperandAt(0); }
virtual void PrintDataTo(StringStream* stream); virtual void PrintDataTo(StringStream* stream);
}; };
...@@ -1248,16 +1249,13 @@ class HToInt32: public HUnaryOperation { ...@@ -1248,16 +1249,13 @@ class HToInt32: public HUnaryOperation {
: HUnaryOperation(value) { : HUnaryOperation(value) {
set_representation(Representation::Integer32()); set_representation(Representation::Integer32());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kTruncatingToInt32);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
return Representation::None(); return Representation::None();
} }
virtual bool CanTruncateToInt32() const {
return true;
}
virtual HValue* Canonicalize() { virtual HValue* Canonicalize() {
if (value()->representation().IsInteger32()) { if (value()->representation().IsInteger32()) {
return value(); return value();
...@@ -3154,6 +3152,8 @@ class HAdd: public HArithmeticBinaryOperation { ...@@ -3154,6 +3152,8 @@ class HAdd: public HArithmeticBinaryOperation {
virtual HType CalculateInferredType(); virtual HType CalculateInferredType();
virtual HValue* Canonicalize();
DECLARE_CONCRETE_INSTRUCTION(Add) DECLARE_CONCRETE_INSTRUCTION(Add)
protected: protected:
...@@ -3172,6 +3172,8 @@ class HSub: public HArithmeticBinaryOperation { ...@@ -3172,6 +3172,8 @@ class HSub: public HArithmeticBinaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual HValue* Canonicalize();
static HInstruction* NewHSub(Zone* zone, static HInstruction* NewHSub(Zone* zone,
HValue* context, HValue* context,
HValue* left, HValue* left,
...@@ -3257,7 +3259,6 @@ class HDiv: public HArithmeticBinaryOperation { ...@@ -3257,7 +3259,6 @@ class HDiv: public HArithmeticBinaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
static HInstruction* NewHDiv(Zone* zone, static HInstruction* NewHDiv(Zone* zone,
HValue* context, HValue* context,
HValue* left, HValue* left,
......
...@@ -2067,13 +2067,9 @@ void HGraph::InsertRepresentationChanges() { ...@@ -2067,13 +2067,9 @@ void HGraph::InsertRepresentationChanges() {
for (int i = 0; i < phi_list()->length(); i++) { for (int i = 0; i < phi_list()->length(); i++) {
HPhi* phi = phi_list()->at(i); HPhi* phi = phi_list()->at(i);
if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue; if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue;
for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { if (!phi->CheckUsesForFlag(HValue::kTruncatingToInt32)) {
HValue* use = it.value();
if (!use->CheckFlag(HValue::kTruncatingToInt32)) {
phi->ClearFlag(HValue::kTruncatingToInt32); phi->ClearFlag(HValue::kTruncatingToInt32);
change = true; change = true;
break;
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment