Revision: 11737
Author:   [email protected]
Date:     Fri Jun  8 02:21:23 2012
Log:      Improve representation inference

- Extend HValue interface to allow splitting observed input representation (comming from type feedback) from required input representation (dictated by instruction itself). Currently all instructions except for bitwise binary operations have this representations match. For bitwise binary operations hydrogen builder unconditionaly forces Integer32 representation for those operations that have Double type feedback. Thus causing representation inference to incorrectly count such uses as Integer32 instead of Double. This change also prepares for more fine grained type feedback for inputs of binary operations.

- For phies that are not convertable to Integer32 discard direct and indirect use count of Integer32 type to avoid propagation of these uses to connected phies.

[email protected]
BUG=v8:2096

Review URL: https://chromiumcodereview.appspot.com/10540049
http://code.google.com/p/v8/source/detail?r=11737

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 Wed May 23 07:24:29 2012 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Jun 8 02:21:23 2012
@@ -1298,14 +1298,33 @@
   for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
     HValue* value = it.value();
     if (!value->IsPhi()) {
-      Representation rep = value->RequiredInputRepresentation(it.index());
+      Representation rep = value->ObservedInputRepresentation(it.index());
       non_phi_uses_[rep.kind()] += value->LoopWeight();
+      if (FLAG_trace_representation) {
+        PrintF("%d %s is used by %d %s as %s\n",
+               this->id(),
+               this->Mnemonic(),
+               value->id(),
+               value->Mnemonic(),
+               rep.Mnemonic());
+      }
     }
   }
 }


 void HPhi::AddNonPhiUsesFrom(HPhi* other) {
+  if (FLAG_trace_representation) {
+    PrintF("adding to %d %s uses of %d %s: i%d d%d t%d\n",
+           this->id(),
+           this->Mnemonic(),
+           other->id(),
+           other->Mnemonic(),
+           other->non_phi_uses_[Representation::kInteger32],
+           other->non_phi_uses_[Representation::kDouble],
+           other->non_phi_uses_[Representation::kTagged]);
+  }
+
   for (int i = 0; i < Representation::kNumRepresentations; i++) {
     indirect_uses_[i] += other->non_phi_uses_[i];
   }
@@ -1317,6 +1336,12 @@
     dest[i] += indirect_uses_[i];
   }
 }
+
+
+void HPhi::ResetInteger32Uses() {
+  non_phi_uses_[Representation::kInteger32] = 0;
+  indirect_uses_[Representation::kInteger32] = 0;
+}


 void HSimulate::PrintDataTo(StringStream* stream) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue May 29 09:39:26 2012 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Jun 8 02:21:23 2012
@@ -719,6 +719,11 @@
   virtual Representation InferredRepresentation() {
     return representation();
   }
+
+  // Type feedback access.
+  virtual Representation ObservedInputRepresentation(int index) {
+    return RequiredInputRepresentation(index);
+  }

   // This gives the instruction an opportunity to replace itself with an
   // instruction that does the same in some better way.  To replace an
@@ -2402,10 +2407,14 @@

   bool AllOperandsConvertibleToInteger() {
     for (int i = 0; i < OperandCount(); ++i) {
-      if (!OperandAt(i)->IsConvertibleToInteger()) return false;
+      if (!OperandAt(i)->IsConvertibleToInteger()) {
+        return false;
+      }
     }
     return true;
   }
+
+  void ResetInteger32Uses();

  protected:
   virtual void DeleteFromGraph();
@@ -2556,6 +2565,7 @@
     if (IsCommutative() && left()->IsConstant()) return right();
     return left();
   }
+
   HValue* MostConstantOperand() {
     if (IsCommutative() && left()->IsConstant()) return left();
     return right();
@@ -2721,6 +2731,9 @@
     set_representation(Representation::Tagged());
     SetFlag(kFlexibleRepresentation);
     SetAllSideEffects();
+    observed_input_representation_[0] = Representation::Tagged();
+    observed_input_representation_[1] = Representation::None();
+    observed_input_representation_[2] = Representation::None();
   }

   virtual Representation RequiredInputRepresentation(int index) {
@@ -2740,7 +2753,19 @@

   virtual HType CalculateInferredType();

+  virtual Representation ObservedInputRepresentation(int index) {
+    return observed_input_representation_[index];
+  }
+
+  void InitializeObservedInputRepresentation(Representation r) {
+    observed_input_representation_[1] = r;
+    observed_input_representation_[2] = r;
+  }
+
   DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
+
+ private:
+  Representation observed_input_representation_[3];
 };


=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Tue Jun  5 09:56:53 2012
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Jun  8 02:21:23 2012
@@ -2140,8 +2140,16 @@

   for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
     HValue* use = it.value();
-    Representation rep = use->RequiredInputRepresentation(it.index());
+    Representation rep = use->ObservedInputRepresentation(it.index());
     if (rep.IsNone()) continue;
+    if (FLAG_trace_representation) {
+      PrintF("%d %s is used by %d %s as %s\n",
+             value->id(),
+             value->Mnemonic(),
+             use->id(),
+             use->Mnemonic(),
+             rep.Mnemonic());
+    }
     if (use->IsPhi()) HPhi::cast(use)->AddIndirectUsesTo(&use_count[0]);
     use_count[rep.kind()] += use->LoopWeight();
   }
@@ -2205,21 +2213,34 @@
     }
   }

-  // (3) Use the phi reachability information from step 2 to
-  //     (a) sum up the non-phi use counts of all connected phis.
- // (b) push information about values which can't be converted to integer - // without deoptimization through the phi use-def chains, avoiding
-  //         unnecessary deoptimizations later.
+  // (3a) Use the phi reachability information from step 2 to
+  // push information about values which can't be converted to integer
+  // without deoptimization through the phi use-def chains, avoiding
+  // unnecessary deoptimizations later.
   for (int i = 0; i < phi_count; ++i) {
     HPhi* phi = phi_list->at(i);
     bool cti = phi->AllOperandsConvertibleToInteger();
+    if (cti) continue;
+
     for (BitVector::Iterator it(connected_phis.at(i));
          !it.Done();
+         it.Advance()) {
+      HPhi* phi = phi_list->at(it.Current());
+      phi->set_is_convertible_to_integer(false);
+      phi->ResetInteger32Uses();
+    }
+  }
+
+  // (3b) Use the phi reachability information from step 2 to
+  // sum up the non-phi use counts of all connected phis.
+  for (int i = 0; i < phi_count; ++i) {
+    HPhi* phi = phi_list->at(i);
+    for (BitVector::Iterator it(connected_phis.at(i));
+         !it.Done();
          it.Advance()) {
       int index = it.Current();
-      HPhi* it_use = phi_list->at(it.Current());
- if (index != i) phi->AddNonPhiUsesFrom(it_use); // Don't count twice!
-      if (!cti) it_use->set_is_convertible_to_integer(false);
+      HPhi* it_use = phi_list->at(index);
+ if (index != i) phi->AddNonPhiUsesFrom(it_use); // Don't count twice.
     }
   }

@@ -7503,8 +7524,10 @@
   }
   Representation rep = ToRepresentation(info);
   // We only generate either int32 or generic tagged bitwise operations.
-  if (instr->IsBitwiseBinaryOperation() && rep.IsDouble()) {
-    rep = Representation::Integer32();
+  if (instr->IsBitwiseBinaryOperation()) {
+    HBitwiseBinaryOperation::cast(instr)->
+         InitializeObservedInputRepresentation(rep);
+    if (rep.IsDouble()) rep = Representation::Integer32();
   }
   TraceRepresentation(expr->op(), info, instr, rep);
   instr->AssumeRepresentation(rep);

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

Reply via email to