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
This commit is contained in:
fschneider@chromium.org 2012-02-29 13:41:18 +00:00
parent c5dbc7b2e1
commit b854d09721
3 changed files with 37 additions and 18 deletions

View File

@ -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) {
Advance();
}
@ -831,12 +839,12 @@ void HLoadFieldByIndex::PrintDataTo(StringStream* stream) {
HValue* HConstant::Canonicalize() {
return HasNoUses() && !IsBlockEntry() ? NULL : this;
return HasNoUses() ? NULL : this;
}
HValue* HTypeof::Canonicalize() {
return HasNoUses() && !IsBlockEntry() ? NULL : this;
return HasNoUses() ? NULL : this;
}
@ -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() {
return (from().Equals(to())) ? value() : this;
}

View File

@ -645,6 +645,9 @@ class HValue: public ZoneObject {
void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
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_; }
void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
@ -824,6 +827,8 @@ class HInstruction: public HValue {
bool has_position() const { return position_ != RelocInfo::kNoPosition; }
void set_position(int position) { position_ = position; }
bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
#ifdef DEBUG
@ -1121,10 +1126,6 @@ class HUnaryOperation: public HTemplateInstruction<1> {
return reinterpret_cast<HUnaryOperation*>(value);
}
virtual bool CanTruncateToInt32() const {
return CheckFlag(kTruncatingToInt32);
}
HValue* value() { return OperandAt(0); }
virtual void PrintDataTo(StringStream* stream);
};
@ -1248,16 +1249,13 @@ class HToInt32: public HUnaryOperation {
: HUnaryOperation(value) {
set_representation(Representation::Integer32());
SetFlag(kUseGVN);
SetFlag(kTruncatingToInt32);
}
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
virtual bool CanTruncateToInt32() const {
return true;
}
virtual HValue* Canonicalize() {
if (value()->representation().IsInteger32()) {
return value();
@ -3154,6 +3152,8 @@ class HAdd: public HArithmeticBinaryOperation {
virtual HType CalculateInferredType();
virtual HValue* Canonicalize();
DECLARE_CONCRETE_INSTRUCTION(Add)
protected:
@ -3172,6 +3172,8 @@ class HSub: public HArithmeticBinaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
virtual HValue* Canonicalize();
static HInstruction* NewHSub(Zone* zone,
HValue* context,
HValue* left,
@ -3257,7 +3259,6 @@ class HDiv: public HArithmeticBinaryOperation {
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
static HInstruction* NewHDiv(Zone* zone,
HValue* context,
HValue* left,

View File

@ -2067,13 +2067,9 @@ void HGraph::InsertRepresentationChanges() {
for (int i = 0; i < phi_list()->length(); i++) {
HPhi* phi = phi_list()->at(i);
if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue;
for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
HValue* use = it.value();
if (!use->CheckFlag(HValue::kTruncatingToInt32)) {
phi->ClearFlag(HValue::kTruncatingToInt32);
change = true;
break;
}
if (!phi->CheckUsesForFlag(HValue::kTruncatingToInt32)) {
phi->ClearFlag(HValue::kTruncatingToInt32);
change = true;
}
}
}