Revision: 21899
Author:   [email protected]
Date:     Fri Jun 20 11:26:17 2014 UTC
Log:      ARM: Avoid duplicate vmla when merging vmul and vadd

Avoid generating duplicate vmla instructions for vmul/vadd sequences where the
vmul has more than one use.

For example: function f(a, b, c) { return (a * b) + c + (a * b); }

Previously, this would produce a vmul for the subexpression (a * b), then vmla
for (a * b) + c, then vmla for (a * b) + [(a * b) + c].

Now it produces vmul, vadd, vadd, as expected.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/323423003
http://code.google.com/p/v8/source/detail?r=21899

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

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Fri Jun 20 08:40:11 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.cc Fri Jun 20 11:26:17 2014 UTC
@@ -1500,8 +1500,8 @@
     return DefineAsRegister(mul);

   } else if (instr->representation().IsDouble()) {
-    if (instr->UseCount() == 1 && (instr->uses().value()->IsAdd() ||
-                                   instr->uses().value()->IsSub())) {
+    if (instr->HasOneUse() && (instr->uses().value()->IsAdd() ||
+                               instr->uses().value()->IsSub())) {
HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value());

       if (use->IsAdd() && instr == use->left()) {
@@ -1547,7 +1547,7 @@
     }
     return result;
   } else if (instr->representation().IsDouble()) {
-    if (instr->right()->IsMul()) {
+    if (instr->right()->IsMul() && instr->right()->HasOneUse()) {
       return DoMultiplySub(instr->left(), HMul::cast(instr->right()));
     }

@@ -1618,12 +1618,12 @@
     LInstruction* result = DefineAsRegister(add);
     return result;
   } else if (instr->representation().IsDouble()) {
-    if (instr->left()->IsMul()) {
+    if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
       return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
     }

-    if (instr->right()->IsMul()) {
-      ASSERT(!instr->left()->IsMul());
+    if (instr->right()->IsMul() && instr->right()->HasOneUse()) {
+      ASSERT(!instr->left()->IsMul() || !instr->left()->HasOneUse());
       return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
     }

=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Jun 20 08:40:11 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Jun 20 11:26:17 2014 UTC
@@ -1581,7 +1581,7 @@
           val, representation(), false, false));
     }
   }
-  if (op() == kMathFloor && value()->IsDiv() && value()->UseCount() == 1) {
+  if (op() == kMathFloor && value()->IsDiv() && value()->HasOneUse()) {
     HDiv* hdiv = HDiv::cast(value());

     HValue* left = hdiv->left();
@@ -2149,7 +2149,7 @@
   added_index()->SetOperandAt(1, index_base);
   added_index()->SetOperandAt(2, added_constant());
   first_check_in_block()->SetOperandAt(0, added_index());
-  if (previous_index->UseCount() == 0) {
+  if (previous_index->HasNoUses()) {
     previous_index->DeleteAndReplaceWith(NULL);
   }
 }
@@ -2893,7 +2893,7 @@
// TODO(titzer): this seems like a hack that should be fixed by custom OSR.
     return true;
   }
-  if (UseCount() == 0) return true;
+  if (HasNoUses()) return true;
   if (IsCell()) return false;
   if (representation().IsDouble()) return false;
   if (representation().IsExternal()) return false;
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Mon Jun 16 13:03:59 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Jun 20 11:26:17 2014 UTC
@@ -663,6 +663,9 @@
   void DeleteAndReplaceWith(HValue* other);
   void ReplaceAllUsesWith(HValue* other);
   bool HasNoUses() const { return use_list_ == NULL; }
+  bool HasOneUse() const {
+    return use_list_ != NULL && use_list_->tail() == NULL;
+  }
   bool HasMultipleUses() const {
     return use_list_ != NULL && use_list_->tail() != NULL;
   }
@@ -3760,7 +3763,7 @@
// Otherwise, if there is only one use of the right operand, it would be
     // better off on the left for platforms that only have 2-arg arithmetic
     // ops (e.g ia32, x64) that clobber the left operand.
-    return right()->UseCount() == 1;
+    return right()->HasOneUse();
   }

   HValue* BetterLeftOperand() {
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Fri Jun 20 08:40:11 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Fri Jun 20 11:26:17 2014 UTC
@@ -1492,7 +1492,7 @@

   } else if (instr->representation().IsDouble()) {
     if (kArchVariant == kMips32r2) {
-      if (instr->UseCount() == 1 && instr->uses().value()->IsAdd()) {
+      if (instr->HasOneUse() && instr->uses().value()->IsAdd()) {
         HAdd* add = HAdd::cast(instr->uses().value());
         if (instr == add->left()) {
           // This mul is the lhs of an add. The add and mul will be folded

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to