Eliminate overflow check after integer add and sub operation if result is truncated...
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Feb 2012 13:41:18 +0000 (13:41 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 29 Feb 2012 13:41:18 +0000 (13:41 +0000)
Review URL: https://chromiumcodereview.appspot.com/9286002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10870 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc

index 074054ce1d0c414ce12c6e8230400a1acd798cba..cbe1fb5e7b2770ef7b2ed45065d9f77ae609d4c4 100644 (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;
 }
index c05069ea91f76fc6fcd51f0c5b5868f14ebdbb78..cee90a9df1f6628852519bd73bd395eeaeecd948 100644 (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,
index bc048b336254bb92088d77039e7d23e5e4933d07..ffd3d1e570c737dde7d96f3c98469b6441c45f96 100644 (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;
       }
     }
   }