Avoid creating unnecessary branches in Hydrogen
Review URL: https://codereview.chromium.org/12281019 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13704 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8ef28eb5ee
commit
e93011892e
@ -2784,11 +2784,9 @@ bool HStoreKeyed::NeedsCanonicalization() {
|
|||||||
|
|
||||||
|
|
||||||
#define H_CONSTANT_INT32(val) \
|
#define H_CONSTANT_INT32(val) \
|
||||||
new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \
|
new(zone) HConstant(val, Representation::Integer32())
|
||||||
Representation::Integer32())
|
|
||||||
#define H_CONSTANT_DOUBLE(val) \
|
#define H_CONSTANT_DOUBLE(val) \
|
||||||
new(zone) HConstant(FACTORY->NewNumber(val, TENURED), \
|
new(zone) HConstant(val, Representation::Double())
|
||||||
Representation::Double())
|
|
||||||
|
|
||||||
#define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
|
#define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
|
||||||
HInstruction* HInstr::New##HInstr(Zone* zone, \
|
HInstruction* HInstr::New##HInstr(Zone* zone, \
|
||||||
@ -2933,7 +2931,8 @@ HInstruction* HShr::NewHShr(Zone* zone,
|
|||||||
return H_CONSTANT_DOUBLE(
|
return H_CONSTANT_DOUBLE(
|
||||||
static_cast<double>(static_cast<uint32_t>(left_val)));
|
static_cast<double>(static_cast<uint32_t>(left_val)));
|
||||||
}
|
}
|
||||||
return H_CONSTANT_INT32(static_cast<uint32_t>(left_val) >> right_val);
|
return H_CONSTANT_INT32(static_cast<int32_t>(
|
||||||
|
static_cast<uint32_t>(left_val) >> right_val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(zone) HShr(context, left, right);
|
return new(zone) HShr(context, left, right);
|
||||||
|
@ -3620,6 +3620,16 @@ void TestContext::BuildBranch(HValue* value) {
|
|||||||
if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
|
if (value != NULL && value->CheckFlag(HValue::kIsArguments)) {
|
||||||
builder->Bailout("arguments object value in a test context");
|
builder->Bailout("arguments object value in a test context");
|
||||||
}
|
}
|
||||||
|
if (value->IsConstant()) {
|
||||||
|
HConstant* constant_value = HConstant::cast(value);
|
||||||
|
if (constant_value->ToBoolean()) {
|
||||||
|
builder->current_block()->Goto(if_true(), builder->function_state());
|
||||||
|
} else {
|
||||||
|
builder->current_block()->Goto(if_false(), builder->function_state());
|
||||||
|
}
|
||||||
|
builder->set_current_block(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
|
HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
|
||||||
HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
|
HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
|
||||||
TypeFeedbackId test_id = condition()->test_id();
|
TypeFeedbackId test_id = condition()->test_id();
|
||||||
@ -3627,8 +3637,8 @@ void TestContext::BuildBranch(HValue* value) {
|
|||||||
HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
|
HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
|
||||||
builder->current_block()->Finish(test);
|
builder->current_block()->Finish(test);
|
||||||
|
|
||||||
empty_true->Goto(if_true(), owner()->function_state());
|
empty_true->Goto(if_true(), builder->function_state());
|
||||||
empty_false->Goto(if_false(), owner()->function_state());
|
empty_false->Goto(if_false(), builder->function_state());
|
||||||
builder->set_current_block(NULL);
|
builder->set_current_block(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9037,6 +9047,17 @@ void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
|
|||||||
} else if (ast_context()->IsValue()) {
|
} else if (ast_context()->IsValue()) {
|
||||||
CHECK_ALIVE(VisitForValue(expr->left()));
|
CHECK_ALIVE(VisitForValue(expr->left()));
|
||||||
ASSERT(current_block() != NULL);
|
ASSERT(current_block() != NULL);
|
||||||
|
HValue* left_value = Top();
|
||||||
|
|
||||||
|
if (left_value->IsConstant()) {
|
||||||
|
HConstant* left_constant = HConstant::cast(left_value);
|
||||||
|
if ((is_logical_and && left_constant->ToBoolean()) ||
|
||||||
|
(!is_logical_and && !left_constant->ToBoolean())) {
|
||||||
|
Drop(1); // left_value.
|
||||||
|
CHECK_BAILOUT(VisitForValue(expr->right()));
|
||||||
|
}
|
||||||
|
return ast_context()->ReturnValue(Pop());
|
||||||
|
}
|
||||||
|
|
||||||
// We need an extra block to maintain edge-split form.
|
// We need an extra block to maintain edge-split form.
|
||||||
HBasicBlock* empty_block = graph()->CreateBasicBlock();
|
HBasicBlock* empty_block = graph()->CreateBasicBlock();
|
||||||
@ -9044,8 +9065,8 @@ void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
|
|||||||
TypeFeedbackId test_id = expr->left()->test_id();
|
TypeFeedbackId test_id = expr->left()->test_id();
|
||||||
ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id));
|
ToBooleanStub::Types expected(oracle()->ToBooleanTypes(test_id));
|
||||||
HBranch* test = is_logical_and
|
HBranch* test = is_logical_and
|
||||||
? new(zone()) HBranch(Top(), eval_right, empty_block, expected)
|
? new(zone()) HBranch(left_value, eval_right, empty_block, expected)
|
||||||
: new(zone()) HBranch(Top(), empty_block, eval_right, expected);
|
: new(zone()) HBranch(left_value, empty_block, eval_right, expected);
|
||||||
current_block()->Finish(test);
|
current_block()->Finish(test);
|
||||||
|
|
||||||
set_current_block(eval_right);
|
set_current_block(eval_right);
|
||||||
|
Loading…
Reference in New Issue
Block a user