Revision: 8994
Author:   [email protected]
Date:     Tue Aug 23 00:34:45 2011
Log: 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.
Review URL: http://codereview.chromium.org/7634022
http://code.google.com/p/v8/source/detail?r=8994

Modified:
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc

=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Aug 22 07:23:37 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Tue Aug 23 00:34:45 2011
@@ -640,6 +640,7 @@
   stream->Add(" ");
   length()->PrintNameTo(stream);
 }
+

 void HCallConstantFunction::PrintDataTo(StringStream* stream) {
   if (IsApplyFunction()) {
@@ -873,6 +874,21 @@
   result->set_can_be_minus_zero(!representation().IsInteger32());
   return result;
 }
+
+
+Range* HChange::InferRange() {
+  Range* input_range = value()->range();
+  if (from().IsInteger32() &&
+      to().IsTagged() &&
+      input_range != NULL && input_range->IsInSmiRange()) {
+    set_type(HType::Smi());
+  }
+  Range* result = (input_range != NULL)
+      ? input_range->Copy()
+      : HValue::InferRange();
+  if (to().IsInteger32()) result->set_can_be_minus_zero(false);
+  return result;
+}


 Range* HConstant::InferRange() {
@@ -1220,6 +1236,7 @@
           ? left()->range()->Copy()
           : new Range();
       result->Sar(c->Integer32Value());
+      result->set_can_be_minus_zero(false);
       return result;
     }
   }
@@ -1243,6 +1260,7 @@
             ? left()->range()->Copy()
             : new Range();
         result->Sar(c->Integer32Value());
+        result->set_can_be_minus_zero(false);
         return result;
       }
     }
@@ -1259,6 +1277,7 @@
           ? left()->range()->Copy()
           : new Range();
       result->Shl(c->Integer32Value());
+      result->set_can_be_minus_zero(false);
       return result;
     }
   }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Aug 22 07:23:37 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Tue Aug 23 00:34:45 2011
@@ -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);
@@ -1114,6 +1116,8 @@
   virtual Representation RequiredInputRepresentation(int index) const {
     return from_;
   }
+
+  virtual Range* InferRange();

   virtual void PrintDataTo(StringStream* stream);

=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Mon Aug 22 07:23:37 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Tue Aug 23 00:34:45 2011
@@ -2325,15 +2325,15 @@
   HInferRepresentation rep(graph());
   rep.Analyze();

+  graph()->MarkDeoptimizeOnUndefined();
+  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