Reviewers: Vyacheslav Egorov,

Description:
Insert representation changes before doing range analysis and fix a bug in
Range::Copy.

This improves our static type information by calculating the result type
of conversions (HChange) during range analysis. It allows e.g. to eliminate
the write barrier in the following example where it was not possible before:

function f(x) {
  var y = x + 1;
  if (y > 0 && y < 100) {
    a[0] = y;
  }
}


* Fix bug in Range::Copy. The minus-zero flags has to be preserved by default.

Please review this at http://codereview.chromium.org/7634022/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/hydrogen-instructions.h
  M     src/hydrogen-instructions.cc
  M     src/hydrogen.cc


Index: src/hydrogen-instructions.cc
===================================================================
--- src/hydrogen-instructions.cc        (revision 8984)
+++ src/hydrogen-instructions.cc        (working copy)
@@ -641,6 +641,7 @@
   length()->PrintNameTo(stream);
 }

+
 void HCallConstantFunction::PrintDataTo(StringStream* stream) {
   if (IsApplyFunction()) {
     stream->Add("optimized apply ");
@@ -875,6 +876,17 @@
 }


+Range* HChange::InferRange() {
+  Range* input_range = value()->range();
+  if (from().IsInteger32() &&
+      to().IsTagged() &&
+      input_range != NULL && input_range->IsInSmiRange()) {
+    set_type(HType::Smi());
+  }
+  return input_range != NULL ? input_range->Copy() : HValue::InferRange();
+}
+
+
 Range* HConstant::InferRange() {
   if (has_int32_value_) {
     Range* result = new Range(int32_value_, int32_value_);
@@ -1220,6 +1232,7 @@
           ? left()->range()->Copy()
           : new Range();
       result->Sar(c->Integer32Value());
+      result->set_can_be_minus_zero(false);
       return result;
     }
   }
@@ -1243,6 +1256,7 @@
             ? left()->range()->Copy()
             : new Range();
         result->Sar(c->Integer32Value());
+        result->set_can_be_minus_zero(false);
         return result;
       }
     }
@@ -1259,6 +1273,7 @@
           ? left()->range()->Copy()
           : new Range();
       result->Shl(c->Integer32Value());
+      result->set_can_be_minus_zero(false);
       return result;
     }
   }
Index: src/hydrogen-instructions.h
===================================================================
--- src/hydrogen-instructions.h (revision 8984)
+++ src/hydrogen-instructions.h (working copy)
@@ -227,14 +227,20 @@
   Range* next() const { return next_; }
   Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
   Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
-  Range* Copy() const { return new Range(lower_, upper_); }
+  Range* Copy() const {
+    Range* result = new Range(lower_, upper_);
+    result->set_can_be_minus_zero(CanBeMinusZero());
+    return result;
+  }
   int32_t Mask() const;
   void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
   bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
   bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
   bool CanBeNegative() const { return lower_ < 0; }
bool Includes(int value) const { return lower_ <= value && upper_ >= value; } - bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
+  bool IsMostGeneric() const {
+    return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
+  }
   bool IsInSmiRange() const {
     return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
   }
@@ -578,9 +584,9 @@
   virtual bool IsConvertibleToInteger() const { return true; }

   HType type() const { return type_; }
-  void set_type(HType type) {
-    ASSERT(HasNoUses());
-    type_ = type;
+  void set_type(HType new_type) {
+    ASSERT(new_type.IsSubtypeOf(type_));
+    type_ = new_type;
   }

   // An operation needs to override this function iff:
@@ -1100,10 +1106,6 @@
     set_representation(to);
     SetFlag(kUseGVN);
     if (is_truncating) SetFlag(kTruncatingToInt32);
-    if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
-        value->range()->IsInSmiRange()) {
-      set_type(HType::Smi());
-    }
   }

   virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
@@ -1115,6 +1117,8 @@
     return from_;
   }

+  virtual Range* InferRange();
+
   virtual void PrintDataTo(StringStream* stream);

   DECLARE_CONCRETE_INSTRUCTION(Change)
Index: src/hydrogen.cc
===================================================================
--- src/hydrogen.cc     (revision 8984)
+++ src/hydrogen.cc     (working copy)
@@ -2325,15 +2325,15 @@
   HInferRepresentation rep(graph());
   rep.Analyze();

+  graph()->InsertRepresentationChanges();
+
   if (FLAG_use_range) {
     HRangeAnalysis rangeAnalysis(graph());
     rangeAnalysis.Analyze();
   }
-
   graph()->InitializeInferredTypes();
   graph()->Canonicalize();
   graph()->MarkDeoptimizeOnUndefined();
-  graph()->InsertRepresentationChanges();
   graph()->ComputeMinusZeroChecks();

   // Eliminate redundant stack checks on backwards branches.


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to