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

Side by Side Diff: src/hydrogen.cc

Issue 18331004: Refactoring and cleanup of control instructions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More tweaks Created 7 years, 5 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
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 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 first_true_block_(NULL), 713 first_true_block_(NULL),
714 first_false_block_(NULL), 714 first_false_block_(NULL),
715 split_edge_merge_block_(NULL), 715 split_edge_merge_block_(NULL),
716 merge_block_(NULL) { 716 merge_block_(NULL) {
717 continuation->Continue(&first_true_block_, 717 continuation->Continue(&first_true_block_,
718 &first_false_block_, 718 &first_false_block_,
719 &position_); 719 &position_);
720 } 720 }
721 721
722 722
723 HInstruction* HGraphBuilder::IfBuilder::IfCompare(
724 HValue* left,
725 HValue* right,
726 Token::Value token) {
727 HCompareIDAndBranch* compare =
728 new(zone()) HCompareIDAndBranch(left, right, token);
729 AddCompare(compare);
730 return compare;
731 }
732
733
734 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left,
735 Handle<Map> map) {
736 HCompareMap* compare =
737 new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_);
738 AddCompare(compare);
739 return compare;
740 }
741
742
743 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) { 723 void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
744 if (split_edge_merge_block_ != NULL) { 724 if (split_edge_merge_block_ != NULL) {
745 HEnvironment* env = first_false_block_->last_environment(); 725 HEnvironment* env = first_false_block_->last_environment();
746 HBasicBlock* split_edge = 726 HBasicBlock* split_edge =
747 builder_->CreateBasicBlock(env->Copy()); 727 builder_->CreateBasicBlock(env->Copy());
748 if (did_or_) { 728 if (did_or_) {
749 compare->SetSuccessorAt(0, split_edge); 729 compare->SetSuccessorAt(0, split_edge);
750 compare->SetSuccessorAt(1, first_false_block_); 730 compare->SetSuccessorAt(1, first_false_block_);
751 } else { 731 } else {
752 compare->SetSuccessorAt(0, first_true_block_); 732 compare->SetSuccessorAt(0, first_true_block_);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 did_then_ = true; 793 did_then_ = true;
814 if (needs_compare_) { 794 if (needs_compare_) {
815 // Handle if's without any expressions, they jump directly to the "else" 795 // Handle if's without any expressions, they jump directly to the "else"
816 // branch. However, we must pretend that the "then" branch is reachable, 796 // branch. However, we must pretend that the "then" branch is reachable,
817 // so that the graph builder visits it and sees any live range extending 797 // so that the graph builder visits it and sees any live range extending
818 // constructs within it. 798 // constructs within it.
819 HConstant* constant_false = builder_->graph()->GetConstantFalse(); 799 HConstant* constant_false = builder_->graph()->GetConstantFalse();
820 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); 800 ToBooleanStub::Types boolean_type = ToBooleanStub::Types();
821 boolean_type.Add(ToBooleanStub::BOOLEAN); 801 boolean_type.Add(ToBooleanStub::BOOLEAN);
822 HBranch* branch = 802 HBranch* branch =
823 new(zone()) HBranch(constant_false, first_true_block_, 803 new(zone()) HBranch(constant_false, boolean_type, first_true_block_,
824 first_false_block_, boolean_type); 804 first_false_block_);
825 builder_->current_block()->Finish(branch); 805 builder_->current_block()->Finish(branch);
826 } 806 }
827 builder_->set_current_block(first_true_block_); 807 builder_->set_current_block(first_true_block_);
828 } 808 }
829 809
830 810
831 void HGraphBuilder::IfBuilder::Else() { 811 void HGraphBuilder::IfBuilder::Else() {
832 ASSERT(did_then_); 812 ASSERT(did_then_);
833 ASSERT(!captured_); 813 ASSERT(!captured_);
834 ASSERT(!finished_); 814 ASSERT(!finished_);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 builder_->current_block()->GotoNoSimulate(header_block_); 898 builder_->current_block()->GotoNoSimulate(header_block_);
919 899
920 HEnvironment* body_env = env->Copy(); 900 HEnvironment* body_env = env->Copy();
921 HEnvironment* exit_env = env->Copy(); 901 HEnvironment* exit_env = env->Copy();
922 body_block_ = builder_->CreateBasicBlock(body_env); 902 body_block_ = builder_->CreateBasicBlock(body_env);
923 exit_block_ = builder_->CreateBasicBlock(exit_env); 903 exit_block_ = builder_->CreateBasicBlock(exit_env);
924 // Remove the phi from the expression stack 904 // Remove the phi from the expression stack
925 body_env->Pop(); 905 body_env->Pop();
926 906
927 builder_->set_current_block(header_block_); 907 builder_->set_current_block(header_block_);
928 HCompareIDAndBranch* compare = 908 HCompareNumericAndBranch* compare =
929 new(zone()) HCompareIDAndBranch(phi_, terminating, token); 909 new(zone()) HCompareNumericAndBranch(phi_, terminating, token);
930 compare->SetSuccessorAt(0, body_block_); 910 compare->SetSuccessorAt(0, body_block_);
931 compare->SetSuccessorAt(1, exit_block_); 911 compare->SetSuccessorAt(1, exit_block_);
932 builder_->current_block()->Finish(compare); 912 builder_->current_block()->Finish(compare);
933 913
934 builder_->set_current_block(body_block_); 914 builder_->set_current_block(body_block_);
935 if (direction_ == kPreIncrement || direction_ == kPreDecrement) { 915 if (direction_ == kPreIncrement || direction_ == kPreDecrement) {
936 HValue* one = builder_->graph()->GetConstant1(); 916 HValue* one = builder_->graph()->GetConstant1();
937 if (direction_ == kPreIncrement) { 917 if (direction_ == kPreIncrement) {
938 increment_ = HAdd::New(zone(), context_, phi_, one); 918 increment_ = HAdd::New(zone(), context_, phi_, one);
939 } else { 919 } else {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 1113
1134 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, 1114 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
1135 HValue* elements, 1115 HValue* elements,
1136 ElementsKind kind, 1116 ElementsKind kind,
1137 HValue* length, 1117 HValue* length,
1138 HValue* key, 1118 HValue* key,
1139 bool is_js_array) { 1119 bool is_js_array) {
1140 Zone* zone = this->zone(); 1120 Zone* zone = this->zone();
1141 IfBuilder length_checker(this); 1121 IfBuilder length_checker(this);
1142 1122
1143 length_checker.IfCompare(length, key, Token::EQ); 1123 length_checker.If<HCompareNumericAndBranch>(length, key, Token::EQ);
1144 length_checker.Then(); 1124 length_checker.Then();
1145 1125
1146 HValue* current_capacity = Add<HFixedArrayBaseLength>(elements); 1126 HValue* current_capacity = Add<HFixedArrayBaseLength>(elements);
1147 1127
1148 IfBuilder capacity_checker(this); 1128 IfBuilder capacity_checker(this);
1149 1129
1150 capacity_checker.IfCompare(length, current_capacity, Token::EQ); 1130 capacity_checker.If<HCompareNumericAndBranch>(length, current_capacity,
1131 Token::EQ);
1151 capacity_checker.Then(); 1132 capacity_checker.Then();
1152 1133
1153 HValue* context = environment()->LookupContext(); 1134 HValue* context = environment()->LookupContext();
1154 1135
1155 HValue* new_capacity = 1136 HValue* new_capacity =
1156 BuildNewElementsCapacity(context, current_capacity); 1137 BuildNewElementsCapacity(context, current_capacity);
1157 1138
1158 HValue* new_elements = BuildGrowElementsCapacity(object, elements, 1139 HValue* new_elements = BuildGrowElementsCapacity(object, elements,
1159 kind, length, 1140 kind, length,
1160 new_capacity); 1141 new_capacity);
(...skipping 27 matching lines...) Expand all
1188 1169
1189 1170
1190 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, 1171 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object,
1191 HValue* elements, 1172 HValue* elements,
1192 ElementsKind kind, 1173 ElementsKind kind,
1193 HValue* length) { 1174 HValue* length) {
1194 Heap* heap = isolate()->heap(); 1175 Heap* heap = isolate()->heap();
1195 1176
1196 IfBuilder cow_checker(this); 1177 IfBuilder cow_checker(this);
1197 1178
1198 cow_checker.IfCompareMap(elements, 1179 cow_checker.If<HCompareMap>(elements,
1199 Handle<Map>(heap->fixed_cow_array_map())); 1180 Handle<Map>(heap->fixed_cow_array_map()));
Michael Starzinger 2013/07/01 12:30:39 nit: Use factory->fixed_cow_array_map() instead.
danno 2013/07/05 09:52:39 Done.
1200 cow_checker.Then(); 1181 cow_checker.Then();
1201 1182
1202 HValue* capacity = Add<HFixedArrayBaseLength>(elements); 1183 HValue* capacity = Add<HFixedArrayBaseLength>(elements);
1203 1184
1204 HValue* new_elements = BuildGrowElementsCapacity(object, elements, 1185 HValue* new_elements = BuildGrowElementsCapacity(object, elements,
1205 kind, length, capacity); 1186 kind, length, capacity);
1206 1187
1207 environment()->Push(new_elements); 1188 environment()->Push(new_elements);
1208 1189
1209 cow_checker.Else(); 1190 cow_checker.Else();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 } else { 1239 } else {
1259 length = Add<HFixedArrayBaseLength>(elements); 1240 length = Add<HFixedArrayBaseLength>(elements);
1260 } 1241 }
1261 HValue* checked_key = NULL; 1242 HValue* checked_key = NULL;
1262 if (IsExternalArrayElementsKind(elements_kind)) { 1243 if (IsExternalArrayElementsKind(elements_kind)) {
1263 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1244 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1264 NoObservableSideEffectsScope no_effects(this); 1245 NoObservableSideEffectsScope no_effects(this);
1265 HLoadExternalArrayPointer* external_elements = 1246 HLoadExternalArrayPointer* external_elements =
1266 Add<HLoadExternalArrayPointer>(elements); 1247 Add<HLoadExternalArrayPointer>(elements);
1267 IfBuilder length_checker(this); 1248 IfBuilder length_checker(this);
1268 length_checker.IfCompare(key, length, Token::LT); 1249 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
1269 length_checker.Then(); 1250 length_checker.Then();
1270 IfBuilder negative_checker(this); 1251 IfBuilder negative_checker(this);
1271 HValue* bounds_check = negative_checker.IfCompare( 1252 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
1272 key, graph()->GetConstant0(), Token::GTE); 1253 key, graph()->GetConstant0(), Token::GTE);
1273 negative_checker.Then(); 1254 negative_checker.Then();
1274 HInstruction* result = BuildExternalArrayElementAccess( 1255 HInstruction* result = BuildExternalArrayElementAccess(
1275 external_elements, key, val, bounds_check, 1256 external_elements, key, val, bounds_check,
1276 elements_kind, is_store); 1257 elements_kind, is_store);
1277 AddInstruction(result); 1258 AddInstruction(result);
1278 negative_checker.ElseDeopt(); 1259 negative_checker.ElseDeopt();
1279 length_checker.End(); 1260 length_checker.End();
1280 return result; 1261 return result;
1281 } else { 1262 } else {
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 class HRangeAnalysis BASE_EMBEDDED { 2567 class HRangeAnalysis BASE_EMBEDDED {
2587 public: 2568 public:
2588 explicit HRangeAnalysis(HGraph* graph) : 2569 explicit HRangeAnalysis(HGraph* graph) :
2589 graph_(graph), zone_(graph->zone()), changed_ranges_(16, zone_) { } 2570 graph_(graph), zone_(graph->zone()), changed_ranges_(16, zone_) { }
2590 2571
2591 void Analyze(); 2572 void Analyze();
2592 2573
2593 private: 2574 private:
2594 void TraceRange(const char* msg, ...); 2575 void TraceRange(const char* msg, ...);
2595 void Analyze(HBasicBlock* block); 2576 void Analyze(HBasicBlock* block);
2596 void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest); 2577 void InferControlFlowRange(HCompareNumericAndBranch* test, HBasicBlock* dest);
2597 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other); 2578 void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other);
2598 void InferRange(HValue* value); 2579 void InferRange(HValue* value);
2599 void RollBackTo(int index); 2580 void RollBackTo(int index);
2600 void AddRange(HValue* value, Range* range); 2581 void AddRange(HValue* value, Range* range);
2601 2582
2602 HGraph* graph_; 2583 HGraph* graph_;
2603 Zone* zone_; 2584 Zone* zone_;
2604 ZoneList<HValue*> changed_ranges_; 2585 ZoneList<HValue*> changed_ranges_;
2605 }; 2586 };
2606 2587
(...skipping 15 matching lines...) Expand all
2622 2603
2623 2604
2624 void HRangeAnalysis::Analyze(HBasicBlock* block) { 2605 void HRangeAnalysis::Analyze(HBasicBlock* block) {
2625 TraceRange("Analyzing block B%d\n", block->block_id()); 2606 TraceRange("Analyzing block B%d\n", block->block_id());
2626 2607
2627 int last_changed_range = changed_ranges_.length() - 1; 2608 int last_changed_range = changed_ranges_.length() - 1;
2628 2609
2629 // Infer range based on control flow. 2610 // Infer range based on control flow.
2630 if (block->predecessors()->length() == 1) { 2611 if (block->predecessors()->length() == 1) {
2631 HBasicBlock* pred = block->predecessors()->first(); 2612 HBasicBlock* pred = block->predecessors()->first();
2632 if (pred->end()->IsCompareIDAndBranch()) { 2613 if (pred->end()->IsCompareNumericAndBranch()) {
2633 InferControlFlowRange(HCompareIDAndBranch::cast(pred->end()), block); 2614 InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()), block);
2634 } 2615 }
2635 } 2616 }
2636 2617
2637 // Process phi instructions. 2618 // Process phi instructions.
2638 for (int i = 0; i < block->phis()->length(); ++i) { 2619 for (int i = 0; i < block->phis()->length(); ++i) {
2639 HPhi* phi = block->phis()->at(i); 2620 HPhi* phi = block->phis()->at(i);
2640 InferRange(phi); 2621 InferRange(phi);
2641 } 2622 }
2642 2623
2643 // Go through all instructions of the current block. 2624 // Go through all instructions of the current block.
2644 HInstruction* instr = block->first(); 2625 HInstruction* instr = block->first();
2645 while (instr != block->end()) { 2626 while (instr != block->end()) {
2646 InferRange(instr); 2627 InferRange(instr);
2647 instr = instr->next(); 2628 instr = instr->next();
2648 } 2629 }
2649 2630
2650 // Continue analysis in all dominated blocks. 2631 // Continue analysis in all dominated blocks.
2651 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { 2632 for (int i = 0; i < block->dominated_blocks()->length(); ++i) {
2652 Analyze(block->dominated_blocks()->at(i)); 2633 Analyze(block->dominated_blocks()->at(i));
2653 } 2634 }
2654 2635
2655 RollBackTo(last_changed_range); 2636 RollBackTo(last_changed_range);
2656 } 2637 }
2657 2638
2658 2639
2659 void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test, 2640 void HRangeAnalysis::InferControlFlowRange(HCompareNumericAndBranch* test,
2660 HBasicBlock* dest) { 2641 HBasicBlock* dest) {
2661 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); 2642 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
2662 if (test->representation().IsSmiOrInteger32()) { 2643 if (test->representation().IsSmiOrInteger32()) {
2663 Token::Value op = test->token(); 2644 Token::Value op = test->token();
2664 if (test->SecondSuccessor() == dest) { 2645 if (test->SecondSuccessor() == dest) {
2665 op = Token::NegateCompareOp(op); 2646 op = Token::NegateCompareOp(op);
2666 } 2647 }
2667 Token::Value inverted_op = Token::ReverseCompareOp(op); 2648 Token::Value inverted_op = Token::ReverseCompareOp(op);
2668 UpdateControlFlowRange(op, test->left(), test->right()); 2649 UpdateControlFlowRange(op, test->left(), test->right());
2669 UpdateControlFlowRange(inverted_op, test->right(), test->left()); 2650 UpdateControlFlowRange(inverted_op, test->right(), test->left());
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
3074 HValue* input = phi->OperandAt(i); 3055 HValue* input = phi->OperandAt(i);
3075 if (input->IsPhi()) { 3056 if (input->IsPhi()) {
3076 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input)); 3057 RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi::cast(input));
3077 } 3058 }
3078 } 3059 }
3079 } 3060 }
3080 3061
3081 3062
3082 void HGraph::MarkDeoptimizeOnUndefined() { 3063 void HGraph::MarkDeoptimizeOnUndefined() {
3083 HPhase phase("H_MarkDeoptimizeOnUndefined", this); 3064 HPhase phase("H_MarkDeoptimizeOnUndefined", this);
3084 // Compute DeoptimizeOnUndefined flag for phis. 3065 // Compute DeoptimizeOnUndefined flag for phis. Any phi that can reach a use
3085 // Any phi that can reach a use with DeoptimizeOnUndefined set must 3066 // with DeoptimizeOnUndefined set must have DeoptimizeOnUndefined set.
3086 // have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with 3067 // Currently only HCompareNumericAndBranch, with double input representation,
3087 // double input representation, has this flag set. 3068 // has this flag set. The flag is used by HChange tagged->double, which must
3088 // The flag is used by HChange tagged->double, which must deoptimize 3069 // deoptimize if one of its uses has this flag set.
3089 // if one of its uses has this flag set.
3090 for (int i = 0; i < phi_list()->length(); i++) { 3070 for (int i = 0; i < phi_list()->length(); i++) {
3091 HPhi* phi = phi_list()->at(i); 3071 HPhi* phi = phi_list()->at(i);
3092 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { 3072 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
3093 HValue* use_value = it.value(); 3073 HValue* use_value = it.value();
3094 if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) { 3074 if (!use_value->CheckFlag(HValue::kAllowUndefinedAsNaN)) {
3095 RecursivelyMarkPhiDeoptimizeOnUndefined(phi); 3075 RecursivelyMarkPhiDeoptimizeOnUndefined(phi);
3096 break; 3076 break;
3097 } 3077 }
3098 } 3078 }
3099 } 3079 }
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after
3603 builder->current_block()->Goto(if_true(), builder->function_state()); 3583 builder->current_block()->Goto(if_true(), builder->function_state());
3604 } else { 3584 } else {
3605 builder->current_block()->Goto(if_false(), builder->function_state()); 3585 builder->current_block()->Goto(if_false(), builder->function_state());
3606 } 3586 }
3607 builder->set_current_block(NULL); 3587 builder->set_current_block(NULL);
3608 return; 3588 return;
3609 } 3589 }
3610 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); 3590 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
3611 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); 3591 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
3612 ToBooleanStub::Types expected(condition()->to_boolean_types()); 3592 ToBooleanStub::Types expected(condition()->to_boolean_types());
3613 HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected); 3593 HBranch* test = new(zone()) HBranch(value, expected, empty_true, empty_false);
3614 builder->current_block()->Finish(test); 3594 builder->current_block()->Finish(test);
3615 3595
3616 empty_true->Goto(if_true(), builder->function_state()); 3596 empty_true->Goto(if_true(), builder->function_state());
3617 empty_false->Goto(if_false(), builder->function_state()); 3597 empty_false->Goto(if_false(), builder->function_state());
3618 builder->set_current_block(NULL); 3598 builder->set_current_block(NULL);
3619 } 3599 }
3620 3600
3621 3601
3622 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts. 3602 // HOptimizedGraphBuilder infrastructure for bailing out and checking bailouts.
3623 #define CHECK_BAILOUT(call) \ 3603 #define CHECK_BAILOUT(call) \
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
4820 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 4800 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
4821 HBasicBlock* body_block = graph()->CreateBasicBlock(); 4801 HBasicBlock* body_block = graph()->CreateBasicBlock();
4822 4802
4823 HControlInstruction* compare; 4803 HControlInstruction* compare;
4824 4804
4825 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) { 4805 if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
4826 if (!clause->compare_type()->Is(Type::Smi())) { 4806 if (!clause->compare_type()->Is(Type::Smi())) {
4827 AddSoftDeoptimize(); 4807 AddSoftDeoptimize();
4828 } 4808 }
4829 4809
4830 HCompareIDAndBranch* compare_ = 4810 HCompareNumericAndBranch* compare_ =
4831 new(zone()) HCompareIDAndBranch(tag_value, 4811 new(zone()) HCompareNumericAndBranch(tag_value,
4832 label_value, 4812 label_value,
4833 Token::EQ_STRICT); 4813 Token::EQ_STRICT);
4834 compare_->set_observed_input_representation( 4814 compare_->set_observed_input_representation(
4835 Representation::Smi(), Representation::Smi()); 4815 Representation::Smi(), Representation::Smi());
4836 compare = compare_; 4816 compare = compare_;
4837 } else { 4817 } else {
4838 compare = new(zone()) HStringCompareAndBranch(context, tag_value, 4818 compare = new(zone()) HStringCompareAndBranch(context, tag_value,
4839 label_value, 4819 label_value,
4840 Token::EQ_STRICT); 4820 Token::EQ_STRICT);
4841 } 4821 }
4842 4822
4843 compare->SetSuccessorAt(0, body_block); 4823 compare->SetSuccessorAt(0, body_block);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
4928 return statement->OsrEntryId() == current_info()->osr_ast_id(); 4908 return statement->OsrEntryId() == current_info()->osr_ast_id();
4929 } 4909 }
4930 4910
4931 4911
4932 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { 4912 bool HOptimizedGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
4933 if (!HasOsrEntryAt(statement)) return false; 4913 if (!HasOsrEntryAt(statement)) return false;
4934 4914
4935 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); 4915 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
4936 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); 4916 HBasicBlock* osr_entry = graph()->CreateBasicBlock();
4937 HValue* true_value = graph()->GetConstantTrue(); 4917 HValue* true_value = graph()->GetConstantTrue();
4938 HBranch* test = new(zone()) HBranch(true_value, non_osr_entry, osr_entry); 4918 HBranch* test = new(zone()) HBranch(true_value, ToBooleanStub::Types(),
4919 non_osr_entry, osr_entry);
4939 current_block()->Finish(test); 4920 current_block()->Finish(test);
4940 4921
4941 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); 4922 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock();
4942 non_osr_entry->Goto(loop_predecessor); 4923 non_osr_entry->Goto(loop_predecessor);
4943 4924
4944 set_current_block(osr_entry); 4925 set_current_block(osr_entry);
4945 osr_entry->set_osr_entry(); 4926 osr_entry->set_osr_entry();
4946 BailoutId osr_entry_id = statement->OsrEntryId(); 4927 BailoutId osr_entry_id = statement->OsrEntryId();
4947 int first_expression_index = environment()->first_expression_index(); 4928 int first_expression_index = environment()->first_expression_index();
4948 int length = environment()->length(); 4929 int length = environment()->length();
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
5177 bool osr_entry = PreProcessOsrEntry(stmt); 5158 bool osr_entry = PreProcessOsrEntry(stmt);
5178 HBasicBlock* loop_entry = CreateLoopHeaderBlock(); 5159 HBasicBlock* loop_entry = CreateLoopHeaderBlock();
5179 current_block()->Goto(loop_entry); 5160 current_block()->Goto(loop_entry);
5180 set_current_block(loop_entry); 5161 set_current_block(loop_entry);
5181 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); 5162 if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
5182 5163
5183 HValue* index = environment()->ExpressionStackAt(0); 5164 HValue* index = environment()->ExpressionStackAt(0);
5184 HValue* limit = environment()->ExpressionStackAt(1); 5165 HValue* limit = environment()->ExpressionStackAt(1);
5185 5166
5186 // Check that we still have more keys. 5167 // Check that we still have more keys.
5187 HCompareIDAndBranch* compare_index = 5168 HCompareNumericAndBranch* compare_index =
5188 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); 5169 new(zone()) HCompareNumericAndBranch(index, limit, Token::LT);
5189 compare_index->set_observed_input_representation( 5170 compare_index->set_observed_input_representation(
5190 Representation::Smi(), Representation::Smi()); 5171 Representation::Smi(), Representation::Smi());
5191 5172
5192 HBasicBlock* loop_body = graph()->CreateBasicBlock(); 5173 HBasicBlock* loop_body = graph()->CreateBasicBlock();
5193 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 5174 HBasicBlock* loop_successor = graph()->CreateBasicBlock();
5194 5175
5195 compare_index->SetSuccessorAt(0, loop_body); 5176 compare_index->SetSuccessorAt(0, loop_body);
5196 compare_index->SetSuccessorAt(1, loop_successor); 5177 compare_index->SetSuccessorAt(1, loop_successor);
5197 current_block()->Finish(compare_index); 5178 current_block()->Finish(compare_index);
5198 5179
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
6233 LookupResult lookup(isolate()); 6214 LookupResult lookup(isolate());
6234 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6215 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6235 if (count == 0) { 6216 if (count == 0) {
6236 BuildCheckHeapObject(object); 6217 BuildCheckHeapObject(object);
6237 join = graph()->CreateBasicBlock(); 6218 join = graph()->CreateBasicBlock();
6238 } 6219 }
6239 ++count; 6220 ++count;
6240 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6221 HBasicBlock* if_true = graph()->CreateBasicBlock();
6241 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6222 HBasicBlock* if_false = graph()->CreateBasicBlock();
6242 HCompareMap* compare = 6223 HCompareMap* compare =
6243 new(zone()) HCompareMap(object, map, if_true, if_false); 6224 new(zone()) HCompareMap(object, map, if_true, if_false);
6244 current_block()->Finish(compare); 6225 current_block()->Finish(compare);
6245 6226
6246 set_current_block(if_true); 6227 set_current_block(if_true);
6247 HInstruction* instr; 6228 HInstruction* instr;
6248 CHECK_ALIVE( 6229 CHECK_ALIVE(
6249 instr = BuildStoreNamedField(object, name, value, map, &lookup)); 6230 instr = BuildStoreNamedField(object, name, value, map, &lookup));
6250 instr->set_position(position); 6231 instr->set_position(position);
6251 // Goto will add the HSimulate for the store. 6232 // Goto will add the HSimulate for the store.
6252 AddInstruction(instr); 6233 AddInstruction(instr);
6253 if (!ast_context()->IsEffect()) Push(value); 6234 if (!ast_context()->IsEffect()) Push(value);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
6338 BailoutId ast_id) { 6319 BailoutId ast_id) {
6339 LookupResult lookup(isolate()); 6320 LookupResult lookup(isolate());
6340 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 6321 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
6341 if (type == kUseCell) { 6322 if (type == kUseCell) {
6342 Handle<GlobalObject> global(current_info()->global_object()); 6323 Handle<GlobalObject> global(current_info()->global_object());
6343 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); 6324 Handle<PropertyCell> cell(global->GetPropertyCell(&lookup));
6344 if (cell->type()->IsConstant()) { 6325 if (cell->type()->IsConstant()) {
6345 IfBuilder builder(this); 6326 IfBuilder builder(this);
6346 HValue* constant = Add<HConstant>(cell->type()->AsConstant()); 6327 HValue* constant = Add<HConstant>(cell->type()->AsConstant());
6347 if (cell->type()->AsConstant()->IsNumber()) { 6328 if (cell->type()->AsConstant()->IsNumber()) {
6348 builder.IfCompare(value, constant, Token::EQ); 6329 builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ);
6349 } else { 6330 } else {
6350 builder.If<HCompareObjectEqAndBranch>(value, constant); 6331 builder.If<HCompareObjectEqAndBranch>(value, constant);
6351 } 6332 }
6352 builder.Then(); 6333 builder.Then();
6353 builder.Else(); 6334 builder.Else();
6354 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); 6335 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT);
6355 builder.End(); 6336 builder.End();
6356 } 6337 }
6357 HInstruction* instr = 6338 HInstruction* instr =
6358 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 6339 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
(...skipping 2963 matching lines...) Expand 10 before | Expand all | Expand 10 after
9322 CHECK_ALIVE(VisitForValue(expr->right())); 9303 CHECK_ALIVE(VisitForValue(expr->right()));
9323 } 9304 }
9324 return ast_context()->ReturnValue(Pop()); 9305 return ast_context()->ReturnValue(Pop());
9325 } 9306 }
9326 9307
9327 // We need an extra block to maintain edge-split form. 9308 // We need an extra block to maintain edge-split form.
9328 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 9309 HBasicBlock* empty_block = graph()->CreateBasicBlock();
9329 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 9310 HBasicBlock* eval_right = graph()->CreateBasicBlock();
9330 ToBooleanStub::Types expected(expr->left()->to_boolean_types()); 9311 ToBooleanStub::Types expected(expr->left()->to_boolean_types());
9331 HBranch* test = is_logical_and 9312 HBranch* test = is_logical_and
9332 ? new(zone()) HBranch(left_value, eval_right, empty_block, expected) 9313 ? new(zone()) HBranch(left_value, expected, eval_right, empty_block)
9333 : new(zone()) HBranch(left_value, empty_block, eval_right, expected); 9314 : new(zone()) HBranch(left_value, expected, empty_block, eval_right);
9334 current_block()->Finish(test); 9315 current_block()->Finish(test);
9335 9316
9336 set_current_block(eval_right); 9317 set_current_block(eval_right);
9337 Drop(1); // Value of the left subexpression. 9318 Drop(1); // Value of the left subexpression.
9338 CHECK_BAILOUT(VisitForValue(expr->right())); 9319 CHECK_BAILOUT(VisitForValue(expr->right()));
9339 9320
9340 HBasicBlock* join_block = 9321 HBasicBlock* join_block =
9341 CreateJoin(empty_block, current_block(), expr->id()); 9322 CreateJoin(empty_block, current_block(), expr->id());
9342 set_current_block(join_block); 9323 set_current_block(join_block);
9343 return ast_context()->ReturnValue(Pop()); 9324 return ast_context()->ReturnValue(Pop());
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
9630 new(zone()) HCompareGeneric(context, left, right, op); 9611 new(zone()) HCompareGeneric(context, left, right, op);
9631 result->set_observed_input_representation(1, left_rep); 9612 result->set_observed_input_representation(1, left_rep);
9632 result->set_observed_input_representation(2, right_rep); 9613 result->set_observed_input_representation(2, right_rep);
9633 result->set_position(expr->position()); 9614 result->set_position(expr->position());
9634 return ast_context()->ReturnInstruction(result, expr->id()); 9615 return ast_context()->ReturnInstruction(result, expr->id());
9635 } else { 9616 } else {
9636 // TODO(verwaest): Remove once ToRepresentation properly returns Smi when 9617 // TODO(verwaest): Remove once ToRepresentation properly returns Smi when
9637 // the IC measures Smi. 9618 // the IC measures Smi.
9638 if (left_type->Is(Type::Smi())) left_rep = Representation::Smi(); 9619 if (left_type->Is(Type::Smi())) left_rep = Representation::Smi();
9639 if (right_type->Is(Type::Smi())) right_rep = Representation::Smi(); 9620 if (right_type->Is(Type::Smi())) right_rep = Representation::Smi();
9640 HCompareIDAndBranch* result = 9621 HCompareNumericAndBranch* result =
9641 new(zone()) HCompareIDAndBranch(left, right, op); 9622 new(zone()) HCompareNumericAndBranch(left, right, op);
9642 result->set_observed_input_representation(left_rep, right_rep); 9623 result->set_observed_input_representation(left_rep, right_rep);
9643 result->set_position(expr->position()); 9624 result->set_position(expr->position());
9644 return ast_context()->ReturnControl(result, expr->id()); 9625 return ast_context()->ReturnControl(result, expr->id());
9645 } 9626 }
9646 } 9627 }
9647 } 9628 }
9648 9629
9649 9630
9650 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 9631 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
9651 HValue* value, 9632 HValue* value,
(...skipping 1629 matching lines...) Expand 10 before | Expand all | Expand 10 after
11281 if (ShouldProduceTraceOutput()) { 11262 if (ShouldProduceTraceOutput()) {
11282 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11263 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11283 } 11264 }
11284 11265
11285 #ifdef DEBUG 11266 #ifdef DEBUG
11286 graph_->Verify(false); // No full verify. 11267 graph_->Verify(false); // No full verify.
11287 #endif 11268 #endif
11288 } 11269 }
11289 11270
11290 } } // namespace v8::internal 11271 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698