OLD | NEW |
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 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 } | 821 } |
822 builder_->set_current_block(first_true_block_); | 822 builder_->set_current_block(first_true_block_); |
823 } | 823 } |
824 | 824 |
825 | 825 |
826 void HGraphBuilder::IfBuilder::Else() { | 826 void HGraphBuilder::IfBuilder::Else() { |
827 ASSERT(did_then_); | 827 ASSERT(did_then_); |
828 ASSERT(!captured_); | 828 ASSERT(!captured_); |
829 ASSERT(!finished_); | 829 ASSERT(!finished_); |
830 last_true_block_ = builder_->current_block(); | 830 last_true_block_ = builder_->current_block(); |
831 ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished()); | |
832 builder_->set_current_block(first_false_block_); | 831 builder_->set_current_block(first_false_block_); |
833 did_else_ = true; | 832 did_else_ = true; |
834 } | 833 } |
835 | 834 |
836 | 835 |
837 void HGraphBuilder::IfBuilder::Deopt(const char* reason) { | 836 void HGraphBuilder::IfBuilder::Deopt(const char* reason) { |
838 ASSERT(did_then_); | 837 ASSERT(did_then_); |
839 if (did_else_) { | 838 if (did_else_) { |
840 deopt_else_ = true; | 839 deopt_else_ = true; |
841 } else { | 840 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
857 } | 856 } |
858 } | 857 } |
859 | 858 |
860 | 859 |
861 void HGraphBuilder::IfBuilder::End() { | 860 void HGraphBuilder::IfBuilder::End() { |
862 if (!captured_) { | 861 if (!captured_) { |
863 ASSERT(did_then_); | 862 ASSERT(did_then_); |
864 if (!did_else_) { | 863 if (!did_else_) { |
865 last_true_block_ = builder_->current_block(); | 864 last_true_block_ = builder_->current_block(); |
866 } | 865 } |
867 if (first_true_block_ == NULL) { | 866 if (last_true_block_ == NULL || last_true_block_->IsFinished()) { |
| 867 ASSERT(did_else_); |
868 // Return on true. Nothing to do, just continue the false block. | 868 // Return on true. Nothing to do, just continue the false block. |
869 } else if (first_false_block_ == NULL) { | 869 } else if (first_false_block_ == NULL || |
| 870 (did_else_ && builder_->current_block()->IsFinished())) { |
870 // Deopt on false. Nothing to do except switching to the true block. | 871 // Deopt on false. Nothing to do except switching to the true block. |
871 builder_->set_current_block(last_true_block_); | 872 builder_->set_current_block(last_true_block_); |
872 } else { | 873 } else { |
873 merge_block_ = builder_->graph()->CreateBasicBlock(); | 874 merge_block_ = builder_->graph()->CreateBasicBlock(); |
874 ASSERT(!finished_); | 875 ASSERT(!finished_); |
875 if (!did_else_) Else(); | 876 if (!did_else_) Else(); |
876 ASSERT(!last_true_block_->IsFinished()); | 877 ASSERT(!last_true_block_->IsFinished()); |
877 HBasicBlock* last_false_block = builder_->current_block(); | 878 HBasicBlock* last_false_block = builder_->current_block(); |
878 ASSERT(!last_false_block->IsFinished()); | 879 ASSERT(!last_false_block->IsFinished()); |
879 if (deopt_then_) { | 880 if (deopt_then_) { |
(...skipping 19 matching lines...) Expand all Loading... |
899 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, | 900 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
900 HValue* context, | 901 HValue* context, |
901 LoopBuilder::Direction direction) | 902 LoopBuilder::Direction direction) |
902 : builder_(builder), | 903 : builder_(builder), |
903 context_(context), | 904 context_(context), |
904 direction_(direction), | 905 direction_(direction), |
905 finished_(false) { | 906 finished_(false) { |
906 header_block_ = builder->CreateLoopHeaderBlock(); | 907 header_block_ = builder->CreateLoopHeaderBlock(); |
907 body_block_ = NULL; | 908 body_block_ = NULL; |
908 exit_block_ = NULL; | 909 exit_block_ = NULL; |
| 910 exit_trampoline_block_ = NULL; |
| 911 increment_amount_ = builder_->graph()->GetConstant1(); |
909 } | 912 } |
910 | 913 |
911 | 914 |
| 915 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, |
| 916 HValue* context, |
| 917 LoopBuilder::Direction direction, |
| 918 HValue* increment_amount) |
| 919 : builder_(builder), |
| 920 context_(context), |
| 921 direction_(direction), |
| 922 finished_(false) { |
| 923 header_block_ = builder->CreateLoopHeaderBlock(); |
| 924 body_block_ = NULL; |
| 925 exit_block_ = NULL; |
| 926 exit_trampoline_block_ = NULL; |
| 927 increment_amount_ = increment_amount; |
| 928 } |
| 929 |
| 930 |
912 HValue* HGraphBuilder::LoopBuilder::BeginBody( | 931 HValue* HGraphBuilder::LoopBuilder::BeginBody( |
913 HValue* initial, | 932 HValue* initial, |
914 HValue* terminating, | 933 HValue* terminating, |
915 Token::Value token) { | 934 Token::Value token) { |
916 HEnvironment* env = builder_->environment(); | 935 HEnvironment* env = builder_->environment(); |
917 phi_ = header_block_->AddNewPhi(env->values()->length()); | 936 phi_ = header_block_->AddNewPhi(env->values()->length()); |
918 phi_->AddInput(initial); | 937 phi_->AddInput(initial); |
919 env->Push(initial); | 938 env->Push(initial); |
920 builder_->current_block()->GotoNoSimulate(header_block_); | 939 builder_->current_block()->GotoNoSimulate(header_block_); |
921 | 940 |
922 HEnvironment* body_env = env->Copy(); | 941 HEnvironment* body_env = env->Copy(); |
923 HEnvironment* exit_env = env->Copy(); | 942 HEnvironment* exit_env = env->Copy(); |
| 943 // Remove the phi from the expression stack |
| 944 body_env->Pop(); |
| 945 exit_env->Pop(); |
924 body_block_ = builder_->CreateBasicBlock(body_env); | 946 body_block_ = builder_->CreateBasicBlock(body_env); |
925 exit_block_ = builder_->CreateBasicBlock(exit_env); | 947 exit_block_ = builder_->CreateBasicBlock(exit_env); |
926 // Remove the phi from the expression stack | |
927 body_env->Pop(); | |
928 | 948 |
929 builder_->set_current_block(header_block_); | 949 builder_->set_current_block(header_block_); |
| 950 env->Pop(); |
930 HCompareNumericAndBranch* compare = | 951 HCompareNumericAndBranch* compare = |
931 new(zone()) HCompareNumericAndBranch(phi_, terminating, token); | 952 new(zone()) HCompareNumericAndBranch(phi_, terminating, token); |
932 compare->SetSuccessorAt(0, body_block_); | 953 compare->SetSuccessorAt(0, body_block_); |
933 compare->SetSuccessorAt(1, exit_block_); | 954 compare->SetSuccessorAt(1, exit_block_); |
934 builder_->current_block()->Finish(compare); | 955 builder_->current_block()->Finish(compare); |
935 | 956 |
936 builder_->set_current_block(body_block_); | 957 builder_->set_current_block(body_block_); |
937 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { | 958 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { |
938 HValue* one = builder_->graph()->GetConstant1(); | 959 HValue* one = builder_->graph()->GetConstant1(); |
939 if (direction_ == kPreIncrement) { | 960 if (direction_ == kPreIncrement) { |
940 increment_ = HAdd::New(zone(), context_, phi_, one); | 961 increment_ = HAdd::New(zone(), context_, phi_, one); |
941 } else { | 962 } else { |
942 increment_ = HSub::New(zone(), context_, phi_, one); | 963 increment_ = HSub::New(zone(), context_, phi_, one); |
943 } | 964 } |
944 increment_->ClearFlag(HValue::kCanOverflow); | 965 increment_->ClearFlag(HValue::kCanOverflow); |
945 builder_->AddInstruction(increment_); | 966 builder_->AddInstruction(increment_); |
946 return increment_; | 967 return increment_; |
947 } else { | 968 } else { |
948 return phi_; | 969 return phi_; |
949 } | 970 } |
950 } | 971 } |
951 | 972 |
952 | 973 |
| 974 void HGraphBuilder::LoopBuilder::Break() { |
| 975 if (exit_trampoline_block_ == NULL) { |
| 976 // Its the first time we saw a break. |
| 977 HEnvironment* env = exit_block_->last_environment()->Copy(); |
| 978 exit_trampoline_block_ = builder_->CreateBasicBlock(env); |
| 979 exit_block_->GotoNoSimulate(exit_trampoline_block_); |
| 980 } |
| 981 |
| 982 builder_->current_block()->GotoNoSimulate(exit_trampoline_block_); |
| 983 } |
| 984 |
| 985 |
953 void HGraphBuilder::LoopBuilder::EndBody() { | 986 void HGraphBuilder::LoopBuilder::EndBody() { |
954 ASSERT(!finished_); | 987 ASSERT(!finished_); |
955 | 988 |
956 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { | 989 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { |
957 HValue* one = builder_->graph()->GetConstant1(); | |
958 if (direction_ == kPostIncrement) { | 990 if (direction_ == kPostIncrement) { |
959 increment_ = HAdd::New(zone(), context_, phi_, one); | 991 increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); |
960 } else { | 992 } else { |
961 increment_ = HSub::New(zone(), context_, phi_, one); | 993 increment_ = HSub::New(zone(), context_, phi_, increment_amount_); |
962 } | 994 } |
963 increment_->ClearFlag(HValue::kCanOverflow); | 995 increment_->ClearFlag(HValue::kCanOverflow); |
964 builder_->AddInstruction(increment_); | 996 builder_->AddInstruction(increment_); |
965 } | 997 } |
966 | 998 |
967 // Push the new increment value on the expression stack to merge into the phi. | 999 // Push the new increment value on the expression stack to merge into the phi. |
968 builder_->environment()->Push(increment_); | 1000 builder_->environment()->Push(increment_); |
969 HBasicBlock* last_block = builder_->current_block(); | 1001 HBasicBlock* last_block = builder_->current_block(); |
970 last_block->GotoNoSimulate(header_block_); | 1002 last_block->GotoNoSimulate(header_block_); |
971 header_block_->loop_information()->RegisterBackEdge(last_block); | 1003 header_block_->loop_information()->RegisterBackEdge(last_block); |
972 | 1004 |
973 builder_->set_current_block(exit_block_); | 1005 if (exit_trampoline_block_ != NULL) { |
974 // Pop the phi from the expression stack | 1006 builder_->set_current_block(exit_trampoline_block_); |
975 builder_->environment()->Pop(); | 1007 } else { |
| 1008 builder_->set_current_block(exit_block_); |
| 1009 } |
976 finished_ = true; | 1010 finished_ = true; |
977 } | 1011 } |
978 | 1012 |
979 | 1013 |
980 HGraph* HGraphBuilder::CreateGraph() { | 1014 HGraph* HGraphBuilder::CreateGraph() { |
981 graph_ = new(zone()) HGraph(info_); | 1015 graph_ = new(zone()) HGraph(info_); |
982 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); | 1016 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); |
983 CompilationPhase phase("H_Block building", info_); | 1017 CompilationPhase phase("H_Block building", info_); |
984 set_current_block(graph()->entry_block()); | 1018 set_current_block(graph()->entry_block()); |
985 if (!BuildGraph()) return NULL; | 1019 if (!BuildGraph()) return NULL; |
(...skipping 8863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9849 if (ShouldProduceTraceOutput()) { | 9883 if (ShouldProduceTraceOutput()) { |
9850 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9884 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9851 } | 9885 } |
9852 | 9886 |
9853 #ifdef DEBUG | 9887 #ifdef DEBUG |
9854 graph_->Verify(false); // No full verify. | 9888 graph_->Verify(false); // No full verify. |
9855 #endif | 9889 #endif |
9856 } | 9890 } |
9857 | 9891 |
9858 } } // namespace v8::internal | 9892 } } // namespace v8::internal |
OLD | NEW |