Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(502)

Unified Diff: src/hydrogen.cc

Issue 23503058: Hydrogen binop improvements (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix a comment Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index b5cebbe327e10f9612bfd8cdee581ed7fc80b0d2..3ece7bd8e69b32691a9d57b6dec4821c6bbe12df 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -737,7 +737,8 @@ HGraphBuilder::IfBuilder::IfBuilder(
}
-void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
+HControlInstruction* HGraphBuilder::IfBuilder::AddCompare(
+ HControlInstruction* compare) {
if (split_edge_merge_block_ != NULL) {
HEnvironment* env = first_false_block_->last_environment();
HBasicBlock* split_edge =
@@ -756,6 +757,7 @@ void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
}
builder_->current_block()->Finish(compare);
needs_compare_ = false;
+ return compare;
}
@@ -7581,10 +7583,10 @@ static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
// directions that can be replaced by one rotate right instruction or not.
// Returns the operand and the shift amount for the rotate instruction in the
// former case.
-bool HOptimizedGraphBuilder::MatchRotateRight(HValue* left,
- HValue* right,
- HValue** operand,
- HValue** shift_amount) {
+bool HGraphBuilder::MatchRotateRight(HValue* left,
+ HValue* right,
+ HValue** operand,
+ HValue** shift_amount) {
HShl* shl;
HShr* shr;
if (left->IsShl() && right->IsShr()) {
@@ -7620,6 +7622,18 @@ bool CanBeZero(HValue* right) {
}
+HValue* HGraphBuilder::EnforceNumberType(HValue* number,
+ Handle<Type> expected) {
+ if (expected->Is(Type::Smi())) {
+ return Add<HForceRepresentation>(number, Representation::Smi());
+ }
+ if (expected->Is(Type::Signed32())) {
+ return Add<HForceRepresentation>(number, Representation::Integer32());
+ }
+ return number;
+}
+
+
HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
if (value->IsConstant()) {
HConstant* constant = HConstant::cast(value);
@@ -7630,6 +7644,63 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
}
}
+ Handle<Type> expected_type = *expected;
+
+ // Separate the number type from the rest.
+ Handle<Type> expected_obj = handle(Type::Intersect(
+ expected_type, handle(Type::NonNumber(), isolate())), isolate());
+ Handle<Type> expected_number = handle(Type::Intersect(
+ expected_type, handle(Type::Number(), isolate())), isolate());
+
+ // We expect to get a number.
+ // (We need to check first, since Type::None->Is(Type::Any()) == true.
+ if (expected_obj->Is(Type::None())) {
+ ASSERT(!expected_number->Is(Type::None()));
+ return value;
+ }
+
+ if (expected_obj->Is(Type::Undefined())) {
+ // This is already done by HChange.
+ *expected = handle(Type::Union(
+ expected_number, handle(Type::Double(), isolate())), isolate());
+ return value;
+ }
+
+ if (expected_obj->Is(Type::Null())) {
+ *expected = handle(Type::Union(
+ expected_number, handle(Type::Smi(), isolate())), isolate());
+ IfBuilder if_null(this);
+ if_null.If<HCompareObjectEqAndBranch>(value,
+ graph()->GetConstantNull());
+ if_null.Then();
+ Push(graph()->GetConstant0());
+ if_null.Else();
+ Push(value);
+ if_null.End();
+ return Pop();
+ }
+
+ if (expected_obj->Is(Type::Boolean())) {
+ *expected = handle(Type::Union(
+ expected_number, handle(Type::Smi(), isolate())), isolate());
+ IfBuilder if_true(this);
+ if_true.If<HCompareObjectEqAndBranch>(value,
+ graph()->GetConstantTrue());
+ if_true.Then();
+ Push(graph()->GetConstant1());
+ if_true.Else();
+ IfBuilder if_false(this);
+ if_false.If<HCompareObjectEqAndBranch>(value,
+ graph()->GetConstantFalse());
+ if_false.Then();
+ Push(graph()->GetConstant0());
+ if_false.Else();
+ Push(value);
+ if_false.End();
+ if_true.End();
+ return Pop();
+ }
+
return value;
}
@@ -7643,38 +7714,72 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
Handle<Type> right_type = expr->right()->bounds().lower;
Handle<Type> result_type = expr->bounds().lower;
Maybe<int> fixed_right_arg = expr->fixed_right_arg();
+
+ return HGraphBuilder::BuildBinaryOperation(expr->op(), left, right,
+ left_type, right_type, result_type, fixed_right_arg, context);
+}
+
+
+HInstruction* HGraphBuilder::BuildBinaryOperation(
+ Token::Value op,
+ HValue* left,
+ HValue* right,
+ Handle<Type> left_type,
+ Handle<Type> right_type,
+ Handle<Type> result_type,
+ Maybe<int> fixed_right_arg,
+ HValue* context) {
+
Representation left_rep = Representation::FromType(left_type);
Representation right_rep = Representation::FromType(right_type);
- Representation result_rep = Representation::FromType(result_type);
- if (expr->op() != Token::ADD ||
- (left->type().IsNonString() && right->type().IsNonString())) {
- // For addition we can only truncate the arguments to number if we can
- // prove that we will not end up in string concatenation mode.
- left = TruncateToNumber(left, &left_type);
- right = TruncateToNumber(right, &right_type);
- }
+ bool maybe_string_add = op == Token::ADD &&
+ (left_type->Maybe(Type::String()) ||
+ right_type->Maybe(Type::String()));
if (left_type->Is(Type::None())) {
Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
Deoptimizer::SOFT);
- // TODO(rossberg): we should be able to get rid of non-continuous defaults.
+ // TODO(rossberg): we should be able to get rid of non-continuous
+ // defaults.
left_type = handle(Type::Any(), isolate());
+ } else {
+ if (!maybe_string_add) left = TruncateToNumber(left, &left_type);
+ left_rep = Representation::FromType(left_type);
}
+
if (right_type->Is(Type::None())) {
Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation",
Deoptimizer::SOFT);
right_type = handle(Type::Any(), isolate());
+ } else {
+ if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
+ right_rep = Representation::FromType(right_type);
}
+
+ Representation result_rep = Representation::FromType(result_type);
+
+ bool is_string_add = op == Token::ADD &&
+ (left_type->Is(Type::String()) ||
+ right_type->Is(Type::String()));
+
HInstruction* instr = NULL;
- switch (expr->op()) {
+ switch (op) {
case Token::ADD:
- if (left_type->Is(Type::String()) && right_type->Is(Type::String())) {
- BuildCheckHeapObject(left);
- AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
- BuildCheckHeapObject(right);
- AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
- instr = HStringAdd::New(zone(), context, left, right);
+ if (is_string_add) {
+ StringAddFlags flags = STRING_ADD_CHECK_BOTH;
+ if (left_type->Is(Type::String())) {
+ BuildCheckHeapObject(left);
+ AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
+ flags = STRING_ADD_CHECK_RIGHT;
+ }
+ if (right_type->Is(Type::String())) {
+ BuildCheckHeapObject(right);
+ AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
+ flags = (flags == STRING_ADD_CHECK_BOTH)
+ ? STRING_ADD_CHECK_LEFT : STRING_ADD_CHECK_NONE;
+ }
+ instr = HStringAdd::New(zone(), context, left, right, flags);
} else {
instr = HAdd::New(zone(), context, left, right);
}
@@ -7693,7 +7798,7 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
break;
case Token::BIT_XOR:
case Token::BIT_AND:
- instr = NewUncasted<HBitwise>(expr->op(), left, right);
+ instr = NewUncasted<HBitwise>(op, left, right);
break;
case Token::BIT_OR: {
HValue* operand, *shift_amount;
@@ -7702,7 +7807,7 @@ HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
MatchRotateRight(left, right, &operand, &shift_amount)) {
instr = new(zone()) HRor(context, operand, shift_amount);
} else {
- instr = NewUncasted<HBitwise>(expr->op(), left, right);
+ instr = NewUncasted<HBitwise>(op, left, right);
}
break;
}
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698