Enable inlining for Math.min/max in more cases.
Review URL: https://chromiumcodereview.appspot.com/9372021 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10755 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8d4d655620
commit
30bcc481e1
@ -5361,33 +5361,44 @@ bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr,
|
||||
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.
|
||||
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());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(left_operand->representation().Equals(
|
||||
right_operand->representation()));
|
||||
ASSERT(!left_operand->representation().IsTagged());
|
||||
|
||||
Token::Value op = (id == kMathMin) ? Token::LT : Token::GT;
|
||||
|
||||
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();
|
||||
|
||||
|
@ -146,6 +146,14 @@ function crankshaft_test_1(arg) {
|
||||
// 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));
|
||||
|
Loading…
Reference in New Issue
Block a user