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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 last_true_block_(NULL), 730 last_true_block_(NULL),
731 first_false_block_(NULL), 731 first_false_block_(NULL),
732 split_edge_merge_block_(NULL), 732 split_edge_merge_block_(NULL),
733 merge_block_(NULL) { 733 merge_block_(NULL) {
734 continuation->Continue(&first_true_block_, 734 continuation->Continue(&first_true_block_,
735 &first_false_block_, 735 &first_false_block_,
736 &position_); 736 &position_);
737 } 737 }
738 738
739 739
740 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { 740 HControlInstruction* HGraphBuilder::IfBuilder::AddCompare(
741 HControlInstruction* compare) {
741 if (split_edge_merge_block_ != NULL) { 742 if (split_edge_merge_block_ != NULL) {
742 HEnvironment* env = first_false_block_->last_environment(); 743 HEnvironment* env = first_false_block_->last_environment();
743 HBasicBlock* split_edge = 744 HBasicBlock* split_edge =
744 builder_->CreateBasicBlock(env->Copy()); 745 builder_->CreateBasicBlock(env->Copy());
745 if (did_or_) { 746 if (did_or_) {
746 compare->SetSuccessorAt(0, split_edge); 747 compare->SetSuccessorAt(0, split_edge);
747 compare->SetSuccessorAt(1, first_false_block_); 748 compare->SetSuccessorAt(1, first_false_block_);
748 } else { 749 } else {
749 compare->SetSuccessorAt(0, first_true_block_); 750 compare->SetSuccessorAt(0, first_true_block_);
750 compare->SetSuccessorAt(1, split_edge); 751 compare->SetSuccessorAt(1, split_edge);
751 } 752 }
752 split_edge->GotoNoSimulate(split_edge_merge_block_); 753 split_edge->GotoNoSimulate(split_edge_merge_block_);
753 } else { 754 } else {
754 compare->SetSuccessorAt(0, first_true_block_); 755 compare->SetSuccessorAt(0, first_true_block_);
755 compare->SetSuccessorAt(1, first_false_block_); 756 compare->SetSuccessorAt(1, first_false_block_);
756 } 757 }
757 builder_->current_block()->Finish(compare); 758 builder_->current_block()->Finish(compare);
758 needs_compare_ = false; 759 needs_compare_ = false;
760 return compare;
759 } 761 }
760 762
761 763
762 void HGraphBuilder::IfBuilder::Or() { 764 void HGraphBuilder::IfBuilder::Or() {
763 ASSERT(!did_and_); 765 ASSERT(!did_and_);
764 did_or_ = true; 766 did_or_ = true;
765 HEnvironment* env = first_false_block_->last_environment(); 767 HEnvironment* env = first_false_block_->last_environment();
766 if (split_edge_merge_block_ == NULL) { 768 if (split_edge_merge_block_ == NULL) {
767 split_edge_merge_block_ = 769 split_edge_merge_block_ =
768 builder_->CreateBasicBlock(env->Copy()); 770 builder_->CreateBasicBlock(env->Copy());
(...skipping 6805 matching lines...) Expand 10 before | Expand all | Expand 10 after
7574 return false; 7576 return false;
7575 } 7577 }
7576 return (sub->right() == sa); 7578 return (sub->right() == sa);
7577 } 7579 }
7578 7580
7579 7581
7580 // Checks if the left and the right are shift instructions with the oposite 7582 // Checks if the left and the right are shift instructions with the oposite
7581 // directions that can be replaced by one rotate right instruction or not. 7583 // directions that can be replaced by one rotate right instruction or not.
7582 // Returns the operand and the shift amount for the rotate instruction in the 7584 // Returns the operand and the shift amount for the rotate instruction in the
7583 // former case. 7585 // former case.
7584 bool HOptimizedGraphBuilder::MatchRotateRight(HValue* left, 7586 bool HGraphBuilder::MatchRotateRight(HValue* left,
7585 HValue* right, 7587 HValue* right,
7586 HValue** operand, 7588 HValue** operand,
7587 HValue** shift_amount) { 7589 HValue** shift_amount) {
7588 HShl* shl; 7590 HShl* shl;
7589 HShr* shr; 7591 HShr* shr;
7590 if (left->IsShl() && right->IsShr()) { 7592 if (left->IsShl() && right->IsShr()) {
7591 shl = HShl::cast(left); 7593 shl = HShl::cast(left);
7592 shr = HShr::cast(right); 7594 shr = HShr::cast(right);
7593 } else if (left->IsShr() && right->IsShl()) { 7595 } else if (left->IsShr() && right->IsShl()) {
7594 shl = HShl::cast(right); 7596 shl = HShl::cast(right);
7595 shr = HShr::cast(left); 7597 shr = HShr::cast(left);
7596 } else { 7598 } else {
7597 return false; 7599 return false;
(...skipping 15 matching lines...) Expand all
7613 HConstant* right_const = HConstant::cast(right); 7615 HConstant* right_const = HConstant::cast(right);
7614 if (right_const->HasInteger32Value() && 7616 if (right_const->HasInteger32Value() &&
7615 (right_const->Integer32Value() & 0x1f) != 0) { 7617 (right_const->Integer32Value() & 0x1f) != 0) {
7616 return false; 7618 return false;
7617 } 7619 }
7618 } 7620 }
7619 return true; 7621 return true;
7620 } 7622 }
7621 7623
7622 7624
7625 HValue* HGraphBuilder::EnforceNumberType(HValue* number,
7626 Handle<Type> expected) {
7627 if (expected->Is(Type::Smi())) {
7628 return Add<HForceRepresentation>(number, Representation::Smi());
7629 }
7630 if (expected->Is(Type::Signed32())) {
7631 return Add<HForceRepresentation>(number, Representation::Integer32());
7632 }
7633 return number;
7634 }
7635
7636
7623 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) { 7637 HValue* HGraphBuilder::TruncateToNumber(HValue* value, Handle<Type>* expected) {
7624 if (value->IsConstant()) { 7638 if (value->IsConstant()) {
7625 HConstant* constant = HConstant::cast(value); 7639 HConstant* constant = HConstant::cast(value);
7626 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone()); 7640 Maybe<HConstant*> number = constant->CopyToTruncatedNumber(zone());
7627 if (number.has_value) { 7641 if (number.has_value) {
7628 *expected = handle(Type::Number(), isolate()); 7642 *expected = handle(Type::Number(), isolate());
7629 return AddInstruction(number.value); 7643 return AddInstruction(number.value);
7630 } 7644 }
7631 } 7645 }
7632 7646
7647 Handle<Type> expected_type = *expected;
7648
7649 // Separate the number type from the rest.
7650 Handle<Type> expected_obj = handle(Type::Intersect(
7651 expected_type, handle(Type::NonNumber(), isolate())), isolate());
7652 Handle<Type> expected_number = handle(Type::Intersect(
7653 expected_type, handle(Type::Number(), isolate())), isolate());
7654
7655 // We expect to get a number.
7656 // (We need to check first, since Type::None->Is(Type::Any()) == true.
7657 if (expected_obj->Is(Type::None())) {
7658 ASSERT(!expected_number->Is(Type::None()));
7659 return value;
7660 }
7661
7662 if (expected_obj->Is(Type::Undefined())) {
7663 // This is already done by HChange.
7664 *expected = handle(Type::Union(
7665 expected_number, handle(Type::Double(), isolate())), isolate());
7666 return value;
7667 }
7668
7669 if (expected_obj->Is(Type::Null())) {
7670 *expected = handle(Type::Union(
7671 expected_number, handle(Type::Smi(), isolate())), isolate());
7672 IfBuilder if_null(this);
7673 if_null.If<HCompareObjectEqAndBranch>(value,
7674 graph()->GetConstantNull());
7675 if_null.Then();
7676 Push(graph()->GetConstant0());
7677 if_null.Else();
7678 Push(value);
7679 if_null.End();
7680 return Pop();
7681 }
7682
7683 if (expected_obj->Is(Type::Boolean())) {
7684 *expected = handle(Type::Union(
7685 expected_number, handle(Type::Smi(), isolate())), isolate());
7686 IfBuilder if_true(this);
7687 if_true.If<HCompareObjectEqAndBranch>(value,
7688 graph()->GetConstantTrue());
7689 if_true.Then();
7690 Push(graph()->GetConstant1());
7691 if_true.Else();
7692 IfBuilder if_false(this);
7693 if_false.If<HCompareObjectEqAndBranch>(value,
7694 graph()->GetConstantFalse());
7695 if_false.Then();
7696 Push(graph()->GetConstant0());
7697 if_false.Else();
7698 Push(value);
7699 if_false.End();
7700 if_true.End();
7701 return Pop();
7702 }
7703
7633 return value; 7704 return value;
7634 } 7705 }
7635 7706
7636 7707
7637 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation( 7708 HInstruction* HOptimizedGraphBuilder::BuildBinaryOperation(
7638 BinaryOperation* expr, 7709 BinaryOperation* expr,
7639 HValue* left, 7710 HValue* left,
7640 HValue* right) { 7711 HValue* right) {
7641 HValue* context = environment()->context(); 7712 HValue* context = environment()->context();
7642 Handle<Type> left_type = expr->left()->bounds().lower; 7713 Handle<Type> left_type = expr->left()->bounds().lower;
7643 Handle<Type> right_type = expr->right()->bounds().lower; 7714 Handle<Type> right_type = expr->right()->bounds().lower;
7644 Handle<Type> result_type = expr->bounds().lower; 7715 Handle<Type> result_type = expr->bounds().lower;
7645 Maybe<int> fixed_right_arg = expr->fixed_right_arg(); 7716 Maybe<int> fixed_right_arg = expr->fixed_right_arg();
7717
7718 return HGraphBuilder::BuildBinaryOperation(expr->op(), left, right,
7719 left_type, right_type, result_type, fixed_right_arg, context);
7720 }
7721
7722
7723 HInstruction* HGraphBuilder::BuildBinaryOperation(
7724 Token::Value op,
7725 HValue* left,
7726 HValue* right,
7727 Handle<Type> left_type,
7728 Handle<Type> right_type,
7729 Handle<Type> result_type,
7730 Maybe<int> fixed_right_arg,
7731 HValue* context) {
7732
7646 Representation left_rep = Representation::FromType(left_type); 7733 Representation left_rep = Representation::FromType(left_type);
7647 Representation right_rep = Representation::FromType(right_type); 7734 Representation right_rep = Representation::FromType(right_type);
7648 Representation result_rep = Representation::FromType(result_type);
7649 7735
7650 if (expr->op() != Token::ADD || 7736 bool maybe_string_add = op == Token::ADD &&
7651 (left->type().IsNonString() && right->type().IsNonString())) { 7737 (left_type->Maybe(Type::String()) ||
7652 // For addition we can only truncate the arguments to number if we can 7738 right_type->Maybe(Type::String()));
7653 // prove that we will not end up in string concatenation mode.
7654 left = TruncateToNumber(left, &left_type);
7655 right = TruncateToNumber(right, &right_type);
7656 }
7657 7739
7658 if (left_type->Is(Type::None())) { 7740 if (left_type->Is(Type::None())) {
7659 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation", 7741 Add<HDeoptimize>("Insufficient type feedback for LHS of binary operation",
7660 Deoptimizer::SOFT); 7742 Deoptimizer::SOFT);
7661 // TODO(rossberg): we should be able to get rid of non-continuous defaults. 7743 // TODO(rossberg): we should be able to get rid of non-continuous
7744 // defaults.
7662 left_type = handle(Type::Any(), isolate()); 7745 left_type = handle(Type::Any(), isolate());
7746 } else {
7747 if (!maybe_string_add) left = TruncateToNumber(left, &left_type);
7748 left_rep = Representation::FromType(left_type);
7663 } 7749 }
7750
7664 if (right_type->Is(Type::None())) { 7751 if (right_type->Is(Type::None())) {
7665 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation", 7752 Add<HDeoptimize>("Insufficient type feedback for RHS of binary operation",
7666 Deoptimizer::SOFT); 7753 Deoptimizer::SOFT);
7667 right_type = handle(Type::Any(), isolate()); 7754 right_type = handle(Type::Any(), isolate());
7755 } else {
7756 if (!maybe_string_add) right = TruncateToNumber(right, &right_type);
7757 right_rep = Representation::FromType(right_type);
7668 } 7758 }
7759
7760 Representation result_rep = Representation::FromType(result_type);
7761
7762 bool is_string_add = op == Token::ADD &&
7763 (left_type->Is(Type::String()) ||
7764 right_type->Is(Type::String()));
7765
7669 HInstruction* instr = NULL; 7766 HInstruction* instr = NULL;
7670 switch (expr->op()) { 7767 switch (op) {
7671 case Token::ADD: 7768 case Token::ADD:
7672 if (left_type->Is(Type::String()) && right_type->Is(Type::String())) { 7769 if (is_string_add) {
7673 BuildCheckHeapObject(left); 7770 StringAddFlags flags = STRING_ADD_CHECK_BOTH;
7674 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 7771 if (left_type->Is(Type::String())) {
7675 BuildCheckHeapObject(right); 7772 BuildCheckHeapObject(left);
7676 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 7773 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
7677 instr = HStringAdd::New(zone(), context, left, right); 7774 flags = STRING_ADD_CHECK_RIGHT;
7775 }
7776 if (right_type->Is(Type::String())) {
7777 BuildCheckHeapObject(right);
7778 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
7779 flags = (flags == STRING_ADD_CHECK_BOTH)
7780 ? STRING_ADD_CHECK_LEFT : STRING_ADD_CHECK_NONE;
7781 }
7782 instr = HStringAdd::New(zone(), context, left, right, flags);
7678 } else { 7783 } else {
7679 instr = HAdd::New(zone(), context, left, right); 7784 instr = HAdd::New(zone(), context, left, right);
7680 } 7785 }
7681 break; 7786 break;
7682 case Token::SUB: 7787 case Token::SUB:
7683 instr = HSub::New(zone(), context, left, right); 7788 instr = HSub::New(zone(), context, left, right);
7684 break; 7789 break;
7685 case Token::MUL: 7790 case Token::MUL:
7686 instr = HMul::New(zone(), context, left, right); 7791 instr = HMul::New(zone(), context, left, right);
7687 break; 7792 break;
7688 case Token::MOD: 7793 case Token::MOD:
7689 instr = HMod::New(zone(), context, left, right, fixed_right_arg); 7794 instr = HMod::New(zone(), context, left, right, fixed_right_arg);
7690 break; 7795 break;
7691 case Token::DIV: 7796 case Token::DIV:
7692 instr = HDiv::New(zone(), context, left, right); 7797 instr = HDiv::New(zone(), context, left, right);
7693 break; 7798 break;
7694 case Token::BIT_XOR: 7799 case Token::BIT_XOR:
7695 case Token::BIT_AND: 7800 case Token::BIT_AND:
7696 instr = NewUncasted<HBitwise>(expr->op(), left, right); 7801 instr = NewUncasted<HBitwise>(op, left, right);
7697 break; 7802 break;
7698 case Token::BIT_OR: { 7803 case Token::BIT_OR: {
7699 HValue* operand, *shift_amount; 7804 HValue* operand, *shift_amount;
7700 if (left_type->Is(Type::Signed32()) && 7805 if (left_type->Is(Type::Signed32()) &&
7701 right_type->Is(Type::Signed32()) && 7806 right_type->Is(Type::Signed32()) &&
7702 MatchRotateRight(left, right, &operand, &shift_amount)) { 7807 MatchRotateRight(left, right, &operand, &shift_amount)) {
7703 instr = new(zone()) HRor(context, operand, shift_amount); 7808 instr = new(zone()) HRor(context, operand, shift_amount);
7704 } else { 7809 } else {
7705 instr = NewUncasted<HBitwise>(expr->op(), left, right); 7810 instr = NewUncasted<HBitwise>(op, left, right);
7706 } 7811 }
7707 break; 7812 break;
7708 } 7813 }
7709 case Token::SAR: 7814 case Token::SAR:
7710 instr = HSar::New(zone(), context, left, right); 7815 instr = HSar::New(zone(), context, left, right);
7711 break; 7816 break;
7712 case Token::SHR: 7817 case Token::SHR:
7713 instr = HShr::New(zone(), context, left, right); 7818 instr = HShr::New(zone(), context, left, right);
7714 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 7819 if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
7715 CanBeZero(right)) { 7820 CanBeZero(right)) {
(...skipping 1917 matching lines...) Expand 10 before | Expand all | Expand 10 after
9633 if (ShouldProduceTraceOutput()) { 9738 if (ShouldProduceTraceOutput()) {
9634 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9739 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9635 } 9740 }
9636 9741
9637 #ifdef DEBUG 9742 #ifdef DEBUG
9638 graph_->Verify(false); // No full verify. 9743 graph_->Verify(false); // No full verify.
9639 #endif 9744 #endif
9640 } 9745 }
9641 9746
9642 } } // namespace v8::internal 9747 } } // namespace v8::internal
OLDNEW
« 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