| 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/base/adapters.h" | 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/linkage.h" | 6 #include "src/compiler/linkage.h" |
| 7 #include "src/compiler/register-allocator.h" | 7 #include "src/compiler/register-allocator.h" |
| 8 #include "src/string-stream.h" | 8 #include "src/string-stream.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 3156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3167 } | 3167 } |
| 3168 } | 3168 } |
| 3169 } | 3169 } |
| 3170 } | 3170 } |
| 3171 | 3171 |
| 3172 | 3172 |
| 3173 namespace { | 3173 namespace { |
| 3174 | 3174 |
| 3175 class LiveRangeBound { | 3175 class LiveRangeBound { |
| 3176 public: | 3176 public: |
| 3177 explicit LiveRangeBound(const LiveRange* range) | 3177 explicit LiveRangeBound(const LiveRange* range, bool skip) |
| 3178 : range_(range), start_(range->Start()), end_(range->End()) { | 3178 : range_(range), start_(range->Start()), end_(range->End()), skip_(skip) { |
| 3179 DCHECK(!range->IsEmpty()); | 3179 DCHECK(!range->IsEmpty()); |
| 3180 } | 3180 } |
| 3181 | 3181 |
| 3182 bool CanCover(LifetimePosition position) { | 3182 bool CanCover(LifetimePosition position) { |
| 3183 return start_ <= position && position < end_; | 3183 return start_ <= position && position < end_; |
| 3184 } | 3184 } |
| 3185 | 3185 |
| 3186 const LiveRange* const range_; | 3186 const LiveRange* const range_; |
| 3187 const LifetimePosition start_; | 3187 const LifetimePosition start_; |
| 3188 const LifetimePosition end_; | 3188 const LifetimePosition end_; |
| 3189 const bool skip_; |
| 3189 | 3190 |
| 3190 private: | 3191 private: |
| 3191 DISALLOW_COPY_AND_ASSIGN(LiveRangeBound); | 3192 DISALLOW_COPY_AND_ASSIGN(LiveRangeBound); |
| 3192 }; | 3193 }; |
| 3193 | 3194 |
| 3194 | 3195 |
| 3195 struct FindResult { | 3196 struct FindResult { |
| 3196 const LiveRange* cur_cover_; | 3197 const LiveRange* cur_cover_; |
| 3197 const LiveRange* pred_cover_; | 3198 const LiveRange* pred_cover_; |
| 3198 }; | 3199 }; |
| 3199 | 3200 |
| 3200 | 3201 |
| 3201 class LiveRangeBoundArray { | 3202 class LiveRangeBoundArray { |
| 3202 public: | 3203 public: |
| 3203 LiveRangeBoundArray() : length_(0), start_(nullptr) {} | 3204 LiveRangeBoundArray() : length_(0), start_(nullptr) {} |
| 3204 | 3205 |
| 3205 bool ShouldInitialize() { return start_ == nullptr; } | 3206 bool ShouldInitialize() { return start_ == nullptr; } |
| 3206 | 3207 |
| 3207 void Initialize(Zone* zone, const LiveRange* const range) { | 3208 void Initialize(Zone* zone, const TopLevelLiveRange* const range) { |
| 3208 size_t length = 0; | 3209 length_ = range->GetChildCount(); |
| 3209 for (auto i = range; i != nullptr; i = i->next()) length++; | 3210 |
| 3210 start_ = zone->NewArray<LiveRangeBound>(length); | 3211 start_ = zone->NewArray<LiveRangeBound>(length_); |
| 3211 length_ = length; | 3212 LiveRangeBound* curr = start_; |
| 3212 auto curr = start_; | 3213 // Normally, spilled ranges do not need connecting moves, because the spill |
| 3213 for (auto i = range; i != nullptr; i = i->next(), ++curr) { | 3214 // location has been assigned at definition. For ranges spilled in deferred |
| 3214 new (curr) LiveRangeBound(i); | 3215 // blocks, that is not the case, so we need to connect the spilled children. |
| 3216 bool spilled_in_blocks = range->IsSpilledOnlyInDeferredBlocks(); |
| 3217 for (const LiveRange *i = range; i != nullptr; i = i->next(), ++curr) { |
| 3218 new (curr) LiveRangeBound(i, !spilled_in_blocks && i->spilled()); |
| 3215 } | 3219 } |
| 3216 } | 3220 } |
| 3217 | 3221 |
| 3218 LiveRangeBound* Find(const LifetimePosition position) const { | 3222 LiveRangeBound* Find(const LifetimePosition position) const { |
| 3219 size_t left_index = 0; | 3223 size_t left_index = 0; |
| 3220 size_t right_index = length_; | 3224 size_t right_index = length_; |
| 3221 while (true) { | 3225 while (true) { |
| 3222 size_t current_index = left_index + (right_index - left_index) / 2; | 3226 size_t current_index = left_index + (right_index - left_index) / 2; |
| 3223 DCHECK(right_index > current_index); | 3227 DCHECK(right_index > current_index); |
| 3224 auto bound = &start_[current_index]; | 3228 auto bound = &start_[current_index]; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3237 pred->last_instruction_index()); | 3241 pred->last_instruction_index()); |
| 3238 return Find(pred_end); | 3242 return Find(pred_end); |
| 3239 } | 3243 } |
| 3240 | 3244 |
| 3241 LiveRangeBound* FindSucc(const InstructionBlock* succ) { | 3245 LiveRangeBound* FindSucc(const InstructionBlock* succ) { |
| 3242 auto succ_start = LifetimePosition::GapFromInstructionIndex( | 3246 auto succ_start = LifetimePosition::GapFromInstructionIndex( |
| 3243 succ->first_instruction_index()); | 3247 succ->first_instruction_index()); |
| 3244 return Find(succ_start); | 3248 return Find(succ_start); |
| 3245 } | 3249 } |
| 3246 | 3250 |
| 3247 void Find(const InstructionBlock* block, const InstructionBlock* pred, | 3251 bool FindConnectableSubranges(const InstructionBlock* block, |
| 3248 FindResult* result) const { | 3252 const InstructionBlock* pred, |
| 3249 auto pred_end = LifetimePosition::InstructionFromInstructionIndex( | 3253 FindResult* result) const { |
| 3250 pred->last_instruction_index()); | 3254 LifetimePosition pred_end = |
| 3251 auto bound = Find(pred_end); | 3255 LifetimePosition::InstructionFromInstructionIndex( |
| 3256 pred->last_instruction_index()); |
| 3257 LiveRangeBound* bound = Find(pred_end); |
| 3252 result->pred_cover_ = bound->range_; | 3258 result->pred_cover_ = bound->range_; |
| 3253 auto cur_start = LifetimePosition::GapFromInstructionIndex( | 3259 LifetimePosition cur_start = LifetimePosition::GapFromInstructionIndex( |
| 3254 block->first_instruction_index()); | 3260 block->first_instruction_index()); |
| 3255 // Common case. | 3261 |
| 3256 if (bound->CanCover(cur_start)) { | 3262 if (bound->CanCover(cur_start)) { |
| 3257 result->cur_cover_ = bound->range_; | 3263 // Both blocks are covered by the same range, so there is nothing to |
| 3258 return; | 3264 // connect. |
| 3265 return false; |
| 3259 } | 3266 } |
| 3260 result->cur_cover_ = Find(cur_start)->range_; | 3267 bound = Find(cur_start); |
| 3268 if (bound->skip_) { |
| 3269 return false; |
| 3270 } |
| 3271 result->cur_cover_ = bound->range_; |
| 3261 DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr); | 3272 DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr); |
| 3273 return (result->cur_cover_ != result->pred_cover_); |
| 3262 } | 3274 } |
| 3263 | 3275 |
| 3264 private: | 3276 private: |
| 3265 size_t length_; | 3277 size_t length_; |
| 3266 LiveRangeBound* start_; | 3278 LiveRangeBound* start_; |
| 3267 | 3279 |
| 3268 DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray); | 3280 DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray); |
| 3269 }; | 3281 }; |
| 3270 | 3282 |
| 3271 | 3283 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3339 auto& live_in_sets = data()->live_in_sets(); | 3351 auto& live_in_sets = data()->live_in_sets(); |
| 3340 for (auto block : code()->instruction_blocks()) { | 3352 for (auto block : code()->instruction_blocks()) { |
| 3341 if (CanEagerlyResolveControlFlow(block)) continue; | 3353 if (CanEagerlyResolveControlFlow(block)) continue; |
| 3342 auto live = live_in_sets[block->rpo_number().ToInt()]; | 3354 auto live = live_in_sets[block->rpo_number().ToInt()]; |
| 3343 BitVector::Iterator iterator(live); | 3355 BitVector::Iterator iterator(live); |
| 3344 while (!iterator.Done()) { | 3356 while (!iterator.Done()) { |
| 3345 auto* array = finder.ArrayFor(iterator.Current()); | 3357 auto* array = finder.ArrayFor(iterator.Current()); |
| 3346 for (auto pred : block->predecessors()) { | 3358 for (auto pred : block->predecessors()) { |
| 3347 FindResult result; | 3359 FindResult result; |
| 3348 const auto* pred_block = code()->InstructionBlockAt(pred); | 3360 const auto* pred_block = code()->InstructionBlockAt(pred); |
| 3349 array->Find(block, pred_block, &result); | 3361 if (!array->FindConnectableSubranges(block, pred_block, &result)) { |
| 3350 if (result.cur_cover_ == result.pred_cover_ || | |
| 3351 (!result.cur_cover_->TopLevel()->IsSpilledOnlyInDeferredBlocks() && | |
| 3352 result.cur_cover_->spilled())) | |
| 3353 continue; | 3362 continue; |
| 3363 } |
| 3354 auto pred_op = result.pred_cover_->GetAssignedOperand(); | 3364 auto pred_op = result.pred_cover_->GetAssignedOperand(); |
| 3355 auto cur_op = result.cur_cover_->GetAssignedOperand(); | 3365 auto cur_op = result.cur_cover_->GetAssignedOperand(); |
| 3356 if (pred_op.Equals(cur_op)) continue; | 3366 if (pred_op.Equals(cur_op)) continue; |
| 3357 ResolveControlFlow(block, cur_op, pred_block, pred_op); | 3367 ResolveControlFlow(block, cur_op, pred_block, pred_op); |
| 3358 } | 3368 } |
| 3359 iterator.Advance(); | 3369 iterator.Advance(); |
| 3360 } | 3370 } |
| 3361 } | 3371 } |
| 3362 } | 3372 } |
| 3363 | 3373 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3455 auto eliminate = moves->PrepareInsertAfter(move); | 3465 auto eliminate = moves->PrepareInsertAfter(move); |
| 3456 to_insert.push_back(move); | 3466 to_insert.push_back(move); |
| 3457 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3467 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
| 3458 } | 3468 } |
| 3459 } | 3469 } |
| 3460 | 3470 |
| 3461 | 3471 |
| 3462 } // namespace compiler | 3472 } // namespace compiler |
| 3463 } // namespace internal | 3473 } // namespace internal |
| 3464 } // namespace v8 | 3474 } // namespace v8 |
| OLD | NEW |