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 while (!unhandled_->empty()) {
599 // (1) Remove interval with the lowest start position from unhandled.
600 LiveInterval* current = unhandled_->back();
601 unhandled_->pop_back();
602
603 // Make sure the interval is an expected state.
604 DCHECK(!current->IsFixed() && !current->HasSpillSlot());
605 // Make sure we are going in the right order.
606 DCHECK(unhandled_->empty() || unhandled_->back()->GetStart() >= current->GetStart());
607 // Make sure a low interval is always with a high.
608 DCHECK_IMPLIES(current->IsLowInterval(), unhandled_->back()->IsHighInterval());
609 // Make sure a high interval is always with a low.
610 DCHECK(current->IsLowInterval() ||
611 unhandled_->empty() ||
612 !unhandled_->back()->IsHighInterval());
613
614 size_t position = current->GetStart();
615
616 // Remember the inactive_ size here since the ones moved to inactive_ from
617 // active_ below shouldn't need to be re-checked.
618 size_t inactive_intervals_to_handle = inactive_.size();
619
620 // (2) Remove currently active intervals that are dead at this position.
621 // Move active intervals that have a lifetime hole at this position
622 // to inactive.
623 auto active_kept_end = std::remove_if(
624 active_.begin(),
625 active_.end(),
626 [this, position](LiveInterval* interval) {
627 if (interval->IsDeadAt(position)) {
628 handled_.push_back(interval);
629 return true;
630 } else if (!interval->Covers(position)) {
631 inactive_.push_back(interval);
632 return true;
633 } else {
634 return false; // Keep this interval.
635 }
636 });
637 active_.erase(active_kept_end, active_.end());
638
639 // (3) Remove currently inactive intervals that are dead at this position.
640 // Move inactive intervals that cover this position to active.
641 auto inactive_to_handle_end = inactive_.begin() + inactive_intervals_to_handle;
642 auto inactive_kept_end = std::remove_if(
643 inactive_.begin(),
644 inactive_to_handle_end,
645 [this, position](LiveInterval* interval) {
646 DCHECK(interval->GetStart() < position || interval->IsFixed());
647 if (interval->IsDeadAt(position)) {
648 handled_.push_back(interval);
649 return true;
650 } else if (interval->Covers(position)) {
651 active_.push_back(interval);
652 return true;
653 } else {
654 return false; // Keep this interval.
655 }
656 });
657 inactive_.erase(inactive_kept_end, inactive_to_handle_end);
658
659 if (current->IsHighInterval() && !current->GetLowInterval()->HasRegister()) {
660 DCHECK(!current->HasRegister());
661 // Allocating the low part was unsucessful. The splitted interval for the high part
662 // will be handled next (it is in the `unhandled_` list).
663 continue;
664 }
665
666 // (4) Try to find an available register.
667 bool success = TryAllocateFreeReg(current);
668
669 // (5) If no register could be found, we need to spill.
670 if (!success) {
671 success = AllocateBlockedReg(current);
672 }
673
674 // (6) If the interval had a register allocated, add it to the list of active
675 // intervals.
676 if (success) {
677 codegen_->AddAllocatedRegister((current_register_type_ == RegisterType::kCoreRegister)
678 ? Location::RegisterLocation(current->GetRegister())
679 : Location::FpuRegisterLocation(current->GetRegister()));
680 active_.push_back(current);
681 if (current->HasHighInterval() && !current->GetHighInterval()->HasRegister()) {
682 current->GetHighInterval()->SetRegister(GetHighForLowRegister(current->GetRegister()));
683 }
684 }
685 }
686 }
687
FreeIfNotCoverAt(LiveInterval * interval,size_t position,size_t * free_until)688 static void FreeIfNotCoverAt(LiveInterval* interval, size_t position, size_t* free_until) {
689 DCHECK(!interval->IsHighInterval());
690 // Note that the same instruction may occur multiple times in the input list,
691 // so `free_until` may have changed already.
692 // Since `position` is not the current scan position, we need to use CoversSlow.
693 if (interval->IsDeadAt(position)) {
694 // Set the register to be free. Note that inactive intervals might later
695 // update this.
696 free_until[interval->GetRegister()] = kMaxLifetimePosition;
697 if (interval->HasHighInterval()) {
698 DCHECK(interval->GetHighInterval()->IsDeadAt(position));
699 free_until[interval->GetHighInterval()->GetRegister()] = kMaxLifetimePosition;
700 }
701 } else if (!interval->CoversSlow(position)) {
702 // The interval becomes inactive at `defined_by`. We make its register
703 // available only until the next use strictly after `defined_by`.
704 free_until[interval->GetRegister()] = interval->FirstUseAfter(position);
705 if (interval->HasHighInterval()) {
706 DCHECK(!interval->GetHighInterval()->CoversSlow(position));
707 free_until[interval->GetHighInterval()->GetRegister()] = free_until[interval->GetRegister()];
708 }
709 }
710 }
711
712 // Find a free register. If multiple are found, pick the register that
713 // is free the longest.
TryAllocateFreeReg(LiveInterval * current)714 bool RegisterAllocatorLinearScan::TryAllocateFreeReg(LiveInterval* current) {
715 size_t* free_until = registers_array_;
716
717 // First set all registers to be free.
718 for (size_t i = 0; i < number_of_registers_; ++i) {
719 free_until[i] = kMaxLifetimePosition;
720 }
721
722 // For each active interval, set its register(s) to not free.
723 for (LiveInterval* interval : active_) {
724 DCHECK(interval->HasRegister() || interval->IsFixed());
725 uint32_t register_mask = GetRegisterMask(interval, current_register_type_);
726 DCHECK_NE(register_mask, 0u);
727 for (uint32_t reg : LowToHighBits(register_mask)) {
728 free_until[reg] = 0;
729 }
730 }
731
732 // An interval that starts an instruction (that is, it is not split), may
733 // re-use the registers used by the inputs of that instruciton, based on the
734 // location summary.
735 HInstruction* defined_by = current->GetDefinedBy();
736 if (defined_by != nullptr && !current->IsSplit()) {
737 LocationSummary* locations = defined_by->GetLocations();
738 if (!locations->OutputCanOverlapWithInputs() && locations->Out().IsUnallocated()) {
739 HInputsRef inputs = defined_by->GetInputs();
740 for (size_t i = 0; i < inputs.size(); ++i) {
741 if (locations->InAt(i).IsValid()) {
742 // Take the last interval of the input. It is the location of that interval
743 // that will be used at `defined_by`.
744 LiveInterval* interval = inputs[i]->GetLiveInterval()->GetLastSibling();
745 // Note that interval may have not been processed yet.
746 // TODO: Handle non-split intervals last in the work list.
747 if (interval->HasRegister() && interval->SameRegisterKind(*current)) {
748 // The input must be live until the end of `defined_by`, to comply to
749 // the linear scan algorithm. So we use `defined_by`'s end lifetime
750 // position to check whether the input is dead or is inactive after
751 // `defined_by`.
752 DCHECK(interval->CoversSlow(defined_by->GetLifetimePosition()));
753 size_t position = defined_by->GetLifetimePosition() + 1;
754 FreeIfNotCoverAt(interval, position, free_until);
755 }
756 }
757 }
758 }
759 }
760
761 // For each inactive interval, set its register to be free until
762 // the next intersection with `current`.
763 for (LiveInterval* inactive : inactive_) {
764 // Temp/Slow-path-safepoint interval has no holes.
765 DCHECK(!inactive->IsTemp());
766 if (!current->IsSplit() && !inactive->IsFixed()) {
767 // Neither current nor inactive are fixed.
768 // Thanks to SSA, a non-split interval starting in a hole of an
769 // inactive interval should never intersect with that inactive interval.
770 // Only if it's not fixed though, because fixed intervals don't come from SSA.
771 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
772 continue;
773 }
774
775 DCHECK(inactive->HasRegister() || inactive->IsFixed());
776 uint32_t register_mask = GetRegisterMask(inactive, current_register_type_);
777 DCHECK_NE(register_mask, 0u);
778 for (uint32_t reg : LowToHighBits(register_mask)) {
779 if (free_until[reg] == 0) {
780 // Already used by some active interval. Clear the register bit.
781 register_mask &= ~(1u << reg);
782 }
783 }
784 if (register_mask != 0u) {
785 size_t next_intersection = inactive->FirstIntersectionWith(current);
786 if (next_intersection != kNoLifetime) {
787 for (uint32_t reg : LowToHighBits(register_mask)) {
788 free_until[reg] = std::min(free_until[reg], next_intersection);
789 }
790 }
791 }
792 }
793
794 int reg = kNoRegister;
795 if (current->HasRegister()) {
796 // Some instructions have a fixed register output.
797 reg = current->GetRegister();
798 if (free_until[reg] == 0) {
799 DCHECK(current->IsHighInterval());
800 // AllocateBlockedReg will spill the holder of the register.
801 return false;
802 }
803 } else {
804 DCHECK(!current->IsHighInterval());
805 int hint = current->FindFirstRegisterHint(free_until, liveness_);
806 if ((hint != kNoRegister)
807 // For simplicity, if the hint we are getting for a pair cannot be used,
808 // we are just going to allocate a new pair.
809 && !(current->IsLowInterval() && IsBlocked(GetHighForLowRegister(hint)))) {
810 DCHECK(!IsBlocked(hint));
811 reg = hint;
812 } else if (current->IsLowInterval()) {
813 reg = FindAvailableRegisterPair(free_until, current->GetStart());
814 } else {
815 reg = FindAvailableRegister(free_until, current);
816 }
817 }
818
819 DCHECK_NE(reg, kNoRegister);
820 // If we could not find a register, we need to spill.
821 if (free_until[reg] == 0) {
822 return false;
823 }
824
825 if (current->IsLowInterval()) {
826 // If the high register of this interval is not available, we need to spill.
827 int high_reg = current->GetHighInterval()->GetRegister();
828 if (high_reg == kNoRegister) {
829 high_reg = GetHighForLowRegister(reg);
830 }
831 if (free_until[high_reg] == 0) {
832 return false;
833 }
834 }
835
836 current->SetRegister(reg);
837 if (!current->IsDeadAt(free_until[reg])) {
838 // If the register is only available for a subset of live ranges
839 // covered by `current`, split `current` before the position where
840 // the register is not available anymore.
841 LiveInterval* split = SplitBetween(current, current->GetStart(), free_until[reg]);
842 DCHECK(split != nullptr);
843 AddSorted(unhandled_, split);
844 }
845 return true;
846 }
847
IsBlocked(int reg) const848 bool RegisterAllocatorLinearScan::IsBlocked(int reg) const {
849 return (current_register_type_ == RegisterType::kCoreRegister)
850 ? blocked_core_registers_[reg]
851 : blocked_fp_registers_[reg];
852 }
853
FindAvailableRegisterPair(size_t * next_use,size_t starting_at) const854 int RegisterAllocatorLinearScan::FindAvailableRegisterPair(size_t* next_use, size_t starting_at) const {
855 int reg = kNoRegister;
856 // Pick the register pair that is used the last.
857 for (size_t i = 0; i < number_of_registers_; ++i) {
858 if (IsBlocked(i)) continue;
859 if (!IsLowRegister(i)) continue;
860 int high_register = GetHighForLowRegister(i);
861 if (IsBlocked(high_register)) continue;
862 int existing_high_register = GetHighForLowRegister(reg);
863 if ((reg == kNoRegister) || (next_use[i] >= next_use[reg]
864 && next_use[high_register] >= next_use[existing_high_register])) {
865 reg = i;
866 if (next_use[i] == kMaxLifetimePosition
867 && next_use[high_register] == kMaxLifetimePosition) {
868 break;
869 }
870 } else if (next_use[reg] <= starting_at || next_use[existing_high_register] <= starting_at) {
871 // If one of the current register is known to be unavailable, just unconditionally
872 // try a new one.
873 reg = i;
874 }
875 }
876 return reg;
877 }
878
IsCallerSaveRegister(int reg) const879 bool RegisterAllocatorLinearScan::IsCallerSaveRegister(int reg) const {
880 uint32_t registers_blocked_for_call = (current_register_type_ == RegisterType::kCoreRegister)
881 ? core_registers_blocked_for_call_
882 : fp_registers_blocked_for_call_;
883 DCHECK_LT(static_cast<size_t>(reg), BitSizeOf<uint32_t>());
884 return (registers_blocked_for_call & (1u << reg)) != 0u;
885 }
886
FindAvailableRegister(size_t * next_use,LiveInterval * current) const887 int RegisterAllocatorLinearScan::FindAvailableRegister(size_t* next_use, LiveInterval* current) const {
888 // We special case intervals that do not span a safepoint to try to find a caller-save
889 // register if one is available. We iterate from 0 to the number of registers,
890 // so if there are caller-save registers available at the end, we continue the iteration.
891 bool prefers_caller_save = !current->HasWillCallSafepoint();
892 int reg = kNoRegister;
893 for (size_t i = 0; i < number_of_registers_; ++i) {
894 if (IsBlocked(i)) {
895 // Register cannot be used. Continue.
896 continue;
897 }
898
899 // Best case: we found a register fully available.
900 if (next_use[i] == kMaxLifetimePosition) {
901 if (prefers_caller_save && !IsCallerSaveRegister(i)) {
902 // We can get shorter encodings on some platforms by using
903 // small register numbers. So only update the candidate if the previous
904 // one was not available for the whole method.
905 if (reg == kNoRegister || next_use[reg] != kMaxLifetimePosition) {
906 reg = i;
907 }
908 // Continue the iteration in the hope of finding a caller save register.
909 continue;
910 } else {
911 reg = i;
912 // We know the register is good enough. Return it.
913 break;
914 }
915 }
916
917 // If we had no register before, take this one as a reference.
918 if (reg == kNoRegister) {
919 reg = i;
920 continue;
921 }
922
923 // Pick the register that is used the last.
924 if (next_use[i] > next_use[reg]) {
925 reg = i;
926 continue;
927 }
928 }
929 return reg;
930 }
931
932 // Remove interval and its other half if any. Return iterator to the following element.
RemoveIntervalAndPotentialOtherHalf(ScopedArenaVector<LiveInterval * > * intervals,ScopedArenaVector<LiveInterval * >::iterator pos)933 static ArenaVector<LiveInterval*>::iterator RemoveIntervalAndPotentialOtherHalf(
934 ScopedArenaVector<LiveInterval*>* intervals, ScopedArenaVector<LiveInterval*>::iterator pos) {
935 DCHECK(intervals->begin() <= pos && pos < intervals->end());
936 LiveInterval* interval = *pos;
937 if (interval->IsLowInterval()) {
938 DCHECK(pos + 1 < intervals->end());
939 DCHECK_EQ(*(pos + 1), interval->GetHighInterval());
940 return intervals->erase(pos, pos + 2);
941 } else if (interval->IsHighInterval()) {
942 DCHECK(intervals->begin() < pos);
943 DCHECK_EQ(*(pos - 1), interval->GetLowInterval());
944 return intervals->erase(pos - 1, pos + 1);
945 } else {
946 return intervals->erase(pos);
947 }
948 }
949
TrySplitNonPairOrUnalignedPairIntervalAt(size_t position,size_t first_register_use,size_t * next_use)950 bool RegisterAllocatorLinearScan::TrySplitNonPairOrUnalignedPairIntervalAt(size_t position,
951 size_t first_register_use,
952 size_t* next_use) {
953 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
954 LiveInterval* active = *it;
955 // Special fixed intervals that represent multiple registers do not report having a register.
956 if (active->IsFixed()) continue;
957 DCHECK(active->HasRegister());
958 if (active->IsHighInterval()) continue;
959 if (first_register_use > next_use[active->GetRegister()]) continue;
960
961 // Split the first interval found that is either:
962 // 1) A non-pair interval.
963 // 2) A pair interval whose high is not low + 1.
964 // 3) A pair interval whose low is not even.
965 if (!active->IsLowInterval() ||
966 IsLowOfUnalignedPairInterval(active) ||
967 !IsLowRegister(active->GetRegister())) {
968 LiveInterval* split = Split(active, position);
969 if (split != active) {
970 handled_.push_back(active);
971 }
972 RemoveIntervalAndPotentialOtherHalf(&active_, it);
973 AddSorted(unhandled_, split);
974 return true;
975 }
976 }
977 return false;
978 }
979
980 // Find the register that is used the last, and spill the interval
981 // that holds it. If the first use of `current` is after that register
982 // we spill `current` instead.
AllocateBlockedReg(LiveInterval * current)983 bool RegisterAllocatorLinearScan::AllocateBlockedReg(LiveInterval* current) {
984 size_t first_register_use = current->FirstRegisterUse();
985 if (current->HasRegister()) {
986 DCHECK(current->IsHighInterval());
987 // The low interval has allocated the register for the high interval. In
988 // case the low interval had to split both intervals, we may end up in a
989 // situation where the high interval does not have a register use anymore.
990 // We must still proceed in order to split currently active and inactive
991 // uses of the high interval's register, and put the high interval in the
992 // active set.
993 DCHECK_IMPLIES(first_register_use == kNoLifetime, current->GetNextSibling() != nullptr);
994 } else if (first_register_use == kNoLifetime) {
995 AllocateSpillSlotFor(current);
996 return false;
997 }
998
999 // First set all registers as not being used.
1000 size_t* next_use = registers_array_;
1001 for (size_t i = 0; i < number_of_registers_; ++i) {
1002 next_use[i] = kMaxLifetimePosition;
1003 }
1004
1005 // For each active interval, find the next use of its register after the
1006 // start of current.
1007 for (LiveInterval* active : active_) {
1008 if (active->IsFixed()) {
1009 uint32_t register_mask = GetRegisterMask(active, current_register_type_);
1010 DCHECK_NE(register_mask, 0u);
1011 for (uint32_t reg : LowToHighBits(register_mask)) {
1012 next_use[reg] = current->GetStart();
1013 }
1014 } else {
1015 DCHECK(active->HasRegister());
1016 size_t use = active->FirstRegisterUseAfter(current->GetStart());
1017 if (use != kNoLifetime) {
1018 next_use[active->GetRegister()] = use;
1019 }
1020 }
1021 }
1022
1023 // For each inactive interval, find the next use of its register after the
1024 // start of current.
1025 for (LiveInterval* inactive : inactive_) {
1026 // Temp/Slow-path-safepoint interval has no holes.
1027 DCHECK(!inactive->IsTemp());
1028 if (!current->IsSplit() && !inactive->IsFixed()) {
1029 // Neither current nor inactive are fixed.
1030 // Thanks to SSA, a non-split interval starting in a hole of an
1031 // inactive interval should never intersect with that inactive interval.
1032 // Only if it's not fixed though, because fixed intervals don't come from SSA.
1033 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
1034 continue;
1035 }
1036 DCHECK(inactive->HasRegister() || inactive->IsFixed());
1037 size_t next_intersection = inactive->FirstIntersectionWith(current);
1038 if (next_intersection != kNoLifetime) {
1039 if (inactive->IsFixed()) {
1040 uint32_t register_mask = GetRegisterMask(inactive, current_register_type_);
1041 DCHECK_NE(register_mask, 0u);
1042 for (uint32_t reg : LowToHighBits(register_mask)) {
1043 next_use[reg] = std::min(next_intersection, next_use[reg]);
1044 }
1045 } else {
1046 size_t use = inactive->FirstUseAfter(current->GetStart());
1047 if (use != kNoLifetime) {
1048 next_use[inactive->GetRegister()] = std::min(use, next_use[inactive->GetRegister()]);
1049 }
1050 }
1051 }
1052 }
1053
1054 int reg = kNoRegister;
1055 bool should_spill = false;
1056 if (current->HasRegister()) {
1057 DCHECK(current->IsHighInterval());
1058 reg = current->GetRegister();
1059 // When allocating the low part, we made sure the high register was available.
1060 DCHECK_LT(first_register_use, next_use[reg]);
1061 } else if (current->IsLowInterval()) {
1062 reg = FindAvailableRegisterPair(next_use, first_register_use);
1063 // We should spill if both registers are not available.
1064 should_spill = (first_register_use >= next_use[reg])
1065 || (first_register_use >= next_use[GetHighForLowRegister(reg)]);
1066 } else {
1067 DCHECK(!current->IsHighInterval());
1068 reg = FindAvailableRegister(next_use, current);
1069 should_spill = (first_register_use >= next_use[reg]);
1070 }
1071
1072 DCHECK_NE(reg, kNoRegister);
1073 if (should_spill) {
1074 DCHECK(!current->IsHighInterval());
1075 bool is_allocation_at_use_site = (current->GetStart() >= (first_register_use - 1));
1076 if (is_allocation_at_use_site) {
1077 if (!current->IsLowInterval()) {
1078 DumpInterval(std::cerr, current);
1079 DumpAllIntervals(std::cerr);
1080 // This situation has the potential to infinite loop, so we make it a non-debug CHECK.
1081 HInstruction* at = liveness_.GetInstructionFromPosition(first_register_use / 2);
1082 CHECK(false) << "There is not enough registers available for "
1083 << current->GetParent()->GetDefinedBy()->DebugName() << " "
1084 << current->GetParent()->GetDefinedBy()->GetId()
1085 << " at " << first_register_use - 1 << " "
1086 << (at == nullptr ? "" : at->DebugName());
1087 }
1088
1089 // If we're allocating a register for `current` because the instruction at
1090 // that position requires it, but we think we should spill, then there are
1091 // non-pair intervals or unaligned pair intervals blocking the allocation.
1092 // We split the first interval found, and put ourselves first in the
1093 // `unhandled_` list.
1094 bool success = TrySplitNonPairOrUnalignedPairIntervalAt(current->GetStart(),
1095 first_register_use,
1096 next_use);
1097 DCHECK(success);
1098 LiveInterval* existing = unhandled_->back();
1099 DCHECK(existing->IsHighInterval());
1100 DCHECK_EQ(existing->GetLowInterval(), current);
1101 unhandled_->push_back(current);
1102 } else {
1103 // If the first use of that instruction is after the last use of the found
1104 // register, we split this interval just before its first register use.
1105 AllocateSpillSlotFor(current);
1106 LiveInterval* split = SplitBetween(current, current->GetStart(), first_register_use - 1);
1107 DCHECK(current != split);
1108 AddSorted(unhandled_, split);
1109 }
1110 return false;
1111 } else {
1112 // Use this register and spill the active and inactives interval that
1113 // have that register.
1114 current->SetRegister(reg);
1115
1116 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
1117 LiveInterval* active = *it;
1118 DCHECK_IMPLIES(active->IsFixed(),
1119 (GetRegisterMask(active, current_register_type_) & (1u << reg)) == 0u);
1120 if (active->GetRegister() == reg) {
1121 DCHECK(!active->IsFixed());
1122 LiveInterval* split = Split(active, current->GetStart());
1123 if (split != active) {
1124 handled_.push_back(active);
1125 }
1126 RemoveIntervalAndPotentialOtherHalf(&active_, it);
1127 AddSorted(unhandled_, split);
1128 break;
1129 }
1130 }
1131
1132 // NOTE: Retrieve end() on each iteration because we're removing elements in the loop body.
1133 for (auto it = inactive_.begin(); it != inactive_.end(); ) {
1134 LiveInterval* inactive = *it;
1135 bool erased = false;
1136 if ((GetRegisterMask(inactive, current_register_type_) & (1u << reg)) != 0u) {
1137 if (!current->IsSplit() && !inactive->IsFixed()) {
1138 // Neither current nor inactive are fixed.
1139 // Thanks to SSA, a non-split interval starting in a hole of an
1140 // inactive interval should never intersect with that inactive interval.
1141 // Only if it's not fixed though, because fixed intervals don't come from SSA.
1142 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
1143 } else {
1144 size_t next_intersection = inactive->FirstIntersectionWith(current);
1145 if (next_intersection != kNoLifetime) {
1146 if (inactive->IsFixed()) {
1147 LiveInterval* split = Split(current, next_intersection);
1148 DCHECK_NE(split, current);
1149 AddSorted(unhandled_, split);
1150 } else {
1151 // Split at the start of `current`, which will lead to splitting
1152 // at the end of the lifetime hole of `inactive`.
1153 LiveInterval* split = Split(inactive, current->GetStart());
1154 // If it's inactive, it must start before the current interval.
1155 DCHECK_NE(split, inactive);
1156 it = RemoveIntervalAndPotentialOtherHalf(&inactive_, it);
1157 erased = true;
1158 handled_.push_back(inactive);
1159 AddSorted(unhandled_, split);
1160 }
1161 }
1162 }
1163 }
1164 // If we have erased the element, `it` already points to the next element.
1165 // Otherwise we need to move to the next element.
1166 if (!erased) {
1167 ++it;
1168 }
1169 }
1170
1171 return true;
1172 }
1173 }
1174
AddSorted(ScopedArenaVector<LiveInterval * > * array,LiveInterval * interval)1175 void RegisterAllocatorLinearScan::AddSorted(ScopedArenaVector<LiveInterval*>* array,
1176 LiveInterval* interval) {
1177 DCHECK(!interval->IsFixed() && !interval->HasSpillSlot());
1178 size_t insert_at = 0;
1179 for (size_t i = array->size(); i > 0; --i) {
1180 LiveInterval* current = (*array)[i - 1u];
1181 // High intervals must be processed right after their low equivalent.
1182 if (current->StartsAfter(interval) && !current->IsHighInterval()) {
1183 insert_at = i;
1184 break;
1185 }
1186 }
1187
1188 // Insert the high interval before the low, to ensure the low is processed before.
1189 auto insert_pos = array->begin() + insert_at;
1190 if (interval->HasHighInterval()) {
1191 array->insert(insert_pos, { interval->GetHighInterval(), interval });
1192 } else if (interval->HasLowInterval()) {
1193 array->insert(insert_pos, { interval, interval->GetLowInterval() });
1194 } else {
1195 array->insert(insert_pos, interval);
1196 }
1197 }
1198
AllocateSpillSlotFor(LiveInterval * interval)1199 void RegisterAllocatorLinearScan::AllocateSpillSlotFor(LiveInterval* interval) {
1200 if (interval->IsHighInterval()) {
1201 // The low interval already took care of allocating the spill slot.
1202 DCHECK(!interval->GetLowInterval()->HasRegister());
1203 DCHECK(interval->GetLowInterval()->GetParent()->HasSpillSlot());
1204 return;
1205 }
1206
1207 LiveInterval* parent = interval->GetParent();
1208
1209 // An instruction gets a spill slot for its entire lifetime. If the parent
1210 // of this interval already has a spill slot, there is nothing to do.
1211 if (parent->HasSpillSlot()) {
1212 return;
1213 }
1214
1215 HInstruction* defined_by = parent->GetDefinedBy();
1216 DCHECK_IMPLIES(defined_by->IsPhi(), !defined_by->AsPhi()->IsCatchPhi());
1217
1218 if (defined_by->IsParameterValue()) {
1219 // Parameters have their own stack slot.
1220 parent->SetSpillSlot(codegen_->GetStackSlotOfParameter(defined_by->AsParameterValue()));
1221 return;
1222 }
1223
1224 if (defined_by->IsCurrentMethod()) {
1225 parent->SetSpillSlot(0);
1226 return;
1227 }
1228
1229 if (defined_by->IsConstant()) {
1230 // Constants don't need a spill slot.
1231 return;
1232 }
1233
1234 ScopedArenaVector<size_t>* spill_slots = nullptr;
1235 switch (interval->GetType()) {
1236 case DataType::Type::kFloat64:
1237 spill_slots = &double_spill_slots_;
1238 break;
1239 case DataType::Type::kInt64:
1240 spill_slots = &long_spill_slots_;
1241 break;
1242 case DataType::Type::kFloat32:
1243 spill_slots = &float_spill_slots_;
1244 break;
1245 case DataType::Type::kReference:
1246 case DataType::Type::kInt32:
1247 case DataType::Type::kUint16:
1248 case DataType::Type::kUint8:
1249 case DataType::Type::kInt8:
1250 case DataType::Type::kBool:
1251 case DataType::Type::kInt16:
1252 spill_slots = &int_spill_slots_;
1253 break;
1254 case DataType::Type::kUint32:
1255 case DataType::Type::kUint64:
1256 case DataType::Type::kVoid:
1257 LOG(FATAL) << "Unexpected type for interval " << interval->GetType();
1258 }
1259
1260 // Find first available spill slots.
1261 size_t number_of_spill_slots_needed = parent->NumberOfSpillSlotsNeeded();
1262 size_t slot = 0;
1263 for (size_t e = spill_slots->size(); slot < e; ++slot) {
1264 bool found = true;
1265 for (size_t s = slot, u = std::min(slot + number_of_spill_slots_needed, e); s < u; s++) {
1266 if ((*spill_slots)[s] > parent->GetStart()) {
1267 found = false; // failure
1268 break;
1269 }
1270 }
1271 if (found) {
1272 break; // success
1273 }
1274 }
1275
1276 // Need new spill slots?
1277 size_t upper = slot + number_of_spill_slots_needed;
1278 if (upper > spill_slots->size()) {
1279 spill_slots->resize(upper);
1280 }
1281 // Set slots to end.
1282 size_t end = interval->GetLastSibling()->GetEnd();
1283 for (size_t s = slot; s < upper; s++) {
1284 (*spill_slots)[s] = end;
1285 }
1286
1287 // Note that the exact spill slot location will be computed when we resolve,
1288 // that is when we know the number of spill slots for each type.
1289 parent->SetSpillSlot(slot);
1290 }
1291
AllocateSpillSlotForCatchPhi(HPhi * phi)1292 void RegisterAllocatorLinearScan::AllocateSpillSlotForCatchPhi(HPhi* phi) {
1293 LiveInterval* interval = phi->GetLiveInterval();
1294
1295 HInstruction* previous_phi = phi->GetPrevious();
1296 DCHECK(previous_phi == nullptr || previous_phi->AsPhi()->GetRegNumber() <= phi->GetRegNumber())
1297 << "Phis expected to be sorted by vreg number, so that equivalent phis are adjacent.";
1298
1299 if (phi->IsVRegEquivalentOf(previous_phi)) {
1300 // This is an equivalent of the previous phi. We need to assign the same
1301 // catch phi slot.
1302 DCHECK(previous_phi->GetLiveInterval()->HasSpillSlot());
1303 interval->SetSpillSlot(previous_phi->GetLiveInterval()->GetSpillSlot());
1304 } else {
1305 // Allocate a new spill slot for this catch phi.
1306 // TODO: Reuse spill slots when intervals of phis from different catch
1307 // blocks do not overlap.
1308 interval->SetSpillSlot(catch_phi_spill_slots_);
1309 catch_phi_spill_slots_ += interval->NumberOfSpillSlotsNeeded();
1310 }
1311 }
1312
1313 } // namespace art
1314