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

Side by Side Diff: src/hydrogen.cc

Issue 66983002: Add ability to do "else-if" clauses in IfBuilder (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | no next file » | 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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 if (IsConstantFalse(constant)) return true; 738 if (IsConstantFalse(constant)) return true;
739 if (IsConstantHole(constant)) return true; 739 if (IsConstantHole(constant)) return true;
740 if (IsConstantNull(constant)) return true; 740 if (IsConstantNull(constant)) return true;
741 return false; 741 return false;
742 } 742 }
743 743
744 744
745 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) 745 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder)
746 : builder_(builder), 746 : builder_(builder),
747 finished_(false), 747 finished_(false),
748 deopt_then_(false),
749 deopt_else_(false),
750 did_then_(false), 748 did_then_(false),
751 did_else_(false), 749 did_else_(false),
750 did_else_if_(false),
752 did_and_(false), 751 did_and_(false),
753 did_or_(false), 752 did_or_(false),
754 captured_(false), 753 captured_(false),
755 needs_compare_(true), 754 needs_compare_(true),
755 pending_merge_block_(false),
756 split_edge_merge_block_(NULL), 756 split_edge_merge_block_(NULL),
757 merge_block_(NULL) { 757 merge_at_join_blocks_(NULL),
758 normal_merge_at_join_block_count_(0),
759 deopt_merge_at_join_block_count_(0) {
758 HEnvironment* env = builder->environment(); 760 HEnvironment* env = builder->environment();
759 first_true_block_ = builder->CreateBasicBlock(env->Copy()); 761 first_true_block_ = builder->CreateBasicBlock(env->Copy());
760 last_true_block_ = NULL;
761 first_false_block_ = builder->CreateBasicBlock(env->Copy()); 762 first_false_block_ = builder->CreateBasicBlock(env->Copy());
762 } 763 }
763 764
764 765
765 HGraphBuilder::IfBuilder::IfBuilder( 766 HGraphBuilder::IfBuilder::IfBuilder(
766 HGraphBuilder* builder, 767 HGraphBuilder* builder,
767 HIfContinuation* continuation) 768 HIfContinuation* continuation)
768 : builder_(builder), 769 : builder_(builder),
769 finished_(false), 770 finished_(false),
770 deopt_then_(false),
771 deopt_else_(false),
772 did_then_(false), 771 did_then_(false),
773 did_else_(false), 772 did_else_(false),
773 did_else_if_(false),
774 did_and_(false), 774 did_and_(false),
775 did_or_(false), 775 did_or_(false),
776 captured_(false), 776 captured_(false),
777 needs_compare_(false), 777 needs_compare_(false),
778 pending_merge_block_(false),
778 first_true_block_(NULL), 779 first_true_block_(NULL),
779 last_true_block_(NULL),
780 first_false_block_(NULL), 780 first_false_block_(NULL),
781 split_edge_merge_block_(NULL), 781 split_edge_merge_block_(NULL),
782 merge_block_(NULL) { 782 merge_at_join_blocks_(NULL),
783 normal_merge_at_join_block_count_(0),
784 deopt_merge_at_join_block_count_(0) {
783 continuation->Continue(&first_true_block_, 785 continuation->Continue(&first_true_block_,
784 &first_false_block_); 786 &first_false_block_);
785 } 787 }
786 788
787 789
788 HControlInstruction* HGraphBuilder::IfBuilder::AddCompare( 790 HControlInstruction* HGraphBuilder::IfBuilder::AddCompare(
789 HControlInstruction* compare) { 791 HControlInstruction* compare) {
792 ASSERT(did_then_ == did_else_);
793 if (did_else_) {
794 // Handle if-then-elseif
795 did_else_if_ = true;
796 did_else_ = false;
797 did_then_ = false;
798 did_and_ = false;
799 did_or_ = false;
800 pending_merge_block_ = false;
801 split_edge_merge_block_ = NULL;
802 HEnvironment* env = builder_->environment();
803 first_true_block_ = builder_->CreateBasicBlock(env->Copy());
804 first_false_block_ = builder_->CreateBasicBlock(env->Copy());
805 }
790 if (split_edge_merge_block_ != NULL) { 806 if (split_edge_merge_block_ != NULL) {
791 HEnvironment* env = first_false_block_->last_environment(); 807 HEnvironment* env = first_false_block_->last_environment();
792 HBasicBlock* split_edge = 808 HBasicBlock* split_edge =
793 builder_->CreateBasicBlock(env->Copy()); 809 builder_->CreateBasicBlock(env->Copy());
794 if (did_or_) { 810 if (did_or_) {
795 compare->SetSuccessorAt(0, split_edge); 811 compare->SetSuccessorAt(0, split_edge);
796 compare->SetSuccessorAt(1, first_false_block_); 812 compare->SetSuccessorAt(1, first_false_block_);
797 } else { 813 } else {
798 compare->SetSuccessorAt(0, first_true_block_); 814 compare->SetSuccessorAt(0, first_true_block_);
799 compare->SetSuccessorAt(1, split_edge); 815 compare->SetSuccessorAt(1, split_edge);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 builder_->GotoNoSimulate(first_false_block_, split_edge_merge_block_); 851 builder_->GotoNoSimulate(first_false_block_, split_edge_merge_block_);
836 first_false_block_ = split_edge_merge_block_; 852 first_false_block_ = split_edge_merge_block_;
837 } 853 }
838 builder_->set_current_block(first_true_block_); 854 builder_->set_current_block(first_true_block_);
839 first_true_block_ = builder_->CreateBasicBlock(env->Copy()); 855 first_true_block_ = builder_->CreateBasicBlock(env->Copy());
840 } 856 }
841 857
842 858
843 void HGraphBuilder::IfBuilder::CaptureContinuation( 859 void HGraphBuilder::IfBuilder::CaptureContinuation(
844 HIfContinuation* continuation) { 860 HIfContinuation* continuation) {
861 ASSERT(!did_else_if_);
845 ASSERT(!finished_); 862 ASSERT(!finished_);
846 ASSERT(!captured_); 863 ASSERT(!captured_);
847 HBasicBlock* true_block = last_true_block_ == NULL 864
848 ? first_true_block_ 865 HBasicBlock* true_block = NULL;
849 : last_true_block_; 866 HBasicBlock* false_block = NULL;
850 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL) 867 Finish(&true_block, &false_block);
851 ? builder_->current_block() 868 ASSERT(true_block != NULL);
852 : first_false_block_; 869 ASSERT(false_block != NULL);
853 continuation->Capture(true_block, false_block); 870 continuation->Capture(true_block, false_block);
854 captured_ = true; 871 captured_ = true;
855 End(); 872 End();
856 } 873 }
857 874
858 875
859 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { 876 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) {
877 ASSERT(!did_else_if_);
860 ASSERT(!finished_); 878 ASSERT(!finished_);
861 ASSERT(!captured_); 879 ASSERT(!captured_);
862 ASSERT(did_then_); 880 HBasicBlock* true_block = NULL;
863 if (!did_else_) Else(); 881 HBasicBlock* false_block = NULL;
864 HBasicBlock* true_block = last_true_block_ == NULL 882 Finish(&true_block, &false_block);
865 ? first_true_block_ 883 merge_at_join_blocks_ = NULL;
866 : last_true_block_;
867 HBasicBlock* false_block = builder_->current_block();
868 if (true_block != NULL && !true_block->IsFinished()) { 884 if (true_block != NULL && !true_block->IsFinished()) {
869 ASSERT(continuation->IsTrueReachable()); 885 ASSERT(continuation->IsTrueReachable());
870 builder_->GotoNoSimulate(true_block, continuation->true_branch()); 886 builder_->GotoNoSimulate(true_block, continuation->true_branch());
871 } 887 }
872 if (false_block != NULL && !false_block->IsFinished()) { 888 if (false_block != NULL && !false_block->IsFinished()) {
873 ASSERT(continuation->IsFalseReachable()); 889 ASSERT(continuation->IsFalseReachable());
874 builder_->GotoNoSimulate(false_block, continuation->false_branch()); 890 builder_->GotoNoSimulate(false_block, continuation->false_branch());
875 } 891 }
876 captured_ = true; 892 captured_ = true;
877 End(); 893 End();
(...skipping 10 matching lines...) Expand all
888 // so that the graph builder visits it and sees any live range extending 904 // so that the graph builder visits it and sees any live range extending
889 // constructs within it. 905 // constructs within it.
890 HConstant* constant_false = builder_->graph()->GetConstantFalse(); 906 HConstant* constant_false = builder_->graph()->GetConstantFalse();
891 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); 907 ToBooleanStub::Types boolean_type = ToBooleanStub::Types();
892 boolean_type.Add(ToBooleanStub::BOOLEAN); 908 boolean_type.Add(ToBooleanStub::BOOLEAN);
893 HBranch* branch = builder()->New<HBranch>( 909 HBranch* branch = builder()->New<HBranch>(
894 constant_false, boolean_type, first_true_block_, first_false_block_); 910 constant_false, boolean_type, first_true_block_, first_false_block_);
895 builder_->FinishCurrentBlock(branch); 911 builder_->FinishCurrentBlock(branch);
896 } 912 }
897 builder_->set_current_block(first_true_block_); 913 builder_->set_current_block(first_true_block_);
914 pending_merge_block_ = true;
898 } 915 }
899 916
900 917
901 void HGraphBuilder::IfBuilder::Else() { 918 void HGraphBuilder::IfBuilder::Else() {
902 ASSERT(did_then_); 919 ASSERT(did_then_);
903 ASSERT(!captured_); 920 ASSERT(!captured_);
904 ASSERT(!finished_); 921 ASSERT(!finished_);
905 last_true_block_ = builder_->current_block(); 922 AddMergeAtJoinBlock(false);
906 builder_->set_current_block(first_false_block_); 923 builder_->set_current_block(first_false_block_);
924 pending_merge_block_ = true;
907 did_else_ = true; 925 did_else_ = true;
908 } 926 }
909 927
910 928
911 void HGraphBuilder::IfBuilder::Deopt(const char* reason) { 929 void HGraphBuilder::IfBuilder::Deopt(const char* reason) {
912 ASSERT(did_then_); 930 ASSERT(did_then_);
913 if (did_else_) {
914 deopt_else_ = true;
915 } else {
916 deopt_then_ = true;
917 }
918 builder_->Add<HDeoptimize>(reason, Deoptimizer::EAGER); 931 builder_->Add<HDeoptimize>(reason, Deoptimizer::EAGER);
932 AddMergeAtJoinBlock(true);
919 } 933 }
920 934
921 935
922 void HGraphBuilder::IfBuilder::Return(HValue* value) { 936 void HGraphBuilder::IfBuilder::Return(HValue* value) {
923 HValue* parameter_count = builder_->graph()->GetConstantMinus1(); 937 HValue* parameter_count = builder_->graph()->GetConstantMinus1();
924 builder_->FinishExitCurrentBlock( 938 builder_->FinishExitCurrentBlock(
925 builder_->New<HReturn>(value, parameter_count)); 939 builder_->New<HReturn>(value, parameter_count));
926 if (did_else_) { 940 AddMergeAtJoinBlock(false);
927 first_false_block_ = NULL;
928 } else {
929 first_true_block_ = NULL;
930 }
931 } 941 }
932 942
933 943
934 void HGraphBuilder::IfBuilder::End() { 944 void HGraphBuilder::IfBuilder::Finish() {
935 if (!captured_) { 945 ASSERT(!finished_);
936 ASSERT(did_then_); 946 if (!did_then_) {
937 if (!did_else_) { 947 Then();
938 last_true_block_ = builder_->current_block(); 948 }
939 } 949 AddMergeAtJoinBlock(false);
940 if (last_true_block_ == NULL || last_true_block_->IsFinished()) { 950 if (!did_else_) {
941 ASSERT(did_else_); 951 Else();
942 // Return on true. Nothing to do, just continue the false block. 952 AddMergeAtJoinBlock(false);
943 } else if (first_false_block_ == NULL ||
944 (did_else_ && builder_->current_block()->IsFinished())) {
945 // Deopt on false. Nothing to do except switching to the true block.
946 builder_->set_current_block(last_true_block_);
947 } else {
948 merge_block_ = builder_->graph()->CreateBasicBlock();
949 ASSERT(!finished_);
950 if (!did_else_) Else();
951 ASSERT(!last_true_block_->IsFinished());
952 HBasicBlock* last_false_block = builder_->current_block();
953 ASSERT(!last_false_block->IsFinished());
954 if (deopt_then_) {
955 builder_->GotoNoSimulate(last_false_block, merge_block_);
956 builder_->PadEnvironmentForContinuation(last_true_block_,
957 merge_block_);
958 builder_->GotoNoSimulate(last_true_block_, merge_block_);
959 } else {
960 builder_->GotoNoSimulate(last_true_block_, merge_block_);
961 if (deopt_else_) {
962 builder_->PadEnvironmentForContinuation(last_false_block,
963 merge_block_);
964 }
965 builder_->GotoNoSimulate(last_false_block, merge_block_);
966 }
967 builder_->set_current_block(merge_block_);
968 }
969 } 953 }
970 finished_ = true; 954 finished_ = true;
971 } 955 }
972 956
973 957
958 void HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation,
959 HBasicBlock** else_continuation) {
960 Finish();
961
962 MergeAtJoinBlock* else_record = merge_at_join_blocks_;
963 if (else_continuation != NULL) {
964 *else_continuation = else_record->block_;
965 }
966 MergeAtJoinBlock* then_record = else_record->next_;
967 if (then_continuation != NULL) {
968 *then_continuation = then_record->block_;
969 }
970 ASSERT(then_record->next_ == NULL);
971 }
972
973
974 void HGraphBuilder::IfBuilder::End() {
975 if (captured_) return;
976 Finish();
977
978 int total_merged_blocks = normal_merge_at_join_block_count_ +
979 deopt_merge_at_join_block_count_;
980 ASSERT(total_merged_blocks >= 1);
981 HBasicBlock* merge_block = total_merged_blocks == 1
982 ? NULL : builder_->graph()->CreateBasicBlock();
983
984 // Merge non-deopt blocks first to ensure environment has right size for
985 // padding.
986 MergeAtJoinBlock* current = merge_at_join_blocks_;
987 while (current != NULL) {
988 if (!current->deopt_ && current->block_ != NULL) {
989 // If there is only one block that makes it through to the end of the
990 // if, then just set it as the current block and continue rather then
991 // creating an unnecessary merge block.
992 if (total_merged_blocks == 1) {
993 builder_->set_current_block(current->block_);
994 return;
995 }
996 builder_->GotoNoSimulate(current->block_, merge_block);
997 }
998 current = current->next_;
999 }
1000
1001 // Merge deopt blocks, padding when necessary.
1002 current = merge_at_join_blocks_;
1003 while (current != NULL) {
1004 if (current->deopt_ && current->block_ != NULL) {
1005 builder_->PadEnvironmentForContinuation(current->block_,
1006 merge_block);
1007 builder_->GotoNoSimulate(current->block_, merge_block);
1008 }
1009 current = current->next_;
1010 }
1011 builder_->set_current_block(merge_block);
1012 }
1013
1014
974 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, 1015 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
975 HValue* context, 1016 HValue* context,
976 LoopBuilder::Direction direction) 1017 LoopBuilder::Direction direction)
977 : builder_(builder), 1018 : builder_(builder),
978 context_(context), 1019 context_(context),
979 direction_(direction), 1020 direction_(direction),
980 finished_(false) { 1021 finished_(false) {
981 header_block_ = builder->CreateLoopHeaderBlock(); 1022 header_block_ = builder->CreateLoopHeaderBlock();
982 body_block_ = NULL; 1023 body_block_ = NULL;
983 exit_block_ = NULL; 1024 exit_block_ = NULL;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 1085
1045 void HGraphBuilder::LoopBuilder::Break() { 1086 void HGraphBuilder::LoopBuilder::Break() {
1046 if (exit_trampoline_block_ == NULL) { 1087 if (exit_trampoline_block_ == NULL) {
1047 // Its the first time we saw a break. 1088 // Its the first time we saw a break.
1048 HEnvironment* env = exit_block_->last_environment()->Copy(); 1089 HEnvironment* env = exit_block_->last_environment()->Copy();
1049 exit_trampoline_block_ = builder_->CreateBasicBlock(env); 1090 exit_trampoline_block_ = builder_->CreateBasicBlock(env);
1050 builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); 1091 builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_);
1051 } 1092 }
1052 1093
1053 builder_->GotoNoSimulate(exit_trampoline_block_); 1094 builder_->GotoNoSimulate(exit_trampoline_block_);
1095 builder_->set_current_block(NULL);
1054 } 1096 }
1055 1097
1056 1098
1057 void HGraphBuilder::LoopBuilder::EndBody() { 1099 void HGraphBuilder::LoopBuilder::EndBody() {
1058 ASSERT(!finished_); 1100 ASSERT(!finished_);
1059 1101
1060 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { 1102 if (direction_ == kPostIncrement || direction_ == kPostDecrement) {
1061 if (direction_ == kPostIncrement) { 1103 if (direction_ == kPostIncrement) {
1062 increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); 1104 increment_ = HAdd::New(zone(), context_, phi_, increment_amount_);
1063 } else { 1105 } else {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 if (last->IsReturn() || last->IsAbnormalExit()) { 1154 if (last->IsReturn() || last->IsAbnormalExit()) {
1113 set_current_block(NULL); 1155 set_current_block(NULL);
1114 } 1156 }
1115 } 1157 }
1116 1158
1117 1159
1118 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { 1160 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) {
1119 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() || 1161 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() ||
1120 position_ != RelocInfo::kNoPosition); 1162 position_ != RelocInfo::kNoPosition);
1121 current_block()->FinishExit(instruction, position_); 1163 current_block()->FinishExit(instruction, position_);
1122 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { 1164 set_current_block(NULL);
Michael Starzinger 2013/11/12 09:50:00 This change confuses me. HGraphBuilder::FinishExit
danno 2013/11/14 14:46:40 Done.
1123 set_current_block(NULL);
1124 }
1125 } 1165 }
1126 1166
1127 1167
1128 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { 1168 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
1129 if (FLAG_native_code_counters && counter->Enabled()) { 1169 if (FLAG_native_code_counters && counter->Enabled()) {
1130 HValue* reference = Add<HConstant>(ExternalReference(counter)); 1170 HValue* reference = Add<HConstant>(ExternalReference(counter));
1131 HValue* old_value = Add<HLoadNamedField>(reference, 1171 HValue* old_value = Add<HLoadNamedField>(reference,
1132 HObjectAccess::ForCounter()); 1172 HObjectAccess::ForCounter());
1133 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1()); 1173 HValue* new_value = Add<HAdd>(old_value, graph()->GetConstant1());
1134 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1174 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
(...skipping 8719 matching lines...) Expand 10 before | Expand all | Expand 10 after
9854 if (ShouldProduceTraceOutput()) { 9894 if (ShouldProduceTraceOutput()) {
9855 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9895 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9856 } 9896 }
9857 9897
9858 #ifdef DEBUG 9898 #ifdef DEBUG
9859 graph_->Verify(false); // No full verify. 9899 graph_->Verify(false); // No full verify.
9860 #endif 9900 #endif
9861 } 9901 }
9862 9902
9863 } } // namespace v8::internal 9903 } } // namespace v8::internal
OLDNEW
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698