Cleaned up nil comparisons in Hydrogen.

This consists basically of 2 parts:

   * Restructured BuildCompareNil to make the logic behind it clearer.
     Note that it is intentionally written in a quite stylized way.

   * Replaced a usesless IfBuilder by a plain HInstruction, removing
     some empty blocks.

R=danno@chromium.org

Review URL: https://codereview.chromium.org/22305004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16266 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
svenpanne@chromium.org 2013-08-22 06:44:34 +00:00
parent 3e8effb0bd
commit 40f81949d3

View File

@ -1745,22 +1745,35 @@ void HGraphBuilder::BuildCompareNil(
int position, int position,
HIfContinuation* continuation) { HIfContinuation* continuation) {
IfBuilder if_nil(this, position); IfBuilder if_nil(this, position);
bool needs_or = false; bool some_case_handled = false;
bool some_case_missing = false;
if (type->Maybe(Type::Null())) { if (type->Maybe(Type::Null())) {
if (needs_or) if_nil.Or(); if (some_case_handled) if_nil.Or();
if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull()); if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
needs_or = true; some_case_handled = true;
} else {
some_case_missing = true;
} }
if (type->Maybe(Type::Undefined())) { if (type->Maybe(Type::Undefined())) {
if (needs_or) if_nil.Or(); if (some_case_handled) if_nil.Or();
if_nil.If<HCompareObjectEqAndBranch>(value, if_nil.If<HCompareObjectEqAndBranch>(value,
graph()->GetConstantUndefined()); graph()->GetConstantUndefined());
needs_or = true; some_case_handled = true;
}
if (type->Maybe(Type::Undetectable())) {
if (needs_or) if_nil.Or();
if_nil.If<HIsUndetectableAndBranch>(value);
} else { } else {
some_case_missing = true;
}
if (type->Maybe(Type::Undetectable())) {
if (some_case_handled) if_nil.Or();
if_nil.If<HIsUndetectableAndBranch>(value);
some_case_handled = true;
} else {
some_case_missing = true;
}
if (some_case_missing) {
if_nil.Then(); if_nil.Then();
if_nil.Else(); if_nil.Else();
if (type->NumClasses() == 1) { if (type->NumClasses() == 1) {
@ -8209,21 +8222,23 @@ void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
CHECK_ALIVE(VisitForValue(sub_expr)); CHECK_ALIVE(VisitForValue(sub_expr));
HValue* value = Pop(); HValue* value = Pop();
HIfContinuation continuation;
if (expr->op() == Token::EQ_STRICT) { if (expr->op() == Token::EQ_STRICT) {
IfBuilder if_nil(this); HConstant* nil_constant = nil == kNullValue
if_nil.If<HCompareObjectEqAndBranch>( ? graph()->GetConstantNull()
value, (nil == kNullValue) ? graph()->GetConstantNull() : graph()->GetConstantUndefined();
: graph()->GetConstantUndefined()); HCompareObjectEqAndBranch* instr =
if_nil.Then(); New<HCompareObjectEqAndBranch>(value, nil_constant);
if_nil.Else(); instr->set_position(expr->position());
if_nil.CaptureContinuation(&continuation); return ast_context()->ReturnControl(instr, expr->id());
} else {
ASSERT_EQ(Token::EQ, expr->op());
Handle<Type> type = expr->combined_type()->Is(Type::None())
? handle(Type::Any(), isolate_)
: expr->combined_type();
HIfContinuation continuation;
BuildCompareNil(value, type, expr->position(), &continuation);
return ast_context()->ReturnContinuation(&continuation, expr->id()); return ast_context()->ReturnContinuation(&continuation, expr->id());
} }
Handle<Type> type = expr->combined_type()->Is(Type::None())
? handle(Type::Any(), isolate_) : expr->combined_type();
BuildCompareNil(value, type, expr->position(), &continuation);
return ast_context()->ReturnContinuation(&continuation, expr->id());
} }