Mark all loop conditions.

Previously we marked compare operations that occurred as for loop
conditions so as to avoid inlining the floating-point code for them.
Begin marking all expressions that occur as any loop condition
(because they are never dead code).

Review URL: http://codereview.chromium.org/1074009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4227 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4d1f8cbf
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -725,8 +725,7 @@ CompareOperation::CompareOperation(CompareOperation* other, ...@@ -725,8 +725,7 @@ CompareOperation::CompareOperation(CompareOperation* other,
: Expression(other), : Expression(other),
op_(other->op_), op_(other->op_),
left_(left), left_(left),
right_(right), right_(right) {}
is_for_loop_condition_(other->is_for_loop_condition_) {}
Expression* CopyAstVisitor::DeepCopyExpr(Expression* expr) { Expression* CopyAstVisitor::DeepCopyExpr(Expression* expr) {
......
...@@ -239,6 +239,15 @@ class Expression: public AstNode { ...@@ -239,6 +239,15 @@ class Expression: public AstNode {
// Static type information for this expression. // Static type information for this expression.
StaticType* type() { return &type_; } StaticType* type() { return &type_; }
// True if the expression is a loop condition.
bool is_loop_condition() const {
return LoopConditionField::decode(bitfields_);
}
void set_is_loop_condition(bool flag) {
bitfields_ = (bitfields_ & ~LoopConditionField::mask()) |
LoopConditionField::encode(flag);
}
// AST analysis results // AST analysis results
// True if the expression rooted at this node can be compiled by the // True if the expression rooted at this node can be compiled by the
...@@ -285,6 +294,7 @@ class Expression: public AstNode { ...@@ -285,6 +294,7 @@ class Expression: public AstNode {
class NoNegativeZeroField : public BitField<bool, 1, 1> {}; class NoNegativeZeroField : public BitField<bool, 1, 1> {};
class ToInt32Field : public BitField<bool, 2, 1> {}; class ToInt32Field : public BitField<bool, 2, 1> {};
class NumBitOpsField : public BitField<int, 3, 5> {}; class NumBitOpsField : public BitField<int, 3, 5> {};
class LoopConditionField: public BitField<bool, 8, 1> {};
}; };
...@@ -1428,7 +1438,7 @@ class CountOperation: public Expression { ...@@ -1428,7 +1438,7 @@ class CountOperation: public Expression {
class CompareOperation: public Expression { class CompareOperation: public Expression {
public: public:
CompareOperation(Token::Value op, Expression* left, Expression* right) CompareOperation(Token::Value op, Expression* left, Expression* right)
: op_(op), left_(left), right_(right), is_for_loop_condition_(false) { : op_(op), left_(left), right_(right) {
ASSERT(Token::IsCompareOp(op)); ASSERT(Token::IsCompareOp(op));
} }
...@@ -1444,10 +1454,6 @@ class CompareOperation: public Expression { ...@@ -1444,10 +1454,6 @@ class CompareOperation: public Expression {
Expression* left() const { return left_; } Expression* left() const { return left_; }
Expression* right() const { return right_; } Expression* right() const { return right_; }
// Accessors for flag whether this compare operation is hanging of a for loop.
bool is_for_loop_condition() const { return is_for_loop_condition_; }
void set_is_for_loop_condition() { is_for_loop_condition_ = true; }
// Type testing & conversion // Type testing & conversion
virtual CompareOperation* AsCompareOperation() { return this; } virtual CompareOperation* AsCompareOperation() { return this; }
...@@ -1455,7 +1461,6 @@ class CompareOperation: public Expression { ...@@ -1455,7 +1461,6 @@ class CompareOperation: public Expression {
Token::Value op_; Token::Value op_;
Expression* left_; Expression* left_;
Expression* right_; Expression* right_;
bool is_for_loop_condition_;
}; };
......
...@@ -2472,11 +2472,11 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2472,11 +2472,11 @@ void CodeGenerator::Comparison(AstNode* node,
__ test(left_side.reg(), Immediate(kSmiTagMask)); __ test(left_side.reg(), Immediate(kSmiTagMask));
is_smi.Branch(zero, taken); is_smi.Branch(zero, taken);
bool is_for_loop_compare = (node->AsCompareOperation() != NULL) bool is_loop_condition = (node->AsExpression() != NULL) &&
&& node->AsCompareOperation()->is_for_loop_condition(); node->AsExpression()->is_loop_condition();
if (!is_for_loop_compare if (!is_loop_condition &&
&& CpuFeatures::IsSupported(SSE2) CpuFeatures::IsSupported(SSE2) &&
&& right_val->IsSmi()) { right_val->IsSmi()) {
// Right side is a constant smi and left side has been checked // Right side is a constant smi and left side has been checked
// not to be a smi. // not to be a smi.
CpuFeatures::Scope use_sse2(SSE2); CpuFeatures::Scope use_sse2(SSE2);
...@@ -2720,11 +2720,10 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -2720,11 +2720,10 @@ void CodeGenerator::Comparison(AstNode* node,
// with smi's (not heap numbers) and the code to comparing smi's is inlined // with smi's (not heap numbers) and the code to comparing smi's is inlined
// separately. The same reason applies for for-loop comparison which will // separately. The same reason applies for for-loop comparison which will
// also most likely be smi comparisons. // also most likely be smi comparisons.
bool is_for_loop_compare = (node->AsCompareOperation() != NULL) bool is_loop_condition = (node->AsExpression() != NULL)
&& node->AsCompareOperation()->is_for_loop_condition(); && node->AsExpression()->is_loop_condition();
bool inline_number_compare = loop_nesting() > 0 bool inline_number_compare =
&& cc != equal loop_nesting() > 0 && cc != equal && !is_loop_condition;
&& !is_for_loop_compare;
// Left and right needed in registers for the following code. // Left and right needed in registers for the following code.
left_side.ToRegister(); left_side.ToRegister();
......
// Copyright 2006-2008 the V8 project authors. All rights reserved. // Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -2645,6 +2645,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, ...@@ -2645,6 +2645,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
} }
Expression* cond = ParseExpression(true, CHECK_OK); Expression* cond = ParseExpression(true, CHECK_OK);
if (cond != NULL) cond->set_is_loop_condition(true);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
// Allow do-statements to be terminated with and without // Allow do-statements to be terminated with and without
...@@ -2671,6 +2672,7 @@ WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { ...@@ -2671,6 +2672,7 @@ WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
Expect(Token::WHILE, CHECK_OK); Expect(Token::WHILE, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
Expression* cond = ParseExpression(true, CHECK_OK); Expression* cond = ParseExpression(true, CHECK_OK);
if (cond != NULL) cond->set_is_loop_condition(true);
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Statement* body = ParseStatement(NULL, CHECK_OK); Statement* body = ParseStatement(NULL, CHECK_OK);
...@@ -2764,9 +2766,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { ...@@ -2764,9 +2766,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Expression* cond = NULL; Expression* cond = NULL;
if (peek() != Token::SEMICOLON) { if (peek() != Token::SEMICOLON) {
cond = ParseExpression(true, CHECK_OK); cond = ParseExpression(true, CHECK_OK);
if (cond && cond->AsCompareOperation()) { if (cond != NULL) cond->set_is_loop_condition(true);
cond->AsCompareOperation()->set_is_for_loop_condition();
}
} }
Expect(Token::SEMICOLON, CHECK_OK); Expect(Token::SEMICOLON, CHECK_OK);
......
...@@ -5067,9 +5067,9 @@ void CodeGenerator::Comparison(AstNode* node, ...@@ -5067,9 +5067,9 @@ void CodeGenerator::Comparison(AstNode* node,
Condition left_is_smi = masm_->CheckSmi(left_side.reg()); Condition left_is_smi = masm_->CheckSmi(left_side.reg());
is_smi.Branch(left_is_smi); is_smi.Branch(left_is_smi);
bool is_for_loop_compare = (node->AsCompareOperation() != NULL) bool is_loop_condition = (node->AsExpression() != NULL) &&
&& node->AsCompareOperation()->is_for_loop_condition(); node->AsExpression()->is_loop_condition();
if (!is_for_loop_compare && right_val->IsSmi()) { if (!is_loop_condition && right_val->IsSmi()) {
// Right side is a constant smi and left side has been checked // Right side is a constant smi and left side has been checked
// not to be a smi. // not to be a smi.
JumpTarget not_number; JumpTarget not_number;
......
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