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 3253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3264 } | 3264 } |
3265 | 3265 |
3266 int reg = codes[0]; | 3266 int reg = codes[0]; |
3267 for (int i = 1; i < num_codes; ++i) { | 3267 for (int i = 1; i < num_codes; ++i) { |
3268 int code = codes[i]; | 3268 int code = codes[i]; |
3269 if (use_pos[code] > use_pos[reg]) { | 3269 if (use_pos[code] > use_pos[reg]) { |
3270 reg = code; | 3270 reg = code; |
3271 } | 3271 } |
3272 } | 3272 } |
3273 | 3273 |
3274 LifetimePosition pos = use_pos[reg]; | 3274 if (use_pos[reg] < register_use->pos()) { |
3275 | 3275 // If there is a gap position before the next register use, we can |
3276 if (pos < register_use->pos()) { | 3276 // spill until there. The gap position will then fit the fill move. |
3277 if (LifetimePosition::ExistsGapPositionBetween(current->Start(), | 3277 if (LifetimePosition::ExistsGapPositionBetween(current->Start(), |
3278 register_use->pos())) { | 3278 register_use->pos())) { |
3279 SpillBetween(current, current->Start(), register_use->pos()); | 3279 SpillBetween(current, current->Start(), register_use->pos()); |
3280 } else { | 3280 return; |
3281 // We can't spill up to the first register use, because there is no gap | |
3282 // where the fill before the register use may happen. This happens when | |
3283 // there is high register pressure, we are at the beginning of an | |
3284 // instruction, we are the input to that instruction, and we can't hold | |
3285 // on to the register past the instruction (we likely lose due to an | |
3286 // output or a temp). | |
3287 // We give the `reg` register to this range, but then we need to spill | |
3288 // until the next register use, if any. | |
3289 LifetimePosition after_this_reg_use = register_use->pos().NextFullStart(); | |
3290 if (after_this_reg_use >= current->End()) { | |
3291 // The range ends at this instruction, since the end is at or before | |
3292 // the next gap. It should follow that there is no other use either. | |
3293 DCHECK_NULL(register_use->next()); | |
3294 SetLiveRangeAssignedRegister(current, reg); | |
3295 } else { | |
3296 const UsePosition* next_reg_pos = register_use->next(); | |
3297 for (; next_reg_pos != nullptr; next_reg_pos = next_reg_pos->next()) { | |
3298 if (next_reg_pos->type() == UsePositionType::kRequiresRegister) break; | |
3299 } | |
3300 SetLiveRangeAssignedRegister(current, reg); | |
3301 if (next_reg_pos == nullptr) { | |
3302 SpillAfter(current, after_this_reg_use); | |
3303 } else { | |
3304 SpillBetween(current, after_this_reg_use, next_reg_pos->pos()); | |
3305 } | |
3306 } | |
3307 } | 3281 } |
3308 return; | |
3309 } | 3282 } |
3310 | 3283 |
| 3284 // We couldn't spill until the next register use. Split before the register |
| 3285 // is blocked, if applicable. |
3311 if (block_pos[reg] < current->End()) { | 3286 if (block_pos[reg] < current->End()) { |
3312 // Register becomes blocked before the current range end. Split before that | 3287 // Register becomes blocked before the current range end. Split before that |
3313 // position. | 3288 // position. |
3314 LiveRange* tail = | 3289 LiveRange* tail = |
3315 SplitBetween(current, current->Start(), block_pos[reg].Start()); | 3290 SplitBetween(current, current->Start(), block_pos[reg].Start()); |
3316 AddToUnhandledSorted(tail); | 3291 AddToUnhandledSorted(tail); |
3317 } | 3292 } |
3318 | 3293 |
3319 // Register reg is not blocked for the whole range. | 3294 // Register reg is not blocked for the whole range. |
3320 DCHECK(block_pos[reg] >= current->End()); | 3295 DCHECK(block_pos[reg] >= current->End()); |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4031 } | 4006 } |
4032 } | 4007 } |
4033 } | 4008 } |
4034 } | 4009 } |
4035 } | 4010 } |
4036 | 4011 |
4037 | 4012 |
4038 } // namespace compiler | 4013 } // namespace compiler |
4039 } // namespace internal | 4014 } // namespace internal |
4040 } // namespace v8 | 4015 } // namespace v8 |
OLD | NEW |