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