| 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 |