xref: /aosp_15_r20/art/compiler/optimizing/register_allocator_linear_scan.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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