diff options
author | Mark Mendell <mark.p.mendell@intel.com> | 2015-01-13 09:20:58 -0500 |
---|---|---|
committer | Mark Mendell <mark.p.mendell@intel.com> | 2015-01-15 11:21:37 -0500 |
commit | f85a9ca9859ad843dc03d3a2b600afbaf2e9bbdd (patch) | |
tree | a802042fa7a3a8cb820916d558e630596daaa9b4 /compiler/optimizing/register_allocator.cc | |
parent | 8fccea249b1a6f1469eeea42c2b2cca06ce1c70d (diff) | |
download | art-f85a9ca9859ad843dc03d3a2b600afbaf2e9bbdd.tar.gz art-f85a9ca9859ad843dc03d3a2b600afbaf2e9bbdd.tar.bz2 art-f85a9ca9859ad843dc03d3a2b600afbaf2e9bbdd.zip |
[optimizing compiler] Compute live spill size
The current stack frame calculation assumes that each live register to
be saved/restored has the word size of the machine. This fails for X86,
where a double in an XMM register takes up 8 bytes. Change the
calculation to keep track of the number of core registers and number of
fp registers to handle this distinction.
This is slightly pessimal, as the registers may not be active at the
same time, but the only way to handle this would be to allocate both
classes of registers simultaneously, or remember all the active
intervals, matching them up and compute the size of each safepoint
interval.
Change-Id: If7860aa319b625c214775347728cdf49a56946eb
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
Diffstat (limited to 'compiler/optimizing/register_allocator.cc')
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 1efc52b9ec..d2f4f9b7dc 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -56,7 +56,8 @@ RegisterAllocator::RegisterAllocator(ArenaAllocator* allocator, blocked_core_registers_(codegen->GetBlockedCoreRegisters()), blocked_fp_registers_(codegen->GetBlockedFloatingPointRegisters()), reserved_out_slots_(0), - maximum_number_of_live_registers_(0) { + maximum_number_of_live_core_registers_(0), + maximum_number_of_live_fp_registers_(0) { codegen->SetupBlockedRegisters(); physical_core_register_intervals_.SetSize(codegen->GetNumberOfCoreRegisters()); physical_fp_register_intervals_.SetSize(codegen->GetNumberOfFloatingPointRegisters()); @@ -185,9 +186,6 @@ void RegisterAllocator::AllocateRegistersInternal() { } LinearScan(); - size_t saved_maximum_number_of_live_registers = maximum_number_of_live_registers_; - maximum_number_of_live_registers_ = 0; - inactive_.Reset(); active_.Reset(); handled_.Reset(); @@ -207,7 +205,6 @@ void RegisterAllocator::AllocateRegistersInternal() { } } LinearScan(); - maximum_number_of_live_registers_ += saved_maximum_number_of_live_registers; } void RegisterAllocator::ProcessInstruction(HInstruction* instruction) { @@ -602,8 +599,13 @@ void RegisterAllocator::LinearScan() { if (current->IsSlowPathSafepoint()) { // Synthesized interval to record the maximum number of live registers // at safepoints. No need to allocate a register for it. - maximum_number_of_live_registers_ = - std::max(maximum_number_of_live_registers_, active_.Size()); + 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_->IsEmpty() || unhandled_->Peek()->GetStart() > current->GetStart()); continue; } @@ -1255,8 +1257,9 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) { switch (source.GetKind()) { case Location::kRegister: { locations->AddLiveRegister(source); - DCHECK_LE(locations->GetNumberOfLiveRegisters(), maximum_number_of_live_registers_); - + DCHECK_LE(locations->GetNumberOfLiveRegisters(), + maximum_number_of_live_core_registers_ + + maximum_number_of_live_fp_registers_); if (current->GetType() == Primitive::kPrimNot) { locations->SetRegisterBit(source.reg()); } @@ -1349,7 +1352,8 @@ void RegisterAllocator::ConnectSplitSiblings(LiveInterval* interval, void RegisterAllocator::Resolve() { codegen_->ComputeFrameSize( - spill_slots_.Size(), maximum_number_of_live_registers_, reserved_out_slots_); + spill_slots_.Size(), maximum_number_of_live_core_registers_, + maximum_number_of_live_fp_registers_, reserved_out_slots_); // Adjust the Out Location of instructions. // TODO: Use pointers of Location inside LiveInterval to avoid doing another iteration. |