Reviewers: Jakob,

Description:
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 bitwise 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


Please review this at https://chromiumcodereview.appspot.com/10540049/

SVN Base: https://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
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 57a186280b1713b9d9c65d91d4dc6b7bed2bea0a..e725b38291ac06d49838a91e6c6d1346d1740d82 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1298,14 +1298,33 @@ void HPhi::InitRealUses(int phi_id) {
   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];
   }
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 0f6cb6e473d7454dd9cb1709f3b2faef1f1feaf3..8c8f426485f7b4437401042a3898c77de1f10d68 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -720,6 +720,11 @@ class HValue: public ZoneObject {
     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
// instruction with a new one, first add the new instruction to the graph,
@@ -2398,11 +2403,17 @@ class HPhi: public HValue {

   void set_is_convertible_to_integer(bool b) {
     is_convertible_to_integer_ = b;
+    if (!is_convertible_to_integer_) {
+      non_phi_uses_[Representation::kInteger32] = 0;
+      indirect_uses_[Representation::kInteger32] = 0;
+    }
   }

   bool AllOperandsConvertibleToInteger() {
     for (int i = 0; i < OperandCount(); ++i) {
-      if (!OperandAt(i)->IsConvertibleToInteger()) return false;
+      if (!OperandAt(i)->IsConvertibleToInteger()) {
+        return false;
+      }
     }
     return true;
   }
@@ -2556,6 +2567,7 @@ class HBinaryOperation: public HTemplateInstruction<3> {
     if (IsCommutative() && left()->IsConstant()) return right();
     return left();
   }
+
   HValue* MostConstantOperand() {
     if (IsCommutative() && left()->IsConstant()) return left();
     return right();
@@ -2721,6 +2733,9 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
     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 +2755,18 @@ class HBitwiseBinaryOperation: public HBinaryOperation {

   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];
 };


Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index e2fbfb59c4b6fbf3462ba1343b7e8fcb1354997e..48e43e7741c017f3ead3c79320b8d316ff7f068b 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2140,8 +2140,16 @@ Representation HInferRepresentation::TryChange(HValue* value) {

   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();
   }
@@ -2213,6 +2221,7 @@ void HInferRepresentation::Analyze() {
   for (int i = 0; i < phi_count; ++i) {
     HPhi* phi = phi_list->at(i);
     bool cti = phi->AllOperandsConvertibleToInteger();
+    phi->set_is_convertible_to_integer(false);
     for (BitVector::Iterator it(connected_phis.at(i));
          !it.Done();
          it.Advance()) {
@@ -7503,8 +7512,10 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
   }
   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