Revision: 10755
Author:   [email protected]
Date:     Mon Feb 20 05:21:15 2012
Log:      Enable inlining for Math.min/max in more cases.

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

Modified:
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/test/mjsunit/math-min-max.js

=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Thu Feb 16 09:32:30 2012
+++ /branches/bleeding_edge/src/hydrogen.cc     Mon Feb 20 05:21:15 2012
@@ -5361,32 +5361,43 @@
         AddCheckConstantFunction(expr, receiver, receiver_map, true);
         HValue* right = Pop();
         HValue* left = Pop();
-        // Do not inline if the return representation is not certain.
-        if (!left->representation().Equals(right->representation())) {
-          Push(left);
-          Push(right);
-          return false;
+        Pop();  // Pop receiver.
+
+        HValue* left_operand = left;
+        HValue* right_operand = right;
+
+ // If we do not have two integers, we convert to double for comparison.
+        if (!left->representation().IsInteger32() ||
+            !right->representation().IsInteger32()) {
+          if (!left->representation().IsDouble()) {
+            HChange* left_convert = new(zone()) HChange(
+                left,
+                Representation::Double(),
+                false,  // Do not truncate when converting to double.
+                true);  // Deoptimize for undefined.
+            left_convert->SetFlag(HValue::kBailoutOnMinusZero);
+            left_operand = AddInstruction(left_convert);
+          }
+          if (!right->representation().IsDouble()) {
+            HChange* right_convert = new(zone()) HChange(
+                right,
+                Representation::Double(),
+                false,  // Do not truncate when converting to double.
+                true);  // Deoptimize for undefined.
+            right_convert->SetFlag(HValue::kBailoutOnMinusZero);
+            right_operand = AddInstruction(right_convert);
+          }
         }

-        Pop();  // Pop receiver.
+        ASSERT(left_operand->representation().Equals(
+               right_operand->representation()));
+        ASSERT(!left_operand->representation().IsTagged());
+
         Token::Value op = (id == kMathMin) ? Token::LT : Token::GT;
-        HCompareIDAndBranch* compare = NULL;
-
-        if (left->representation().IsTagged()) {
-          HChange* left_cvt =
- new(zone()) HChange(left, Representation::Double(), false, true);
-          left_cvt->SetFlag(HValue::kBailoutOnMinusZero);
-          AddInstruction(left_cvt);
-          HChange* right_cvt =
- new(zone()) HChange(right, Representation::Double(), false, true);
-          right_cvt->SetFlag(HValue::kBailoutOnMinusZero);
-          AddInstruction(right_cvt);
- compare = new(zone()) HCompareIDAndBranch(left_cvt, right_cvt, op);
-          compare->SetInputRepresentation(Representation::Double());
-        } else {
-          compare = new(zone()) HCompareIDAndBranch(left, right, op);
-          compare->SetInputRepresentation(left->representation());
-        }
+
+        HCompareIDAndBranch* compare =
+ new(zone()) HCompareIDAndBranch(left_operand, right_operand, op);
+        compare->SetInputRepresentation(left_operand->representation());

         HBasicBlock* return_left = graph()->CreateBasicBlock();
         HBasicBlock* return_right = graph()->CreateBasicBlock();
=======================================
--- /branches/bleeding_edge/test/mjsunit/math-min-max.js Wed Jan 11 07:43:33 2012 +++ /branches/bleeding_edge/test/mjsunit/math-min-max.js Mon Feb 20 05:21:15 2012
@@ -146,6 +146,14 @@
   // Double representation.
   assertEquals(v0, Math.max(v0++, v9++));
   assertEquals(v9, Math.min(v0++, v9++));
+  // Mixed representation.
+  assertEquals(v1, Math.min(v1++, v9++));  // int32, double
+  assertEquals(v0, Math.max(v0++, v2++));  // double, int32
+  assertEquals(v1, Math.min(v1++, v6));    // int32, tagged
+  assertEquals(v2, Math.max(v5, v2++));    // tagged, int32
+  assertEquals(v6, Math.min(v6, v9++));    // tagged, double
+  assertEquals(v0, Math.max(v0++, v5));    // double, tagged
+
   // Minus zero.
   assertEquals(Infinity, 1/Math.max(v7, v8));
   assertEquals(-Infinity, 1/Math.min(v7, v8));

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

Reply via email to