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 loop->Merge(PrepareOsrEntry()); | |
813 } | |
814 return loop; | |
806 } | 815 } |
807 | 816 |
808 | 817 |
809 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 818 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
810 int offset, int count) { | 819 int offset, int count) { |
811 bool should_update = false; | 820 bool should_update = false; |
812 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 821 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
813 if (*state_values == nullptr || (*state_values)->InputCount() != count) { | 822 if (*state_values == nullptr || (*state_values)->InputCount() != count) { |
814 should_update = true; | 823 should_update = true; |
815 } else { | 824 } else { |
(...skipping 3359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4175 // potentially extending an existing Phi node if possible. | 4184 // potentially extending an existing Phi node if possible. |
4176 for (int i = 0; i < static_cast<int>(values_.size()); ++i) { | 4185 for (int i = 0; i < static_cast<int>(values_.size()); ++i) { |
4177 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control); | 4186 values_[i] = builder_->MergeValue(values_[i], other->values_[i], control); |
4178 } | 4187 } |
4179 for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) { | 4188 for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) { |
4180 contexts_[i] = | 4189 contexts_[i] = |
4181 builder_->MergeValue(contexts_[i], other->contexts_[i], control); | 4190 builder_->MergeValue(contexts_[i], other->contexts_[i], control); |
4182 } | 4191 } |
4183 } | 4192 } |
4184 | 4193 |
4194 AstGraphBuilder::Environment* AstGraphBuilder::Environment::PrepareOsrEntry() { | |
Michael Starzinger
2016/09/29 13:14:34
As discussed offline: This function creates a copy
Jarin
2016/09/29 13:40:25
Done. Thanks!
| |
4195 int size = static_cast<int>(values()->size()); | |
4196 Graph* graph = builder_->graph(); | |
4185 | 4197 |
4186 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned, | 4198 // Create the OSR environment. |
4187 bool is_osr) { | 4199 Environment* osr_env = CopyForOsrEntry(); |
4200 // Set the control and effect to the OSR loop entry. | |
4201 Node* osr_loop_entry = graph->NewNode(builder_->common()->OsrLoopEntry(), | |
4202 graph->start(), graph->start()); | |
4203 osr_env->UpdateControlDependency(osr_loop_entry); | |
4204 osr_env->UpdateEffectDependency(osr_loop_entry); | |
4205 // Set OSR values. | |
4206 for (int i = 0; i < size; ++i) { | |
4207 osr_env->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 osr_env->contexts()->at(i) = osr_context; | |
4225 } | |
4226 return osr_env; | |
4227 } | |
4228 | |
4229 void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) { | |
4188 int size = static_cast<int>(values()->size()); | 4230 int size = static_cast<int>(values()->size()); |
4189 | 4231 |
4190 Node* control = builder_->NewLoop(); | 4232 Node* control = builder_->NewLoop(); |
4191 if (assigned == nullptr) { | 4233 if (assigned == nullptr) { |
4192 // Assume that everything is updated in the loop. | 4234 // Assume that everything is updated in the loop. |
4193 for (int i = 0; i < size; ++i) { | 4235 for (int i = 0; i < size; ++i) { |
4194 values()->at(i) = builder_->NewPhi(1, values()->at(i), control); | 4236 values()->at(i) = builder_->NewPhi(1, values()->at(i), control); |
4195 } | 4237 } |
4196 } else { | 4238 } else { |
4197 // Only build phis for those locals assigned in this loop. | 4239 // Only build phis for those locals assigned in this loop. |
(...skipping 14 matching lines...) Expand all Loading... | |
4212 builder_->exit_controls_.push_back(terminate); | 4254 builder_->exit_controls_.push_back(terminate); |
4213 } | 4255 } |
4214 | 4256 |
4215 if (builder_->info()->is_osr()) { | 4257 if (builder_->info()->is_osr()) { |
4216 // Introduce phis for all context values in the case of an OSR graph. | 4258 // Introduce phis for all context values in the case of an OSR graph. |
4217 for (size_t i = 0; i < contexts()->size(); ++i) { | 4259 for (size_t i = 0; i < contexts()->size(); ++i) { |
4218 Node* context = contexts()->at(i); | 4260 Node* context = contexts()->at(i); |
4219 contexts()->at(i) = builder_->NewPhi(1, context, control); | 4261 contexts()->at(i) = builder_->NewPhi(1, context, control); |
4220 } | 4262 } |
4221 } | 4263 } |
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 } | 4264 } |
4257 | 4265 |
4258 | 4266 |
4259 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) { | 4267 Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) { |
4260 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count); | 4268 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count); |
4261 Node** buffer = EnsureInputBufferSize(count + 1); | 4269 Node** buffer = EnsureInputBufferSize(count + 1); |
4262 MemsetPointer(buffer, input, count); | 4270 MemsetPointer(buffer, input, count); |
4263 buffer[count] = control; | 4271 buffer[count] = control; |
4264 return graph()->NewNode(phi_op, count + 1, buffer, true); | 4272 return graph()->NewNode(phi_op, count + 1, buffer, true); |
4265 } | 4273 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4324 // Phi does not exist yet, introduce one. | 4332 // Phi does not exist yet, introduce one. |
4325 value = NewPhi(inputs, value, control); | 4333 value = NewPhi(inputs, value, control); |
4326 value->ReplaceInput(inputs - 1, other); | 4334 value->ReplaceInput(inputs - 1, other); |
4327 } | 4335 } |
4328 return value; | 4336 return value; |
4329 } | 4337 } |
4330 | 4338 |
4331 } // namespace compiler | 4339 } // namespace compiler |
4332 } // namespace internal | 4340 } // namespace internal |
4333 } // namespace v8 | 4341 } // namespace v8 |
OLD | NEW |