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

Side by Side Diff: src/compiler/register-allocator.cc

Issue 1412573009: [turbofan] reduce ResolveControlFlow overhead. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698