1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "register_allocator_linear_scan.h"
18
19 #include <iostream>
20 #include <sstream>
21
22 #include "base/bit_utils_iterator.h"
23 #include "base/bit_vector-inl.h"
24 #include "base/pointer_size.h"
25 #include "code_generator.h"
26 #include "linear_order.h"
27 #include "register_allocation_resolver.h"
28 #include "ssa_liveness_analysis.h"
29
30 namespace art HIDDEN {
31
32 static constexpr size_t kMaxLifetimePosition = -1;
33 static constexpr size_t kDefaultNumberOfSpillSlots = 4;
34
35 // For simplicity, we implement register pairs as (reg, reg + 1).
36 // Note that this is a requirement for double registers on ARM, since we
37 // allocate SRegister.
GetHighForLowRegister(int reg)38 static int GetHighForLowRegister(int reg) { return reg + 1; }
IsLowRegister(int reg)39 static bool IsLowRegister(int reg) { return (reg & 1) == 0; }
IsLowOfUnalignedPairInterval(LiveInterval * low)40 static bool IsLowOfUnalignedPairInterval(LiveInterval* low) {
41 return GetHighForLowRegister(low->GetRegister()) != low->GetHighInterval()->GetRegister();
42 }
43
RegisterAllocatorLinearScan(ScopedArenaAllocator * allocator,CodeGenerator * codegen,const SsaLivenessAnalysis & liveness)44 RegisterAllocatorLinearScan::RegisterAllocatorLinearScan(ScopedArenaAllocator* allocator,
45 CodeGenerator* codegen,
46 const SsaLivenessAnalysis& liveness)
47 : RegisterAllocator(allocator, codegen, liveness),
48 unhandled_core_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
49 unhandled_fp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
50 unhandled_(nullptr),
51 handled_(allocator->Adapter(kArenaAllocRegisterAllocator)),
52 active_(allocator->Adapter(kArenaAllocRegisterAllocator)),
53 inactive_(allocator->Adapter(kArenaAllocRegisterAllocator)),
54 physical_core_register_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
55 physical_fp_register_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
56 block_registers_for_call_interval_(
57 LiveInterval::MakeFixedInterval(allocator, kNoRegister, DataType::Type::kVoid)),
58 block_registers_special_interval_(
59 LiveInterval::MakeFixedInterval(allocator, kNoRegister, DataType::Type::kVoid)),
60 temp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
61 int_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
62 long_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
63 float_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
64 double_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
65 catch_phi_spill_slots_(0),
66 safepoints_(allocator->Adapter(kArenaAllocRegisterAllocator)),
67 current_register_type_(RegisterType::kCoreRegister),
68 number_of_registers_(-1),
69 registers_array_(nullptr),
70 blocked_core_registers_(codegen->GetBlockedCoreRegisters()),
71 blocked_fp_registers_(codegen->GetBlockedFloatingPointRegisters()),
72 reserved_out_slots_(0) {
73 temp_intervals_.reserve(4);
74 int_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
75 long_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
76 float_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
77 double_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
78
79 codegen->SetupBlockedRegisters();
80 physical_core_register_intervals_.resize(codegen->GetNumberOfCoreRegisters(), nullptr);
81 physical_fp_register_intervals_.resize(codegen->GetNumberOfFloatingPointRegisters(), nullptr);
82 }
83
~RegisterAllocatorLinearScan()84 RegisterAllocatorLinearScan::~RegisterAllocatorLinearScan() {}
85
AllocateRegisters()86 void RegisterAllocatorLinearScan::AllocateRegisters() {
87 AllocateRegistersInternal();
88 RegisterAllocationResolver(codegen_, liveness_)
89 .Resolve(ArrayRef<HInstruction* const>(safepoints_),
90 reserved_out_slots_,
91 int_spill_slots_.size(),
92 long_spill_slots_.size(),
93 float_spill_slots_.size(),
94 double_spill_slots_.size(),
95 catch_phi_spill_slots_,
96 ArrayRef<LiveInterval* const>(temp_intervals_));
97
98 if (kIsDebugBuild) {
99 current_register_type_ = RegisterType::kCoreRegister;
100 ValidateInternal(true);
101 current_register_type_ = RegisterType::kFpRegister;
102 ValidateInternal(true);
103 // Check that the linear order is still correct with regards to lifetime positions.
104 // Since only parallel moves have been inserted during the register allocation,
105 // these checks are mostly for making sure these moves have been added correctly.
106 size_t current_liveness = 0;
107 for (HBasicBlock* block : codegen_->GetGraph()->GetLinearOrder()) {
108 for (HInstructionIterator inst_it(block->GetPhis()); !inst_it.Done(); inst_it.Advance()) {
109 HInstruction* instruction = inst_it.Current();
110 DCHECK_LE(current_liveness, instruction->GetLifetimePosition());
111 current_liveness = instruction->GetLifetimePosition();
112 }
113 for (HInstructionIterator inst_it(block->GetInstructions());
114 !inst_it.Done();
115 inst_it.Advance()) {
116 HInstruction* instruction = inst_it.Current();
117 DCHECK_LE(current_liveness, instruction->GetLifetimePosition()) << instruction->DebugName();
118 current_liveness = instruction->GetLifetimePosition();
119 }
120 }
121 }
122 }
123
BlockRegister(Location location,size_t position,bool will_call)124 void RegisterAllocatorLinearScan::BlockRegister(Location location,
125 size_t position,
126 bool will_call) {
127 DCHECK(location.IsRegister() || location.IsFpuRegister());
128 int reg = location.reg();
129 if (will_call) {
130 uint32_t registers_blocked_for_call =
131 location.IsRegister() ? core_registers_blocked_for_call_ : fp_registers_blocked_for_call_;
132 if ((registers_blocked_for_call & (1u << reg)) != 0u) {
133 // Register is already marked as blocked by the `block_registers_for_call_interval_`.
134 return;
135 }
136 }
137 DCHECK(location.IsRegister() || location.IsFpuRegister());
138 LiveInterval* interval = location.IsRegister()
139 ? physical_core_register_intervals_[reg]
140 : physical_fp_register_intervals_[reg];
141 DataType::Type type = location.IsRegister()
142 ? DataType::Type::kInt32
143 : DataType::Type::kFloat32;
144 if (interval == nullptr) {
145 interval = LiveInterval::MakeFixedInterval(allocator_, reg, type);
146 if (location.IsRegister()) {
147 physical_core_register_intervals_[reg] = interval;
148 } else {
149 physical_fp_register_intervals_[reg] = interval;
150 }
151 }
152 DCHECK(interval->GetRegister() == reg);
153 interval->AddRange(position, position + 1u);
154 }
155
AllocateRegistersInternal()156 void RegisterAllocatorLinearScan::AllocateRegistersInternal() {
157 // Iterate post-order, to ensure the list is sorted, and the last added interval
158 // is the one with the lowest start position.
159 for (HBasicBlock* block : codegen_->GetGraph()->GetLinearPostOrder()) {
160 for (HBackwardInstructionIterator back_it(block->GetInstructions()); !back_it.Done();
161 back_it.Advance()) {
162 ProcessInstruction(back_it.Current());
163 }
164 for (HInstructionIterator inst_it(block->GetPhis()); !inst_it.Done(); inst_it.Advance()) {
165 ProcessInstruction(inst_it.Current());
166 }
167
168 if (block->IsCatchBlock() ||
169 (block->IsLoopHeader() && block->GetLoopInformation()->IsIrreducible())) {
170 // By blocking all registers at the top of each catch block or irreducible loop, we force
171 // intervals belonging to the live-in set of the catch/header block to be spilled.
172 // TODO(ngeoffray): Phis in this block could be allocated in register.
173 size_t position = block->GetLifetimeStart();
174 DCHECK_EQ(liveness_.GetInstructionFromPosition(position / 2u), nullptr);
175 block_registers_special_interval_->AddRange(position, position + 1u);
176 }
177 }
178
179 // Add the current method to the `reserved_out_slots_`. ArtMethod* takes 2 vregs for 64 bits.
180 PointerSize pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet());
181 reserved_out_slots_ += static_cast<size_t>(pointer_size) / kVRegSize;
182
183 number_of_registers_ = codegen_->GetNumberOfCoreRegisters();
184 registers_array_ = allocator_->AllocArray<size_t>(number_of_registers_,
185 kArenaAllocRegisterAllocator);
186 current_register_type_ = RegisterType::kCoreRegister;
187 unhandled_ = &unhandled_core_intervals_;
188 // Add intervals representing groups of physical registers blocked for calls,
189 // catch blocks and irreducible loop headers.
190 for (LiveInterval* block_registers_interval : { block_registers_for_call_interval_,
191 block_registers_special_interval_ }) {
192 if (block_registers_interval->GetFirstRange() != nullptr) {
193 block_registers_interval->ResetSearchCache();
194 inactive_.push_back(block_registers_interval);
195 }
196 }
197 for (LiveInterval* fixed : physical_core_register_intervals_) {
198 if (fixed != nullptr) {
199 // Fixed interval is added to inactive_ instead of unhandled_.
200 // It's also the only type of inactive interval whose start position
201 // can be after the current interval during linear scan.
202 // Fixed interval is never split and never moves to unhandled_.
203 inactive_.push_back(fixed);
204 }
205 }
206 LinearScan();
207
208 inactive_.clear();
209 active_.clear();
210 handled_.clear();
211
212 number_of_registers_ = codegen_->GetNumberOfFloatingPointRegisters();
213 registers_array_ = allocator_->AllocArray<size_t>(number_of_registers_,
214 kArenaAllocRegisterAllocator);
215 current_register_type_ = RegisterType::kFpRegister;
216 unhandled_ = &unhandled_fp_intervals_;
217 // Add intervals representing groups of physical registers blocked for calls,
218 // catch blocks and irreducible loop headers.
219 for (LiveInterval* block_registers_interval : { block_registers_for_call_interval_,
220 block_registers_special_interval_ }) {
221 if (block_registers_interval->GetFirstRange() != nullptr) {
222 block_registers_interval->ResetSearchCache();
223 inactive_.push_back(block_registers_interval);
224 }
225 }
226 for (LiveInterval* fixed : physical_fp_register_intervals_) {
227 if (fixed != nullptr) {
228 // Fixed interval is added to inactive_ instead of unhandled_.
229 // It's also the only type of inactive interval whose start position
230 // can be after the current interval during linear scan.
231 // Fixed interval is never split and never moves to unhandled_.
232 inactive_.push_back(fixed);
233 }
234 }
235 LinearScan();
236 }
237
ProcessInstruction(HInstruction * instruction)238 void RegisterAllocatorLinearScan::ProcessInstruction(HInstruction* instruction) {
239 LocationSummary* locations = instruction->GetLocations();
240
241 // Check for early returns.
242 if (locations == nullptr) {
243 return;
244 }
245 if (TryRemoveSuspendCheckEntry(instruction)) {
246 return;
247 }
248
249 if (locations->CanCall()) {
250 // Update the `reserved_out_slots_` for invokes that make a call, including intrinsics
251 // that make the call only on the slow-path. Same for the `HStringBuilderAppend`.
252 if (instruction->IsInvoke()) {
253 reserved_out_slots_ = std::max<size_t>(
254 reserved_out_slots_, instruction->AsInvoke()->GetNumberOfOutVRegs());
255 } else if (instruction->IsStringBuilderAppend()) {
256 reserved_out_slots_ = std::max<size_t>(
257 reserved_out_slots_, instruction->AsStringBuilderAppend()->GetNumberOfOutVRegs());
258 }
259 }
260 bool will_call = locations->WillCall();
261 if (will_call) {
262 // If a call will happen, add the range to a fixed interval that represents all the
263 // caller-save registers blocked at call sites.
264 const size_t position = instruction->GetLifetimePosition();
265 DCHECK_NE(liveness_.GetInstructionFromPosition(position / 2u), nullptr);
266 block_registers_for_call_interval_->AddRange(position, position + 1u);
267 }
268 CheckForTempLiveIntervals(instruction, will_call);
269 CheckForSafepoint(instruction);
270 CheckForFixedInputs(instruction, will_call);
271
272 LiveInterval* current = instruction->GetLiveInterval();
273 if (current == nullptr)
274 return;
275
276 const bool core_register = !DataType::IsFloatingPointType(instruction->GetType());
277 ScopedArenaVector<LiveInterval*>& unhandled =
278 core_register ? unhandled_core_intervals_ : unhandled_fp_intervals_;
279
280 DCHECK(unhandled.empty() || current->StartsBeforeOrAt(unhandled.back()));
281
282 if (codegen_->NeedsTwoRegisters(current->GetType())) {
283 current->AddHighInterval();
284 }
285
286 AddSafepointsFor(instruction);
287 current->ResetSearchCache();
288 CheckForFixedOutput(instruction, will_call);
289
290 if (instruction->IsPhi() && instruction->AsPhi()->IsCatchPhi()) {
291 AllocateSpillSlotForCatchPhi(instruction->AsPhi());
292 }
293
294 // If needed, add interval to the list of unhandled intervals.
295 if (current->HasSpillSlot() || instruction->IsConstant()) {
296 // Split just before first register use.
297 size_t first_register_use = current->FirstRegisterUse();
298 if (first_register_use != kNoLifetime) {
299 LiveInterval* split = SplitBetween(current, current->GetStart(), first_register_use - 1);
300 // Don't add directly to `unhandled`, it needs to be sorted and the start
301 // of this new interval might be after intervals already in the list.
302 AddSorted(&unhandled, split);
303 } else {
304 // Nothing to do, we won't allocate a register for this value.
305 }
306 } else {
307 // Don't add directly to `unhandled`, temp or safepoint intervals
308 // for this instruction may have been added, and those can be
309 // processed first.
310 AddSorted(&unhandled, current);
311 }
312 }
313
TryRemoveSuspendCheckEntry(HInstruction * instruction)314 bool RegisterAllocatorLinearScan::TryRemoveSuspendCheckEntry(HInstruction* instruction) {
315 LocationSummary* locations = instruction->GetLocations();
316 if (instruction->IsSuspendCheckEntry() && !codegen_->NeedsSuspendCheckEntry()) {
317 // TODO: We do this here because we do not want the suspend check to artificially
318 // create live registers. We should find another place, but this is currently the
319 // simplest.
320 DCHECK_EQ(locations->GetTempCount(), 0u);
321 instruction->GetBlock()->RemoveInstruction(instruction);
322 return true;
323 }
324 return false;
325 }
326
CheckForTempLiveIntervals(HInstruction * instruction,bool will_call)327 void RegisterAllocatorLinearScan::CheckForTempLiveIntervals(HInstruction* instruction,
328 bool will_call) {
329 LocationSummary* locations = instruction->GetLocations();
330 size_t position = instruction->GetLifetimePosition();
331
332 // Create synthesized intervals for temporaries.
333 for (size_t i = 0; i < locations->GetTempCount(); ++i) {
334 Location temp = locations->GetTemp(i);
335 if (temp.IsRegister() || temp.IsFpuRegister()) {
336 BlockRegister(temp, position, will_call);
337 // Ensure that an explicit temporary register is marked as being allocated.
338 codegen_->AddAllocatedRegister(temp);
339 } else {
340 DCHECK(temp.IsUnallocated());
341 switch (temp.GetPolicy()) {
342 case Location::kRequiresRegister: {
343 LiveInterval* interval =
344 LiveInterval::MakeTempInterval(allocator_, DataType::Type::kInt32);
345 temp_intervals_.push_back(interval);
346 interval->AddTempUse(instruction, i);
347 unhandled_core_intervals_.push_back(interval);
348 break;
349 }
350
351 case Location::kRequiresFpuRegister: {
352 LiveInterval* interval =
353 LiveInterval::MakeTempInterval(allocator_, DataType::Type::kFloat64);
354 temp_intervals_.push_back(interval);
355 interval->AddTempUse(instruction, i);
356 if (codegen_->NeedsTwoRegisters(DataType::Type::kFloat64)) {
357 interval->AddHighInterval(/* is_temp= */ true);
358 LiveInterval* high = interval->GetHighInterval();
359 temp_intervals_.push_back(high);
360 unhandled_fp_intervals_.push_back(high);
361 }
362 unhandled_fp_intervals_.push_back(interval);
363 break;
364 }
365
366 default:
367 LOG(FATAL) << "Unexpected policy for temporary location " << temp.GetPolicy();
368 }
369 }
370 }
371 }
372
CheckForSafepoint(HInstruction * instruction)373 void RegisterAllocatorLinearScan::CheckForSafepoint(HInstruction* instruction) {
374 LocationSummary* locations = instruction->GetLocations();
375 if (locations->NeedsSafepoint()) {
376 safepoints_.push_back(instruction);
377 }
378 }
379
CheckForFixedInputs(HInstruction * instruction,bool will_call)380 void RegisterAllocatorLinearScan::CheckForFixedInputs(HInstruction* instruction, bool will_call) {
381 LocationSummary* locations = instruction->GetLocations();
382 size_t position = instruction->GetLifetimePosition();
383 for (size_t i = 0; i < locations->GetInputCount(); ++i) {
384 Location input = locations->InAt(i);
385 if (input.IsRegister() || input.IsFpuRegister()) {
386 BlockRegister(input, position, will_call);
387 // Ensure that an explicit input register is marked as being allocated.
388 codegen_->AddAllocatedRegister(input);
389 } else if (input.IsPair()) {
390 BlockRegister(input.ToLow(), position, will_call);
391 BlockRegister(input.ToHigh(), position, will_call);
392 // Ensure that an explicit input register pair is marked as being allocated.
393 codegen_->AddAllocatedRegister(input.ToLow());
394 codegen_->AddAllocatedRegister(input.ToHigh());
395 }
396 }
397 }
398
AddSafepointsFor(HInstruction * instruction)399 void RegisterAllocatorLinearScan::AddSafepointsFor(HInstruction* instruction) {
400 LiveInterval* current = instruction->GetLiveInterval();
401 for (size_t safepoint_index = safepoints_.size(); safepoint_index > 0; --safepoint_index) {
402 HInstruction* safepoint = safepoints_[safepoint_index - 1u];
403 size_t safepoint_position = SafepointPosition::ComputePosition(safepoint);
404
405 // Test that safepoints are ordered in the optimal way.
406 DCHECK(safepoint_index == safepoints_.size() ||
407 safepoints_[safepoint_index]->GetLifetimePosition() < safepoint_position);
408
409 if (safepoint_position == current->GetStart()) {
410 // The safepoint is for this instruction, so the location of the instruction
411 // does not need to be saved.
412 DCHECK_EQ(safepoint_index, safepoints_.size());
413 DCHECK_EQ(safepoint, instruction);
414 continue;
415 } else if (current->IsDeadAt(safepoint_position)) {
416 break;
417 } else if (!current->Covers(safepoint_position)) {
418 // Hole in the interval.
419 continue;
420 }
421 current->AddSafepoint(safepoint);
422 }
423 }
424
CheckForFixedOutput(HInstruction * instruction,bool will_call)425 void RegisterAllocatorLinearScan::CheckForFixedOutput(HInstruction* instruction, bool will_call) {
426 LocationSummary* locations = instruction->GetLocations();
427 size_t position = instruction->GetLifetimePosition();
428 LiveInterval* current = instruction->GetLiveInterval();
429 // Some instructions define their output in fixed register/stack slot. We need
430 // to ensure we know these locations before doing register allocation. For a
431 // given register, we create an interval that covers these locations. The register
432 // will be unavailable at these locations when trying to allocate one for an
433 // interval.
434 //
435 // The backwards walking ensures the ranges are ordered on increasing start positions.
436 Location output = locations->Out();
437 if (output.IsUnallocated() && output.GetPolicy() == Location::kSameAsFirstInput) {
438 Location first = locations->InAt(0);
439 if (first.IsRegister() || first.IsFpuRegister()) {
440 current->SetFrom(position + 1u);
441 current->SetRegister(first.reg());
442 } else if (first.IsPair()) {
443 current->SetFrom(position + 1u);
444 current->SetRegister(first.low());
445 LiveInterval* high = current->GetHighInterval();
446 high->SetRegister(first.high());
447 high->SetFrom(position + 1u);
448 }
449 } else if (output.IsRegister() || output.IsFpuRegister()) {
450 // Shift the interval's start by one to account for the blocked register.
451 current->SetFrom(position + 1u);
452 current->SetRegister(output.reg());
453 BlockRegister(output, position, will_call);
454 // Ensure that an explicit output register is marked as being allocated.
455 codegen_->AddAllocatedRegister(output);
456 } else if (output.IsPair()) {
457 current->SetFrom(position + 1u);
458 current->SetRegister(output.low());
459 LiveInterval* high = current->GetHighInterval();
460 high->SetRegister(output.high());
461 high->SetFrom(position + 1u);
462 BlockRegister(output.ToLow(), position, will_call);
463 BlockRegister(output.ToHigh(), position, will_call);
464 // Ensure that an explicit output register pair is marked as being allocated.
465 codegen_->AddAllocatedRegister(output.ToLow());
466 codegen_->AddAllocatedRegister(output.ToHigh());
467 } else if (output.IsStackSlot() || output.IsDoubleStackSlot()) {
468 current->SetSpillSlot(output.GetStackIndex());
469 } else {
470 DCHECK(output.IsUnallocated() || output.IsConstant());
471 }
472 }
473
474 class AllRangesIterator : public ValueObject {
475 public:
AllRangesIterator(LiveInterval * interval)476 explicit AllRangesIterator(LiveInterval* interval)
477 : current_interval_(interval),
478 current_range_(interval->GetFirstRange()) {}
479
Done() const480 bool Done() const { return current_interval_ == nullptr; }
CurrentRange() const481 LiveRange* CurrentRange() const { return current_range_; }
CurrentInterval() const482 LiveInterval* CurrentInterval() const { return current_interval_; }
483
Advance()484 void Advance() {
485 current_range_ = current_range_->GetNext();
486 if (current_range_ == nullptr) {
487 current_interval_ = current_interval_->GetNextSibling();
488 if (current_interval_ != nullptr) {
489 current_range_ = current_interval_->GetFirstRange();
490 }
491 }
492 }
493
494 private:
495 LiveInterval* current_interval_;
496 LiveRange* current_range_;
497
498 DISALLOW_COPY_AND_ASSIGN(AllRangesIterator);
499 };
500
ValidateInternal(bool log_fatal_on_failure) const501 bool RegisterAllocatorLinearScan::ValidateInternal(bool log_fatal_on_failure) const {
502 auto should_process = [](RegisterType current_register_type, LiveInterval* interval) {
503 if (interval == nullptr) {
504 return false;
505 }
506 RegisterType register_type = DataType::IsFloatingPointType(interval->GetType())
507 ? RegisterType::kFpRegister
508 : RegisterType::kCoreRegister;
509 return register_type == current_register_type;
510 };
511
512 // To simplify unit testing, we eagerly create the array of intervals, and
513 // call the helper method.
514 ScopedArenaAllocator allocator(allocator_->GetArenaStack());
515 ScopedArenaVector<LiveInterval*> intervals(
516 allocator.Adapter(kArenaAllocRegisterAllocatorValidate));
517 for (size_t i = 0; i < liveness_.GetNumberOfSsaValues(); ++i) {
518 HInstruction* instruction = liveness_.GetInstructionFromSsaIndex(i);
519 if (should_process(current_register_type_, instruction->GetLiveInterval())) {
520 intervals.push_back(instruction->GetLiveInterval());
521 }
522 }
523
524 for (LiveInterval* block_registers_interval : { block_registers_for_call_interval_,
525 block_registers_special_interval_ }) {
526 if (block_registers_interval->GetFirstRange() != nullptr) {
527 intervals.push_back(block_registers_interval);
528 }
529 }
530 const ScopedArenaVector<LiveInterval*>* physical_register_intervals =
531 (current_register_type_ == RegisterType::kCoreRegister)
532 ? &physical_core_register_intervals_
533 : &physical_fp_register_intervals_;
534 for (LiveInterval* fixed : *physical_register_intervals) {
535 if (fixed != nullptr) {
536 intervals.push_back(fixed);
537 }
538 }
539
540 for (LiveInterval* temp : temp_intervals_) {
541 if (should_process(current_register_type_, temp)) {
542 intervals.push_back(temp);
543 }
544 }
545
546 return ValidateIntervals(ArrayRef<LiveInterval* const>(intervals),
547 GetNumberOfSpillSlots(),
548 reserved_out_slots_,
549 *codegen_,
550 &liveness_,
551 current_register_type_,
552 log_fatal_on_failure);
553 }
554
DumpInterval(std::ostream & stream,LiveInterval * interval) const555 void RegisterAllocatorLinearScan::DumpInterval(std::ostream& stream, LiveInterval* interval) const {
556 interval->Dump(stream);
557 stream << ": ";
558 if (interval->HasRegister()) {
559 if (interval->IsFloatingPoint()) {
560 codegen_->DumpFloatingPointRegister(stream, interval->GetRegister());
561 } else {
562 codegen_->DumpCoreRegister(stream, interval->GetRegister());
563 }
564 } else if (interval->IsFixed()) {
565 DCHECK_EQ(interval->GetType(), DataType::Type::kVoid);
566 DCHECK(interval == block_registers_for_call_interval_ ||
567 interval == block_registers_special_interval_);
568 stream << (interval == block_registers_for_call_interval_ ? "block-for-call" : "block-special");
569 } else {
570 stream << "spilled";
571 }
572 stream << std::endl;
573 }
574
DumpAllIntervals(std::ostream & stream) const575 void RegisterAllocatorLinearScan::DumpAllIntervals(std::ostream& stream) const {
576 stream << "inactive: " << std::endl;
577 for (LiveInterval* inactive_interval : inactive_) {
578 DumpInterval(stream, inactive_interval);
579 }
580 stream << "active: " << std::endl;
581 for (LiveInterval* active_interval : active_) {
582 DumpInterval(stream, active_interval);
583 }
584 stream << "unhandled: " << std::endl;
585 auto unhandled = (unhandled_ != nullptr) ?
586 unhandled_ : &unhandled_core_intervals_;
587 for (LiveInterval* unhandled_interval : *unhandled) {
588 DumpInterval(stream, unhandled_interval);
589 }
590 stream << "handled: " << std::endl;
591 for (LiveInterval* handled_interval : handled_) {
592 DumpInterval(stream, handled_interval);
593 }
594 }
595
596 // By the book implementation of a linear scan register allocator.
LinearScan()597 void RegisterAllocatorLinearScan::LinearScan() {
598 size_t last_position = std::numeric_limits<size_t>::max();
599 while (!unhandled_->empty()) {
600 // (1) Remove interval with the lowest start position from unhandled.
601 LiveInterval* current = unhandled_->back();
602 unhandled_->pop_back();
603
604 // Make sure the interval is an expected state.
605 DCHECK(!current->IsFixed() && !current->HasSpillSlot());
606 // Make sure we are going in the right order.
607 DCHECK(unhandled_->empty() || unhandled_->back()->GetStart() >= current->GetStart());
608 // Make sure a low interval is always with a high.
609 DCHECK_IMPLIES(current->IsLowInterval(), unhandled_->back()->IsHighInterval());
610 // Make sure a high interval is always with a low.
611 DCHECK(current->IsLowInterval() ||
612 unhandled_->empty() ||
613 !unhandled_->back()->IsHighInterval());
614
615 size_t position = current->GetStart();
616 if (position != last_position) {
617 // Remember the inactive_ size here since the ones moved to inactive_ from
618 // active_ below shouldn't need to be re-checked.
619 size_t inactive_intervals_to_handle = inactive_.size();
620
621 // (2) Remove currently active intervals that are dead at this position.
622 // Move active intervals that have a lifetime hole at this position
623 // to inactive.
624 auto active_kept_end = std::remove_if(
625 active_.begin(),
626 active_.end(),
627 [this, position](LiveInterval* interval) {
628 if (interval->IsDeadAt(position)) {
629 handled_.push_back(interval);
630 return true;
631 } else if (!interval->Covers(position)) {
632 inactive_.push_back(interval);
633 return true;
634 } else {
635 return false; // Keep this interval.
636 }
637 });
638 active_.erase(active_kept_end, active_.end());
639
640 // (3) Remove currently inactive intervals that are dead at this position.
641 // Move inactive intervals that cover this position to active.
642 auto inactive_to_handle_end = inactive_.begin() + inactive_intervals_to_handle;
643 auto inactive_kept_end = std::remove_if(
644 inactive_.begin(),
645 inactive_to_handle_end,
646 [this, position](LiveInterval* interval) {
647 DCHECK(interval->GetStart() < position || interval->IsFixed());
648 if (interval->IsDeadAt(position)) {
649 handled_.push_back(interval);
650 return true;
651 } else if (interval->Covers(position)) {
652 active_.push_back(interval);
653 return true;
654 } else {
655 return false; // Keep this interval.
656 }
657 });
658 inactive_.erase(inactive_kept_end, inactive_to_handle_end);
659
660 last_position = position;
661 } else {
662 // Active and inactive intervals should not change for the same position.
663 DCHECK(std::none_of(active_.begin(),
664 active_.end(),
665 [position](LiveInterval* interval) {
666 return interval->IsDeadAt(position) || !interval->Covers(position);
667 }));
668 DCHECK(std::none_of(inactive_.begin(),
669 inactive_.end(),
670 [position](LiveInterval* interval) {
671 return interval->IsDeadAt(position) || interval->Covers(position);
672 }));
673 }
674
675 if (current->IsHighInterval() && !current->GetLowInterval()->HasRegister()) {
676 DCHECK(!current->HasRegister());
677 // Allocating the low part was unsucessful. The splitted interval for the high part
678 // will be handled next (it is in the `unhandled_` list).
679 continue;
680 }
681
682 // (4) Try to find an available register.
683 bool success = TryAllocateFreeReg(current);
684
685 // (5) If no register could be found, we need to spill.
686 if (!success) {
687 success = AllocateBlockedReg(current);
688 }
689
690 // (6) If the interval had a register allocated, add it to the list of active
691 // intervals.
692 if (success) {
693 codegen_->AddAllocatedRegister((current_register_type_ == RegisterType::kCoreRegister)
694 ? Location::RegisterLocation(current->GetRegister())
695 : Location::FpuRegisterLocation(current->GetRegister()));
696 active_.push_back(current);
697 if (current->HasHighInterval() && !current->GetHighInterval()->HasRegister()) {
698 current->GetHighInterval()->SetRegister(GetHighForLowRegister(current->GetRegister()));
699 }
700 }
701 }
702 }
703
FreeIfNotCoverAt(LiveInterval * interval,size_t position,size_t * free_until)704 static void FreeIfNotCoverAt(LiveInterval* interval, size_t position, size_t* free_until) {
705 DCHECK(!interval->IsHighInterval());
706 // Note that the same instruction may occur multiple times in the input list,
707 // so `free_until` may have changed already.
708 // Since `position` is not the current scan position, we need to use CoversSlow.
709 if (interval->IsDeadAt(position)) {
710 // Set the register to be free. Note that inactive intervals might later
711 // update this.
712 free_until[interval->GetRegister()] = kMaxLifetimePosition;
713 if (interval->HasHighInterval()) {
714 DCHECK(interval->GetHighInterval()->IsDeadAt(position));
715 free_until[interval->GetHighInterval()->GetRegister()] = kMaxLifetimePosition;
716 }
717 } else if (!interval->CoversSlow(position)) {
718 // The interval becomes inactive at `defined_by`. We make its register
719 // available only until the next use strictly after `defined_by`.
720 free_until[interval->GetRegister()] = interval->FirstUseAfter(position);
721 if (interval->HasHighInterval()) {
722 DCHECK(!interval->GetHighInterval()->CoversSlow(position));
723 free_until[interval->GetHighInterval()->GetRegister()] = free_until[interval->GetRegister()];
724 }
725 }
726 }
727
728 // Find a free register. If multiple are found, pick the register that
729 // is free the longest.
TryAllocateFreeReg(LiveInterval * current)730 bool RegisterAllocatorLinearScan::TryAllocateFreeReg(LiveInterval* current) {
731 size_t* free_until = registers_array_;
732
733 // First set all registers to be free.
734 for (size_t i = 0; i < number_of_registers_; ++i) {
735 free_until[i] = kMaxLifetimePosition;
736 }
737
738 // For each active interval, set its register(s) to not free.
739 for (LiveInterval* interval : active_) {
740 DCHECK(interval->HasRegister() || interval->IsFixed());
741 uint32_t register_mask = GetRegisterMask(interval, current_register_type_);
742 DCHECK_NE(register_mask, 0u);
743 for (uint32_t reg : LowToHighBits(register_mask)) {
744 free_until[reg] = 0;
745 }
746 }
747
748 // An interval that starts an instruction (that is, it is not split), may
749 // re-use the registers used by the inputs of that instruciton, based on the
750 // location summary.
751 HInstruction* defined_by = current->GetDefinedBy();
752 if (defined_by != nullptr && !current->IsSplit()) {
753 LocationSummary* locations = defined_by->GetLocations();
754 if (!locations->OutputCanOverlapWithInputs() && locations->Out().IsUnallocated()) {
755 HInputsRef inputs = defined_by->GetInputs();
756 for (size_t i = 0; i < inputs.size(); ++i) {
757 if (locations->InAt(i).IsValid()) {
758 // Take the last interval of the input. It is the location of that interval
759 // that will be used at `defined_by`.
760 LiveInterval* interval = inputs[i]->GetLiveInterval()->GetLastSibling();
761 // Note that interval may have not been processed yet.
762 // TODO: Handle non-split intervals last in the work list.
763 if (interval->HasRegister() && interval->SameRegisterKind(*current)) {
764 // The input must be live until the end of `defined_by`, to comply to
765 // the linear scan algorithm. So we use `defined_by`'s end lifetime
766 // position to check whether the input is dead or is inactive after
767 // `defined_by`.
768 DCHECK(interval->CoversSlow(defined_by->GetLifetimePosition()));
769 size_t position = defined_by->GetLifetimePosition() + 1;
770 FreeIfNotCoverAt(interval, position, free_until);
771 }
772 }
773 }
774 }
775 }
776
777 // For each inactive interval, set its register to be free until
778 // the next intersection with `current`.
779 for (LiveInterval* inactive : inactive_) {
780 // Temp/Slow-path-safepoint interval has no holes.
781 DCHECK(!inactive->IsTemp());
782 if (!current->IsSplit() && !inactive->IsFixed()) {
783 // Neither current nor inactive are fixed.
784 // Thanks to SSA, a non-split interval starting in a hole of an
785 // inactive interval should never intersect with that inactive interval.
786 // Only if it's not fixed though, because fixed intervals don't come from SSA.
787 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
788 continue;
789 }
790
791 DCHECK(inactive->HasRegister() || inactive->IsFixed());
792 uint32_t register_mask = GetRegisterMask(inactive, current_register_type_);
793 DCHECK_NE(register_mask, 0u);
794 for (uint32_t reg : LowToHighBits(register_mask)) {
795 if (free_until[reg] == 0) {
796 // Already used by some active interval. Clear the register bit.
797 register_mask &= ~(1u << reg);
798 }
799 }
800 if (register_mask != 0u) {
801 size_t next_intersection = inactive->FirstIntersectionWith(current);
802 if (next_intersection != kNoLifetime) {
803 for (uint32_t reg : LowToHighBits(register_mask)) {
804 free_until[reg] = std::min(free_until[reg], next_intersection);
805 }
806 }
807 }
808 }
809
810 int reg = kNoRegister;
811 if (current->HasRegister()) {
812 // Some instructions have a fixed register output.
813 reg = current->GetRegister();
814 if (free_until[reg] == 0) {
815 DCHECK(current->IsHighInterval());
816 // AllocateBlockedReg will spill the holder of the register.
817 return false;
818 }
819 } else {
820 DCHECK(!current->IsHighInterval());
821 int hint = current->FindFirstRegisterHint(free_until, liveness_);
822 if ((hint != kNoRegister)
823 // For simplicity, if the hint we are getting for a pair cannot be used,
824 // we are just going to allocate a new pair.
825 && !(current->IsLowInterval() && IsBlocked(GetHighForLowRegister(hint)))) {
826 DCHECK(!IsBlocked(hint));
827 reg = hint;
828 } else if (current->IsLowInterval()) {
829 reg = FindAvailableRegisterPair(free_until, current->GetStart());
830 } else {
831 reg = FindAvailableRegister(free_until, current);
832 }
833 }
834
835 DCHECK_NE(reg, kNoRegister);
836 // If we could not find a register, we need to spill.
837 if (free_until[reg] == 0) {
838 return false;
839 }
840
841 if (current->IsLowInterval()) {
842 // If the high register of this interval is not available, we need to spill.
843 int high_reg = current->GetHighInterval()->GetRegister();
844 if (high_reg == kNoRegister) {
845 high_reg = GetHighForLowRegister(reg);
846 }
847 if (free_until[high_reg] == 0) {
848 return false;
849 }
850 }
851
852 current->SetRegister(reg);
853 if (!current->IsDeadAt(free_until[reg])) {
854 // If the register is only available for a subset of live ranges
855 // covered by `current`, split `current` before the position where
856 // the register is not available anymore.
857 LiveInterval* split = SplitBetween(current, current->GetStart(), free_until[reg]);
858 DCHECK(split != nullptr);
859 AddSorted(unhandled_, split);
860 }
861 return true;
862 }
863
IsBlocked(int reg) const864 bool RegisterAllocatorLinearScan::IsBlocked(int reg) const {
865 return (current_register_type_ == RegisterType::kCoreRegister)
866 ? blocked_core_registers_[reg]
867 : blocked_fp_registers_[reg];
868 }
869
FindAvailableRegisterPair(size_t * next_use,size_t starting_at) const870 int RegisterAllocatorLinearScan::FindAvailableRegisterPair(size_t* next_use, size_t starting_at) const {
871 int reg = kNoRegister;
872 // Pick the register pair that is used the last.
873 for (size_t i = 0; i < number_of_registers_; ++i) {
874 if (IsBlocked(i)) continue;
875 if (!IsLowRegister(i)) continue;
876 int high_register = GetHighForLowRegister(i);
877 if (IsBlocked(high_register)) continue;
878 int existing_high_register = GetHighForLowRegister(reg);
879 if ((reg == kNoRegister) || (next_use[i] >= next_use[reg]
880 && next_use[high_register] >= next_use[existing_high_register])) {
881 reg = i;
882 if (next_use[i] == kMaxLifetimePosition
883 && next_use[high_register] == kMaxLifetimePosition) {
884 break;
885 }
886 } else if (next_use[reg] <= starting_at || next_use[existing_high_register] <= starting_at) {
887 // If one of the current register is known to be unavailable, just unconditionally
888 // try a new one.
889 reg = i;
890 }
891 }
892 return reg;
893 }
894
IsCallerSaveRegister(int reg) const895 bool RegisterAllocatorLinearScan::IsCallerSaveRegister(int reg) const {
896 uint32_t registers_blocked_for_call = (current_register_type_ == RegisterType::kCoreRegister)
897 ? core_registers_blocked_for_call_
898 : fp_registers_blocked_for_call_;
899 DCHECK_LT(static_cast<size_t>(reg), BitSizeOf<uint32_t>());
900 return (registers_blocked_for_call & (1u << reg)) != 0u;
901 }
902
FindAvailableRegister(size_t * next_use,LiveInterval * current) const903 int RegisterAllocatorLinearScan::FindAvailableRegister(size_t* next_use, LiveInterval* current) const {
904 // We special case intervals that do not span a safepoint to try to find a caller-save
905 // register if one is available. We iterate from 0 to the number of registers,
906 // so if there are caller-save registers available at the end, we continue the iteration.
907 bool prefers_caller_save = !current->HasWillCallSafepoint();
908 int reg = kNoRegister;
909 for (size_t i = 0; i < number_of_registers_; ++i) {
910 if (IsBlocked(i)) {
911 // Register cannot be used. Continue.
912 continue;
913 }
914
915 // Best case: we found a register fully available.
916 if (next_use[i] == kMaxLifetimePosition) {
917 if (prefers_caller_save && !IsCallerSaveRegister(i)) {
918 // We can get shorter encodings on some platforms by using
919 // small register numbers. So only update the candidate if the previous
920 // one was not available for the whole method.
921 if (reg == kNoRegister || next_use[reg] != kMaxLifetimePosition) {
922 reg = i;
923 }
924 // Continue the iteration in the hope of finding a caller save register.
925 continue;
926 } else {
927 reg = i;
928 // We know the register is good enough. Return it.
929 break;
930 }
931 }
932
933 // If we had no register before, take this one as a reference.
934 if (reg == kNoRegister) {
935 reg = i;
936 continue;
937 }
938
939 // Pick the register that is used the last.
940 if (next_use[i] > next_use[reg]) {
941 reg = i;
942 continue;
943 }
944 }
945 return reg;
946 }
947
948 // Remove interval and its other half if any. Return iterator to the following element.
RemoveIntervalAndPotentialOtherHalf(ScopedArenaVector<LiveInterval * > * intervals,ScopedArenaVector<LiveInterval * >::iterator pos)949 static ArenaVector<LiveInterval*>::iterator RemoveIntervalAndPotentialOtherHalf(
950 ScopedArenaVector<LiveInterval*>* intervals, ScopedArenaVector<LiveInterval*>::iterator pos) {
951 DCHECK(intervals->begin() <= pos && pos < intervals->end());
952 LiveInterval* interval = *pos;
953 if (interval->IsLowInterval()) {
954 DCHECK(pos + 1 < intervals->end());
955 DCHECK_EQ(*(pos + 1), interval->GetHighInterval());
956 return intervals->erase(pos, pos + 2);
957 } else if (interval->IsHighInterval()) {
958 DCHECK(intervals->begin() < pos);
959 DCHECK_EQ(*(pos - 1), interval->GetLowInterval());
960 return intervals->erase(pos - 1, pos + 1);
961 } else {
962 return intervals->erase(pos);
963 }
964 }
965
TrySplitNonPairOrUnalignedPairIntervalAt(size_t position,size_t first_register_use,size_t * next_use)966 bool RegisterAllocatorLinearScan::TrySplitNonPairOrUnalignedPairIntervalAt(size_t position,
967 size_t first_register_use,
968 size_t* next_use) {
969 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
970 LiveInterval* active = *it;
971 // Special fixed intervals that represent multiple registers do not report having a register.
972 if (active->IsFixed()) continue;
973 DCHECK(active->HasRegister());
974 if (active->IsHighInterval()) continue;
975 if (first_register_use > next_use[active->GetRegister()]) continue;
976
977 // Split the first interval found that is either:
978 // 1) A non-pair interval.
979 // 2) A pair interval whose high is not low + 1.
980 // 3) A pair interval whose low is not even.
981 if (!active->IsLowInterval() ||
982 IsLowOfUnalignedPairInterval(active) ||
983 !IsLowRegister(active->GetRegister())) {
984 LiveInterval* split = Split(active, position);
985 if (split != active) {
986 handled_.push_back(active);
987 }
988 RemoveIntervalAndPotentialOtherHalf(&active_, it);
989 AddSorted(unhandled_, split);
990 return true;
991 }
992 }
993 return false;
994 }
995
996 // Find the register that is used the last, and spill the interval
997 // that holds it. If the first use of `current` is after that register
998 // we spill `current` instead.
AllocateBlockedReg(LiveInterval * current)999 bool RegisterAllocatorLinearScan::AllocateBlockedReg(LiveInterval* current) {
1000 size_t first_register_use = current->FirstRegisterUse();
1001 if (current->HasRegister()) {
1002 DCHECK(current->IsHighInterval());
1003 // The low interval has allocated the register for the high interval. In
1004 // case the low interval had to split both intervals, we may end up in a
1005 // situation where the high interval does not have a register use anymore.
1006 // We must still proceed in order to split currently active and inactive
1007 // uses of the high interval's register, and put the high interval in the
1008 // active set.
1009 DCHECK_IMPLIES(first_register_use == kNoLifetime, current->GetNextSibling() != nullptr);
1010 } else if (first_register_use == kNoLifetime) {
1011 AllocateSpillSlotFor(current);
1012 return false;
1013 }
1014
1015 // First set all registers as not being used.
1016 size_t* next_use = registers_array_;
1017 for (size_t i = 0; i < number_of_registers_; ++i) {
1018 next_use[i] = kMaxLifetimePosition;
1019 }
1020
1021 // For each active interval, find the next use of its register after the
1022 // start of current.
1023 for (LiveInterval* active : active_) {
1024 if (active->IsFixed()) {
1025 uint32_t register_mask = GetRegisterMask(active, current_register_type_);
1026 DCHECK_NE(register_mask, 0u);
1027 for (uint32_t reg : LowToHighBits(register_mask)) {
1028 next_use[reg] = current->GetStart();
1029 }
1030 } else {
1031 DCHECK(active->HasRegister());
1032 size_t use = active->FirstRegisterUseAfter(current->GetStart());
1033 if (use != kNoLifetime) {
1034 next_use[active->GetRegister()] = use;
1035 }
1036 }
1037 }
1038
1039 // For each inactive interval, find the next use of its register after the
1040 // start of current.
1041 for (LiveInterval* inactive : inactive_) {
1042 // Temp/Slow-path-safepoint interval has no holes.
1043 DCHECK(!inactive->IsTemp());
1044 if (!current->IsSplit() && !inactive->IsFixed()) {
1045 // Neither current nor inactive are fixed.
1046 // Thanks to SSA, a non-split interval starting in a hole of an
1047 // inactive interval should never intersect with that inactive interval.
1048 // Only if it's not fixed though, because fixed intervals don't come from SSA.
1049 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
1050 continue;
1051 }
1052 DCHECK(inactive->HasRegister() || inactive->IsFixed());
1053 size_t next_intersection = inactive->FirstIntersectionWith(current);
1054 if (next_intersection != kNoLifetime) {
1055 if (inactive->IsFixed()) {
1056 uint32_t register_mask = GetRegisterMask(inactive, current_register_type_);
1057 DCHECK_NE(register_mask, 0u);
1058 for (uint32_t reg : LowToHighBits(register_mask)) {
1059 next_use[reg] = std::min(next_intersection, next_use[reg]);
1060 }
1061 } else {
1062 size_t use = inactive->FirstUseAfter(current->GetStart());
1063 if (use != kNoLifetime) {
1064 next_use[inactive->GetRegister()] = std::min(use, next_use[inactive->GetRegister()]);
1065 }
1066 }
1067 }
1068 }
1069
1070 int reg = kNoRegister;
1071 bool should_spill = false;
1072 if (current->HasRegister()) {
1073 DCHECK(current->IsHighInterval());
1074 reg = current->GetRegister();
1075 // When allocating the low part, we made sure the high register was available.
1076 DCHECK_LT(first_register_use, next_use[reg]);
1077 } else if (current->IsLowInterval()) {
1078 reg = FindAvailableRegisterPair(next_use, first_register_use);
1079 // We should spill if both registers are not available.
1080 should_spill = (first_register_use >= next_use[reg])
1081 || (first_register_use >= next_use[GetHighForLowRegister(reg)]);
1082 } else {
1083 DCHECK(!current->IsHighInterval());
1084 reg = FindAvailableRegister(next_use, current);
1085 should_spill = (first_register_use >= next_use[reg]);
1086 }
1087
1088 DCHECK_NE(reg, kNoRegister);
1089 if (should_spill) {
1090 DCHECK(!current->IsHighInterval());
1091 bool is_allocation_at_use_site = (current->GetStart() >= (first_register_use - 1));
1092 if (is_allocation_at_use_site) {
1093 if (!current->IsLowInterval()) {
1094 DumpInterval(std::cerr, current);
1095 DumpAllIntervals(std::cerr);
1096 // This situation has the potential to infinite loop, so we make it a non-debug CHECK.
1097 HInstruction* at = liveness_.GetInstructionFromPosition(first_register_use / 2);
1098 CHECK(false) << "There is not enough registers available for "
1099 << current->GetParent()->GetDefinedBy()->DebugName() << " "
1100 << current->GetParent()->GetDefinedBy()->GetId()
1101 << " at " << first_register_use - 1 << " "
1102 << (at == nullptr ? "" : at->DebugName());
1103 }
1104
1105 // If we're allocating a register for `current` because the instruction at
1106 // that position requires it, but we think we should spill, then there are
1107 // non-pair intervals or unaligned pair intervals blocking the allocation.
1108 // We split the first interval found, and put ourselves first in the
1109 // `unhandled_` list.
1110 bool success = TrySplitNonPairOrUnalignedPairIntervalAt(current->GetStart(),
1111 first_register_use,
1112 next_use);
1113 DCHECK(success);
1114 LiveInterval* existing = unhandled_->back();
1115 DCHECK(existing->IsHighInterval());
1116 DCHECK_EQ(existing->GetLowInterval(), current);
1117 unhandled_->push_back(current);
1118 } else {
1119 // If the first use of that instruction is after the last use of the found
1120 // register, we split this interval just before its first register use.
1121 AllocateSpillSlotFor(current);
1122 LiveInterval* split = SplitBetween(current, current->GetStart(), first_register_use - 1);
1123 DCHECK(current != split);
1124 AddSorted(unhandled_, split);
1125 }
1126 return false;
1127 } else {
1128 // Use this register and spill the active and inactives interval that
1129 // have that register.
1130 current->SetRegister(reg);
1131
1132 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
1133 LiveInterval* active = *it;
1134 DCHECK_IMPLIES(active->IsFixed(),
1135 (GetRegisterMask(active, current_register_type_) & (1u << reg)) == 0u);
1136 if (active->GetRegister() == reg) {
1137 DCHECK(!active->IsFixed());
1138 LiveInterval* split = Split(active, current->GetStart());
1139 if (split != active) {
1140 handled_.push_back(active);
1141 }
1142 RemoveIntervalAndPotentialOtherHalf(&active_, it);
1143 AddSorted(unhandled_, split);
1144 break;
1145 }
1146 }
1147
1148 // NOTE: Retrieve end() on each iteration because we're removing elements in the loop body.
1149 for (auto it = inactive_.begin(); it != inactive_.end(); ) {
1150 LiveInterval* inactive = *it;
1151 bool erased = false;
1152 if ((GetRegisterMask(inactive, current_register_type_) & (1u << reg)) != 0u) {
1153 if (!current->IsSplit() && !inactive->IsFixed()) {
1154 // Neither current nor inactive are fixed.
1155 // Thanks to SSA, a non-split interval starting in a hole of an
1156 // inactive interval should never intersect with that inactive interval.
1157 // Only if it's not fixed though, because fixed intervals don't come from SSA.
1158 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
1159 } else {
1160 size_t next_intersection = inactive->FirstIntersectionWith(current);
1161 if (next_intersection != kNoLifetime) {
1162 if (inactive->IsFixed()) {
1163 LiveInterval* split = Split(current, next_intersection);
1164 DCHECK_NE(split, current);
1165 AddSorted(unhandled_, split);
1166 } else {
1167 // Split at the start of `current`, which will lead to splitting
1168 // at the end of the lifetime hole of `inactive`.
1169 LiveInterval* split = Split(inactive, current->GetStart());
1170 // If it's inactive, it must start before the current interval.
1171 DCHECK_NE(split, inactive);
1172 it = RemoveIntervalAndPotentialOtherHalf(&inactive_, it);
1173 erased = true;
1174 handled_.push_back(inactive);
1175 AddSorted(unhandled_, split);
1176 }
1177 }
1178 }
1179 }
1180 // If we have erased the element, `it` already points to the next element.
1181 // Otherwise we need to move to the next element.
1182 if (!erased) {
1183 ++it;
1184 }
1185 }
1186
1187 return true;
1188 }
1189 }
1190
AddSorted(ScopedArenaVector<LiveInterval * > * array,LiveInterval * interval)1191 void RegisterAllocatorLinearScan::AddSorted(ScopedArenaVector<LiveInterval*>* array,
1192 LiveInterval* interval) {
1193 DCHECK(!interval->IsFixed() && !interval->HasSpillSlot());
1194 size_t insert_at = 0;
1195 for (size_t i = array->size(); i > 0; --i) {
1196 LiveInterval* current = (*array)[i - 1u];
1197 // High intervals must be processed right after their low equivalent.
1198 if (current->StartsAfter(interval) && !current->IsHighInterval()) {
1199 insert_at = i;
1200 break;
1201 }
1202 }
1203
1204 // Insert the high interval before the low, to ensure the low is processed before.
1205 auto insert_pos = array->begin() + insert_at;
1206 if (interval->HasHighInterval()) {
1207 array->insert(insert_pos, { interval->GetHighInterval(), interval });
1208 } else if (interval->HasLowInterval()) {
1209 array->insert(insert_pos, { interval, interval->GetLowInterval() });
1210 } else {
1211 array->insert(insert_pos, interval);
1212 }
1213 }
1214
AllocateSpillSlotFor(LiveInterval * interval)1215 void RegisterAllocatorLinearScan::AllocateSpillSlotFor(LiveInterval* interval) {
1216 if (interval->IsHighInterval()) {
1217 // The low interval already took care of allocating the spill slot.
1218 DCHECK(!interval->GetLowInterval()->HasRegister());
1219 DCHECK(interval->GetLowInterval()->GetParent()->HasSpillSlot());
1220 return;
1221 }
1222
1223 LiveInterval* parent = interval->GetParent();
1224
1225 // An instruction gets a spill slot for its entire lifetime. If the parent
1226 // of this interval already has a spill slot, there is nothing to do.
1227 if (parent->HasSpillSlot()) {
1228 return;
1229 }
1230
1231 HInstruction* defined_by = parent->GetDefinedBy();
1232 DCHECK_IMPLIES(defined_by->IsPhi(), !defined_by->AsPhi()->IsCatchPhi());
1233
1234 if (defined_by->IsParameterValue()) {
1235 // Parameters have their own stack slot.
1236 parent->SetSpillSlot(codegen_->GetStackSlotOfParameter(defined_by->AsParameterValue()));
1237 return;
1238 }
1239
1240 if (defined_by->IsCurrentMethod()) {
1241 parent->SetSpillSlot(0);
1242 return;
1243 }
1244
1245 if (defined_by->IsConstant()) {
1246 // Constants don't need a spill slot.
1247 return;
1248 }
1249
1250 ScopedArenaVector<size_t>* spill_slots = nullptr;
1251 switch (interval->GetType()) {
1252 case DataType::Type::kFloat64:
1253 spill_slots = &double_spill_slots_;
1254 break;
1255 case DataType::Type::kInt64:
1256 spill_slots = &long_spill_slots_;
1257 break;
1258 case DataType::Type::kFloat32:
1259 spill_slots = &float_spill_slots_;
1260 break;
1261 case DataType::Type::kReference:
1262 case DataType::Type::kInt32:
1263 case DataType::Type::kUint16:
1264 case DataType::Type::kUint8:
1265 case DataType::Type::kInt8:
1266 case DataType::Type::kBool:
1267 case DataType::Type::kInt16:
1268 spill_slots = &int_spill_slots_;
1269 break;
1270 case DataType::Type::kUint32:
1271 case DataType::Type::kUint64:
1272 case DataType::Type::kVoid:
1273 LOG(FATAL) << "Unexpected type for interval " << interval->GetType();
1274 }
1275
1276 // Find first available spill slots.
1277 size_t number_of_spill_slots_needed = parent->NumberOfSpillSlotsNeeded();
1278 size_t slot = 0;
1279 for (size_t e = spill_slots->size(); slot < e; ++slot) {
1280 bool found = true;
1281 for (size_t s = slot, u = std::min(slot + number_of_spill_slots_needed, e); s < u; s++) {
1282 if ((*spill_slots)[s] > parent->GetStart()) {
1283 found = false; // failure
1284 break;
1285 }
1286 }
1287 if (found) {
1288 break; // success
1289 }
1290 }
1291
1292 // Need new spill slots?
1293 size_t upper = slot + number_of_spill_slots_needed;
1294 if (upper > spill_slots->size()) {
1295 spill_slots->resize(upper);
1296 }
1297 // Set slots to end.
1298 size_t end = interval->GetLastSibling()->GetEnd();
1299 for (size_t s = slot; s < upper; s++) {
1300 (*spill_slots)[s] = end;
1301 }
1302
1303 // Note that the exact spill slot location will be computed when we resolve,
1304 // that is when we know the number of spill slots for each type.
1305 parent->SetSpillSlot(slot);
1306 }
1307
AllocateSpillSlotForCatchPhi(HPhi * phi)1308 void RegisterAllocatorLinearScan::AllocateSpillSlotForCatchPhi(HPhi* phi) {
1309 LiveInterval* interval = phi->GetLiveInterval();
1310
1311 HInstruction* previous_phi = phi->GetPrevious();
1312 DCHECK(previous_phi == nullptr || previous_phi->AsPhi()->GetRegNumber() <= phi->GetRegNumber())
1313 << "Phis expected to be sorted by vreg number, so that equivalent phis are adjacent.";
1314
1315 if (phi->IsVRegEquivalentOf(previous_phi)) {
1316 // This is an equivalent of the previous phi. We need to assign the same
1317 // catch phi slot.
1318 DCHECK(previous_phi->GetLiveInterval()->HasSpillSlot());
1319 interval->SetSpillSlot(previous_phi->GetLiveInterval()->GetSpillSlot());
1320 } else {
1321 // Allocate a new spill slot for this catch phi.
1322 // TODO: Reuse spill slots when intervals of phis from different catch
1323 // blocks do not overlap.
1324 interval->SetSpillSlot(catch_phi_spill_slots_);
1325 catch_phi_spill_slots_ += interval->NumberOfSpillSlotsNeeded();
1326 }
1327 }
1328
1329 } // namespace art
1330