| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 | 214 |
| 215 void HBasicBlock::SetJoinId(BailoutId ast_id) { | 215 void HBasicBlock::SetJoinId(BailoutId ast_id) { |
| 216 int length = predecessors_.length(); | 216 int length = predecessors_.length(); |
| 217 ASSERT(length > 0); | 217 ASSERT(length > 0); |
| 218 for (int i = 0; i < length; i++) { | 218 for (int i = 0; i < length; i++) { |
| 219 HBasicBlock* predecessor = predecessors_[i]; | 219 HBasicBlock* predecessor = predecessors_[i]; |
| 220 ASSERT(predecessor->end()->IsGoto()); | 220 ASSERT(predecessor->end()->IsGoto()); |
| 221 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); | 221 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); |
| 222 // We only need to verify the ID once. | 222 // We only need to verify the ID once. |
| 223 ASSERT(i != 0 || | 223 ASSERT(i != 0 || |
| 224 predecessor->last_environment()->closure()->shared() | 224 (predecessor->last_environment()->closure().is_null() || |
| 225 ->VerifyBailoutId(ast_id)); | 225 predecessor->last_environment()->closure()->shared() |
| 226 ->VerifyBailoutId(ast_id))); |
| 226 simulate->set_ast_id(ast_id); | 227 simulate->set_ast_id(ast_id); |
| 227 } | 228 } |
| 228 } | 229 } |
| 229 | 230 |
| 230 | 231 |
| 231 bool HBasicBlock::Dominates(HBasicBlock* other) const { | 232 bool HBasicBlock::Dominates(HBasicBlock* other) const { |
| 232 HBasicBlock* current = other->dominator(); | 233 HBasicBlock* current = other->dominator(); |
| 233 while (current != NULL) { | 234 while (current != NULL) { |
| 234 if (current == this) return true; | 235 if (current == this) return true; |
| 235 current = current->dominator(); | 236 current = current->dominator(); |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 if (!pointer->is_set()) { | 596 if (!pointer->is_set()) { |
| 596 HConstant* constant = | 597 HConstant* constant = |
| 597 new(zone()) HConstant(value, Representation::Integer32()); | 598 new(zone()) HConstant(value, Representation::Integer32()); |
| 598 constant->InsertAfter(GetConstantUndefined()); | 599 constant->InsertAfter(GetConstantUndefined()); |
| 599 pointer->set(constant); | 600 pointer->set(constant); |
| 600 } | 601 } |
| 601 return pointer->get(); | 602 return pointer->get(); |
| 602 } | 603 } |
| 603 | 604 |
| 604 | 605 |
| 606 HConstant* HGraph::GetConstant0() { |
| 607 return GetConstantInt32(&constant_0_, 0); |
| 608 } |
| 609 |
| 610 |
| 605 HConstant* HGraph::GetConstant1() { | 611 HConstant* HGraph::GetConstant1() { |
| 606 return GetConstantInt32(&constant_1_, 1); | 612 return GetConstantInt32(&constant_1_, 1); |
| 607 } | 613 } |
| 608 | 614 |
| 609 | 615 |
| 610 HConstant* HGraph::GetConstantMinus1() { | 616 HConstant* HGraph::GetConstantMinus1() { |
| 611 return GetConstantInt32(&constant_minus1_, -1); | 617 return GetConstantInt32(&constant_minus1_, -1); |
| 612 } | 618 } |
| 613 | 619 |
| 614 | 620 |
| 615 HConstant* HGraph::GetConstantTrue() { | 621 HConstant* HGraph::GetConstantTrue() { |
| 616 return GetConstant(&constant_true_, isolate()->factory()->true_value()); | 622 return GetConstant(&constant_true_, isolate()->factory()->true_value()); |
| 617 } | 623 } |
| 618 | 624 |
| 619 | 625 |
| 620 HConstant* HGraph::GetConstantFalse() { | 626 HConstant* HGraph::GetConstantFalse() { |
| 621 return GetConstant(&constant_false_, isolate()->factory()->false_value()); | 627 return GetConstant(&constant_false_, isolate()->factory()->false_value()); |
| 622 } | 628 } |
| 623 | 629 |
| 624 | 630 |
| 625 HConstant* HGraph::GetConstantHole() { | 631 HConstant* HGraph::GetConstantHole() { |
| 626 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); | 632 return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value()); |
| 627 } | 633 } |
| 628 | 634 |
| 629 | 635 |
| 636 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id) |
| 637 : builder_(builder), |
| 638 finished_(false), |
| 639 id_(id) { |
| 640 HEnvironment* env = builder->environment(); |
| 641 HEnvironment* true_env = env->Copy(); |
| 642 HEnvironment* false_env = env->Copy(); |
| 643 HEnvironment* merge_env = env->Copy(); |
| 644 true_block_ = builder->CreateBasicBlock(true_env); |
| 645 false_block_ = builder->CreateBasicBlock(false_env); |
| 646 merge_block_ = builder->CreateBasicBlock(merge_env); |
| 647 } |
| 648 |
| 649 |
| 650 void HGraphBuilder::IfBuilder::BeginTrue(HValue* left, |
| 651 HValue* right, |
| 652 Token::Value token) { |
| 653 HCompareIDAndBranch* compare = |
| 654 new(zone()) HCompareIDAndBranch(left, right, token); |
| 655 compare->ChangeRepresentation(Representation::Integer32()); |
| 656 compare->SetSuccessorAt(0, true_block_); |
| 657 compare->SetSuccessorAt(1, false_block_); |
| 658 builder_->current_block()->Finish(compare); |
| 659 builder_->set_current_block(true_block_); |
| 660 } |
| 661 |
| 662 |
| 663 void HGraphBuilder::IfBuilder::BeginFalse() { |
| 664 builder_->current_block()->Goto(merge_block_); |
| 665 builder_->set_current_block(false_block_); |
| 666 } |
| 667 |
| 668 |
| 669 void HGraphBuilder::IfBuilder::End() { |
| 670 ASSERT(!finished_); |
| 671 builder_->current_block()->Goto(merge_block_); |
| 672 builder_->set_current_block(merge_block_); |
| 673 merge_block_->SetJoinId(id_); |
| 674 finished_ = true; |
| 675 } |
| 676 |
| 677 |
| 678 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
| 679 HValue* context, |
| 680 LoopBuilder::Direction direction, |
| 681 BailoutId id) |
| 682 : builder_(builder), |
| 683 context_(context), |
| 684 direction_(direction), |
| 685 id_(id), |
| 686 finished_(false) { |
| 687 HEnvironment* env = builder_->environment(); |
| 688 HEnvironment* body_env = env->Copy(); |
| 689 HEnvironment* exit_env = env->Copy(); |
| 690 header_block_ = builder->CreateLoopHeaderBlock(); |
| 691 body_block_ = builder->CreateBasicBlock(body_env); |
| 692 exit_block_ = builder->CreateBasicBlock(exit_env); |
| 693 } |
| 694 |
| 695 |
| 696 HValue* HGraphBuilder::LoopBuilder::BeginBody(HValue* initial, |
| 697 HValue* terminating, |
| 698 Token::Value token) { |
| 699 phi_ = new(zone()) HPhi(0, zone()); |
| 700 header_block_->AddPhi(phi_); |
| 701 phi_->AddInput(initial); |
| 702 phi_->ChangeRepresentation(Representation::Integer32()); |
| 703 HEnvironment* env = builder_->environment(); |
| 704 env->Push(initial); |
| 705 builder_->current_block()->Goto(header_block_); |
| 706 builder_->set_current_block(header_block_); |
| 707 |
| 708 builder_->set_current_block(header_block_); |
| 709 HCompareIDAndBranch* compare = |
| 710 new(zone()) HCompareIDAndBranch(phi_, terminating, token); |
| 711 compare->ChangeRepresentation(Representation::Integer32()); |
| 712 compare->SetSuccessorAt(0, body_block_); |
| 713 compare->SetSuccessorAt(1, exit_block_); |
| 714 builder_->current_block()->Finish(compare); |
| 715 |
| 716 builder_->set_current_block(body_block_); |
| 717 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { |
| 718 HValue* one = builder_->graph()->GetConstant1(); |
| 719 if (direction_ == kPreIncrement) { |
| 720 increment_ = new(zone()) HAdd(context_, phi_, one); |
| 721 } else { |
| 722 increment_ = new(zone()) HSub(context_, phi_, one); |
| 723 } |
| 724 increment_->ClearFlag(HValue::kCanOverflow); |
| 725 increment_->ChangeRepresentation(Representation::Integer32()); |
| 726 builder_->AddInstruction(increment_); |
| 727 return increment_; |
| 728 } else { |
| 729 return phi_; |
| 730 } |
| 731 } |
| 732 |
| 733 |
| 734 void HGraphBuilder::LoopBuilder::EndBody() { |
| 735 ASSERT(!finished_); |
| 736 |
| 737 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { |
| 738 HValue* one = builder_->graph()->GetConstant1(); |
| 739 if (direction_ == kPostIncrement) { |
| 740 increment_ = new(zone()) HAdd(context_, phi_, one); |
| 741 } else { |
| 742 increment_ = new(zone()) HSub(context_, phi_, one); |
| 743 } |
| 744 increment_->ClearFlag(HValue::kCanOverflow); |
| 745 increment_->ChangeRepresentation(Representation::Integer32()); |
| 746 builder_->AddInstruction(increment_); |
| 747 } |
| 748 |
| 749 builder_->environment()->Push(increment_); |
| 750 builder_->current_block()->Goto(header_block_); |
| 751 header_block_->loop_information()->RegisterBackEdge(body_block_); |
| 752 header_block_->SetJoinId(BailoutId::StubEntry()); |
| 753 builder_->set_current_block(exit_block_); |
| 754 finished_ = true; |
| 755 } |
| 756 |
| 757 |
| 630 HGraph* HGraphBuilder::CreateGraph() { | 758 HGraph* HGraphBuilder::CreateGraph() { |
| 631 graph_ = new(zone()) HGraph(info_); | 759 graph_ = new(zone()) HGraph(info_); |
| 632 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_); | 760 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_); |
| 633 HPhase phase("H_Block building"); | 761 HPhase phase("H_Block building"); |
| 634 set_current_block(graph()->entry_block()); | 762 set_current_block(graph()->entry_block()); |
| 635 if (!BuildGraph()) return NULL; | 763 if (!BuildGraph()) return NULL; |
| 636 return graph_; | 764 return graph_; |
| 637 } | 765 } |
| 638 | 766 |
| 639 | 767 |
| 640 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 768 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 641 ASSERT(current_block() != NULL); | 769 ASSERT(current_block() != NULL); |
| 642 current_block()->AddInstruction(instr); | 770 current_block()->AddInstruction(instr); |
| 643 return instr; | 771 return instr; |
| 644 } | 772 } |
| 645 | 773 |
| 646 | 774 |
| 647 void HGraphBuilder::AddSimulate(BailoutId id, | 775 void HGraphBuilder::AddSimulate(BailoutId id, |
| 648 RemovableSimulate removable) { | 776 RemovableSimulate removable) { |
| 649 ASSERT(current_block() != NULL); | 777 ASSERT(current_block() != NULL); |
| 650 current_block()->AddSimulate(id, removable); | 778 current_block()->AddSimulate(id, removable); |
| 651 } | 779 } |
| 652 | 780 |
| 653 | 781 |
| 782 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
| 783 HBasicBlock* b = graph()->CreateBasicBlock(); |
| 784 b->SetInitialEnvironment(env); |
| 785 return b; |
| 786 } |
| 787 |
| 788 |
| 789 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 790 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 791 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 792 header->SetInitialEnvironment(entry_env); |
| 793 header->AttachLoopInformation(); |
| 794 return header; |
| 795 } |
| 796 |
| 797 |
| 654 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 798 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| 655 HValue* external_elements, | 799 HValue* external_elements, |
| 656 HValue* checked_key, | 800 HValue* checked_key, |
| 657 HValue* val, | 801 HValue* val, |
| 658 HValue* dependency, | 802 HValue* dependency, |
| 659 ElementsKind elements_kind, | 803 ElementsKind elements_kind, |
| 660 bool is_store) { | 804 bool is_store) { |
| 661 Zone* zone = this->zone(); | 805 Zone* zone = this->zone(); |
| 662 if (is_store) { | 806 if (is_store) { |
| 663 ASSERT(val != NULL); | 807 ASSERT(val != NULL); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 792 } else { | 936 } else { |
| 793 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); | 937 length = AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| 794 } | 938 } |
| 795 checked_key = AddInstruction(new(zone) HBoundsCheck( | 939 checked_key = AddInstruction(new(zone) HBoundsCheck( |
| 796 key, length, ALLOW_SMI_KEY, checked_index_representation)); | 940 key, length, ALLOW_SMI_KEY, checked_index_representation)); |
| 797 return BuildFastElementAccess(elements, checked_key, val, mapcheck, | 941 return BuildFastElementAccess(elements, checked_key, val, mapcheck, |
| 798 elements_kind, is_store); | 942 elements_kind, is_store); |
| 799 } | 943 } |
| 800 | 944 |
| 801 | 945 |
| 946 HValue* HGraphBuilder::BuildAllocateElements(HContext* context, |
| 947 ElementsKind kind, |
| 948 HValue* capacity) { |
| 949 Zone* zone = this->zone(); |
| 950 |
| 951 int elements_size = IsFastDoubleElementsKind(kind) |
| 952 ? kDoubleSize : kPointerSize; |
| 953 HConstant* elements_size_value = |
| 954 new(zone) HConstant(elements_size, Representation::Integer32()); |
| 955 AddInstruction(elements_size_value); |
| 956 HValue* mul = AddInstruction( |
| 957 new(zone) HMul(context, capacity, elements_size_value)); |
| 958 mul->ChangeRepresentation(Representation::Integer32()); |
| 959 mul->ClearFlag(HValue::kCanOverflow); |
| 960 |
| 961 HConstant* header_size = |
| 962 new(zone) HConstant(FixedArray::kHeaderSize, Representation::Integer32()); |
| 963 AddInstruction(header_size); |
| 964 HValue* total_size = AddInstruction( |
| 965 new(zone) HAdd(context, mul, header_size)); |
| 966 total_size->ChangeRepresentation(Representation::Integer32()); |
| 967 total_size->ClearFlag(HValue::kCanOverflow); |
| 968 |
| 969 HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE; |
| 970 if (IsFastDoubleElementsKind(kind)) { |
| 971 flags = static_cast<HAllocate::Flags>( |
| 972 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED); |
| 973 } |
| 974 |
| 975 HValue* elements = |
| 976 AddInstruction(new(zone) HAllocate(context, total_size, |
| 977 HType::JSArray(), flags)); |
| 978 Isolate* isolate = graph()->isolate(); |
| 979 |
| 980 Factory* factory = isolate->factory(); |
| 981 Handle<Map> map = IsFastDoubleElementsKind(kind) |
| 982 ? factory->fixed_double_array_map() |
| 983 : factory->fixed_array_map(); |
| 984 BuildStoreMap(elements, map, BailoutId::StubEntry()); |
| 985 |
| 986 Handle<String> fixed_array_length_field_name = |
| 987 isolate->factory()->length_field_symbol(); |
| 988 HInstruction* store_length = |
| 989 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, |
| 990 capacity, true, FixedArray::kLengthOffset); |
| 991 AddInstruction(store_length); |
| 992 AddSimulate(BailoutId::StubEntry(), FIXED_SIMULATE); |
| 993 |
| 994 return elements; |
| 995 } |
| 996 |
| 997 |
| 998 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
| 999 HValue* map, |
| 1000 BailoutId id) { |
| 1001 Zone* zone = this->zone(); |
| 1002 Isolate* isolate = graph()->isolate(); |
| 1003 Factory* factory = isolate->factory(); |
| 1004 Handle<String> map_field_name = factory->map_field_symbol(); |
| 1005 HInstruction* store_map = |
| 1006 new(zone) HStoreNamedField(object, map_field_name, map, |
| 1007 true, JSObject::kMapOffset); |
| 1008 store_map->SetGVNFlag(kChangesMaps); |
| 1009 AddInstruction(store_map); |
| 1010 AddSimulate(id, FIXED_SIMULATE); |
| 1011 return store_map; |
| 1012 } |
| 1013 |
| 1014 |
| 1015 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
| 1016 Handle<Map> map, |
| 1017 BailoutId id) { |
| 1018 Zone* zone = this->zone(); |
| 1019 HValue* map_constant = |
| 1020 AddInstruction(new(zone) HConstant(map, Representation::Tagged())); |
| 1021 return BuildStoreMap(object, map_constant, id); |
| 1022 } |
| 1023 |
| 1024 |
| 1025 void HGraphBuilder::BuildCopyElements(HContext* context, |
| 1026 HValue* from_elements, |
| 1027 ElementsKind from_elements_kind, |
| 1028 HValue* to_elements, |
| 1029 ElementsKind to_elements_kind, |
| 1030 HValue* length) { |
| 1031 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
| 1032 |
| 1033 HValue* key = builder.BeginBody(graph()->GetConstant0(), |
| 1034 length, Token::LT); |
| 1035 |
| 1036 HValue* element = |
| 1037 AddInstruction(new(zone()) HLoadKeyed(from_elements, key, NULL, |
| 1038 from_elements_kind, |
| 1039 ALLOW_RETURN_HOLE)); |
| 1040 |
| 1041 AddInstruction(new(zone()) HStoreKeyed(to_elements, key, element, |
| 1042 to_elements_kind)); |
| 1043 AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE); |
| 1044 |
| 1045 builder.EndBody(); |
| 1046 } |
| 1047 |
| 1048 |
| 802 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, | 1049 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info, |
| 803 TypeFeedbackOracle* oracle) | 1050 TypeFeedbackOracle* oracle) |
| 804 : HGraphBuilder(info), | 1051 : HGraphBuilder(info), |
| 805 function_state_(NULL), | 1052 function_state_(NULL), |
| 806 initial_function_state_(this, info, oracle, NORMAL_RETURN), | 1053 initial_function_state_(this, info, oracle, NORMAL_RETURN), |
| 807 ast_context_(NULL), | 1054 ast_context_(NULL), |
| 808 break_scope_(NULL), | 1055 break_scope_(NULL), |
| 809 inlined_count_(0), | 1056 inlined_count_(0), |
| 810 globals_(10, info->zone()), | 1057 globals_(10, info->zone()), |
| 811 inline_bailout_(false) { | 1058 inline_bailout_(false) { |
| (...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2251 TRACE_GVN_1("Updated first-time accumulated %s\n", | 2498 TRACE_GVN_1("Updated first-time accumulated %s\n", |
| 2252 *GetGVNFlagsString(*first_time_changes)); | 2499 *GetGVNFlagsString(*first_time_changes)); |
| 2253 } | 2500 } |
| 2254 } | 2501 } |
| 2255 instr = next; | 2502 instr = next; |
| 2256 } | 2503 } |
| 2257 } | 2504 } |
| 2258 | 2505 |
| 2259 | 2506 |
| 2260 bool HGlobalValueNumberer::AllowCodeMotion() { | 2507 bool HGlobalValueNumberer::AllowCodeMotion() { |
| 2261 return info()->opt_count() + 1 < FLAG_max_opt_count; | 2508 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count; |
| 2262 } | 2509 } |
| 2263 | 2510 |
| 2264 | 2511 |
| 2265 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, | 2512 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, |
| 2266 HBasicBlock* loop_header) { | 2513 HBasicBlock* loop_header) { |
| 2267 // If we've disabled code motion or we're in a block that unconditionally | 2514 // If we've disabled code motion or we're in a block that unconditionally |
| 2268 // deoptimizes, don't move any instructions. | 2515 // deoptimizes, don't move any instructions. |
| 2269 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); | 2516 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); |
| 2270 } | 2517 } |
| 2271 | 2518 |
| (...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3503 int checksum = type_info->own_type_change_checksum(); | 3750 int checksum = type_info->own_type_change_checksum(); |
| 3504 int composite_checksum = graph()->update_type_change_checksum(checksum); | 3751 int composite_checksum = graph()->update_type_change_checksum(checksum); |
| 3505 graph()->set_use_optimistic_licm( | 3752 graph()->set_use_optimistic_licm( |
| 3506 !type_info->matches_inlined_type_change_checksum(composite_checksum)); | 3753 !type_info->matches_inlined_type_change_checksum(composite_checksum)); |
| 3507 type_info->set_inlined_type_change_checksum(composite_checksum); | 3754 type_info->set_inlined_type_change_checksum(composite_checksum); |
| 3508 | 3755 |
| 3509 return true; | 3756 return true; |
| 3510 } | 3757 } |
| 3511 | 3758 |
| 3512 | 3759 |
| 3760 void HGraph::GlobalValueNumbering() { |
| 3761 // Perform common subexpression elimination and loop-invariant code motion. |
| 3762 if (FLAG_use_gvn) { |
| 3763 HPhase phase("H_Global value numbering", this); |
| 3764 HGlobalValueNumberer gvn(this, info()); |
| 3765 bool removed_side_effects = gvn.Analyze(); |
| 3766 // Trigger a second analysis pass to further eliminate duplicate values that |
| 3767 // could only be discovered by removing side-effect-generating instructions |
| 3768 // during the first pass. |
| 3769 if (FLAG_smi_only_arrays && removed_side_effects) { |
| 3770 removed_side_effects = gvn.Analyze(); |
| 3771 ASSERT(!removed_side_effects); |
| 3772 } |
| 3773 } |
| 3774 } |
| 3775 |
| 3776 |
| 3513 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { | 3777 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
| 3514 *bailout_reason = SmartArrayPointer<char>(); | 3778 *bailout_reason = SmartArrayPointer<char>(); |
| 3515 OrderBlocks(); | 3779 OrderBlocks(); |
| 3516 AssignDominators(); | 3780 AssignDominators(); |
| 3517 | 3781 |
| 3518 #ifdef DEBUG | 3782 #ifdef DEBUG |
| 3519 // Do a full verify after building the graph and computing dominators. | 3783 // Do a full verify after building the graph and computing dominators. |
| 3520 Verify(true); | 3784 Verify(true); |
| 3521 #endif | 3785 #endif |
| 3522 | 3786 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3556 | 3820 |
| 3557 InitializeInferredTypes(); | 3821 InitializeInferredTypes(); |
| 3558 | 3822 |
| 3559 // Must be performed before canonicalization to ensure that Canonicalize | 3823 // Must be performed before canonicalization to ensure that Canonicalize |
| 3560 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with | 3824 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with |
| 3561 // zero. | 3825 // zero. |
| 3562 ComputeSafeUint32Operations(); | 3826 ComputeSafeUint32Operations(); |
| 3563 | 3827 |
| 3564 Canonicalize(); | 3828 Canonicalize(); |
| 3565 | 3829 |
| 3566 // Perform common subexpression elimination and loop-invariant code motion. | 3830 GlobalValueNumbering(); |
| 3567 if (FLAG_use_gvn) { | |
| 3568 HPhase phase("H_Global value numbering", this); | |
| 3569 HGlobalValueNumberer gvn(this, info()); | |
| 3570 bool removed_side_effects = gvn.Analyze(); | |
| 3571 // Trigger a second analysis pass to further eliminate duplicate values that | |
| 3572 // could only be discovered by removing side-effect-generating instructions | |
| 3573 // during the first pass. | |
| 3574 if (FLAG_smi_only_arrays && removed_side_effects) { | |
| 3575 removed_side_effects = gvn.Analyze(); | |
| 3576 ASSERT(!removed_side_effects); | |
| 3577 } | |
| 3578 } | |
| 3579 | 3831 |
| 3580 if (FLAG_use_range) { | 3832 if (FLAG_use_range) { |
| 3581 HRangeAnalysis rangeAnalysis(this); | 3833 HRangeAnalysis rangeAnalysis(this); |
| 3582 rangeAnalysis.Analyze(); | 3834 rangeAnalysis.Analyze(); |
| 3583 } | 3835 } |
| 3584 ComputeMinusZeroChecks(); | 3836 ComputeMinusZeroChecks(); |
| 3585 | 3837 |
| 3586 // Eliminate redundant stack checks on backwards branches. | 3838 // Eliminate redundant stack checks on backwards branches. |
| 3587 HStackCheckEliminator sce(this); | 3839 HStackCheckEliminator sce(this); |
| 3588 sce.Process(); | 3840 sce.Process(); |
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4194 } | 4446 } |
| 4195 | 4447 |
| 4196 | 4448 |
| 4197 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { | 4449 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { |
| 4198 for (int i = 0; i < statements->length(); i++) { | 4450 for (int i = 0; i < statements->length(); i++) { |
| 4199 CHECK_ALIVE(Visit(statements->at(i))); | 4451 CHECK_ALIVE(Visit(statements->at(i))); |
| 4200 } | 4452 } |
| 4201 } | 4453 } |
| 4202 | 4454 |
| 4203 | 4455 |
| 4204 HBasicBlock* HOptimizedGraphBuilder::CreateBasicBlock(HEnvironment* env) { | |
| 4205 HBasicBlock* b = graph()->CreateBasicBlock(); | |
| 4206 b->SetInitialEnvironment(env); | |
| 4207 return b; | |
| 4208 } | |
| 4209 | |
| 4210 | |
| 4211 HBasicBlock* HOptimizedGraphBuilder::CreateLoopHeaderBlock() { | |
| 4212 HBasicBlock* header = graph()->CreateBasicBlock(); | |
| 4213 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | |
| 4214 header->SetInitialEnvironment(entry_env); | |
| 4215 header->AttachLoopInformation(); | |
| 4216 return header; | |
| 4217 } | |
| 4218 | |
| 4219 | |
| 4220 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { | 4456 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { |
| 4221 ASSERT(!HasStackOverflow()); | 4457 ASSERT(!HasStackOverflow()); |
| 4222 ASSERT(current_block() != NULL); | 4458 ASSERT(current_block() != NULL); |
| 4223 ASSERT(current_block()->HasPredecessor()); | 4459 ASSERT(current_block()->HasPredecessor()); |
| 4224 if (stmt->scope() != NULL) { | 4460 if (stmt->scope() != NULL) { |
| 4225 return Bailout("ScopedBlock"); | 4461 return Bailout("ScopedBlock"); |
| 4226 } | 4462 } |
| 4227 BreakAndContinueInfo break_info(stmt); | 4463 BreakAndContinueInfo break_info(stmt); |
| 4228 { BreakAndContinueScope push(&break_info, this); | 4464 { BreakAndContinueScope push(&break_info, this); |
| 4229 CHECK_BAILOUT(VisitStatements(stmt->statements())); | 4465 CHECK_BAILOUT(VisitStatements(stmt->statements())); |
| (...skipping 2301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6531 int num_untransitionable_maps = 0; | 6767 int num_untransitionable_maps = 0; |
| 6532 Handle<Map> untransitionable_map; | 6768 Handle<Map> untransitionable_map; |
| 6533 HTransitionElementsKind* transition = NULL; | 6769 HTransitionElementsKind* transition = NULL; |
| 6534 for (int i = 0; i < maps->length(); ++i) { | 6770 for (int i = 0; i < maps->length(); ++i) { |
| 6535 Handle<Map> map = maps->at(i); | 6771 Handle<Map> map = maps->at(i); |
| 6536 ASSERT(map->IsMap()); | 6772 ASSERT(map->IsMap()); |
| 6537 if (!transition_target.at(i).is_null()) { | 6773 if (!transition_target.at(i).is_null()) { |
| 6538 ASSERT(Map::IsValidElementsTransition( | 6774 ASSERT(Map::IsValidElementsTransition( |
| 6539 map->elements_kind(), | 6775 map->elements_kind(), |
| 6540 transition_target.at(i)->elements_kind())); | 6776 transition_target.at(i)->elements_kind())); |
| 6777 HValue* context = environment()->LookupContext(); |
| 6541 transition = new(zone()) HTransitionElementsKind( | 6778 transition = new(zone()) HTransitionElementsKind( |
| 6542 object, map, transition_target.at(i)); | 6779 context, object, map, transition_target.at(i)); |
| 6543 AddInstruction(transition); | 6780 AddInstruction(transition); |
| 6544 } else { | 6781 } else { |
| 6545 type_todo[map->elements_kind()] = true; | 6782 type_todo[map->elements_kind()] = true; |
| 6546 if (IsExternalArrayElementsKind(map->elements_kind())) { | 6783 if (IsExternalArrayElementsKind(map->elements_kind())) { |
| 6547 todo_external_array = true; | 6784 todo_external_array = true; |
| 6548 } | 6785 } |
| 6549 num_untransitionable_maps++; | 6786 num_untransitionable_maps++; |
| 6550 untransitionable_map = map; | 6787 untransitionable_map = map; |
| 6551 } | 6788 } |
| 6552 } | 6789 } |
| (...skipping 3231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9784 ast_id_(BailoutId::None()), | 10021 ast_id_(BailoutId::None()), |
| 9785 zone_(zone) { | 10022 zone_(zone) { |
| 9786 Initialize(0, 0, 0); | 10023 Initialize(0, 0, 0); |
| 9787 } | 10024 } |
| 9788 | 10025 |
| 9789 | 10026 |
| 9790 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) | 10027 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
| 9791 : values_(0, zone), | 10028 : values_(0, zone), |
| 9792 frame_type_(JS_FUNCTION), | 10029 frame_type_(JS_FUNCTION), |
| 9793 parameter_count_(0), | 10030 parameter_count_(0), |
| 9794 specials_count_(1), | 10031 specials_count_(0), |
| 9795 local_count_(0), | 10032 local_count_(0), |
| 9796 outer_(NULL), | 10033 outer_(NULL), |
| 9797 entry_(NULL), | 10034 entry_(NULL), |
| 9798 pop_count_(0), | 10035 pop_count_(0), |
| 9799 push_count_(0), | 10036 push_count_(0), |
| 9800 ast_id_(other->ast_id()), | 10037 ast_id_(other->ast_id()), |
| 9801 zone_(zone) { | 10038 zone_(zone) { |
| 9802 Initialize(other); | 10039 Initialize(other); |
| 9803 } | 10040 } |
| 9804 | 10041 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9839 closure_ = other->closure(); | 10076 closure_ = other->closure(); |
| 9840 values_.AddAll(other->values_, zone()); | 10077 values_.AddAll(other->values_, zone()); |
| 9841 assigned_variables_.Union(other->assigned_variables_, zone()); | 10078 assigned_variables_.Union(other->assigned_variables_, zone()); |
| 9842 frame_type_ = other->frame_type_; | 10079 frame_type_ = other->frame_type_; |
| 9843 parameter_count_ = other->parameter_count_; | 10080 parameter_count_ = other->parameter_count_; |
| 9844 local_count_ = other->local_count_; | 10081 local_count_ = other->local_count_; |
| 9845 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. | 10082 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. |
| 9846 entry_ = other->entry_; | 10083 entry_ = other->entry_; |
| 9847 pop_count_ = other->pop_count_; | 10084 pop_count_ = other->pop_count_; |
| 9848 push_count_ = other->push_count_; | 10085 push_count_ = other->push_count_; |
| 10086 specials_count_ = other->specials_count_; |
| 9849 ast_id_ = other->ast_id_; | 10087 ast_id_ = other->ast_id_; |
| 9850 } | 10088 } |
| 9851 | 10089 |
| 9852 | 10090 |
| 9853 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { | 10091 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { |
| 9854 ASSERT(!block->IsLoopHeader()); | 10092 ASSERT(!block->IsLoopHeader()); |
| 9855 ASSERT(values_.length() == other->values_.length()); | 10093 ASSERT(values_.length() == other->values_.length()); |
| 9856 | 10094 |
| 9857 int length = values_.length(); | 10095 int length = values_.length(); |
| 9858 for (int i = 0; i < length; ++i) { | 10096 for (int i = 0; i < length; ++i) { |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10384 } | 10622 } |
| 10385 } | 10623 } |
| 10386 | 10624 |
| 10387 #ifdef DEBUG | 10625 #ifdef DEBUG |
| 10388 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10626 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 10389 if (allocator_ != NULL) allocator_->Verify(); | 10627 if (allocator_ != NULL) allocator_->Verify(); |
| 10390 #endif | 10628 #endif |
| 10391 } | 10629 } |
| 10392 | 10630 |
| 10393 } } // namespace v8::internal | 10631 } } // namespace v8::internal |
| OLD | NEW |