blob: 768ed2d26a9e677d4191513cf18bb870b76b5566 [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"
Andreas Gampe542451c2016-07-26 09:02:02 -070023#include "base/enums.h"
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010024#include "code_generator.h"
Matthew Gharrity5d6e27d2016-07-18 13:38:44 -070025#include "register_allocation_resolver.h"
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010026#include "ssa_liveness_analysis.h"
27
28namespace art {
29
30static constexpr size_t kMaxLifetimePosition = -1;
Nicolas Geoffray31d76b42014-06-09 15:02:22 +010031static constexpr size_t kDefaultNumberOfSpillSlots = 4;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010032
Nicolas Geoffray840e5462015-01-07 16:01:24 +000033// For simplicity, we implement register pairs as (reg, reg + 1).
34// Note that this is a requirement for double registers on ARM, since we
35// allocate SRegister.
36static int GetHighForLowRegister(int reg) { return reg + 1; }
37static bool IsLowRegister(int reg) { return (reg & 1) == 0; }
Nicolas Geoffray234d69d2015-03-09 10:28:50 +000038static bool IsLowOfUnalignedPairInterval(LiveInterval* low) {
39 return GetHighForLowRegister(low->GetRegister()) != low->GetHighInterval()->GetRegister();
40}
Nicolas Geoffray840e5462015-01-07 16:01:24 +000041
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -070042RegisterAllocatorLinearScan::RegisterAllocatorLinearScan(ArenaAllocator* allocator,
43 CodeGenerator* codegen,
44 const SsaLivenessAnalysis& liveness)
45 : RegisterAllocator(allocator, codegen, liveness),
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010046 unhandled_core_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
47 unhandled_fp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
Nicolas Geoffray39468442014-09-02 15:17:15 +010048 unhandled_(nullptr),
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010049 handled_(allocator->Adapter(kArenaAllocRegisterAllocator)),
50 active_(allocator->Adapter(kArenaAllocRegisterAllocator)),
51 inactive_(allocator->Adapter(kArenaAllocRegisterAllocator)),
52 physical_core_register_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
53 physical_fp_register_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
54 temp_intervals_(allocator->Adapter(kArenaAllocRegisterAllocator)),
55 int_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
56 long_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
57 float_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
58 double_spill_slots_(allocator->Adapter(kArenaAllocRegisterAllocator)),
David Brazdil77a48ae2015-09-15 12:34:04 +000059 catch_phi_spill_slots_(0),
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010060 safepoints_(allocator->Adapter(kArenaAllocRegisterAllocator)),
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010061 processing_core_registers_(false),
62 number_of_registers_(-1),
63 registers_array_(nullptr),
Nicolas Geoffray102cbed2014-10-15 18:31:05 +010064 blocked_core_registers_(codegen->GetBlockedCoreRegisters()),
65 blocked_fp_registers_(codegen->GetBlockedFloatingPointRegisters()),
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +010066 reserved_out_slots_(0),
Mark Mendellf85a9ca2015-01-13 09:20:58 -050067 maximum_number_of_live_core_registers_(0),
68 maximum_number_of_live_fp_registers_(0) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010069 temp_intervals_.reserve(4);
70 int_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
71 long_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
72 float_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
73 double_spill_slots_.reserve(kDefaultNumberOfSpillSlots);
74
David Brazdil58282f42016-01-14 12:45:10 +000075 codegen->SetupBlockedRegisters();
Vladimir Marko2aaa4b52015-09-17 17:03:26 +010076 physical_core_register_intervals_.resize(codegen->GetNumberOfCoreRegisters(), nullptr);
77 physical_fp_register_intervals_.resize(codegen->GetNumberOfFloatingPointRegisters(), nullptr);
Nicolas Geoffray39468442014-09-02 15:17:15 +010078 // Always reserve for the current method and the graph's max out registers.
79 // TODO: compute it instead.
Mathieu Chartiere401d142015-04-22 13:56:20 -070080 // ArtMethod* takes 2 vregs for 64 bits.
Andreas Gampe542451c2016-07-26 09:02:02 -070081 size_t ptr_size = static_cast<size_t>(InstructionSetPointerSize(codegen->GetInstructionSet()));
82 reserved_out_slots_ = ptr_size / kVRegSize + codegen->GetGraph()->GetMaximumNumberOfOutVRegs();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010083}
84
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +010085static bool ShouldProcess(bool processing_core_registers, LiveInterval* interval) {
Nicolas Geoffray39468442014-09-02 15:17:15 +010086 if (interval == nullptr) return false;
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +010087 bool is_core_register = (interval->GetType() != Primitive::kPrimDouble)
88 && (interval->GetType() != Primitive::kPrimFloat);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010089 return processing_core_registers == is_core_register;
90}
91
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -070092void RegisterAllocatorLinearScan::AllocateRegisters() {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +010093 AllocateRegistersInternal();
Matthew Gharrity5d6e27d2016-07-18 13:38:44 -070094 RegisterAllocationResolver(allocator_, codegen_, liveness_)
95 .Resolve(maximum_number_of_live_core_registers_,
96 maximum_number_of_live_fp_registers_,
97 reserved_out_slots_,
98 int_spill_slots_.size(),
99 long_spill_slots_.size(),
100 float_spill_slots_.size(),
101 double_spill_slots_.size(),
102 catch_phi_spill_slots_,
103 temp_intervals_);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100104
105 if (kIsDebugBuild) {
106 processing_core_registers_ = true;
107 ValidateInternal(true);
108 processing_core_registers_ = false;
109 ValidateInternal(true);
Nicolas Geoffray59768572014-12-01 09:50:04 +0000110 // Check that the linear order is still correct with regards to lifetime positions.
111 // Since only parallel moves have been inserted during the register allocation,
112 // these checks are mostly for making sure these moves have been added correctly.
113 size_t current_liveness = 0;
Nicolas Geoffray0d9f17d2015-04-15 14:17:44 +0100114 for (HLinearOrderIterator it(*codegen_->GetGraph()); !it.Done(); it.Advance()) {
Nicolas Geoffray59768572014-12-01 09:50:04 +0000115 HBasicBlock* block = it.Current();
116 for (HInstructionIterator inst_it(block->GetPhis()); !inst_it.Done(); inst_it.Advance()) {
117 HInstruction* instruction = inst_it.Current();
118 DCHECK_LE(current_liveness, instruction->GetLifetimePosition());
119 current_liveness = instruction->GetLifetimePosition();
120 }
121 for (HInstructionIterator inst_it(block->GetInstructions());
122 !inst_it.Done();
123 inst_it.Advance()) {
124 HInstruction* instruction = inst_it.Current();
125 DCHECK_LE(current_liveness, instruction->GetLifetimePosition()) << instruction->DebugName();
126 current_liveness = instruction->GetLifetimePosition();
127 }
128 }
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100129 }
130}
131
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700132void RegisterAllocatorLinearScan::BlockRegister(Location location, size_t start, size_t end) {
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +0100133 int reg = location.reg();
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100134 DCHECK(location.IsRegister() || location.IsFpuRegister());
135 LiveInterval* interval = location.IsRegister()
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100136 ? physical_core_register_intervals_[reg]
137 : physical_fp_register_intervals_[reg];
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100138 Primitive::Type type = location.IsRegister()
139 ? Primitive::kPrimInt
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000140 : Primitive::kPrimFloat;
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100141 if (interval == nullptr) {
142 interval = LiveInterval::MakeFixedInterval(allocator_, reg, type);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100143 if (location.IsRegister()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100144 physical_core_register_intervals_[reg] = interval;
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100145 } else {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100146 physical_fp_register_intervals_[reg] = interval;
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100147 }
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100148 }
149 DCHECK(interval->GetRegister() == reg);
150 interval->AddRange(start, end);
151}
152
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700153void RegisterAllocatorLinearScan::BlockRegisters(size_t start, size_t end, bool caller_save_only) {
David Brazdil77a48ae2015-09-15 12:34:04 +0000154 for (size_t i = 0; i < codegen_->GetNumberOfCoreRegisters(); ++i) {
155 if (!caller_save_only || !codegen_->IsCoreCalleeSaveRegister(i)) {
156 BlockRegister(Location::RegisterLocation(i), start, end);
157 }
158 }
159 for (size_t i = 0; i < codegen_->GetNumberOfFloatingPointRegisters(); ++i) {
160 if (!caller_save_only || !codegen_->IsFloatingPointCalleeSaveRegister(i)) {
161 BlockRegister(Location::FpuRegisterLocation(i), start, end);
162 }
163 }
164}
165
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700166void RegisterAllocatorLinearScan::AllocateRegistersInternal() {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100167 // Iterate post-order, to ensure the list is sorted, and the last added interval
168 // is the one with the lowest start position.
Nicolas Geoffray0d9f17d2015-04-15 14:17:44 +0100169 for (HLinearPostOrderIterator it(*codegen_->GetGraph()); !it.Done(); it.Advance()) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100170 HBasicBlock* block = it.Current();
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800171 for (HBackwardInstructionIterator back_it(block->GetInstructions()); !back_it.Done();
172 back_it.Advance()) {
173 ProcessInstruction(back_it.Current());
Nicolas Geoffray39468442014-09-02 15:17:15 +0100174 }
Andreas Gampe277ccbd2014-11-03 21:36:10 -0800175 for (HInstructionIterator inst_it(block->GetPhis()); !inst_it.Done(); inst_it.Advance()) {
176 ProcessInstruction(inst_it.Current());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100177 }
David Brazdil77a48ae2015-09-15 12:34:04 +0000178
Nicolas Geoffray15bd2282016-01-05 15:55:41 +0000179 if (block->IsCatchBlock() ||
Nicolas Geoffrayad4ed082016-01-27 14:15:23 +0000180 (block->IsLoopHeader() && block->GetLoopInformation()->IsIrreducible())) {
Nicolas Geoffray15bd2282016-01-05 15:55:41 +0000181 // By blocking all registers at the top of each catch block or irreducible loop, we force
182 // intervals belonging to the live-in set of the catch/header block to be spilled.
183 // TODO(ngeoffray): Phis in this block could be allocated in register.
David Brazdil77a48ae2015-09-15 12:34:04 +0000184 size_t position = block->GetLifetimeStart();
185 BlockRegisters(position, position + 1);
186 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100187 }
188
Nicolas Geoffray39468442014-09-02 15:17:15 +0100189 number_of_registers_ = codegen_->GetNumberOfCoreRegisters();
Vladimir Marko5233f932015-09-29 19:01:15 +0100190 registers_array_ = allocator_->AllocArray<size_t>(number_of_registers_,
191 kArenaAllocRegisterAllocator);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100192 processing_core_registers_ = true;
193 unhandled_ = &unhandled_core_intervals_;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100194 for (LiveInterval* fixed : physical_core_register_intervals_) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100195 if (fixed != nullptr) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700196 // Fixed interval is added to inactive_ instead of unhandled_.
197 // It's also the only type of inactive interval whose start position
198 // can be after the current interval during linear scan.
199 // Fixed interval is never split and never moves to unhandled_.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100200 inactive_.push_back(fixed);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100201 }
202 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100203 LinearScan();
Nicolas Geoffray39468442014-09-02 15:17:15 +0100204
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100205 inactive_.clear();
206 active_.clear();
207 handled_.clear();
Nicolas Geoffray39468442014-09-02 15:17:15 +0100208
209 number_of_registers_ = codegen_->GetNumberOfFloatingPointRegisters();
Vladimir Marko5233f932015-09-29 19:01:15 +0100210 registers_array_ = allocator_->AllocArray<size_t>(number_of_registers_,
211 kArenaAllocRegisterAllocator);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100212 processing_core_registers_ = false;
213 unhandled_ = &unhandled_fp_intervals_;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100214 for (LiveInterval* fixed : physical_fp_register_intervals_) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100215 if (fixed != nullptr) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700216 // Fixed interval is added to inactive_ instead of unhandled_.
217 // It's also the only type of inactive interval whose start position
218 // can be after the current interval during linear scan.
219 // Fixed interval is never split and never moves to unhandled_.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100220 inactive_.push_back(fixed);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100221 }
222 }
Nicolas Geoffray39468442014-09-02 15:17:15 +0100223 LinearScan();
224}
225
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700226void RegisterAllocatorLinearScan::ProcessInstruction(HInstruction* instruction) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100227 LocationSummary* locations = instruction->GetLocations();
228 size_t position = instruction->GetLifetimePosition();
229
230 if (locations == nullptr) return;
231
232 // Create synthesized intervals for temporaries.
233 for (size_t i = 0; i < locations->GetTempCount(); ++i) {
234 Location temp = locations->GetTemp(i);
Nicolas Geoffray52839d12014-11-07 17:47:25 +0000235 if (temp.IsRegister() || temp.IsFpuRegister()) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100236 BlockRegister(temp, position, position + 1);
Nicolas Geoffray45b83af2015-07-06 15:12:53 +0000237 // Ensure that an explicit temporary register is marked as being allocated.
238 codegen_->AddAllocatedRegister(temp);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100239 } else {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100240 DCHECK(temp.IsUnallocated());
Roland Levillain5368c212014-11-27 15:03:41 +0000241 switch (temp.GetPolicy()) {
242 case Location::kRequiresRegister: {
243 LiveInterval* interval =
244 LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimInt);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100245 temp_intervals_.push_back(interval);
Nicolas Geoffrayf01d3442015-03-27 17:15:49 +0000246 interval->AddTempUse(instruction, i);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100247 unhandled_core_intervals_.push_back(interval);
Roland Levillain5368c212014-11-27 15:03:41 +0000248 break;
249 }
250
251 case Location::kRequiresFpuRegister: {
252 LiveInterval* interval =
253 LiveInterval::MakeTempInterval(allocator_, Primitive::kPrimDouble);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100254 temp_intervals_.push_back(interval);
Nicolas Geoffrayf01d3442015-03-27 17:15:49 +0000255 interval->AddTempUse(instruction, i);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000256 if (codegen_->NeedsTwoRegisters(Primitive::kPrimDouble)) {
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100257 interval->AddHighInterval(/* is_temp */ true);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000258 LiveInterval* high = interval->GetHighInterval();
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100259 temp_intervals_.push_back(high);
260 unhandled_fp_intervals_.push_back(high);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000261 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100262 unhandled_fp_intervals_.push_back(interval);
Roland Levillain5368c212014-11-27 15:03:41 +0000263 break;
264 }
265
266 default:
267 LOG(FATAL) << "Unexpected policy for temporary location "
268 << temp.GetPolicy();
269 }
Nicolas Geoffray39468442014-09-02 15:17:15 +0100270 }
271 }
272
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100273 bool core_register = (instruction->GetType() != Primitive::kPrimDouble)
274 && (instruction->GetType() != Primitive::kPrimFloat);
275
Alexandre Rames8158f282015-08-07 10:26:17 +0100276 if (locations->NeedsSafepoint()) {
Nicolas Geoffrayc0572a42015-02-06 14:35:25 +0000277 if (codegen_->IsLeafMethod()) {
278 // TODO: We do this here because we do not want the suspend check to artificially
279 // create live registers. We should find another place, but this is currently the
280 // simplest.
281 DCHECK(instruction->IsSuspendCheckEntry());
282 instruction->GetBlock()->RemoveInstruction(instruction);
283 return;
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100284 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100285 safepoints_.push_back(instruction);
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100286 if (locations->OnlyCallsOnSlowPath()) {
287 // We add a synthesized range at this position to record the live registers
288 // at this position. Ideally, we could just update the safepoints when locations
289 // are updated, but we currently need to know the full stack size before updating
290 // locations (because of parameters and the fact that we don't have a frame pointer).
291 // And knowing the full stack size requires to know the maximum number of live
292 // registers at calls in slow paths.
293 // By adding the following interval in the algorithm, we can compute this
294 // maximum before updating locations.
295 LiveInterval* interval = LiveInterval::MakeSlowPathInterval(allocator_, instruction);
Nicolas Geoffrayacd03392014-11-26 15:46:52 +0000296 interval->AddRange(position, position + 1);
Nicolas Geoffray87d03762014-11-19 15:17:56 +0000297 AddSorted(&unhandled_core_intervals_, interval);
298 AddSorted(&unhandled_fp_intervals_, interval);
Nicolas Geoffray3bca0df2014-09-19 11:01:00 +0100299 }
300 }
301
302 if (locations->WillCall()) {
David Brazdil77a48ae2015-09-15 12:34:04 +0000303 BlockRegisters(position, position + 1, /* caller_save_only */ true);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100304 }
305
Vladimir Marko372f10e2016-05-17 16:30:10 +0100306 for (size_t i = 0; i < locations->GetInputCount(); ++i) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100307 Location input = locations->InAt(i);
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100308 if (input.IsRegister() || input.IsFpuRegister()) {
309 BlockRegister(input, position, position + 1);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000310 } else if (input.IsPair()) {
311 BlockRegister(input.ToLow(), position, position + 1);
312 BlockRegister(input.ToHigh(), position, position + 1);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100313 }
314 }
315
Nicolas Geoffray39468442014-09-02 15:17:15 +0100316 LiveInterval* current = instruction->GetLiveInterval();
317 if (current == nullptr) return;
318
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100319 ArenaVector<LiveInterval*>& unhandled = core_register
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100320 ? unhandled_core_intervals_
321 : unhandled_fp_intervals_;
322
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100323 DCHECK(unhandled.empty() || current->StartsBeforeOrAt(unhandled.back()));
Nicolas Geoffray87d03762014-11-19 15:17:56 +0000324
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000325 if (codegen_->NeedsTwoRegisters(current->GetType())) {
326 current->AddHighInterval();
327 }
328
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100329 for (size_t safepoint_index = safepoints_.size(); safepoint_index > 0; --safepoint_index) {
330 HInstruction* safepoint = safepoints_[safepoint_index - 1u];
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100331 size_t safepoint_position = safepoint->GetLifetimePosition();
332
333 // Test that safepoints are ordered in the optimal way.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100334 DCHECK(safepoint_index == safepoints_.size() ||
335 safepoints_[safepoint_index]->GetLifetimePosition() < safepoint_position);
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100336
337 if (safepoint_position == current->GetStart()) {
338 // The safepoint is for this instruction, so the location of the instruction
339 // does not need to be saved.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100340 DCHECK_EQ(safepoint_index, safepoints_.size());
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100341 DCHECK_EQ(safepoint, instruction);
342 continue;
343 } else if (current->IsDeadAt(safepoint_position)) {
344 break;
345 } else if (!current->Covers(safepoint_position)) {
346 // Hole in the interval.
347 continue;
348 }
349 current->AddSafepoint(safepoint);
350 }
David Brazdil3fc992f2015-04-16 18:31:55 +0100351 current->ResetSearchCache();
Nicolas Geoffray5588e582015-04-14 14:10:59 +0100352
Nicolas Geoffray39468442014-09-02 15:17:15 +0100353 // Some instructions define their output in fixed register/stack slot. We need
354 // to ensure we know these locations before doing register allocation. For a
355 // given register, we create an interval that covers these locations. The register
356 // will be unavailable at these locations when trying to allocate one for an
357 // interval.
358 //
359 // The backwards walking ensures the ranges are ordered on increasing start positions.
360 Location output = locations->Out();
Calin Juravled0d48522014-11-04 16:40:20 +0000361 if (output.IsUnallocated() && output.GetPolicy() == Location::kSameAsFirstInput) {
362 Location first = locations->InAt(0);
363 if (first.IsRegister() || first.IsFpuRegister()) {
364 current->SetFrom(position + 1);
365 current->SetRegister(first.reg());
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000366 } else if (first.IsPair()) {
367 current->SetFrom(position + 1);
368 current->SetRegister(first.low());
369 LiveInterval* high = current->GetHighInterval();
370 high->SetRegister(first.high());
371 high->SetFrom(position + 1);
Calin Juravled0d48522014-11-04 16:40:20 +0000372 }
373 } else if (output.IsRegister() || output.IsFpuRegister()) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100374 // Shift the interval's start by one to account for the blocked register.
375 current->SetFrom(position + 1);
Nicolas Geoffray56b9ee62014-10-09 11:47:51 +0100376 current->SetRegister(output.reg());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100377 BlockRegister(output, position, position + 1);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000378 } else if (output.IsPair()) {
379 current->SetFrom(position + 1);
380 current->SetRegister(output.low());
381 LiveInterval* high = current->GetHighInterval();
382 high->SetRegister(output.high());
383 high->SetFrom(position + 1);
384 BlockRegister(output.ToLow(), position, position + 1);
385 BlockRegister(output.ToHigh(), position, position + 1);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100386 } else if (output.IsStackSlot() || output.IsDoubleStackSlot()) {
387 current->SetSpillSlot(output.GetStackIndex());
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000388 } else {
389 DCHECK(output.IsUnallocated() || output.IsConstant());
Nicolas Geoffray39468442014-09-02 15:17:15 +0100390 }
391
David Brazdil77a48ae2015-09-15 12:34:04 +0000392 if (instruction->IsPhi() && instruction->AsPhi()->IsCatchPhi()) {
393 AllocateSpillSlotForCatchPhi(instruction->AsPhi());
394 }
395
Nicolas Geoffray39468442014-09-02 15:17:15 +0100396 // If needed, add interval to the list of unhandled intervals.
397 if (current->HasSpillSlot() || instruction->IsConstant()) {
Nicolas Geoffrayc8147a72014-10-21 16:06:20 +0100398 // Split just before first register use.
Nicolas Geoffray39468442014-09-02 15:17:15 +0100399 size_t first_register_use = current->FirstRegisterUse();
400 if (first_register_use != kNoLifetime) {
Nicolas Geoffray8cbab3c2015-04-23 15:14:36 +0100401 LiveInterval* split = SplitBetween(current, current->GetStart(), first_register_use - 1);
Nicolas Geoffrayb5f62b32014-10-30 10:58:41 +0000402 // Don't add directly to `unhandled`, it needs to be sorted and the start
Nicolas Geoffray39468442014-09-02 15:17:15 +0100403 // of this new interval might be after intervals already in the list.
404 AddSorted(&unhandled, split);
405 } else {
406 // Nothing to do, we won't allocate a register for this value.
407 }
408 } else {
Nicolas Geoffrayb5f62b32014-10-30 10:58:41 +0000409 // Don't add directly to `unhandled`, temp or safepoint intervals
410 // for this instruction may have been added, and those can be
411 // processed first.
412 AddSorted(&unhandled, current);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100413 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100414}
415
Nicolas Geoffray31d76b42014-06-09 15:02:22 +0100416class AllRangesIterator : public ValueObject {
417 public:
418 explicit AllRangesIterator(LiveInterval* interval)
419 : current_interval_(interval),
420 current_range_(interval->GetFirstRange()) {}
421
422 bool Done() const { return current_interval_ == nullptr; }
423 LiveRange* CurrentRange() const { return current_range_; }
424 LiveInterval* CurrentInterval() const { return current_interval_; }
425
426 void Advance() {
427 current_range_ = current_range_->GetNext();
428 if (current_range_ == nullptr) {
429 current_interval_ = current_interval_->GetNextSibling();
430 if (current_interval_ != nullptr) {
431 current_range_ = current_interval_->GetFirstRange();
432 }
433 }
434 }
435
436 private:
437 LiveInterval* current_interval_;
438 LiveRange* current_range_;
439
440 DISALLOW_COPY_AND_ASSIGN(AllRangesIterator);
441};
442
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700443bool RegisterAllocatorLinearScan::ValidateInternal(bool log_fatal_on_failure) const {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100444 // To simplify unit testing, we eagerly create the array of intervals, and
445 // call the helper method.
Vladimir Markof6a35de2016-03-21 12:01:50 +0000446 ArenaVector<LiveInterval*> intervals(allocator_->Adapter(kArenaAllocRegisterAllocatorValidate));
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100447 for (size_t i = 0; i < liveness_.GetNumberOfSsaValues(); ++i) {
448 HInstruction* instruction = liveness_.GetInstructionFromSsaIndex(i);
449 if (ShouldProcess(processing_core_registers_, instruction->GetLiveInterval())) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100450 intervals.push_back(instruction->GetLiveInterval());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100451 }
452 }
453
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100454 const ArenaVector<LiveInterval*>* physical_register_intervals = processing_core_registers_
455 ? &physical_core_register_intervals_
456 : &physical_fp_register_intervals_;
457 for (LiveInterval* fixed : *physical_register_intervals) {
458 if (fixed != nullptr) {
459 intervals.push_back(fixed);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100460 }
461 }
462
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100463 for (LiveInterval* temp : temp_intervals_) {
Nicolas Geoffray39468442014-09-02 15:17:15 +0100464 if (ShouldProcess(processing_core_registers_, temp)) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100465 intervals.push_back(temp);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100466 }
467 }
468
Nicolas Geoffray776b3182015-02-23 14:14:57 +0000469 return ValidateIntervals(intervals, GetNumberOfSpillSlots(), reserved_out_slots_, *codegen_,
Nicolas Geoffray39468442014-09-02 15:17:15 +0100470 allocator_, processing_core_registers_, log_fatal_on_failure);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100471}
472
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700473void RegisterAllocatorLinearScan::DumpInterval(std::ostream& stream, LiveInterval* interval) const {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100474 interval->Dump(stream);
475 stream << ": ";
476 if (interval->HasRegister()) {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100477 if (interval->IsFloatingPoint()) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100478 codegen_->DumpFloatingPointRegister(stream, interval->GetRegister());
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100479 } else {
480 codegen_->DumpCoreRegister(stream, interval->GetRegister());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100481 }
482 } else {
483 stream << "spilled";
484 }
485 stream << std::endl;
486}
487
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700488void RegisterAllocatorLinearScan::DumpAllIntervals(std::ostream& stream) const {
Mingyao Yang296bd602014-10-06 16:47:28 -0700489 stream << "inactive: " << std::endl;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100490 for (LiveInterval* inactive_interval : inactive_) {
491 DumpInterval(stream, inactive_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700492 }
493 stream << "active: " << std::endl;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100494 for (LiveInterval* active_interval : active_) {
495 DumpInterval(stream, active_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700496 }
497 stream << "unhandled: " << std::endl;
498 auto unhandled = (unhandled_ != nullptr) ?
499 unhandled_ : &unhandled_core_intervals_;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100500 for (LiveInterval* unhandled_interval : *unhandled) {
501 DumpInterval(stream, unhandled_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700502 }
503 stream << "handled: " << std::endl;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100504 for (LiveInterval* handled_interval : handled_) {
505 DumpInterval(stream, handled_interval);
Mingyao Yang296bd602014-10-06 16:47:28 -0700506 }
507}
508
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100509// By the book implementation of a linear scan register allocator.
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700510void RegisterAllocatorLinearScan::LinearScan() {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100511 while (!unhandled_->empty()) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100512 // (1) Remove interval with the lowest start position from unhandled.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100513 LiveInterval* current = unhandled_->back();
514 unhandled_->pop_back();
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100515
516 // Make sure the interval is an expected state.
Nicolas Geoffray39468442014-09-02 15:17:15 +0100517 DCHECK(!current->IsFixed() && !current->HasSpillSlot());
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100518 // Make sure we are going in the right order.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100519 DCHECK(unhandled_->empty() || unhandled_->back()->GetStart() >= current->GetStart());
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100520 // Make sure a low interval is always with a high.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100521 DCHECK(!current->IsLowInterval() || unhandled_->back()->IsHighInterval());
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100522 // Make sure a high interval is always with a low.
523 DCHECK(current->IsLowInterval() ||
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100524 unhandled_->empty() ||
525 !unhandled_->back()->IsHighInterval());
Nicolas Geoffray87d03762014-11-19 15:17:56 +0000526
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100527 size_t position = current->GetStart();
528
Mingyao Yang296bd602014-10-06 16:47:28 -0700529 // Remember the inactive_ size here since the ones moved to inactive_ from
530 // active_ below shouldn't need to be re-checked.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100531 size_t inactive_intervals_to_handle = inactive_.size();
Mingyao Yang296bd602014-10-06 16:47:28 -0700532
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100533 // (2) Remove currently active intervals that are dead at this position.
534 // Move active intervals that have a lifetime hole at this position
535 // to inactive.
Vladimir Markob95fb772015-09-30 13:32:31 +0100536 auto active_kept_end = std::remove_if(
537 active_.begin(),
538 active_.end(),
539 [this, position](LiveInterval* interval) {
540 if (interval->IsDeadAt(position)) {
541 handled_.push_back(interval);
542 return true;
543 } else if (!interval->Covers(position)) {
544 inactive_.push_back(interval);
545 return true;
546 } else {
547 return false; // Keep this interval.
548 }
549 });
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100550 active_.erase(active_kept_end, active_.end());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100551
552 // (3) Remove currently inactive intervals that are dead at this position.
553 // Move inactive intervals that cover this position to active.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100554 auto inactive_to_handle_end = inactive_.begin() + inactive_intervals_to_handle;
Vladimir Markob95fb772015-09-30 13:32:31 +0100555 auto inactive_kept_end = std::remove_if(
556 inactive_.begin(),
557 inactive_to_handle_end,
558 [this, position](LiveInterval* interval) {
559 DCHECK(interval->GetStart() < position || interval->IsFixed());
560 if (interval->IsDeadAt(position)) {
561 handled_.push_back(interval);
562 return true;
563 } else if (interval->Covers(position)) {
564 active_.push_back(interval);
565 return true;
566 } else {
567 return false; // Keep this interval.
568 }
569 });
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100570 inactive_.erase(inactive_kept_end, inactive_to_handle_end);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100571
Nicolas Geoffrayacd03392014-11-26 15:46:52 +0000572 if (current->IsSlowPathSafepoint()) {
573 // Synthesized interval to record the maximum number of live registers
574 // at safepoints. No need to allocate a register for it.
Mark Mendellf85a9ca2015-01-13 09:20:58 -0500575 if (processing_core_registers_) {
576 maximum_number_of_live_core_registers_ =
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100577 std::max(maximum_number_of_live_core_registers_, active_.size());
Mark Mendellf85a9ca2015-01-13 09:20:58 -0500578 } else {
579 maximum_number_of_live_fp_registers_ =
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100580 std::max(maximum_number_of_live_fp_registers_, active_.size());
Mark Mendellf85a9ca2015-01-13 09:20:58 -0500581 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100582 DCHECK(unhandled_->empty() || unhandled_->back()->GetStart() > current->GetStart());
Nicolas Geoffrayacd03392014-11-26 15:46:52 +0000583 continue;
584 }
585
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000586 if (current->IsHighInterval() && !current->GetLowInterval()->HasRegister()) {
587 DCHECK(!current->HasRegister());
588 // Allocating the low part was unsucessful. The splitted interval for the high part
589 // will be handled next (it is in the `unhandled_` list).
590 continue;
591 }
592
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100593 // (4) Try to find an available register.
594 bool success = TryAllocateFreeReg(current);
595
596 // (5) If no register could be found, we need to spill.
597 if (!success) {
598 success = AllocateBlockedReg(current);
599 }
600
601 // (6) If the interval had a register allocated, add it to the list of active
602 // intervals.
603 if (success) {
Nicolas Geoffray98893962015-01-21 12:32:32 +0000604 codegen_->AddAllocatedRegister(processing_core_registers_
605 ? Location::RegisterLocation(current->GetRegister())
606 : Location::FpuRegisterLocation(current->GetRegister()));
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100607 active_.push_back(current);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000608 if (current->HasHighInterval() && !current->GetHighInterval()->HasRegister()) {
609 current->GetHighInterval()->SetRegister(GetHighForLowRegister(current->GetRegister()));
610 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100611 }
612 }
613}
614
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000615static void FreeIfNotCoverAt(LiveInterval* interval, size_t position, size_t* free_until) {
616 DCHECK(!interval->IsHighInterval());
617 // Note that the same instruction may occur multiple times in the input list,
618 // so `free_until` may have changed already.
David Brazdil3fc992f2015-04-16 18:31:55 +0100619 // Since `position` is not the current scan position, we need to use CoversSlow.
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000620 if (interval->IsDeadAt(position)) {
621 // Set the register to be free. Note that inactive intervals might later
622 // update this.
623 free_until[interval->GetRegister()] = kMaxLifetimePosition;
624 if (interval->HasHighInterval()) {
625 DCHECK(interval->GetHighInterval()->IsDeadAt(position));
626 free_until[interval->GetHighInterval()->GetRegister()] = kMaxLifetimePosition;
627 }
David Brazdil3fc992f2015-04-16 18:31:55 +0100628 } else if (!interval->CoversSlow(position)) {
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000629 // The interval becomes inactive at `defined_by`. We make its register
630 // available only until the next use strictly after `defined_by`.
631 free_until[interval->GetRegister()] = interval->FirstUseAfter(position);
632 if (interval->HasHighInterval()) {
David Brazdil3fc992f2015-04-16 18:31:55 +0100633 DCHECK(!interval->GetHighInterval()->CoversSlow(position));
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000634 free_until[interval->GetHighInterval()->GetRegister()] = free_until[interval->GetRegister()];
635 }
636 }
637}
638
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100639// Find a free register. If multiple are found, pick the register that
640// is free the longest.
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700641bool RegisterAllocatorLinearScan::TryAllocateFreeReg(LiveInterval* current) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100642 size_t* free_until = registers_array_;
643
644 // First set all registers to be free.
645 for (size_t i = 0; i < number_of_registers_; ++i) {
646 free_until[i] = kMaxLifetimePosition;
647 }
648
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100649 // For each active interval, set its register to not free.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100650 for (LiveInterval* interval : active_) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100651 DCHECK(interval->HasRegister());
652 free_until[interval->GetRegister()] = 0;
653 }
654
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000655 // An interval that starts an instruction (that is, it is not split), may
656 // re-use the registers used by the inputs of that instruciton, based on the
657 // location summary.
658 HInstruction* defined_by = current->GetDefinedBy();
659 if (defined_by != nullptr && !current->IsSplit()) {
660 LocationSummary* locations = defined_by->GetLocations();
661 if (!locations->OutputCanOverlapWithInputs() && locations->Out().IsUnallocated()) {
Vladimir Markoe9004912016-06-16 16:50:52 +0100662 HInputsRef inputs = defined_by->GetInputs();
Vladimir Marko372f10e2016-05-17 16:30:10 +0100663 for (size_t i = 0; i < inputs.size(); ++i) {
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000664 // Take the last interval of the input. It is the location of that interval
665 // that will be used at `defined_by`.
Vladimir Marko372f10e2016-05-17 16:30:10 +0100666 LiveInterval* interval = inputs[i]->GetLiveInterval()->GetLastSibling();
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000667 // Note that interval may have not been processed yet.
668 // TODO: Handle non-split intervals last in the work list.
Nicolas Geoffray94015b92015-06-04 18:21:04 +0100669 if (locations->InAt(i).IsValid()
670 && interval->HasRegister()
671 && interval->SameRegisterKind(*current)) {
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000672 // The input must be live until the end of `defined_by`, to comply to
673 // the linear scan algorithm. So we use `defined_by`'s end lifetime
674 // position to check whether the input is dead or is inactive after
675 // `defined_by`.
David Brazdil3fc992f2015-04-16 18:31:55 +0100676 DCHECK(interval->CoversSlow(defined_by->GetLifetimePosition()));
Nicolas Geoffray829280c2015-01-28 10:20:37 +0000677 size_t position = defined_by->GetLifetimePosition() + 1;
678 FreeIfNotCoverAt(interval, position, free_until);
679 }
680 }
681 }
682 }
683
Mingyao Yang296bd602014-10-06 16:47:28 -0700684 // For each inactive interval, set its register to be free until
685 // the next intersection with `current`.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100686 for (LiveInterval* inactive : inactive_) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700687 // Temp/Slow-path-safepoint interval has no holes.
688 DCHECK(!inactive->IsTemp() && !inactive->IsSlowPathSafepoint());
689 if (!current->IsSplit() && !inactive->IsFixed()) {
690 // Neither current nor inactive are fixed.
691 // Thanks to SSA, a non-split interval starting in a hole of an
692 // inactive interval should never intersect with that inactive interval.
693 // Only if it's not fixed though, because fixed intervals don't come from SSA.
694 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
695 continue;
696 }
697
698 DCHECK(inactive->HasRegister());
699 if (free_until[inactive->GetRegister()] == 0) {
700 // Already used by some active interval. No need to intersect.
701 continue;
702 }
703 size_t next_intersection = inactive->FirstIntersectionWith(current);
704 if (next_intersection != kNoLifetime) {
705 free_until[inactive->GetRegister()] =
706 std::min(free_until[inactive->GetRegister()], next_intersection);
707 }
708 }
709
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000710 int reg = kNoRegister;
Nicolas Geoffray39468442014-09-02 15:17:15 +0100711 if (current->HasRegister()) {
712 // Some instructions have a fixed register output.
713 reg = current->GetRegister();
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000714 if (free_until[reg] == 0) {
715 DCHECK(current->IsHighInterval());
716 // AllocateBlockedReg will spill the holder of the register.
717 return false;
718 }
Nicolas Geoffray39468442014-09-02 15:17:15 +0100719 } else {
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000720 DCHECK(!current->IsHighInterval());
Nicolas Geoffrayfbda5f32015-04-29 14:16:00 +0100721 int hint = current->FindFirstRegisterHint(free_until, liveness_);
Nicolas Geoffrayf2975812015-08-07 18:13:03 -0700722 if ((hint != kNoRegister)
723 // For simplicity, if the hint we are getting for a pair cannot be used,
724 // we are just going to allocate a new pair.
725 && !(current->IsLowInterval() && IsBlocked(GetHighForLowRegister(hint)))) {
Nicolas Geoffray01ef3452014-10-01 11:32:17 +0100726 DCHECK(!IsBlocked(hint));
727 reg = hint;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000728 } else if (current->IsLowInterval()) {
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000729 reg = FindAvailableRegisterPair(free_until, current->GetStart());
Nicolas Geoffray01ef3452014-10-01 11:32:17 +0100730 } else {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100731 reg = FindAvailableRegister(free_until, current);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100732 }
733 }
734
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000735 DCHECK_NE(reg, kNoRegister);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100736 // If we could not find a register, we need to spill.
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000737 if (free_until[reg] == 0) {
738 return false;
739 }
740
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000741 if (current->IsLowInterval()) {
742 // If the high register of this interval is not available, we need to spill.
743 int high_reg = current->GetHighInterval()->GetRegister();
744 if (high_reg == kNoRegister) {
745 high_reg = GetHighForLowRegister(reg);
746 }
747 if (free_until[high_reg] == 0) {
748 return false;
749 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100750 }
751
752 current->SetRegister(reg);
753 if (!current->IsDeadAt(free_until[reg])) {
754 // If the register is only available for a subset of live ranges
Nicolas Geoffray82726882015-06-01 13:51:57 +0100755 // covered by `current`, split `current` before the position where
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100756 // the register is not available anymore.
Nicolas Geoffray82726882015-06-01 13:51:57 +0100757 LiveInterval* split = SplitBetween(current, current->GetStart(), free_until[reg]);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100758 DCHECK(split != nullptr);
Nicolas Geoffray39468442014-09-02 15:17:15 +0100759 AddSorted(unhandled_, split);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100760 }
761 return true;
762}
763
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700764bool RegisterAllocatorLinearScan::IsBlocked(int reg) const {
Nicolas Geoffray102cbed2014-10-15 18:31:05 +0100765 return processing_core_registers_
766 ? blocked_core_registers_[reg]
767 : blocked_fp_registers_[reg];
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100768}
769
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700770int RegisterAllocatorLinearScan::FindAvailableRegisterPair(size_t* next_use, size_t starting_at) const {
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000771 int reg = kNoRegister;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000772 // Pick the register pair that is used the last.
773 for (size_t i = 0; i < number_of_registers_; ++i) {
774 if (IsBlocked(i)) continue;
775 if (!IsLowRegister(i)) continue;
776 int high_register = GetHighForLowRegister(i);
777 if (IsBlocked(high_register)) continue;
778 int existing_high_register = GetHighForLowRegister(reg);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000779 if ((reg == kNoRegister) || (next_use[i] >= next_use[reg]
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000780 && next_use[high_register] >= next_use[existing_high_register])) {
781 reg = i;
782 if (next_use[i] == kMaxLifetimePosition
783 && next_use[high_register] == kMaxLifetimePosition) {
784 break;
785 }
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000786 } else if (next_use[reg] <= starting_at || next_use[existing_high_register] <= starting_at) {
787 // If one of the current register is known to be unavailable, just unconditionally
788 // try a new one.
789 reg = i;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000790 }
791 }
792 return reg;
793}
794
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700795bool RegisterAllocatorLinearScan::IsCallerSaveRegister(int reg) const {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100796 return processing_core_registers_
797 ? !codegen_->IsCoreCalleeSaveRegister(reg)
798 : !codegen_->IsFloatingPointCalleeSaveRegister(reg);
799}
800
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700801int RegisterAllocatorLinearScan::FindAvailableRegister(size_t* next_use, LiveInterval* current) const {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100802 // We special case intervals that do not span a safepoint to try to find a caller-save
803 // register if one is available. We iterate from 0 to the number of registers,
804 // so if there are caller-save registers available at the end, we continue the iteration.
805 bool prefers_caller_save = !current->HasWillCallSafepoint();
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000806 int reg = kNoRegister;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000807 for (size_t i = 0; i < number_of_registers_; ++i) {
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100808 if (IsBlocked(i)) {
809 // Register cannot be used. Continue.
810 continue;
811 }
812
813 // Best case: we found a register fully available.
814 if (next_use[i] == kMaxLifetimePosition) {
815 if (prefers_caller_save && !IsCallerSaveRegister(i)) {
816 // We can get shorter encodings on some platforms by using
817 // small register numbers. So only update the candidate if the previous
818 // one was not available for the whole method.
819 if (reg == kNoRegister || next_use[reg] != kMaxLifetimePosition) {
820 reg = i;
821 }
822 // Continue the iteration in the hope of finding a caller save register.
823 continue;
824 } else {
825 reg = i;
826 // We know the register is good enough. Return it.
827 break;
828 }
829 }
830
831 // If we had no register before, take this one as a reference.
832 if (reg == kNoRegister) {
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000833 reg = i;
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100834 continue;
835 }
836
837 // Pick the register that is used the last.
838 if (next_use[i] > next_use[reg]) {
839 reg = i;
840 continue;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000841 }
842 }
843 return reg;
844}
845
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100846// Remove interval and its other half if any. Return iterator to the following element.
847static ArenaVector<LiveInterval*>::iterator RemoveIntervalAndPotentialOtherHalf(
848 ArenaVector<LiveInterval*>* intervals, ArenaVector<LiveInterval*>::iterator pos) {
849 DCHECK(intervals->begin() <= pos && pos < intervals->end());
850 LiveInterval* interval = *pos;
851 if (interval->IsLowInterval()) {
852 DCHECK(pos + 1 < intervals->end());
853 DCHECK_EQ(*(pos + 1), interval->GetHighInterval());
854 return intervals->erase(pos, pos + 2);
855 } else if (interval->IsHighInterval()) {
856 DCHECK(intervals->begin() < pos);
857 DCHECK_EQ(*(pos - 1), interval->GetLowInterval());
858 return intervals->erase(pos - 1, pos + 1);
859 } else {
860 return intervals->erase(pos);
861 }
862}
863
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700864bool RegisterAllocatorLinearScan::TrySplitNonPairOrUnalignedPairIntervalAt(size_t position,
865 size_t first_register_use,
866 size_t* next_use) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100867 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
868 LiveInterval* active = *it;
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000869 DCHECK(active->HasRegister());
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000870 if (active->IsFixed()) continue;
871 if (active->IsHighInterval()) continue;
872 if (first_register_use > next_use[active->GetRegister()]) continue;
873
Nicolas Geoffray2e92bc22015-08-20 19:52:26 +0100874 // Split the first interval found that is either:
875 // 1) A non-pair interval.
876 // 2) A pair interval whose high is not low + 1.
877 // 3) A pair interval whose low is not even.
878 if (!active->IsLowInterval() ||
879 IsLowOfUnalignedPairInterval(active) ||
880 !IsLowRegister(active->GetRegister())) {
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000881 LiveInterval* split = Split(active, position);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000882 if (split != active) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100883 handled_.push_back(active);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000884 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100885 RemoveIntervalAndPotentialOtherHalf(&active_, it);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000886 AddSorted(unhandled_, split);
887 return true;
888 }
889 }
890 return false;
891}
892
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100893// Find the register that is used the last, and spill the interval
894// that holds it. If the first use of `current` is after that register
895// we spill `current` instead.
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -0700896bool RegisterAllocatorLinearScan::AllocateBlockedReg(LiveInterval* current) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100897 size_t first_register_use = current->FirstRegisterUse();
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -0700898 if (current->HasRegister()) {
899 DCHECK(current->IsHighInterval());
900 // The low interval has allocated the register for the high interval. In
901 // case the low interval had to split both intervals, we may end up in a
902 // situation where the high interval does not have a register use anymore.
903 // We must still proceed in order to split currently active and inactive
904 // uses of the high interval's register, and put the high interval in the
905 // active set.
906 DCHECK(first_register_use != kNoLifetime || (current->GetNextSibling() != nullptr));
907 } else if (first_register_use == kNoLifetime) {
Nicolas Geoffray31d76b42014-06-09 15:02:22 +0100908 AllocateSpillSlotFor(current);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100909 return false;
910 }
911
912 // First set all registers as not being used.
913 size_t* next_use = registers_array_;
914 for (size_t i = 0; i < number_of_registers_; ++i) {
915 next_use[i] = kMaxLifetimePosition;
916 }
917
918 // For each active interval, find the next use of its register after the
919 // start of current.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100920 for (LiveInterval* active : active_) {
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100921 DCHECK(active->HasRegister());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100922 if (active->IsFixed()) {
923 next_use[active->GetRegister()] = current->GetStart();
924 } else {
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000925 size_t use = active->FirstRegisterUseAfter(current->GetStart());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100926 if (use != kNoLifetime) {
927 next_use[active->GetRegister()] = use;
928 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100929 }
930 }
931
932 // For each inactive interval, find the next use of its register after the
933 // start of current.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +0100934 for (LiveInterval* inactive : inactive_) {
Mingyao Yang296bd602014-10-06 16:47:28 -0700935 // Temp/Slow-path-safepoint interval has no holes.
936 DCHECK(!inactive->IsTemp() && !inactive->IsSlowPathSafepoint());
937 if (!current->IsSplit() && !inactive->IsFixed()) {
938 // Neither current nor inactive are fixed.
939 // Thanks to SSA, a non-split interval starting in a hole of an
940 // inactive interval should never intersect with that inactive interval.
941 // Only if it's not fixed though, because fixed intervals don't come from SSA.
942 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
943 continue;
944 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100945 DCHECK(inactive->HasRegister());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100946 size_t next_intersection = inactive->FirstIntersectionWith(current);
947 if (next_intersection != kNoLifetime) {
948 if (inactive->IsFixed()) {
949 next_use[inactive->GetRegister()] =
950 std::min(next_intersection, next_use[inactive->GetRegister()]);
951 } else {
Nicolas Geoffray1ba19812015-04-21 09:12:40 +0100952 size_t use = inactive->FirstUseAfter(current->GetStart());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +0100953 if (use != kNoLifetime) {
954 next_use[inactive->GetRegister()] = std::min(use, next_use[inactive->GetRegister()]);
955 }
956 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100957 }
958 }
959
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000960 int reg = kNoRegister;
961 bool should_spill = false;
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000962 if (current->HasRegister()) {
963 DCHECK(current->IsHighInterval());
964 reg = current->GetRegister();
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000965 // When allocating the low part, we made sure the high register was available.
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000966 DCHECK_LT(first_register_use, next_use[reg]);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000967 } else if (current->IsLowInterval()) {
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000968 reg = FindAvailableRegisterPair(next_use, first_register_use);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000969 // We should spill if both registers are not available.
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000970 should_spill = (first_register_use >= next_use[reg])
971 || (first_register_use >= next_use[GetHighForLowRegister(reg)]);
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000972 } else {
973 DCHECK(!current->IsHighInterval());
Nicolas Geoffray8826f672015-04-17 09:15:11 +0100974 reg = FindAvailableRegister(next_use, current);
Nicolas Geoffray119a8852016-02-06 17:01:15 +0000975 should_spill = (first_register_use >= next_use[reg]);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100976 }
977
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000978 DCHECK_NE(reg, kNoRegister);
979 if (should_spill) {
Nicolas Geoffray840e5462015-01-07 16:01:24 +0000980 DCHECK(!current->IsHighInterval());
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000981 bool is_allocation_at_use_site = (current->GetStart() >= (first_register_use - 1));
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -0700982 if (is_allocation_at_use_site) {
983 if (!current->IsLowInterval()) {
984 DumpInterval(std::cerr, current);
985 DumpAllIntervals(std::cerr);
986 // This situation has the potential to infinite loop, so we make it a non-debug CHECK.
987 HInstruction* at = liveness_.GetInstructionFromPosition(first_register_use / 2);
988 CHECK(false) << "There is not enough registers available for "
989 << current->GetParent()->GetDefinedBy()->DebugName() << " "
990 << current->GetParent()->GetDefinedBy()->GetId()
991 << " at " << first_register_use - 1 << " "
992 << (at == nullptr ? "" : at->DebugName());
993 }
994
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +0000995 // If we're allocating a register for `current` because the instruction at
996 // that position requires it, but we think we should spill, then there are
Nicolas Geoffray234d69d2015-03-09 10:28:50 +0000997 // non-pair intervals or unaligned pair intervals blocking the allocation.
998 // We split the first interval found, and put ourselves first in the
999 // `unhandled_` list.
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -07001000 bool success = TrySplitNonPairOrUnalignedPairIntervalAt(current->GetStart(),
1001 first_register_use,
1002 next_use);
1003 DCHECK(success);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001004 LiveInterval* existing = unhandled_->back();
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001005 DCHECK(existing->IsHighInterval());
1006 DCHECK_EQ(existing->GetLowInterval(), current);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001007 unhandled_->push_back(current);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001008 } else {
1009 // If the first use of that instruction is after the last use of the found
1010 // register, we split this interval just before its first register use.
1011 AllocateSpillSlotFor(current);
Nicolas Geoffray8cbab3c2015-04-23 15:14:36 +01001012 LiveInterval* split = SplitBetween(current, current->GetStart(), first_register_use - 1);
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -07001013 DCHECK(current != split);
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001014 AddSorted(unhandled_, split);
1015 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001016 return false;
1017 } else {
1018 // Use this register and spill the active and inactives interval that
1019 // have that register.
1020 current->SetRegister(reg);
1021
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001022 for (auto it = active_.begin(), end = active_.end(); it != end; ++it) {
1023 LiveInterval* active = *it;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001024 if (active->GetRegister() == reg) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001025 DCHECK(!active->IsFixed());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001026 LiveInterval* split = Split(active, current->GetStart());
Nicolas Geoffraydd8f8872015-01-15 15:37:37 +00001027 if (split != active) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001028 handled_.push_back(active);
Nicolas Geoffraydd8f8872015-01-15 15:37:37 +00001029 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001030 RemoveIntervalAndPotentialOtherHalf(&active_, it);
Nicolas Geoffray39468442014-09-02 15:17:15 +01001031 AddSorted(unhandled_, split);
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001032 break;
1033 }
1034 }
1035
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001036 // NOTE: Retrieve end() on each iteration because we're removing elements in the loop body.
1037 for (auto it = inactive_.begin(); it != inactive_.end(); ) {
1038 LiveInterval* inactive = *it;
1039 bool erased = false;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001040 if (inactive->GetRegister() == reg) {
Mingyao Yang296bd602014-10-06 16:47:28 -07001041 if (!current->IsSplit() && !inactive->IsFixed()) {
1042 // Neither current nor inactive are fixed.
1043 // Thanks to SSA, a non-split interval starting in a hole of an
1044 // inactive interval should never intersect with that inactive interval.
1045 // Only if it's not fixed though, because fixed intervals don't come from SSA.
1046 DCHECK_EQ(inactive->FirstIntersectionWith(current), kNoLifetime);
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001047 } else {
1048 size_t next_intersection = inactive->FirstIntersectionWith(current);
1049 if (next_intersection != kNoLifetime) {
1050 if (inactive->IsFixed()) {
1051 LiveInterval* split = Split(current, next_intersection);
1052 DCHECK_NE(split, current);
1053 AddSorted(unhandled_, split);
1054 } else {
1055 // Split at the start of `current`, which will lead to splitting
1056 // at the end of the lifetime hole of `inactive`.
1057 LiveInterval* split = Split(inactive, current->GetStart());
1058 // If it's inactive, it must start before the current interval.
1059 DCHECK_NE(split, inactive);
1060 it = RemoveIntervalAndPotentialOtherHalf(&inactive_, it);
1061 erased = true;
1062 handled_.push_back(inactive);
1063 AddSorted(unhandled_, split);
Nicolas Geoffray5b168de2015-03-27 10:27:22 +00001064 }
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001065 }
1066 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001067 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001068 // If we have erased the element, `it` already points to the next element.
1069 // Otherwise we need to move to the next element.
1070 if (!erased) {
1071 ++it;
1072 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001073 }
1074
1075 return true;
1076 }
1077}
1078
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -07001079void RegisterAllocatorLinearScan::AddSorted(ArenaVector<LiveInterval*>* array, LiveInterval* interval) {
Nicolas Geoffrayc8147a72014-10-21 16:06:20 +01001080 DCHECK(!interval->IsFixed() && !interval->HasSpillSlot());
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001081 size_t insert_at = 0;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001082 for (size_t i = array->size(); i > 0; --i) {
1083 LiveInterval* current = (*array)[i - 1u];
Nicolas Geoffray6c2dff82015-01-21 14:56:54 +00001084 // High intervals must be processed right after their low equivalent.
1085 if (current->StartsAfter(interval) && !current->IsHighInterval()) {
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001086 insert_at = i;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001087 break;
Nicolas Geoffrayacd03392014-11-26 15:46:52 +00001088 } else if ((current->GetStart() == interval->GetStart()) && current->IsSlowPathSafepoint()) {
1089 // Ensure the slow path interval is the last to be processed at its location: we want the
1090 // interval to know all live registers at this location.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001091 DCHECK(i == 1 || (*array)[i - 2u]->StartsAfter(current));
Nicolas Geoffrayacd03392014-11-26 15:46:52 +00001092 insert_at = i;
1093 break;
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001094 }
1095 }
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001096
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001097 // Insert the high interval before the low, to ensure the low is processed before.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001098 auto insert_pos = array->begin() + insert_at;
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001099 if (interval->HasHighInterval()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001100 array->insert(insert_pos, { interval->GetHighInterval(), interval });
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001101 } else if (interval->HasLowInterval()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001102 array->insert(insert_pos, { interval, interval->GetLowInterval() });
1103 } else {
1104 array->insert(insert_pos, interval);
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001105 }
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001106}
1107
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -07001108void RegisterAllocatorLinearScan::AllocateSpillSlotFor(LiveInterval* interval) {
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001109 if (interval->IsHighInterval()) {
Nicolas Geoffrayda2b2542015-08-06 19:56:45 -07001110 // The low interval already took care of allocating the spill slot.
1111 DCHECK(!interval->GetLowInterval()->HasRegister());
1112 DCHECK(interval->GetLowInterval()->GetParent()->HasSpillSlot());
Nicolas Geoffray840e5462015-01-07 16:01:24 +00001113 return;
1114 }
1115
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001116 LiveInterval* parent = interval->GetParent();
1117
1118 // An instruction gets a spill slot for its entire lifetime. If the parent
1119 // of this interval already has a spill slot, there is nothing to do.
1120 if (parent->HasSpillSlot()) {
1121 return;
1122 }
1123
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001124 HInstruction* defined_by = parent->GetDefinedBy();
David Brazdil77a48ae2015-09-15 12:34:04 +00001125 DCHECK(!defined_by->IsPhi() || !defined_by->AsPhi()->IsCatchPhi());
1126
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001127 if (defined_by->IsParameterValue()) {
1128 // Parameters have their own stack slot.
1129 parent->SetSpillSlot(codegen_->GetStackSlotOfParameter(defined_by->AsParameterValue()));
1130 return;
1131 }
1132
Nicolas Geoffray76b1e172015-05-27 17:18:33 +01001133 if (defined_by->IsCurrentMethod()) {
1134 parent->SetSpillSlot(0);
1135 return;
1136 }
1137
Nicolas Geoffray96f89a22014-07-11 10:57:49 +01001138 if (defined_by->IsConstant()) {
1139 // Constants don't need a spill slot.
1140 return;
1141 }
1142
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001143 ArenaVector<size_t>* spill_slots = nullptr;
Nicolas Geoffray776b3182015-02-23 14:14:57 +00001144 switch (interval->GetType()) {
1145 case Primitive::kPrimDouble:
1146 spill_slots = &double_spill_slots_;
1147 break;
1148 case Primitive::kPrimLong:
1149 spill_slots = &long_spill_slots_;
1150 break;
1151 case Primitive::kPrimFloat:
1152 spill_slots = &float_spill_slots_;
1153 break;
1154 case Primitive::kPrimNot:
1155 case Primitive::kPrimInt:
1156 case Primitive::kPrimChar:
1157 case Primitive::kPrimByte:
1158 case Primitive::kPrimBoolean:
1159 case Primitive::kPrimShort:
1160 spill_slots = &int_spill_slots_;
1161 break;
1162 case Primitive::kPrimVoid:
1163 LOG(FATAL) << "Unexpected type for interval " << interval->GetType();
1164 }
1165
Nicolas Geoffray412f10c2014-06-19 10:00:34 +01001166 // Find an available spill slot.
1167 size_t slot = 0;
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001168 for (size_t e = spill_slots->size(); slot < e; ++slot) {
Matthew Gharrityf64a6ab2016-07-11 14:45:01 -07001169 if ((*spill_slots)[slot] <= parent->GetStart()) {
1170 if (!parent->NeedsTwoSpillSlots()) {
1171 // One spill slot is sufficient.
1172 break;
1173 }
1174 if (slot == e - 1 || (*spill_slots)[slot + 1] <= parent->GetStart()) {
1175 // Two spill slots are available.
1176 break;
1177 }
Nicolas Geoffray412f10c2014-06-19 10:00:34 +01001178 }
1179 }
1180
David Brazdil77a48ae2015-09-15 12:34:04 +00001181 size_t end = interval->GetLastSibling()->GetEnd();
Nicolas Geoffray01ef3452014-10-01 11:32:17 +01001182 if (parent->NeedsTwoSpillSlots()) {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001183 if (slot + 2u > spill_slots->size()) {
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001184 // We need a new spill slot.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001185 spill_slots->resize(slot + 2u, end);
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001186 }
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001187 (*spill_slots)[slot] = end;
1188 (*spill_slots)[slot + 1] = end;
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001189 } else {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001190 if (slot == spill_slots->size()) {
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001191 // We need a new spill slot.
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001192 spill_slots->push_back(end);
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001193 } else {
Vladimir Marko2aaa4b52015-09-17 17:03:26 +01001194 (*spill_slots)[slot] = end;
Nicolas Geoffray3c049742014-09-24 18:10:46 +01001195 }
Nicolas Geoffray31d76b42014-06-09 15:02:22 +01001196 }
1197
Nicolas Geoffray776b3182015-02-23 14:14:57 +00001198 // Note that the exact spill slot location will be computed when we resolve,
1199 // that is when we know the number of spill slots for each type.
1200 parent->SetSpillSlot(slot);
Nicolas Geoffray86dbb9a2014-06-04 11:12:39 +01001201}
1202
Matthew Gharrity8f49d4b2016-07-14 13:24:00 -07001203void RegisterAllocatorLinearScan::AllocateSpillSlotForCatchPhi(HPhi* phi) {
David Brazdil77a48ae2015-09-15 12:34:04 +00001204 LiveInterval* interval = phi->GetLiveInterval();
1205
1206 HInstruction* previous_phi = phi->GetPrevious();
1207 DCHECK(previous_phi == nullptr ||
1208 previous_phi->AsPhi()->GetRegNumber() <= phi->GetRegNumber())
1209 << "Phis expected to be sorted by vreg number, so that equivalent phis are adjacent.";
1210
1211 if (phi->IsVRegEquivalentOf(previous_phi)) {
1212 // This is an equivalent of the previous phi. We need to assign the same
1213 // catch phi slot.
1214 DCHECK(previous_phi->GetLiveInterval()->HasSpillSlot());
1215 interval->SetSpillSlot(previous_phi->GetLiveInterval()->GetSpillSlot());
1216 } else {
1217 // Allocate a new spill slot for this catch phi.
1218 // TODO: Reuse spill slots when intervals of phis from different catch
1219 // blocks do not overlap.
1220 interval->SetSpillSlot(catch_phi_spill_slots_);
1221 catch_phi_spill_slots_ += interval->NeedsTwoSpillSlots() ? 2 : 1;
1222 }
1223}
1224
Nicolas Geoffraya7062e02014-05-22 12:50:17 +01001225} // namespace art