Commit 7abbd298 authored by whesse@chromium.org's avatar whesse@chromium.org

Add static analysis to AST expressions that records whether a negative zero...

Add static analysis to AST expressions that records whether a negative zero will be treated identically to a positive zero in the expression's context.  Use this flag to avoid some tests in inlined smi code.
Review URL: http://codereview.chromium.org/965001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4130 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c2dc3161
......@@ -251,6 +251,14 @@ class Expression: public AstNode {
bitfields_ |= SideEffectFreeField::encode(is_side_effect_free);
}
// Will the use of this expression treat -0 the same as 0 in all cases?
// If so, we can return 0 instead of -0 if we want to, to optimize code.
bool no_negative_zero() { return NoNegativeZeroField::decode(bitfields_); }
void set_no_negative_zero(bool no_negative_zero) {
bitfields_ &= ~NoNegativeZeroField::mask();
bitfields_ |= NoNegativeZeroField::encode(no_negative_zero);
}
// Will ToInt32 (ECMA 262-3 9.5) or ToUint32 (ECMA 262-3 9.6)
// be applied to the value of this expression?
// If so, we may be able to optimize the calculation of the value.
......@@ -270,7 +278,8 @@ class Expression: public AstNode {
// Using template BitField<type, start, size>.
class SideEffectFreeField : public BitField<bool, 0, 1> {};
class ToInt32Field : public BitField<bool, 1, 1> {};
class NoNegativeZeroField : public BitField<bool, 1, 1> {};
class ToInt32Field : public BitField<bool, 2, 1> {};
};
......
This diff is collapsed.
......@@ -469,7 +469,8 @@ class CodeGenerator: public AstVisitor {
void GenericBinaryOperation(
Token::Value op,
StaticType* type,
OverwriteMode overwrite_mode);
OverwriteMode overwrite_mode,
bool no_negative_zero);
// If possible, combine two constant smi values using op to produce
// a smi result, and push it on the virtual frame, all at compile time.
......@@ -483,7 +484,8 @@ class CodeGenerator: public AstVisitor {
Handle<Object> constant_operand,
StaticType* type,
bool reversed,
OverwriteMode overwrite_mode);
OverwriteMode overwrite_mode,
bool no_negative_zero);
// Emit code to perform a binary operation on two likely smis.
// The code to handle smi arguments is produced inline.
......@@ -491,7 +493,8 @@ class CodeGenerator: public AstVisitor {
Result LikelySmiBinaryOperation(Token::Value op,
Result* left,
Result* right,
OverwriteMode overwrite_mode);
OverwriteMode overwrite_mode,
bool no_negative_zero);
void Comparison(AstNode* node,
Condition cc,
......
......@@ -220,6 +220,7 @@ void AstOptimizer::VisitFunctionBoilerplateLiteral(
void AstOptimizer::VisitConditional(Conditional* node) {
node->condition()->set_no_negative_zero(true);
Visit(node->condition());
Visit(node->then_expression());
Visit(node->else_expression());
......@@ -319,6 +320,7 @@ void AstOptimizer::VisitAssignment(Assignment* node) {
node->type()->SetAsLikelySmiIfUnknown();
node->target()->type()->SetAsLikelySmiIfUnknown();
node->value()->type()->SetAsLikelySmiIfUnknown();
node->value()->set_no_negative_zero(true);
break;
case Token::ASSIGN_ADD:
case Token::ASSIGN_SUB:
......@@ -393,6 +395,7 @@ void AstOptimizer::VisitThrow(Throw* node) {
void AstOptimizer::VisitProperty(Property* node) {
node->key()->set_no_negative_zero(true);
Visit(node->obj());
Visit(node->key());
}
......@@ -422,6 +425,11 @@ void AstOptimizer::VisitCallRuntime(CallRuntime* node) {
void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
if (node->op() == Token::ADD || node->op() == Token::SUB) {
node->expression()->set_no_negative_zero(node->no_negative_zero());
} else {
node->expression()->set_no_negative_zero(true);
}
Visit(node->expression());
if (FLAG_safe_int32_compiler) {
switch (node->op()) {
......@@ -449,6 +457,9 @@ void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
void AstOptimizer::VisitCountOperation(CountOperation* node) {
// Count operations assume that they work on Smis.
node->expression()->set_no_negative_zero(node->is_prefix() ?
true :
node->no_negative_zero());
node->type()->SetAsLikelySmiIfUnknown();
node->expression()->type()->SetAsLikelySmiIfUnknown();
Visit(node->expression());
......@@ -461,7 +472,12 @@ void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
switch (node->op()) {
case Token::COMMA:
case Token::OR:
node->left()->set_no_negative_zero(true);
node->right()->set_no_negative_zero(node->no_negative_zero());
break;
case Token::AND:
node->left()->set_no_negative_zero(node->no_negative_zero());
node->right()->set_no_negative_zero(node->no_negative_zero());
break;
case Token::BIT_OR:
case Token::BIT_XOR:
......@@ -474,6 +490,8 @@ void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
node->right()->type()->SetAsLikelySmiIfUnknown();
node->left()->set_to_int32(true);
node->right()->set_to_int32(true);
node->left()->set_no_negative_zero(true);
node->right()->set_no_negative_zero(true);
break;
case Token::ADD:
case Token::SUB:
......@@ -484,6 +502,13 @@ void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
node->left()->type()->SetAsLikelySmiIfUnknown();
node->right()->type()->SetAsLikelySmiIfUnknown();
}
node->left()->set_no_negative_zero(node->no_negative_zero());
node->right()->set_no_negative_zero(node->no_negative_zero());
if (node->op() == Token::DIV) {
node->right()->set_no_negative_zero(false);
} else if (node->op() == Token::MOD) {
node->right()->set_no_negative_zero(true);
}
break;
default:
UNREACHABLE();
......@@ -551,6 +576,10 @@ void AstOptimizer::VisitCompareOperation(CompareOperation* node) {
node->right()->type()->SetAsLikelySmiIfUnknown();
}
node->left()->set_no_negative_zero(true);
// Only [[HasInstance]] has the right argument passed unchanged to it.
node->right()->set_no_negative_zero(true);
Visit(node->left());
Visit(node->right());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment