blob: a9151ba3c94db5fa52e62e7319ffa27055e94e6c [file] [log] [blame]
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001/*
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
Matthew Gharritye9288852016-07-14 14:08:16 -070017#include "register_allocator_linear_scan.h"
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010018
Nicolas Geoffray234d69d2015-03-09 10:28:50 +000019#include <iostream>
Ian Rogersc7dd2952014-10-21 23:31:19 -070020#include <sstream>
21
Ian Rogerse77493c2014-08-20 15:08:45 -070022#include "base/bit_vector-inl.h"
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010023#include "code_generator.h"
Matthew Gharrity5d6e27d2016-07-18 13:38:44 -070024#include "register_allocation_resolver.h"
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010025#include "ssa_liveness_analysis.h"
26
27namespace art {
28
29static constexpr size_t kMaxLifetimePosition = -1;
Nicolas Geoffray31d76b42014-06-09 15:02:22 +010030static constexpr size_t kDefaultNumberOfSpillSlots = 4;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010031
Nicolas Geoffray840e5462015-01-07 16:01:24 +000032// For simplicity, we implement register pairs as (reg, reg + 1).
33// Note that this is a requirement for double registers on ARM, since we
34// allocate SRegister.
35static int GetHighForLowRegister(int reg) { return reg + 1; }
36static bool IsLowRegister(int reg) { return (reg & 1) == 0; }
Nicolas Geoffray234d69d2015-03-09 10:28:50 +000037static bool IsLowOfUnalignedPairInterval(LiveInterval* low) {
38 return GetHighForLowRegister(low->GetRegister()) != low->GetHighInterval()->GetRegister();
39}
Nicolas Geoffray840e5462015-01-07 16:01:24 +000040
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -070041RegisterAllocatorLinearScan::RegisterAllocatorLinearScan(ArenaAllocator* allocator,
42 CodeGenerator* codegen,
43 const SsaLivenessAnalysis& liveness)
44 : RegisterAllocator(allocator, codegen, liveness),
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010045 unhandled_core_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
46 unhandled_fp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
Nicolas Geoffray39468442014-09-02 15:17:15 +010047 unhandled_(nullptr),
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010048 handled_(allocator->Adapter(kArenaAllocRegisterAllocator)),
49 active_(allocator->Adapter(kArenaAllocRegisterAllocator)),
50 inactive_(allocator->Adapter(kArenaAllocRegisterAllocator)),
51 physical_core_register_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
52 physical_fp_register_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
53 temp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
54 int_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
55 long_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
56 float_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
57 double_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
David Brazdil77a48ae2015-09-15 12:34:04 +000058 catch_phi_spill_slots_(0),
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010059 safepoints_(allocator->Adapter(kArenaAllocRegisterAllocator)),
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010060 processing_core_registers_(false),
61 number_of_registers_(-1),
62 registers_array_(nullptr),
Nicolas Geoffray102cbed2014-10-15 18:31:05 +010063 blocked_core_registers_(codegen->GetBlockedCoreRegisters()),
64 blocked_fp_registers_(codegen->GetBlockedFloatingPointRegisters()),
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +010065 reserved_out_slots_(0),
Mark Mendellf85a9ca2015-01-13 09:20:58 -050066 maximum_number_of_live_core_registers_(0),
67 maximum_number_of_live_fp_registers_(0) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010068 temp_intervals_.reserve(4);
69 int_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
70 long_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
71 float_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
72 double_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
73
David Brazdil58282f42016-01-14 12:45:10 +000074 codegen->SetupBlockedRegisters();
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010075 physical_core_register_intervals_.resize(codegen->GetNumberOfCoreRegisters(), nullptr);
76 physical_fp_register_intervals_.resize(codegen->GetNumberOfFloatingPointRegisters(), nullptr);
Nicolas Geoffray39468442014-09-02 15:17:15 +010077 // Always reserve for the current method and the graph's max out registers.
78 // TODO: compute it instead.
Mathieu Chartiere401d142015-04-22 13:56:20 -070079 // ArtMethod* takes 2 vregs for 64 bits.
80 reserved_out_slots_ = InstructionSetPointerSize(codegen->GetInstructionSet()) / kVRegSize +
81 codegen->GetGraph()->GetMaximumNumberOfOutVRegs();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010082}
83
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +010084static bool ShouldProcess(bool processing_core_registers, LiveInterval* interval) {
Nicolas Geoffray39468442014-09-02 15:17:15 +010085 if (interval == nullptr) return false;
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +010086 bool is_core_register = (interval->GetType() != Primitive::kPrimDouble)
87 && (interval->GetType() != Primitive::kPrimFloat);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010088 return processing_core_registers == is_core_register;
89}
90
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -070091void RegisterAllocatorLinearScan::AllocateRegisters() {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +010092 AllocateRegistersInternal();
Matthew Gharrity5d6e27d2016-07-18 13:38:44 -070093 RegisterAllocationResolver(allocator_, codegen_, liveness_)
94 .Resolve(maximum_number_of_live_core_registers_,
95 maximum_number_of_live_fp_registers_,
96 reserved_out_slots_,
97 int_spill_slots_.size(),
98 long_spill_slots_.size(),
99 float_spill_slots_.size(),
100 double_spill_slots_.size(),
101 catch_phi_spill_slots_,
102 temp_intervals_);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100103
104 if (kIsDebugBuild) {
105 processing_core_registers_ = true;
106 ValidateInternal(true);
107 processing_core_registers_ = false;
108 ValidateInternal(true);
Nicolas Geoffray59768572014-12-01 09:50:04 +0000109 // Check that the linear order is still correct with regards to lifetime positions.
110 // Since only parallel moves have been inserted during the register allocation,
111 // these checks are mostly for making sure these moves have been added correctly.
112 size_t current_liveness = 0;
Nicolas Geoffray0d9f17d2015-04-15 14:17:44 +0100113 for (HLinearOrderIterator it(*codegen_->GetGraph()); !it.Done(); it.Advance()) {
Nicolas Geoffray59768572014-12-01 09:50:04 +0000114 HBasicBlock* block = it.Current();
115 for (HInstructionIterator inst_it(block->GetPhis()); !inst_it.Done(); inst_it.Advance()) {
116 HInstruction* instruction = inst_it.Current();
117 DCHECK_LE(current_liveness, instruction->GetLifetimePosition());
118 current_liveness = instruction->GetLifetimePosition();
119 }
120 for (HInstructionIterator inst_it(block->GetInstructions());
121 !inst_it.Done();
122 inst_it.Advance()) {
123 HInstruction* instruction = inst_it.Current();
124 DCHECK_LE(current_liveness, instruction->GetLifetimePosition()) << instruction->DebugName();
125 current_liveness = instruction->GetLifetimePosition();
126 }
127 }
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100128 }
129}
130
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700131void RegisterAllocatorLinearScan::BlockRegister(Location location, size_t start, size_t end) {
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +0100132 int reg = location.reg();
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100133 DCHECK(location.IsRegister() || location.IsFpuRegister());
134 LiveInterval* interval = location.IsRegister()
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100135 ? physical_core_register_intervals_[reg]
136 : physical_fp_register_intervals_[reg];
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100137 Primitive::Type type = location.IsRegister()
138 ? Primitive::kPrimInt
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000139 : Primitive::kPrimFloat;
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100140 if (interval == nullptr) {
141 interval = LiveInterval::MakeFixedInterval(allocator_, reg, type);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100142 if (location.IsRegister()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100143 physical_core_register_intervals_[reg] = interval;
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100144 } else {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100145 physical_fp_register_intervals_[reg] = interval;
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100146 }
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100147 }
148 DCHECK(interval->GetRegister() == reg);
149 interval->AddRange(start, end);
150}
151
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700152void RegisterAllocatorLinearScan::BlockRegisters(size_t start, size_t end, bool caller_save_only) {
David Brazdil77a48ae2015-09-15 12:34:04 +0000153 for (size_t i = 0; i < codegen_->GetNumberOfCoreRegisters(); ++i) {
154 if (!caller_save_only || !codegen_->IsCoreCalleeSaveRegister(i)) {
155 BlockRegister(Location::RegisterLocation(i), start, end);
156 }
157 }
158 for (size_t i = 0; i < codegen_->GetNumberOfFloatingPointRegisters(); ++i) {
159 if (!caller_save_only || !codegen_->IsFloatingPointCalleeSaveRegister(i)) {
160 BlockRegister(Location::FpuRegisterLocation(i), start, end);
161 }
162 }
163}
164
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700165void RegisterAllocatorLinearScan::AllocateRegistersInternal() {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100166 // Iterate post-order, to ensure the list is sorted, and the last added interval
167 // is the one with the lowest start position.
Nicolas Geoffray0d9f17d2015-04-15 14:17:44 +0100168 for (HLinearPostOrderIterator it(*codegen_->GetGraph()); !it.Done(); it.Advance()) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100169 HBasicBlock* block = it.Current();
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800170 for (HBackwardInstructionIterator back_it(block->GetInstructions()); !back_it.Done();
171 back_it.Advance()) {
172 ProcessInstruction(back_it.Current());
Nicolas Geoffray39468442014-09-02 15:17:15 +0100173 }
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800174 for (HInstructionIterator inst_it(block->GetPhis()); !inst_it.Done(); inst_it.Advance()) {
175 ProcessInstruction(inst_it.Current());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100176 }
David Brazdil77a48ae2015-09-15 12:34:04 +0000177
Nicolas Geoffray15bd2282016-01-05 15:55:41 +0000178 if (block->IsCatchBlock() ||
Nicolas Geoffrayad4ed082016-01-27 14:15:23 +0000179 (block->IsLoopHeader() && block->GetLoopInformation()->IsIrreducible())) {
Nicolas Geoffray15bd2282016-01-05 15:55:41 +0000180 // By blocking all registers at the top of each catch block or irreducible loop, we force
181 // intervals belonging to the live-in set of the catch/header block to be spilled.
182 // TODO(ngeoffray): Phis in this block could be allocated in register.
David Brazdil77a48ae2015-09-15 12:34:04 +0000183 size_t position = block->GetLifetimeStart();
184 BlockRegisters(position, position + 1);
185 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100186 }
187
Nicolas Geoffray39468442014-09-02 15:17:15 +0100188 number_of_registers_ = codegen_->GetNumberOfCoreRegisters();
Vladimir Marko5233f932015-09-29 19:01:15 +0100189 registers_array_ = allocator_->AllocArray<size_t>(number_of_registers_,
190 kArenaAllocRegisterAllocator);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100191 processing_core_registers_ = true;
192 unhandled_ = &unhandled_core_intervals_;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100193 for (LiveInterval* fixed : physical_core_register_intervals_) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100194 if (fixed != nullptr) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700195 // Fixed interval is added to inactive_ instead of unhandled_.
196 // It's also the only type of inactive interval whose start position
197 // can be after the current interval during linear scan.
198 // Fixed interval is never split and never moves to unhandled_.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100199 inactive_.push_back(fixed);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100200 }
201 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100202 LinearScan();
Nicolas Geoffray39468442014-09-02 15:17:15 +0100203
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100204 inactive_.clear();
205 active_.clear();
206 handled_.clear();
Nicolas Geoffray39468442014-09-02 15:17:15 +0100207
208 number_of_registers_ = codegen_->GetNumberOfFloatingPointRegisters();
Vladimir Marko5233f932015-09-29 19:01:15 +0100209 registers_array_ = allocator_->AllocArray<size_t>(number_of_registers_,
210 kArenaAllocRegisterAllocator);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100211 processing_core_registers_ = false;
212 unhandled_ = &unhandled_fp_intervals_;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100213 for (LiveInterval* fixed : physical_fp_register_intervals_) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100214 if (fixed != nullptr) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700215 // Fixed interval is added to inactive_ instead of unhandled_.
216 // It's also the only type of inactive interval whose start position
217 // can be after the current interval during linear scan.
218 // Fixed interval is never split and never moves to unhandled_.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100219 inactive_.push_back(fixed);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100220 }
221 }
Nicolas Geoffray39468442014-09-02 15:17:15 +0100222 LinearScan();
223}
224
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700225void RegisterAllocatorLinearScan::ProcessInstruction(HInstruction* instruction) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100226 LocationSummary* locations = instruction->GetLocations();
227 size_t position = instruction->GetLifetimePosition();
228
229 if (locations == nullptr) return;
230
231 // Create synthesized intervals for temporaries.
232 for (size_t i = 0; i < locations->GetTempCount(); ++i) {
233 Location temp = locations->GetTemp(i);
Nicolas Geoffray52839d12014-11-07 17:47:25 +0000234 if (temp.IsRegister() || temp.IsFpuRegister()) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100235 BlockRegister(temp, position, position + 1);
Nicolas Geoffray45b83af2015-07-06 15:12:53 +0000236 // Ensure that an explicit temporary register is marked as being allocated.
237 codegen_->AddAllocatedRegister(temp);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100238 } else {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100239 DCHECK(temp.IsUnallocated());
Roland Levillain5368c212014-11-27 15:03:41 +0000240 switch (temp.GetPolicy()) {
241 case Location::kRequiresRegister: {
242 LiveInterval* interval =
243 LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimInt);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100244 temp_intervals_.push_back(interval);
Nicolas Geoffrayf01d3442015-03-27 17:15:49 +0000245 interval->AddTempUse(instruction, i);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100246 unhandled_core_intervals_.push_back(interval);
Roland Levillain5368c212014-11-27 15:03:41 +0000247 break;
248 }
249
250 case Location::kRequiresFpuRegister: {
251 LiveInterval* interval =
252 LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimDouble);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100253 temp_intervals_.push_back(interval);
Nicolas Geoffrayf01d3442015-03-27 17:15:49 +0000254 interval->AddTempUse(instruction, i);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000255 if (codegen_->NeedsTwoRegisters(Primitive::kPrimDouble)) {
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100256 interval->AddHighInterval(/* is_temp */ true);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000257 LiveInterval* high = interval->GetHighInterval();
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100258 temp_intervals_.push_back(high);
259 unhandled_fp_intervals_.push_back(high);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000260 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100261 unhandled_fp_intervals_.push_back(interval);
Roland Levillain5368c212014-11-27 15:03:41 +0000262 break;
263 }
264
265 default:
266 LOG(FATAL) << "Unexpected policy for temporary location "
267 << temp.GetPolicy();
268 }
Nicolas Geoffray39468442014-09-02 15:17:15 +0100269 }
270 }
271
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100272 bool core_register = (instruction->GetType() != Primitive::kPrimDouble)
273 && (instruction->GetType() != Primitive::kPrimFloat);
274
Alexandre Rames8158f282015-08-07 10:26:17 +0100275 if (locations->NeedsSafepoint()) {
Nicolas Geoffrayc0572a42015-02-06 14:35:25 +0000276 if (codegen_->IsLeafMethod()) {
277 // TODO: We do this here because we do not want the suspend check to artificially
278 // create live registers. We should find another place, but this is currently the
279 // simplest.
280 DCHECK(instruction->IsSuspendCheckEntry());
281 instruction->GetBlock()->RemoveInstruction(instruction);
282 return;
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100283 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100284 safepoints_.push_back(instruction);
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100285 if (locations->OnlyCallsOnSlowPath()) {
286 // We add a synthesized range at this position to record the live registers
287 // at this position. Ideally, we could just update the safepoints when locations
288 // are updated, but we currently need to know the full stack size before updating
289 // locations (because of parameters and the fact that we don't have a frame pointer).
290 // And knowing the full stack size requires to know the maximum number of live
291 // registers at calls in slow paths.
292 // By adding the following interval in the algorithm, we can compute this
293 // maximum before updating locations.
294 LiveInterval* interval = LiveInterval::MakeSlowPathInterval(allocator_, instruction);
Nicolas Geoffrayacd03392014-11-26 15:46:52 +0000295 interval->AddRange(position, position + 1);
Nicolas Geoffray87d03762014-11-19 15:17:56 +0000296 AddSorted(&unhandled_core_intervals_, interval);
297 AddSorted(&unhandled_fp_intervals_, interval);
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100298 }
299 }
300
301 if (locations->WillCall()) {
David Brazdil77a48ae2015-09-15 12:34:04 +0000302 BlockRegisters(position, position + 1, /* caller_save_only */ true);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100303 }
304
Vladimir Marko372f10e2016-05-17 16:30:10 +0100305 for (size_t i = 0; i < locations->GetInputCount(); ++i) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100306 Location input = locations->InAt(i);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100307 if (input.IsRegister() || input.IsFpuRegister()) {
308 BlockRegister(input, position, position + 1);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000309 } else if (input.IsPair()) {
310 BlockRegister(input.ToLow(), position, position + 1);
311 BlockRegister(input.ToHigh(), position, position + 1);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100312 }
313 }
314
Nicolas Geoffray39468442014-09-02 15:17:15 +0100315 LiveInterval* current = instruction->GetLiveInterval();
316 if (current == nullptr) return;
317
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100318 ArenaVector<LiveInterval*>& unhandled = core_register
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100319 ? unhandled_core_intervals_
320 : unhandled_fp_intervals_;
321
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100322 DCHECK(unhandled.empty() || current->StartsBeforeOrAt(unhandled.back()));
Nicolas Geoffray87d03762014-11-19 15:17:56 +0000323
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000324 if (codegen_->NeedsTwoRegisters(current->GetType())) {
325 current->AddHighInterval();
326 }
327
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100328 for (size_t safepoint_index = safepoints_.size(); safepoint_index > 0; --safepoint_index) {
329 HInstruction* safepoint = safepoints_[safepoint_index - 1u];
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100330 size_t safepoint_position = safepoint->GetLifetimePosition();
331
332 // Test that safepoints are ordered in the optimal way.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100333 DCHECK(safepoint_index == safepoints_.size() ||
334 safepoints_[safepoint_index]->GetLifetimePosition() < safepoint_position);
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100335
336 if (safepoint_position == current->GetStart()) {
337 // The safepoint is for this instruction, so the location of the instruction
338 // does not need to be saved.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100339 DCHECK_EQ(safepoint_index, safepoints_.size());
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100340 DCHECK_EQ(safepoint, instruction);
341 continue;
342 } else if (current->IsDeadAt(safepoint_position)) {
343 break;
344 } else if (!current->Covers(safepoint_position)) {
345 // Hole in the interval.
346 continue;
347 }
348 current->AddSafepoint(safepoint);
349 }
David Brazdil3fc992f2015-04-16 18:31:55 +0100350 current->ResetSearchCache();
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100351
Nicolas Geoffray39468442014-09-02 15:17:15 +0100352 // Some instructions define their output in fixed register/stack slot. We need
353 // to ensure we know these locations before doing register allocation. For a
354 // given register, we create an interval that covers these locations. The register
355 // will be unavailable at these locations when trying to allocate one for an
356 // interval.
357 //
358 // The backwards walking ensures the ranges are ordered on increasing start positions.
359 Location output = locations->Out();
Calin Juravled0d48522014-11-04 16:40:20 +0000360 if (output.IsUnallocated() && output.GetPolicy() == Location::kSameAsFirstInput) {
361 Location first = locations->InAt(0);
362 if (first.IsRegister() || first.IsFpuRegister()) {
363 current->SetFrom(position + 1);
364 current->SetRegister(first.reg());
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000365 } else if (first.IsPair()) {
366 current->SetFrom(position + 1);
367 current->SetRegister(first.low());
368 LiveInterval* high = current->GetHighInterval();
369 high->SetRegister(first.high());
370 high->SetFrom(position + 1);
Calin Juravled0d48522014-11-04 16:40:20 +0000371 }
372 } else if (output.IsRegister() || output.IsFpuRegister()) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100373 // Shift the interval's start by one to account for the blocked register.
374 current->SetFrom(position + 1);
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +0100375 current->SetRegister(output.reg());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100376 BlockRegister(output, position, position + 1);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000377 } else if (output.IsPair()) {
378 current->SetFrom(position + 1);
379 current->SetRegister(output.low());
380 LiveInterval* high = current->GetHighInterval();
381 high->SetRegister(output.high());
382 high->SetFrom(position + 1);
383 BlockRegister(output.ToLow(), position, position + 1);
384 BlockRegister(output.ToHigh(), position, position + 1);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100385 } else if (output.IsStackSlot() || output.IsDoubleStackSlot()) {
386 current->SetSpillSlot(output.GetStackIndex());
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000387 } else {
388 DCHECK(output.IsUnallocated() || output.IsConstant());
Nicolas Geoffray39468442014-09-02 15:17:15 +0100389 }
390
David Brazdil77a48ae2015-09-15 12:34:04 +0000391 if (instruction->IsPhi() && instruction->AsPhi()->IsCatchPhi()) {
392 AllocateSpillSlotForCatchPhi(instruction->AsPhi());
393 }
394
Nicolas Geoffray39468442014-09-02 15:17:15 +0100395 // If needed, add interval to the list of unhandled intervals.
396 if (current->HasSpillSlot() || instruction->IsConstant()) {
Nicolas Geoffrayc8147a72014-10-21 16:06:20 +0100397 // Split just before first register use.
Nicolas Geoffray39468442014-09-02 15:17:15 +0100398 size_t first_register_use = current->FirstRegisterUse();
399 if (first_register_use != kNoLifetime) {
Nicolas Geoffray8cbab3c2015-04-23 15:14:36 +0100400 LiveInterval* split = SplitBetween(current, current->GetStart(), first_register_use - 1);
Nicolas Geoffrayb5f62b32014-10-30 10:58:41 +0000401 // Don't add directly to `unhandled`, it needs to be sorted and the start
Nicolas Geoffray39468442014-09-02 15:17:15 +0100402 // of this new interval might be after intervals already in the list.
403 AddSorted(&unhandled, split);
404 } else {
405 // Nothing to do, we won't allocate a register for this value.
406 }
407 } else {
Nicolas Geoffrayb5f62b32014-10-30 10:58:41 +0000408 // Don't add directly to `unhandled`, temp or safepoint intervals
409 // for this instruction may have been added, and those can be
410 // processed first.
411 AddSorted(&unhandled, current);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100412 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100413}
414
Nicolas Geoffray31d76b42014-06-09 15:02:22 +0100415class AllRangesIterator : public ValueObject {
416 public:
417 explicit AllRangesIterator(LiveInterval* interval)
418 : current_interval_(interval),
419 current_range_(interval->GetFirstRange()) {}
420
421 bool Done() const { return current_interval_ == nullptr; }
422 LiveRange* CurrentRange() const { return current_range_; }
423 LiveInterval* CurrentInterval() const { return current_interval_; }
424
425 void Advance() {
426 current_range_ = current_range_->GetNext();
427 if (current_range_ == nullptr) {
428 current_interval_ = current_interval_->GetNextSibling();
429 if (current_interval_ != nullptr) {
430 current_range_ = current_interval_->GetFirstRange();
431 }
432 }
433 }
434
435 private:
436 LiveInterval* current_interval_;
437 LiveRange* current_range_;
438
439 DISALLOW_COPY_AND_ASSIGN(AllRangesIterator);
440};
441
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700442bool RegisterAllocatorLinearScan::ValidateInternal(bool log_fatal_on_failure) const {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100443 // To simplify unit testing, we eagerly create the array of intervals, and
444 // call the helper method.
Vladimir Markof6a35de2016-03-21 12:01:50 +0000445 ArenaVector<LiveInterval*> intervals(allocator_->Adapter(kArenaAllocRegisterAllocatorValidate));
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100446 for (size_t i = 0; i < liveness_.GetNumberOfSsaValues(); ++i) {
447 HInstruction* instruction = liveness_.GetInstructionFromSsaIndex(i);
448 if (ShouldProcess(processing_core_registers_, instruction->GetLiveInterval())) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100449 intervals.push_back(instruction->GetLiveInterval());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100450 }
451 }
452
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100453 const ArenaVector<LiveInterval*>* physical_register_intervals = processing_core_registers_
454 ? &physical_core_register_intervals_
455 : &physical_fp_register_intervals_;
456 for (LiveInterval* fixed : *physical_register_intervals) {
457 if (fixed != nullptr) {
458 intervals.push_back(fixed);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100459 }
460 }
461
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100462 for (LiveInterval* temp : temp_intervals_) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100463 if (ShouldProcess(processing_core_registers_, temp)) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100464 intervals.push_back(temp);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100465 }
466 }
467
Nicolas Geoffray776b3182015-02-23 14:14:57 +0000468 return ValidateIntervals(intervals, GetNumberOfSpillSlots(), reserved_out_slots_, *codegen_,
Nicolas Geoffray39468442014-09-02 15:17:15 +0100469 allocator_, processing_core_registers_, log_fatal_on_failure);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100470}
471
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700472void RegisterAllocatorLinearScan::DumpInterval(std::ostream& stream, LiveInterval* interval) const {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100473 interval->Dump(stream);
474 stream << ": ";
475 if (interval->HasRegister()) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100476 if (interval->IsFloatingPoint()) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100477 codegen_->DumpFloatingPointRegister(stream, interval->GetRegister());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100478 } else {
479 codegen_->DumpCoreRegister(stream, interval->GetRegister());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100480 }
481 } else {
482 stream << "spilled";
483 }
484 stream << std::endl;
485}
486
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700487void RegisterAllocatorLinearScan::DumpAllIntervals(std::ostream& stream) const {
Mingyao Yang296bd602014-10-06 16:47:28 -0700488 stream << "inactive: " << std::endl;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100489 for (LiveInterval* inactive_interval : inactive_) {
490 DumpInterval(stream, inactive_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700491 }
492 stream << "active: " << std::endl;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100493 for (LiveInterval* active_interval : active_) {
494 DumpInterval(stream, active_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700495 }
496 stream << "unhandled: " << std::endl;
497 auto unhandled = (unhandled_ != nullptr) ?
498 unhandled_ : &unhandled_core_intervals_;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100499 for (LiveInterval* unhandled_interval : *unhandled) {
500 DumpInterval(stream, unhandled_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700501 }
502 stream << "handled: " << std::endl;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100503 for (LiveInterval* handled_interval : handled_) {
504 DumpInterval(stream, handled_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700505 }
506}
507
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100508// By the book implementation of a linear scan register allocator.
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700509void RegisterAllocatorLinearScan::LinearScan() {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100510 while (!unhandled_->empty()) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100511 // (1) Remove interval with the lowest start position from unhandled.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100512 LiveInterval* current = unhandled_->back();
513 unhandled_->pop_back();
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100514
515 // Make sure the interval is an expected state.
Nicolas Geoffray39468442014-09-02 15:17:15 +0100516 DCHECK(!current->IsFixed() && !current->HasSpillSlot());
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100517 // Make sure we are going in the right order.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100518 DCHECK(unhandled_->empty() || unhandled_->back()->GetStart() >= current->GetStart());
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100519 // Make sure a low interval is always with a high.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100520 DCHECK(!current->IsLowInterval() || unhandled_->back()->IsHighInterval());
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100521 // Make sure a high interval is always with a low.
522 DCHECK(current->IsLowInterval() ||
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100523 unhandled_->empty() ||
524 !unhandled_->back()->IsHighInterval());
Nicolas Geoffray87d03762014-11-19 15:17:56 +0000525
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100526 size_t position = current->GetStart();
527
Mingyao Yang296bd602014-10-06 16:47:28 -0700528 // Remember the inactive_ size here since the ones moved to inactive_ from
529 // active_ below shouldn't need to be re-checked.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100530 size_t inactive_intervals_to_handle = inactive_.size();
Mingyao Yang296bd602014-10-06 16:47:28 -0700531
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100532 // (2) Remove currently active intervals that are dead at this position.
533 // Move active intervals that have a lifetime hole at this position
534 // to inactive.
Vladimir Markob95fb772015-09-30 13:32:31 +0100535 auto active_kept_end = std::remove_if(
536 active_.begin(),
537 active_.end(),
538 [this, position](LiveInterval* interval) {
539 if (interval->IsDeadAt(position)) {
540 handled_.push_back(interval);
541 return true;
542 } else if (!interval->Covers(position)) {
543 inactive_.push_back(interval);
544 return true;
545 } else {
546 return false; // Keep this interval.
547 }
548 });
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100549 active_.erase(active_kept_end, active_.end());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100550
551 // (3) Remove currently inactive intervals that are dead at this position.
552 // Move inactive intervals that cover this position to active.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100553 auto inactive_to_handle_end = inactive_.begin() + inactive_intervals_to_handle;
Vladimir Markob95fb772015-09-30 13:32:31 +0100554 auto inactive_kept_end = std::remove_if(
555 inactive_.begin(),
556 inactive_to_handle_end,
557 [this, position](LiveInterval* interval) {
558 DCHECK(interval->GetStart() < position || interval->IsFixed());
559 if (interval->IsDeadAt(position)) {
560 handled_.push_back(interval);
561 return true;
562 } else if (interval->Covers(position)) {
563 active_.push_back(interval);
564 return true;
565 } else {
566 return false; // Keep this interval.
567 }
568 });
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100569 inactive_.erase(inactive_kept_end, inactive_to_handle_end);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100570
Nicolas Geoffrayacd03392014-11-26 15:46:52 +0000571 if (current->IsSlowPathSafepoint()) {
572 // Synthesized interval to record the maximum number of live registers
573 // at safepoints. No need to allocate a register for it.
Mark Mendellf85a9ca2015-01-13 09:20:58 -0500574 if (processing_core_registers_) {
575 maximum_number_of_live_core_registers_ =
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100576 std::max(maximum_number_of_live_core_registers_, active_.size());
Mark Mendellf85a9ca2015-01-13 09:20:58 -0500577 } else {
578 maximum_number_of_live_fp_registers_ =
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100579 std::max(maximum_number_of_live_fp_registers_, active_.size());
Mark Mendellf85a9ca2015-01-13 09:20:58 -0500580 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100581 DCHECK(unhandled_->empty() || unhandled_->back()->GetStart() > current->GetStart());
Nicolas Geoffrayacd03392014-11-26 15:46:52 +0000582 continue;
583 }
584
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000585 if (current->IsHighInterval() && !current->GetLowInterval()->HasRegister()) {
586 DCHECK(!current->HasRegister());
587 // Allocating the low part was unsucessful. The splitted interval for the high part
588 // will be handled next (it is in the `unhandled_` list).
589 continue;
590 }
591
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100592 // (4) Try to find an available register.
593 bool success = TryAllocateFreeReg(current);
594
595 // (5) If no register could be found, we need to spill.
596 if (!success) {
597 success = AllocateBlockedReg(current);
598 }
599
600 // (6) If the interval had a register allocated, add it to the list of active
601 // intervals.
602 if (success) {
Nicolas Geoffray98893962015-01-21 12:32:32 +0000603 codegen_->AddAllocatedRegister(processing_core_registers_
604 ? Location::RegisterLocation(current->GetRegister())
605 : Location::FpuRegisterLocation(current->GetRegister()));
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100606 active_.push_back(current);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000607 if (current->HasHighInterval() && !current->GetHighInterval()->HasRegister()) {
608 current->GetHighInterval()->SetRegister(GetHighForLowRegister(current->GetRegister()));
609 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100610 }
611 }
612}
613
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000614static void FreeIfNotCoverAt(LiveInterval* interval, size_t position, size_t* free_until) {
615 DCHECK(!interval->IsHighInterval());
616 // Note that the same instruction may occur multiple times in the input list,
617 // so `free_until` may have changed already.
David Brazdil3fc992f2015-04-16 18:31:55 +0100618 // Since `position` is not the current scan position, we need to use CoversSlow.
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000619 if (interval->IsDeadAt(position)) {
620 // Set the register to be free. Note that inactive intervals might later
621 // update this.
622 free_until[interval->GetRegister()] = kMaxLifetimePosition;
623 if (interval->HasHighInterval()) {
624 DCHECK(interval->GetHighInterval()->IsDeadAt(position));
625 free_until[interval->GetHighInterval()->GetRegister()] = kMaxLifetimePosition;
626 }
David Brazdil3fc992f2015-04-16 18:31:55 +0100627 } else if (!interval->CoversSlow(position)) {
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000628 // The interval becomes inactive at `defined_by`. We make its register
629 // available only until the next use strictly after `defined_by`.
630 free_until[interval->GetRegister()] = interval->FirstUseAfter(position);
631 if (interval->HasHighInterval()) {
David Brazdil3fc992f2015-04-16 18:31:55 +0100632 DCHECK(!interval->GetHighInterval()->CoversSlow(position));
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000633 free_until[interval->GetHighInterval()->GetRegister()] = free_until[interval->GetRegister()];
634 }
635 }
636}
637
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100638// Find a free register. If multiple are found, pick the register that
639// is free the longest.
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700640bool RegisterAllocatorLinearScan::TryAllocateFreeReg(LiveInterval* current) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100641 size_t* free_until = registers_array_;
642
643 // First set all registers to be free.
644 for (size_t i = 0; i < number_of_registers_; ++i) {
645 free_until[i] = kMaxLifetimePosition;
646 }
647
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100648 // For each active interval, set its register to not free.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100649 for (LiveInterval* interval : active_) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100650 DCHECK(interval->HasRegister());
651 free_until[interval->GetRegister()] = 0;
652 }
653
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000654 // An interval that starts an instruction (that is, it is not split), may
655 // re-use the registers used by the inputs of that instruciton, based on the
656 // location summary.
657 HInstruction* defined_by = current->GetDefinedBy();
658 if (defined_by != nullptr && !current->IsSplit()) {
659 LocationSummary* locations = defined_by->GetLocations();
660 if (!locations->OutputCanOverlapWithInputs() && locations->Out().IsUnallocated()) {
Vladimir Markoe9004912016-06-16 16:50:52 +0100661 HInputsRef inputs = defined_by->GetInputs();
Vladimir Marko372f10e2016-05-17 16:30:10 +0100662 for (size_t i = 0; i < inputs.size(); ++i) {
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000663 // Take the last interval of the input. It is the location of that interval
664 // that will be used at `defined_by`.
Vladimir Marko372f10e2016-05-17 16:30:10 +0100665 LiveInterval* interval = inputs[i]->GetLiveInterval()->GetLastSibling();
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000666 // Note that interval may have not been processed yet.
667 // TODO: Handle non-split intervals last in the work list.
Nicolas Geoffray94015b92015-06-04 18:21:04 +0100668 if (locations->InAt(i).IsValid()
669 && interval->HasRegister()
670 && interval->SameRegisterKind(*current)) {
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000671 // The input must be live until the end of `defined_by`, to comply to
672 // the linear scan algorithm. So we use `defined_by`'s end lifetime
673 // position to check whether the input is dead or is inactive after
674 // `defined_by`.
David Brazdil3fc992f2015-04-16 18:31:55 +0100675 DCHECK(interval->CoversSlow(defined_by->GetLifetimePosition()));
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000676 size_t position = defined_by->GetLifetimePosition() + 1;
677 FreeIfNotCoverAt(interval, position, free_until);
678 }
679 }
680 }
681 }
682
Mingyao Yang296bd602014-10-06 16:47:28 -0700683 // For each inactive interval, set its register to be free until
684 // the next intersection with `current`.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100685 for (LiveInterval* inactive : inactive_) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700686 // Temp/Slow-path-safepoint interval has no holes.
687 DCHECK(!inactive->IsTemp() && !inactive->IsSlowPathSafepoint());
688 if (!current->IsSplit() && !inactive->IsFixed()) {
689 // Neither current nor inactive are fixed.
690 // Thanks to SSA, a non-split interval starting in a hole of an
691 // inactive interval should never intersect with that inactive interval.
692 // Only if it's not fixed though, because fixed intervals don't come from SSA.
693 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
694 continue;
695 }
696
697 DCHECK(inactive->HasRegister());
698 if (free_until[inactive->GetRegister()] == 0) {
699 // Already used by some active interval. No need to intersect.
700 continue;
701 }
702 size_t next_intersection = inactive->FirstIntersectionWith(current);
703 if (next_intersection != kNoLifetime) {
704 free_until[inactive->GetRegister()] =
705 std::min(free_until[inactive->GetRegister()], next_intersection);
706 }
707 }
708
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000709 int reg = kNoRegister;
Nicolas Geoffray39468442014-09-02 15:17:15 +0100710 if (current->HasRegister()) {
711 // Some instructions have a fixed register output.
712 reg = current->GetRegister();
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000713 if (free_until[reg] == 0) {
714 DCHECK(current->IsHighInterval());
715 // AllocateBlockedReg will spill the holder of the register.
716 return false;
717 }
Nicolas Geoffray39468442014-09-02 15:17:15 +0100718 } else {
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000719 DCHECK(!current->IsHighInterval());
Nicolas Geoffrayfbda5f32015-04-29 14:16:00 +0100720 int hint = current->FindFirstRegisterHint(free_until, liveness_);
Nicolas Geoffrayf2975812015-08-07 18:13:03 -0700721 if ((hint != kNoRegister)
722 // For simplicity, if the hint we are getting for a pair cannot be used,
723 // we are just going to allocate a new pair.
724 && !(current->IsLowInterval() && IsBlocked(GetHighForLowRegister(hint)))) {
Nicolas Geoffray01ef3452014-10-01 11:32:17 +0100725 DCHECK(!IsBlocked(hint));
726 reg = hint;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000727 } else if (current->IsLowInterval()) {
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000728 reg = FindAvailableRegisterPair(free_until, current->GetStart());
Nicolas Geoffray01ef3452014-10-01 11:32:17 +0100729 } else {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100730 reg = FindAvailableRegister(free_until, current);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100731 }
732 }
733
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000734 DCHECK_NE(reg, kNoRegister);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100735 // If we could not find a register, we need to spill.
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000736 if (free_until[reg] == 0) {
737 return false;
738 }
739
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000740 if (current->IsLowInterval()) {
741 // If the high register of this interval is not available, we need to spill.
742 int high_reg = current->GetHighInterval()->GetRegister();
743 if (high_reg == kNoRegister) {
744 high_reg = GetHighForLowRegister(reg);
745 }
746 if (free_until[high_reg] == 0) {
747 return false;
748 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100749 }
750
751 current->SetRegister(reg);
752 if (!current->IsDeadAt(free_until[reg])) {
753 // If the register is only available for a subset of live ranges
Nicolas Geoffray82726882015-06-01 13:51:57 +0100754 // covered by `current`, split `current` before the position where
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100755 // the register is not available anymore.
Nicolas Geoffray82726882015-06-01 13:51:57 +0100756 LiveInterval* split = SplitBetween(current, current->GetStart(), free_until[reg]);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100757 DCHECK(split != nullptr);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100758 AddSorted(unhandled_, split);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100759 }
760 return true;
761}
762
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700763bool RegisterAllocatorLinearScan::IsBlocked(int reg) const {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100764 return processing_core_registers_
765 ? blocked_core_registers_[reg]
766 : blocked_fp_registers_[reg];
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100767}
768
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700769int RegisterAllocatorLinearScan::FindAvailableRegisterPair(size_t* next_use, size_t starting_at) const {
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000770 int reg = kNoRegister;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000771 // Pick the register pair that is used the last.
772 for (size_t i = 0; i < number_of_registers_; ++i) {
773 if (IsBlocked(i)) continue;
774 if (!IsLowRegister(i)) continue;
775 int high_register = GetHighForLowRegister(i);
776 if (IsBlocked(high_register)) continue;
777 int existing_high_register = GetHighForLowRegister(reg);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000778 if ((reg == kNoRegister) || (next_use[i] >= next_use[reg]
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000779 && next_use[high_register] >= next_use[existing_high_register])) {
780 reg = i;
781 if (next_use[i] == kMaxLifetimePosition
782 && next_use[high_register] == kMaxLifetimePosition) {
783 break;
784 }
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000785 } else if (next_use[reg] <= starting_at || next_use[existing_high_register] <= starting_at) {
786 // If one of the current register is known to be unavailable, just unconditionally
787 // try a new one.
788 reg = i;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000789 }
790 }
791 return reg;
792}
793
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700794bool RegisterAllocatorLinearScan::IsCallerSaveRegister(int reg) const {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100795 return processing_core_registers_
796 ? !codegen_->IsCoreCalleeSaveRegister(reg)
797 : !codegen_->IsFloatingPointCalleeSaveRegister(reg);
798}
799
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700800int RegisterAllocatorLinearScan::FindAvailableRegister(size_t* next_use, LiveInterval* current) const {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100801 // We special case intervals that do not span a safepoint to try to find a caller-save
802 // register if one is available. We iterate from 0 to the number of registers,
803 // so if there are caller-save registers available at the end, we continue the iteration.
804 bool prefers_caller_save = !current->HasWillCallSafepoint();
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000805 int reg = kNoRegister;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000806 for (size_t i = 0; i < number_of_registers_; ++i) {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100807 if (IsBlocked(i)) {
808 // Register cannot be used. Continue.
809 continue;
810 }
811
812 // Best case: we found a register fully available.
813 if (next_use[i] == kMaxLifetimePosition) {
814 if (prefers_caller_save && !IsCallerSaveRegister(i)) {
815 // We can get shorter encodings on some platforms by using
816 // small register numbers. So only update the candidate if the previous
817 // one was not available for the whole method.
818 if (reg == kNoRegister || next_use[reg] != kMaxLifetimePosition) {
819 reg = i;
820 }
821 // Continue the iteration in the hope of finding a caller save register.
822 continue;
823 } else {
824 reg = i;
825 // We know the register is good enough. Return it.
826 break;
827 }
828 }
829
830 // If we had no register before, take this one as a reference.
831 if (reg == kNoRegister) {
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000832 reg = i;
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100833 continue;
834 }
835
836 // Pick the register that is used the last.
837 if (next_use[i] > next_use[reg]) {
838 reg = i;
839 continue;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000840 }
841 }
842 return reg;
843}
844
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100845// Remove interval and its other half if any. Return iterator to the following element.
846static ArenaVector<LiveInterval*>::iterator RemoveIntervalAndPotentialOtherHalf(
847 ArenaVector<LiveInterval*>* intervals, ArenaVector<LiveInterval*>::iterator pos) {
848 DCHECK(intervals->begin() <= pos && pos < intervals->end());
849 LiveInterval* interval = *pos;
850 if (interval->IsLowInterval()) {
851 DCHECK(pos + 1 < intervals->end());
852 DCHECK_EQ(*(pos + 1), interval->GetHighInterval());
853 return intervals->erase(pos, pos + 2);
854 } else if (interval->IsHighInterval()) {
855 DCHECK(intervals->begin() < pos);
856 DCHECK_EQ(*(pos - 1), interval->GetLowInterval());
857 return intervals->erase(pos - 1, pos + 1);
858 } else {
859 return intervals->erase(pos);
860 }
861}
862
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700863bool RegisterAllocatorLinearScan::TrySplitNonPairOrUnalignedPairIntervalAt(size_t position,
864 size_t first_register_use,
865 size_t* next_use) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100866 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
867 LiveInterval* active = *it;
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000868 DCHECK(active->HasRegister());
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000869 if (active->IsFixed()) continue;
870 if (active->IsHighInterval()) continue;
871 if (first_register_use > next_use[active->GetRegister()]) continue;
872
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100873 // Split the first interval found that is either:
874 // 1) A non-pair interval.
875 // 2) A pair interval whose high is not low + 1.
876 // 3) A pair interval whose low is not even.
877 if (!active->IsLowInterval() ||
878 IsLowOfUnalignedPairInterval(active) ||
879 !IsLowRegister(active->GetRegister())) {
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000880 LiveInterval* split = Split(active, position);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000881 if (split != active) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100882 handled_.push_back(active);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000883 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100884 RemoveIntervalAndPotentialOtherHalf(&active_, it);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000885 AddSorted(unhandled_, split);
886 return true;
887 }
888 }
889 return false;
890}
891
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100892// Find the register that is used the last, and spill the interval
893// that holds it. If the first use of `current` is after that register
894// we spill `current` instead.
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700895bool RegisterAllocatorLinearScan::AllocateBlockedReg(LiveInterval* current) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100896 size_t first_register_use = current->FirstRegisterUse();
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -0700897 if (current->HasRegister()) {
898 DCHECK(current->IsHighInterval());
899 // The low interval has allocated the register for the high interval. In
900 // case the low interval had to split both intervals, we may end up in a
901 // situation where the high interval does not have a register use anymore.
902 // We must still proceed in order to split currently active and inactive
903 // uses of the high interval's register, and put the high interval in the
904 // active set.
905 DCHECK(first_register_use != kNoLifetime || (current->GetNextSibling() != nullptr));
906 } else if (first_register_use == kNoLifetime) {
Nicolas Geoffray31d76b42014-06-09 15:02:22 +0100907 AllocateSpillSlotFor(current);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100908 return false;
909 }
910
911 // First set all registers as not being used.
912 size_t* next_use = registers_array_;
913 for (size_t i = 0; i < number_of_registers_; ++i) {
914 next_use[i] = kMaxLifetimePosition;
915 }
916
917 // For each active interval, find the next use of its register after the
918 // start of current.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100919 for (LiveInterval* active : active_) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100920 DCHECK(active->HasRegister());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100921 if (active->IsFixed()) {
922 next_use[active->GetRegister()] = current->GetStart();
923 } else {
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000924 size_t use = active->FirstRegisterUseAfter(current->GetStart());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100925 if (use != kNoLifetime) {
926 next_use[active->GetRegister()] = use;
927 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100928 }
929 }
930
931 // For each inactive interval, find the next use of its register after the
932 // start of current.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100933 for (LiveInterval* inactive : inactive_) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700934 // Temp/Slow-path-safepoint interval has no holes.
935 DCHECK(!inactive->IsTemp() && !inactive->IsSlowPathSafepoint());
936 if (!current->IsSplit() && !inactive->IsFixed()) {
937 // Neither current nor inactive are fixed.
938 // Thanks to SSA, a non-split interval starting in a hole of an
939 // inactive interval should never intersect with that inactive interval.
940 // Only if it's not fixed though, because fixed intervals don't come from SSA.
941 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
942 continue;
943 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100944 DCHECK(inactive->HasRegister());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100945 size_t next_intersection = inactive->FirstIntersectionWith(current);
946 if (next_intersection != kNoLifetime) {
947 if (inactive->IsFixed()) {
948 next_use[inactive->GetRegister()] =
949 std::min(next_intersection, next_use[inactive->GetRegister()]);
950 } else {
Nicolas Geoffray1ba19812015-04-21 09:12:40 +0100951 size_t use = inactive->FirstUseAfter(current->GetStart());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100952 if (use != kNoLifetime) {
953 next_use[inactive->GetRegister()] = std::min(use, next_use[inactive->GetRegister()]);
954 }
955 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100956 }
957 }
958
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000959 int reg = kNoRegister;
960 bool should_spill = false;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000961 if (current->HasRegister()) {
962 DCHECK(current->IsHighInterval());
963 reg = current->GetRegister();
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000964 // When allocating the low part, we made sure the high register was available.
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000965 DCHECK_LT(first_register_use, next_use[reg]);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000966 } else if (current->IsLowInterval()) {
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000967 reg = FindAvailableRegisterPair(next_use, first_register_use);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000968 // We should spill if both registers are not available.
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000969 should_spill = (first_register_use >= next_use[reg])
970 || (first_register_use >= next_use[GetHighForLowRegister(reg)]);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000971 } else {
972 DCHECK(!current->IsHighInterval());
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100973 reg = FindAvailableRegister(next_use, current);
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000974 should_spill = (first_register_use >= next_use[reg]);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100975 }
976
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000977 DCHECK_NE(reg, kNoRegister);
978 if (should_spill) {
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000979 DCHECK(!current->IsHighInterval());
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000980 bool is_allocation_at_use_site = (current->GetStart() >= (first_register_use - 1));
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -0700981 if (is_allocation_at_use_site) {
982 if (!current->IsLowInterval()) {
983 DumpInterval(std::cerr, current);
984 DumpAllIntervals(std::cerr);
985 // This situation has the potential to infinite loop, so we make it a non-debug CHECK.
986 HInstruction* at = liveness_.GetInstructionFromPosition(first_register_use / 2);
987 CHECK(false) << "There is not enough registers available for "
988 << current->GetParent()->GetDefinedBy()->DebugName() << " "
989 << current->GetParent()->GetDefinedBy()->GetId()
990 << " at " << first_register_use - 1 << " "
991 << (at == nullptr ? "" : at->DebugName());
992 }
993
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000994 // If we're allocating a register for `current` because the instruction at
995 // that position requires it, but we think we should spill, then there are
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000996 // non-pair intervals or unaligned pair intervals blocking the allocation.
997 // We split the first interval found, and put ourselves first in the
998 // `unhandled_` list.
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -0700999 bool success = TrySplitNonPairOrUnalignedPairIntervalAt(current->GetStart(),
1000 first_register_use,
1001 next_use);
1002 DCHECK(success);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001003 LiveInterval* existing = unhandled_->back();
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001004 DCHECK(existing->IsHighInterval());
1005 DCHECK_EQ(existing->GetLowInterval(), current);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001006 unhandled_->push_back(current);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001007 } else {
1008 // If the first use of that instruction is after the last use of the found
1009 // register, we split this interval just before its first register use.
1010 AllocateSpillSlotFor(current);
Nicolas Geoffray8cbab3c2015-04-23 15:14:36 +01001011 LiveInterval* split = SplitBetween(current, current->GetStart(), first_register_use - 1);
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -07001012 DCHECK(current != split);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001013 AddSorted(unhandled_, split);
1014 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001015 return false;
1016 } else {
1017 // Use this register and spill the active and inactives interval that
1018 // have that register.
1019 current->SetRegister(reg);
1020
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001021 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
1022 LiveInterval* active = *it;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001023 if (active->GetRegister() == reg) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001024 DCHECK(!active->IsFixed());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001025 LiveInterval* split = Split(active, current->GetStart());
Nicolas Geoffraydd8f8872015-01-15 15:37:37 +00001026 if (split != active) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001027 handled_.push_back(active);
Nicolas Geoffraydd8f8872015-01-15 15:37:37 +00001028 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001029 RemoveIntervalAndPotentialOtherHalf(&active_, it);
Nicolas Geoffray39468442014-09-02 15:17:15 +01001030 AddSorted(unhandled_, split);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001031 break;
1032 }
1033 }
1034
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001035 // NOTE: Retrieve end() on each iteration because we're removing elements in the loop body.
1036 for (auto it = inactive_.begin(); it != inactive_.end(); ) {
1037 LiveInterval* inactive = *it;
1038 bool erased = false;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001039 if (inactive->GetRegister() == reg) {
Mingyao Yang296bd602014-10-06 16:47:28 -07001040 if (!current->IsSplit() && !inactive->IsFixed()) {
1041 // Neither current nor inactive are fixed.
1042 // Thanks to SSA, a non-split interval starting in a hole of an
1043 // inactive interval should never intersect with that inactive interval.
1044 // Only if it's not fixed though, because fixed intervals don't come from SSA.
1045 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001046 } else {
1047 size_t next_intersection = inactive->FirstIntersectionWith(current);
1048 if (next_intersection != kNoLifetime) {
1049 if (inactive->IsFixed()) {
1050 LiveInterval* split = Split(current, next_intersection);
1051 DCHECK_NE(split, current);
1052 AddSorted(unhandled_, split);
1053 } else {
1054 // Split at the start of `current`, which will lead to splitting
1055 // at the end of the lifetime hole of `inactive`.
1056 LiveInterval* split = Split(inactive, current->GetStart());
1057 // If it's inactive, it must start before the current interval.
1058 DCHECK_NE(split, inactive);
1059 it = RemoveIntervalAndPotentialOtherHalf(&inactive_, it);
1060 erased = true;
1061 handled_.push_back(inactive);
1062 AddSorted(unhandled_, split);
Nicolas Geoffray5b168de2015-03-27 10:27:22 +00001063 }
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001064 }
1065 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001066 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001067 // If we have erased the element, `it` already points to the next element.
1068 // Otherwise we need to move to the next element.
1069 if (!erased) {
1070 ++it;
1071 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001072 }
1073
1074 return true;
1075 }
1076}
1077
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -07001078void RegisterAllocatorLinearScan::AddSorted(ArenaVector<LiveInterval*>* array, LiveInterval* interval) {
Nicolas Geoffrayc8147a72014-10-21 16:06:20 +01001079 DCHECK(!interval->IsFixed() && !interval->HasSpillSlot());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001080 size_t insert_at = 0;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001081 for (size_t i = array->size(); i > 0; --i) {
1082 LiveInterval* current = (*array)[i - 1u];
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001083 // High intervals must be processed right after their low equivalent.
1084 if (current->StartsAfter(interval) && !current->IsHighInterval()) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001085 insert_at = i;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001086 break;
Nicolas Geoffrayacd03392014-11-26 15:46:52 +00001087 } else if ((current->GetStart() == interval->GetStart()) && current->IsSlowPathSafepoint()) {
1088 // Ensure the slow path interval is the last to be processed at its location: we want the
1089 // interval to know all live registers at this location.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001090 DCHECK(i == 1 || (*array)[i - 2u]->StartsAfter(current));
Nicolas Geoffrayacd03392014-11-26 15:46:52 +00001091 insert_at = i;
1092 break;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001093 }
1094 }
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001095
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001096 // Insert the high interval before the low, to ensure the low is processed before.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001097 auto insert_pos = array->begin() + insert_at;
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001098 if (interval->HasHighInterval()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001099 array->insert(insert_pos, { interval->GetHighInterval(), interval });
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001100 } else if (interval->HasLowInterval()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001101 array->insert(insert_pos, { interval, interval->GetLowInterval() });
1102 } else {
1103 array->insert(insert_pos, interval);
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001104 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001105}
1106
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -07001107void RegisterAllocatorLinearScan::AllocateSpillSlotFor(LiveInterval* interval) {
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001108 if (interval->IsHighInterval()) {
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -07001109 // The low interval already took care of allocating the spill slot.
1110 DCHECK(!interval->GetLowInterval()->HasRegister());
1111 DCHECK(interval->GetLowInterval()->GetParent()->HasSpillSlot());
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001112 return;
1113 }
1114
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001115 LiveInterval* parent = interval->GetParent();
1116
1117 // An instruction gets a spill slot for its entire lifetime. If the parent
1118 // of this interval already has a spill slot, there is nothing to do.
1119 if (parent->HasSpillSlot()) {
1120 return;
1121 }
1122
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001123 HInstruction* defined_by = parent->GetDefinedBy();
David Brazdil77a48ae2015-09-15 12:34:04 +00001124 DCHECK(!defined_by->IsPhi() || !defined_by->AsPhi()->IsCatchPhi());
1125
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001126 if (defined_by->IsParameterValue()) {
1127 // Parameters have their own stack slot.
1128 parent->SetSpillSlot(codegen_->GetStackSlotOfParameter(defined_by->AsParameterValue()));
1129 return;
1130 }
1131
Nicolas Geoffray76b1e172015-05-27 17:18:33 +01001132 if (defined_by->IsCurrentMethod()) {
1133 parent->SetSpillSlot(0);
1134 return;
1135 }
1136
Nicolas Geoffray96f89a22014-07-11 10:57:49 +01001137 if (defined_by->IsConstant()) {
1138 // Constants don't need a spill slot.
1139 return;
1140 }
1141
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001142 ArenaVector<size_t>* spill_slots = nullptr;
Nicolas Geoffray776b3182015-02-23 14:14:57 +00001143 switch (interval->GetType()) {
1144 case Primitive::kPrimDouble:
1145 spill_slots = &double_spill_slots_;
1146 break;
1147 case Primitive::kPrimLong:
1148 spill_slots = &long_spill_slots_;
1149 break;
1150 case Primitive::kPrimFloat:
1151 spill_slots = &float_spill_slots_;
1152 break;
1153 case Primitive::kPrimNot:
1154 case Primitive::kPrimInt:
1155 case Primitive::kPrimChar:
1156 case Primitive::kPrimByte:
1157 case Primitive::kPrimBoolean:
1158 case Primitive::kPrimShort:
1159 spill_slots = &int_spill_slots_;
1160 break;
1161 case Primitive::kPrimVoid:
1162 LOG(FATAL) << "Unexpected type for interval " << interval->GetType();
1163 }
1164
Nicolas Geoffray412f10c2014-06-19 10:00:34 +01001165 // Find an available spill slot.
1166 size_t slot = 0;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001167 for (size_t e = spill_slots->size(); slot < e; ++slot) {
Matthew Gharrityf64a6ab2016-07-11 14:45:01 -07001168 if ((*spill_slots)[slot] <= parent->GetStart()) {
1169 if (!parent->NeedsTwoSpillSlots()) {
1170 // One spill slot is sufficient.
1171 break;
1172 }
1173 if (slot == e - 1 || (*spill_slots)[slot + 1] <= parent->GetStart()) {
1174 // Two spill slots are available.
1175 break;
1176 }
Nicolas Geoffray412f10c2014-06-19 10:00:34 +01001177 }
1178 }
1179
David Brazdil77a48ae2015-09-15 12:34:04 +00001180 size_t end = interval->GetLastSibling()->GetEnd();
Nicolas Geoffray01ef3452014-10-01 11:32:17 +01001181 if (parent->NeedsTwoSpillSlots()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001182 if (slot + 2u > spill_slots->size()) {
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001183 // We need a new spill slot.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001184 spill_slots->resize(slot + 2u, end);
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001185 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001186 (*spill_slots)[slot] = end;
1187 (*spill_slots)[slot + 1] = end;
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001188 } else {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001189 if (slot == spill_slots->size()) {
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001190 // We need a new spill slot.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001191 spill_slots->push_back(end);
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001192 } else {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001193 (*spill_slots)[slot] = end;
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001194 }
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001195 }
1196
Nicolas Geoffray776b3182015-02-23 14:14:57 +00001197 // Note that the exact spill slot location will be computed when we resolve,
1198 // that is when we know the number of spill slots for each type.
1199 parent->SetSpillSlot(slot);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001200}
1201
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -07001202void RegisterAllocatorLinearScan::AllocateSpillSlotForCatchPhi(HPhi* phi) {
David Brazdil77a48ae2015-09-15 12:34:04 +00001203 LiveInterval* interval = phi->GetLiveInterval();
1204
1205 HInstruction* previous_phi = phi->GetPrevious();
1206 DCHECK(previous_phi == nullptr ||
1207 previous_phi->AsPhi()->GetRegNumber() <= phi->GetRegNumber())
1208 << "Phis expected to be sorted by vreg number, so that equivalent phis are adjacent.";
1209
1210 if (phi->IsVRegEquivalentOf(previous_phi)) {
1211 // This is an equivalent of the previous phi. We need to assign the same
1212 // catch phi slot.
1213 DCHECK(previous_phi->GetLiveInterval()->HasSpillSlot());
1214 interval->SetSpillSlot(previous_phi->GetLiveInterval()->GetSpillSlot());
1215 } else {
1216 // Allocate a new spill slot for this catch phi.
1217 // TODO: Reuse spill slots when intervals of phis from different catch
1218 // blocks do not overlap.
1219 interval->SetSpillSlot(catch_phi_spill_slots_);
1220 catch_phi_spill_slots_ += interval->NeedsTwoSpillSlots() ? 2 : 1;
1221 }
1222}
1223
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001224} // namespace art