diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 10 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/locations.h | 15 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator_test.cc | 6 |
9 files changed, 42 insertions, 8 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index c75980d856..0dfbad25f5 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -281,16 +281,22 @@ void CodeGenerator::InitLocations(HInstruction* instruction) { HInstruction* previous = instruction->GetPrevious(); Location temp_location = GetTemporaryLocation(instruction->AsTemporary()); Move(previous, temp_location, instruction); - previous->GetLocations()->SetOut(temp_location); } return; } AllocateRegistersLocally(instruction); for (size_t i = 0, e = instruction->InputCount(); i < e; ++i) { Location location = instruction->GetLocations()->InAt(i); + HInstruction* input = instruction->InputAt(i); if (location.IsValid()) { // Move the input to the desired location. - Move(instruction->InputAt(i), location, instruction); + if (input->GetNext()->IsTemporary()) { + // If the input was stored in a temporary, use that temporary to + // perform the move. + Move(input->GetNext(), location, instruction); + } else { + Move(input, location, instruction); + } } } } diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index a031ce3389..91b28c4d99 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -766,6 +766,9 @@ void CodeGeneratorARM::Move(HInstruction* instruction, Location location, HInstr default: LOG(FATAL) << "Unexpected type " << instruction->GetType(); } + } else if (instruction->IsTemporary()) { + Location temp_location = GetTemporaryLocation(instruction->AsTemporary()); + Move32(location, temp_location); } else { DCHECK((instruction->GetNext() == move_for) || instruction->GetNext()->IsTemporary()); switch (instruction->GetType()) { diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 1be5717737..e84346b28d 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -413,7 +413,9 @@ void CodeGeneratorARM64::Move(HInstruction* instruction, __ Mov(temp, value); __ Str(temp, StackOperandFrom(location)); } - + } else if (instruction->IsTemporary()) { + Location temp_location = GetTemporaryLocation(instruction->AsTemporary()); + MoveHelper(location, temp_location, type); } else if (instruction->IsLoadLocal()) { uint32_t stack_slot = GetStackSlot(instruction->AsLoadLocal()->GetLocal()); switch (type) { diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 54a12fdee0..129c374947 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -623,6 +623,9 @@ void CodeGeneratorX86::Move(HInstruction* instruction, Location location, HInstr DCHECK(location.IsConstant()); DCHECK_EQ(location.GetConstant(), instruction); } + } else if (instruction->IsTemporary()) { + Location temp_location = GetTemporaryLocation(instruction->AsTemporary()); + Move32(location, temp_location); } else if (instruction->IsLoadLocal()) { int slot = GetStackSlot(instruction->AsLoadLocal()->GetLocal()); switch (instruction->GetType()) { diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 9237cc3a4d..efe1ef2155 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -559,6 +559,9 @@ void CodeGeneratorX86_64::Move(HInstruction* instruction, default: LOG(FATAL) << "Unexpected local type " << instruction->GetType(); } + } else if (instruction->IsTemporary()) { + Location temp_location = GetTemporaryLocation(instruction->AsTemporary()); + Move(location, temp_location); } else { DCHECK((instruction->GetNext() == move_for) || instruction->GetNext()->IsTemporary()); switch (instruction->GetType()) { diff --git a/compiler/optimizing/locations.h b/compiler/optimizing/locations.h index bed688b5e3..d1555d4e11 100644 --- a/compiler/optimizing/locations.h +++ b/compiler/optimizing/locations.h @@ -417,6 +417,7 @@ class LocationSummary : public ArenaObject<kArenaAllocMisc> { LocationSummary(HInstruction* instruction, CallKind call_kind = kNoCall); void SetInAt(uint32_t at, Location location) { + DCHECK(inputs_.Get(at).IsUnallocated() || inputs_.Get(at).IsInvalid()); inputs_.Put(at, location); } @@ -429,8 +430,17 @@ class LocationSummary : public ArenaObject<kArenaAllocMisc> { } void SetOut(Location location, bool overlaps = true) { + DCHECK(output_.IsUnallocated() || output_.IsInvalid()); output_overlaps_ = overlaps; - output_ = Location(location); + output_ = location; + } + + void UpdateOut(Location location) { + // The only reason for updating an output is for parameters where + // we only know the exact stack slot after doing full register + // allocation. + DCHECK(output_.IsStackSlot() || output_.IsDoubleStackSlot()); + output_ = location; } void AddTemp(Location location) { @@ -442,6 +452,7 @@ class LocationSummary : public ArenaObject<kArenaAllocMisc> { } void SetTempAt(uint32_t at, Location location) { + DCHECK(temps_.Get(at).IsUnallocated() || temps_.Get(at).IsInvalid()); temps_.Put(at, location); } @@ -528,6 +539,8 @@ class LocationSummary : public ArenaObject<kArenaAllocMisc> { // Registers that are in use at this position. RegisterSet live_registers_; + ART_FRIEND_TEST(RegisterAllocatorTest, ExpectedInRegisterHint); + ART_FRIEND_TEST(RegisterAllocatorTest, SameAsFirstInputHint); DISALLOW_COPY_AND_ASSIGN(LocationSummary); }; diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 37e5e6b9aa..47ed8dfe88 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2088,6 +2088,8 @@ class HTemporary : public HTemplateInstruction<0> { size_t GetIndex() const { return index_; } + Primitive::Type GetType() const OVERRIDE { return GetPrevious()->GetType(); } + DECLARE_INSTRUCTION(Temporary); private: diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 0745f9c5da..4a9deea376 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -1164,11 +1164,11 @@ void RegisterAllocator::Resolve() { if (location.IsStackSlot()) { location = Location::StackSlot(location.GetStackIndex() + codegen_->GetFrameSize()); current->SetSpillSlot(location.GetStackIndex()); - locations->SetOut(location); + locations->UpdateOut(location); } else if (location.IsDoubleStackSlot()) { location = Location::DoubleStackSlot(location.GetStackIndex() + codegen_->GetFrameSize()); current->SetSpillSlot(location.GetStackIndex()); - locations->SetOut(location); + locations->UpdateOut(location); } else if (current->HasSpillSlot()) { current->SetSpillSlot(current->GetSpillSlot() + codegen_->GetFrameSize()); } diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc index 9b1a121fbe..3d81362851 100644 --- a/compiler/optimizing/register_allocator_test.cc +++ b/compiler/optimizing/register_allocator_test.cc @@ -622,7 +622,8 @@ TEST(RegisterAllocatorTest, ExpectedInRegisterHint) { liveness.Analyze(); // Check that the field gets put in the register expected by its use. - ret->GetLocations()->SetInAt(0, Location::RegisterLocation(2)); + // Don't use SetInAt because we are overriding an already allocated location. + ret->GetLocations()->inputs_.Put(0, Location::RegisterLocation(2)); RegisterAllocator register_allocator(&allocator, &codegen, liveness); register_allocator.AllocateRegisters(); @@ -684,7 +685,8 @@ TEST(RegisterAllocatorTest, SameAsFirstInputHint) { liveness.Analyze(); // check that both adds get the same register. - first_add->InputAt(0)->GetLocations()->SetOut(Location::RegisterLocation(2)); + // Don't use SetOutput because output is already allocated. + first_add->InputAt(0)->GetLocations()->output_ = Location::RegisterLocation(2); ASSERT_EQ(first_add->GetLocations()->Out().GetPolicy(), Location::kSameAsFirstInput); ASSERT_EQ(second_add->GetLocations()->Out().GetPolicy(), Location::kSameAsFirstInput); |