diff options
| author | Vladimir Marko <vmarko@google.com> | 2016-08-09 11:04:26 +0100 |
|---|---|---|
| committer | Vladimir Marko <vmarko@google.com> | 2016-09-05 17:27:41 +0100 |
| commit | 70e97462116a47ef2e582ea29a037847debcc029 (patch) | |
| tree | ee587e35b9b9483c35875ccc8ddea139978ca823 /compiler/optimizing/register_allocator_linear_scan.cc | |
| parent | 521691ae4dfad47cf6b46858347fa5fa32fd7bcc (diff) | |
| download | art-70e97462116a47ef2e582ea29a037847debcc029.tar.gz art-70e97462116a47ef2e582ea29a037847debcc029.tar.bz2 art-70e97462116a47ef2e582ea29a037847debcc029.zip | |
Avoid excessive spill slots for slow paths.
Reducing the frame size makes stack maps smaller as we need
fewer bits for stack masks and some dex register locations
may use short location kind rather than long. On Nexus 9,
AOSP ToT, the boot.oat size reduction is
prebuilt multi-part boot image:
- 32-bit boot.oat: -416KiB (-0.6%)
- 64-bit boot.oat: -635KiB (-0.9%)
prebuilt multi-part boot image with read barrier:
- 32-bit boot.oat: -483KiB (-0.7%)
- 64-bit boot.oat: -703KiB (-0.9%)
on-device built single boot image:
- 32-bit boot.oat: -380KiB (-0.6%)
- 64-bit boot.oat: -632KiB (-0.9%)
on-device built single boot image with read barrier:
- 32-bit boot.oat: -448KiB (-0.6%)
- 64-bit boot.oat: -692KiB (-0.9%)
The other benefit is that at runtime, threads may need fewer
pages for their stacks, reducing overall memory usage.
We defer the calculation of the maximum spill size from
the main register allocator (linear scan or graph coloring)
to the RegisterAllocationResolver and do it based on the
live registers at slow path safepoints. The old notion of
an artificial slow path safepoint interval is removed as
it is no longer needed.
Test: Run ART test suite on host and Nexus 9.
Bug: 30212852
Change-Id: I40b3d114e278e2c5807982904fa49bf6642c6275
Diffstat (limited to 'compiler/optimizing/register_allocator_linear_scan.cc')
| -rw-r--r-- | compiler/optimizing/register_allocator_linear_scan.cc | 45 |
1 files changed, 4 insertions, 41 deletions
diff --git a/compiler/optimizing/register_allocator_linear_scan.cc b/compiler/optimizing/register_allocator_linear_scan.cc index 768ed2d26a..6910c71ead 100644 --- a/compiler/optimizing/register_allocator_linear_scan.cc +++ b/compiler/optimizing/register_allocator_linear_scan.cc @@ -63,9 +63,7 @@ RegisterAllocatorLinearScan::RegisterAllocatorLinearScan(ArenaAllocator* allocat registers_array_(nullptr), blocked_core_registers_(codegen->GetBlockedCoreRegisters()), blocked_fp_registers_(codegen->GetBlockedFloatingPointRegisters()), - reserved_out_slots_(0), - maximum_number_of_live_core_registers_(0), - maximum_number_of_live_fp_registers_(0) { + reserved_out_slots_(0) { temp_intervals_.reserve(4); int_spill_slots_.reserve(kDefaultNumberOfSpillSlots); long_spill_slots_.reserve(kDefaultNumberOfSpillSlots); @@ -92,8 +90,7 @@ static bool ShouldProcess(bool processing_core_registers, LiveInterval* interval void RegisterAllocatorLinearScan::AllocateRegisters() { AllocateRegistersInternal(); RegisterAllocationResolver(allocator_, codegen_, liveness_) - .Resolve(maximum_number_of_live_core_registers_, - maximum_number_of_live_fp_registers_, + .Resolve(ArrayRef<HInstruction* const>(safepoints_), reserved_out_slots_, int_spill_slots_.size(), long_spill_slots_.size(), @@ -283,20 +280,6 @@ void RegisterAllocatorLinearScan::ProcessInstruction(HInstruction* instruction) return; } safepoints_.push_back(instruction); - if (locations->OnlyCallsOnSlowPath()) { - // We add a synthesized range at this position to record the live registers - // at this position. Ideally, we could just update the safepoints when locations - // are updated, but we currently need to know the full stack size before updating - // locations (because of parameters and the fact that we don't have a frame pointer). - // And knowing the full stack size requires to know the maximum number of live - // registers at calls in slow paths. - // By adding the following interval in the algorithm, we can compute this - // maximum before updating locations. - LiveInterval* interval = LiveInterval::MakeSlowPathInterval(allocator_, instruction); - interval->AddRange(position, position + 1); - AddSorted(&unhandled_core_intervals_, interval); - AddSorted(&unhandled_fp_intervals_, interval); - } } if (locations->WillCall()) { @@ -569,20 +552,6 @@ void RegisterAllocatorLinearScan::LinearScan() { }); inactive_.erase(inactive_kept_end, inactive_to_handle_end); - if (current->IsSlowPathSafepoint()) { - // Synthesized interval to record the maximum number of live registers - // at safepoints. No need to allocate a register for it. - if (processing_core_registers_) { - maximum_number_of_live_core_registers_ = - std::max(maximum_number_of_live_core_registers_, active_.size()); - } else { - maximum_number_of_live_fp_registers_ = - std::max(maximum_number_of_live_fp_registers_, active_.size()); - } - DCHECK(unhandled_->empty() || unhandled_->back()->GetStart() > current->GetStart()); - continue; - } - if (current->IsHighInterval() && !current->GetLowInterval()->HasRegister()) { DCHECK(!current->HasRegister()); // Allocating the low part was unsucessful. The splitted interval for the high part @@ -685,7 +654,7 @@ bool RegisterAllocatorLinearScan::TryAllocateFreeReg(LiveInterval* current) { // the next intersection with `current`. for (LiveInterval* inactive : inactive_) { // Temp/Slow-path-safepoint interval has no holes. - DCHECK(!inactive->IsTemp() && !inactive->IsSlowPathSafepoint()); + DCHECK(!inactive->IsTemp()); if (!current->IsSplit() && !inactive->IsFixed()) { // Neither current nor inactive are fixed. // Thanks to SSA, a non-split interval starting in a hole of an @@ -933,7 +902,7 @@ bool RegisterAllocatorLinearScan::AllocateBlockedReg(LiveInterval* current) { // start of current. for (LiveInterval* inactive : inactive_) { // Temp/Slow-path-safepoint interval has no holes. - DCHECK(!inactive->IsTemp() && !inactive->IsSlowPathSafepoint()); + DCHECK(!inactive->IsTemp()); if (!current->IsSplit() && !inactive->IsFixed()) { // Neither current nor inactive are fixed. // Thanks to SSA, a non-split interval starting in a hole of an @@ -1085,12 +1054,6 @@ void RegisterAllocatorLinearScan::AddSorted(ArenaVector<LiveInterval*>* array, L if (current->StartsAfter(interval) && !current->IsHighInterval()) { insert_at = i; break; - } else if ((current->GetStart() == interval->GetStart()) && current->IsSlowPathSafepoint()) { - // Ensure the slow path interval is the last to be processed at its location: we want the - // interval to know all live registers at this location. - DCHECK(i == 1 || (*array)[i - 2u]->StartsAfter(current)); - insert_at = i; - break; } } |
