OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 } | 780 } |
781 | 781 |
782 | 782 |
783 AstGraphBuilder::Environment* | 783 AstGraphBuilder::Environment* |
784 AstGraphBuilder::Environment::CopyAsUnreachable() { | 784 AstGraphBuilder::Environment::CopyAsUnreachable() { |
785 Environment* env = new (zone()) Environment(this, nullptr); | 785 Environment* env = new (zone()) Environment(this, nullptr); |
786 env->MarkAsUnreachable(); | 786 env->MarkAsUnreachable(); |
787 return env; | 787 return env; |
788 } | 788 } |
789 | 789 |
| 790 AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForOsrEntry() { |
| 791 return new (zone()) |
| 792 Environment(this, builder_->liveness_analyzer()->NewBlock()); |
| 793 } |
790 | 794 |
791 AstGraphBuilder::Environment* | 795 AstGraphBuilder::Environment* |
792 AstGraphBuilder::Environment::CopyAndShareLiveness() { | 796 AstGraphBuilder::Environment::CopyAndShareLiveness() { |
793 if (liveness_block() != nullptr) { | 797 if (liveness_block() != nullptr) { |
794 // Finish the current liveness block before copying. | 798 // Finish the current liveness block before copying. |
795 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); | 799 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); |
796 } | 800 } |
797 Environment* env = new (zone()) Environment(this, liveness_block()); | 801 Environment* env = new (zone()) Environment(this, liveness_block()); |
798 return env; | 802 return env; |
799 } | 803 } |
800 | 804 |
801 | 805 |
802 AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop( | 806 AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop( |
803 BitVector* assigned, bool is_osr) { | 807 BitVector* assigned, bool is_osr) { |
804 PrepareForLoop(assigned, is_osr); | 808 PrepareForLoop(assigned); |
805 return CopyAndShareLiveness(); | 809 Environment* loop = CopyAndShareLiveness(); |
| 810 if (is_osr) { |
| 811 // Create and merge the OSR entry if necessary. |
| 812 Environment* osr_env = CopyForOsrEntry(); |
| 813 osr_env->PrepareForOsrEntry(); |
| 814 loop->Merge(osr_env); |
| 815 } |
| 816 return loop; |
806 } | 817 } |
807 | 818 |
808 | 819 |
809 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 820 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
810 int offset, int count) { | 821 int offset, int count) { |
811 bool should_update = false; | 822 bool should_update = false; |
812 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 823 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
813 if (*state_values == nullptr || (*state_values)->InputCount() != count) { | 824 if (*state_values == nullptr || (*state_values)->InputCount() != count) { |
814 should_update = true; | 825 should_update = true; |
815 } else { | 826 } else { |
(...skipping 3359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4175 // potentially extending an existing Phi node if possible. | 4186 // potentially extending an existing Phi node if possible. |
4176 for (int i = 0; i < static_cast<int>(values_.size()); ++i) { | 4187 for (int i = 0; i < static_cast<int>(values_.size()); ++i) { |
4177 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control); | 4188 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control); |
4178 } | 4189 } |
4179 for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) { | 4190 for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) { |
4180 contexts_[i] = | 4191 contexts_[i] = |
4181 builder_->MergeValue(contexts_[i], other->contexts_[i], control); | 4192 builder_->MergeValue(contexts_[i], other->contexts_[i], control); |
4182 } | 4193 } |
4183 } | 4194 } |
4184 | 4195 |
| 4196 void AstGraphBuilder::Environment::PrepareForOsrEntry() { |
| 4197 int size = static_cast<int>(values()->size()); |
| 4198 Graph* graph = builder_->graph(); |
4185 | 4199 |
4186 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned, | 4200 // Set the control and effect to the OSR loop entry. |
4187 bool is_osr) { | 4201 Node* osr_loop_entry = graph->NewNode(builder_->common()->OsrLoopEntry(), |
| 4202 graph->start(), graph->start()); |
| 4203 UpdateControlDependency(osr_loop_entry); |
| 4204 UpdateEffectDependency(osr_loop_entry); |
| 4205 // Set OSR values. |
| 4206 for (int i = 0; i < size; ++i) { |
| 4207 values()->at(i) = |
| 4208 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); |
| 4209 } |
| 4210 |
| 4211 // Set the contexts. |
| 4212 // The innermost context is the OSR value, and the outer contexts are |
| 4213 // reconstructed by dynamically walking up the context chain. |
| 4214 Node* osr_context = nullptr; |
| 4215 const Operator* op = |
| 4216 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); |
| 4217 const Operator* op_inner = |
| 4218 builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex); |
| 4219 int last = static_cast<int>(contexts()->size() - 1); |
| 4220 for (int i = last; i >= 0; i--) { |
| 4221 osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry) |
| 4222 : graph->NewNode(op, osr_context, osr_context, |
| 4223 osr_loop_entry); |
| 4224 contexts()->at(i) = osr_context; |
| 4225 } |
| 4226 } |
| 4227 |
| 4228 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) { |
4188 int size = static_cast<int>(values()->size()); | 4229 int size = static_cast<int>(values()->size()); |
4189 | 4230 |
4190 Node* control = builder_->NewLoop(); | 4231 Node* control = builder_->NewLoop(); |
4191 if (assigned == nullptr) { | 4232 if (assigned == nullptr) { |
4192 // Assume that everything is updated in the loop. | 4233 // Assume that everything is updated in the loop. |
4193 for (int i = 0; i < size; ++i) { | 4234 for (int i = 0; i < size; ++i) { |
4194 values()->at(i) = builder_->NewPhi(1, values()->at(i), control); | 4235 values()->at(i) = builder_->NewPhi(1, values()->at(i), control); |
4195 } | 4236 } |
4196 } else { | 4237 } else { |
4197 // Only build phis for those locals assigned in this loop. | 4238 // Only build phis for those locals assigned in this loop. |
(...skipping 14 matching lines...) Expand all Loading... |
4212 builder_->exit_controls_.push_back(terminate); | 4253 builder_->exit_controls_.push_back(terminate); |
4213 } | 4254 } |
4214 | 4255 |
4215 if (builder_->info()->is_osr()) { | 4256 if (builder_->info()->is_osr()) { |
4216 // Introduce phis for all context values in the case of an OSR graph. | 4257 // Introduce phis for all context values in the case of an OSR graph. |
4217 for (size_t i = 0; i < contexts()->size(); ++i) { | 4258 for (size_t i = 0; i < contexts()->size(); ++i) { |
4218 Node* context = contexts()->at(i); | 4259 Node* context = contexts()->at(i); |
4219 contexts()->at(i) = builder_->NewPhi(1, context, control); | 4260 contexts()->at(i) = builder_->NewPhi(1, context, control); |
4220 } | 4261 } |
4221 } | 4262 } |
4222 | |
4223 if (is_osr) { | |
4224 // Merge OSR values as inputs to the phis of the loop. | |
4225 Graph* graph = builder_->graph(); | |
4226 Node* osr_loop_entry = builder_->graph()->NewNode( | |
4227 builder_->common()->OsrLoopEntry(), graph->start(), graph->start()); | |
4228 | |
4229 builder_->MergeControl(control, osr_loop_entry); | |
4230 builder_->MergeEffect(effect, osr_loop_entry, control); | |
4231 | |
4232 for (int i = 0; i < size; ++i) { | |
4233 Node* value = values()->at(i); | |
4234 Node* osr_value = | |
4235 graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry); | |
4236 values()->at(i) = builder_->MergeValue(value, osr_value, control); | |
4237 } | |
4238 | |
4239 // Rename all the contexts in the environment. | |
4240 // The innermost context is the OSR value, and the outer contexts are | |
4241 // reconstructed by dynamically walking up the context chain. | |
4242 Node* osr_context = nullptr; | |
4243 const Operator* op = | |
4244 builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true); | |
4245 const Operator* op_inner = | |
4246 builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex); | |
4247 int last = static_cast<int>(contexts()->size() - 1); | |
4248 for (int i = last; i >= 0; i--) { | |
4249 Node* context = contexts()->at(i); | |
4250 osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry) | |
4251 : graph->NewNode(op, osr_context, osr_context, | |
4252 osr_loop_entry); | |
4253 contexts()->at(i) = builder_->MergeValue(context, osr_context, control); | |
4254 } | |
4255 } | |
4256 } | 4263 } |
4257 | 4264 |
4258 | 4265 |
4259 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) { | 4266 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) { |
4260 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count); | 4267 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count); |
4261 Node** buffer = EnsureInputBufferSize(count + 1); | 4268 Node** buffer = EnsureInputBufferSize(count + 1); |
4262 MemsetPointer(buffer, input, count); | 4269 MemsetPointer(buffer, input, count); |
4263 buffer[count] = control; | 4270 buffer[count] = control; |
4264 return graph()->NewNode(phi_op, count + 1, buffer, true); | 4271 return graph()->NewNode(phi_op, count + 1, buffer, true); |
4265 } | 4272 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4324 // Phi does not exist yet, introduce one. | 4331 // Phi does not exist yet, introduce one. |
4325 value = NewPhi(inputs, value, control); | 4332 value = NewPhi(inputs, value, control); |
4326 value->ReplaceInput(inputs - 1, other); | 4333 value->ReplaceInput(inputs - 1, other); |
4327 } | 4334 } |
4328 return value; | 4335 return value; |
4329 } | 4336 } |
4330 | 4337 |
4331 } // namespace compiler | 4338 } // namespace compiler |
4332 } // namespace internal | 4339 } // namespace internal |
4333 } // namespace v8 | 4340 } // namespace v8 |
OLD | NEW |