diff options
author | Alex Light <allight@google.com> | 2021-01-22 14:05:13 +0000 |
---|---|---|
committer | Alex Light <allight@google.com> | 2021-01-22 07:15:51 -0800 |
commit | fc1ce4e8be0d977e3d41699f5ec746d68f63c024 (patch) | |
tree | b656aa7c9e62aa181dfbf7fd4f2a0d32b8bf0704 /compiler/optimizing/code_generator_x86_64.cc | |
parent | c6da1be58086e873c9695f8c4c1a3a8ca718696e (diff) |
Revert^2 "Partial Load Store Elimination"
This reverts commit 47ac53100303e7e864b7f6d65f17b23088ccf1d6.
There was a bug in LSE where we would incorrectly record the
shadow$_monitor_ field as not having a default initial value. This
caused partial LSE to be unable to compile the Object.identityHashCode
function, causing crashes. This issue was fixed in a parent CL. Also
updated all Offsets in LSE_test to be outside of the object header
regardless of configuration.
Test: ./test.py --host
Bug: 67037140
Reason for revert: Fixed issue with shadow$_monitor_ field and offsets
Change-Id: I4fb2afff4d410da818db38ed833927dfc0f6be33
Diffstat (limited to 'compiler/optimizing/code_generator_x86_64.cc')
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 69 |
1 files changed, 58 insertions, 11 deletions
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index d79c2e4911..d54484c065 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -39,6 +39,7 @@ #include "utils/assembler.h" #include "utils/stack_checks.h" #include "utils/x86_64/assembler_x86_64.h" +#include "utils/x86_64/constants_x86_64.h" #include "utils/x86_64/managed_register_x86_64.h" namespace art { @@ -500,6 +501,7 @@ class ReadBarrierMarkSlowPathX86_64 : public SlowPathCode { DCHECK(locations->CanCall()); DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(ref_reg)) << ref_reg; DCHECK(instruction_->IsInstanceFieldGet() || + instruction_->IsPredicatedInstanceFieldGet() || instruction_->IsStaticFieldGet() || instruction_->IsArrayGet() || instruction_->IsArraySet() || @@ -761,6 +763,7 @@ class ReadBarrierForHeapReferenceSlowPathX86_64 : public SlowPathCode { DCHECK(locations->CanCall()); DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(reg_out.AsRegister())) << out_; DCHECK(instruction_->IsInstanceFieldGet() || + instruction_->IsPredicatedInstanceFieldGet() || instruction_->IsStaticFieldGet() || instruction_->IsArrayGet() || instruction_->IsInstanceOf() || @@ -4856,10 +4859,13 @@ void CodeGeneratorX86_64::GenerateMemoryBarrier(MemBarrierKind kind) { } void LocationsBuilderX86_64::HandleFieldGet(HInstruction* instruction) { - DCHECK(instruction->IsInstanceFieldGet() || instruction->IsStaticFieldGet()); + DCHECK(instruction->IsInstanceFieldGet() || + instruction->IsStaticFieldGet() || + instruction->IsPredicatedInstanceFieldGet()); bool object_field_get_with_read_barrier = kEmitCompilerReadBarrier && (instruction->GetType() == DataType::Type::kReference); + bool is_predicated = instruction->IsPredicatedInstanceFieldGet(); LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction, object_field_get_with_read_barrier @@ -4868,25 +4874,38 @@ void LocationsBuilderX86_64::HandleFieldGet(HInstruction* instruction) { if (object_field_get_with_read_barrier && kUseBakerReadBarrier) { locations->SetCustomSlowPathCallerSaves(RegisterSet::Empty()); // No caller-save registers. } - locations->SetInAt(0, Location::RequiresRegister()); + // receiver_input + locations->SetInAt(is_predicated ? 1 : 0, Location::RequiresRegister()); + if (is_predicated) { + if (DataType::IsFloatingPointType(instruction->GetType())) { + locations->SetInAt(0, Location::RequiresFpuRegister()); + } else { + locations->SetInAt(0, Location::RequiresRegister()); + } + } if (DataType::IsFloatingPointType(instruction->GetType())) { - locations->SetOut(Location::RequiresFpuRegister()); + locations->SetOut(is_predicated ? Location::SameAsFirstInput() + : Location::RequiresFpuRegister()); } else { - // The output overlaps for an object field get when read barriers - // are enabled: we do not want the move to overwrite the object's - // location, as we need it to emit the read barrier. - locations->SetOut( - Location::RequiresRegister(), - object_field_get_with_read_barrier ? Location::kOutputOverlap : Location::kNoOutputOverlap); + // The output overlaps for an object field get when read barriers are + // enabled: we do not want the move to overwrite the object's location, as + // we need it to emit the read barrier. For predicated instructions we can + // always overlap since the output is SameAsFirst and the default value. + locations->SetOut(is_predicated ? Location::SameAsFirstInput() : Location::RequiresRegister(), + object_field_get_with_read_barrier || is_predicated + ? Location::kOutputOverlap + : Location::kNoOutputOverlap); } } void InstructionCodeGeneratorX86_64::HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info) { - DCHECK(instruction->IsInstanceFieldGet() || instruction->IsStaticFieldGet()); + DCHECK(instruction->IsInstanceFieldGet() || + instruction->IsStaticFieldGet() || + instruction->IsPredicatedInstanceFieldGet()); LocationSummary* locations = instruction->GetLocations(); - Location base_loc = locations->InAt(0); + Location base_loc = locations->InAt(instruction->IsPredicatedInstanceFieldGet() ? 1 : 0); CpuRegister base = base_loc.AsRegister<CpuRegister>(); Location out = locations->Out(); bool is_volatile = field_info.IsVolatile(); @@ -5032,6 +5051,8 @@ void InstructionCodeGeneratorX86_64::HandleFieldSet(HInstruction* instruction, bool is_volatile = field_info.IsVolatile(); DataType::Type field_type = field_info.GetFieldType(); uint32_t offset = field_info.GetFieldOffset().Uint32Value(); + bool is_predicated = + instruction->IsInstanceFieldSet() && instruction->AsInstanceFieldSet()->GetIsPredicatedSet(); if (is_volatile) { codegen_->GenerateMemoryBarrier(MemBarrierKind::kAnyStore); @@ -5039,6 +5060,12 @@ void InstructionCodeGeneratorX86_64::HandleFieldSet(HInstruction* instruction, bool maybe_record_implicit_null_check_done = false; + NearLabel pred_is_null; + if (is_predicated) { + __ testl(base, base); + __ j(kZero, &pred_is_null); + } + switch (field_type) { case DataType::Type::kBool: case DataType::Type::kUint8: @@ -5145,6 +5172,10 @@ void InstructionCodeGeneratorX86_64::HandleFieldSet(HInstruction* instruction, if (is_volatile) { codegen_->GenerateMemoryBarrier(MemBarrierKind::kAnyAny); } + + if (is_predicated) { + __ Bind(&pred_is_null); + } } void LocationsBuilderX86_64::VisitInstanceFieldSet(HInstanceFieldSet* instruction) { @@ -5155,10 +5186,26 @@ void InstructionCodeGeneratorX86_64::VisitInstanceFieldSet(HInstanceFieldSet* in HandleFieldSet(instruction, instruction->GetFieldInfo(), instruction->GetValueCanBeNull()); } +void LocationsBuilderX86_64::VisitPredicatedInstanceFieldGet( + HPredicatedInstanceFieldGet* instruction) { + HandleFieldGet(instruction); +} + void LocationsBuilderX86_64::VisitInstanceFieldGet(HInstanceFieldGet* instruction) { HandleFieldGet(instruction); } +void InstructionCodeGeneratorX86_64::VisitPredicatedInstanceFieldGet( + HPredicatedInstanceFieldGet* instruction) { + NearLabel finish; + LocationSummary* locations = instruction->GetLocations(); + CpuRegister target = locations->InAt(1).AsRegister<CpuRegister>(); + __ testl(target, target); + __ j(kZero, &finish); + HandleFieldGet(instruction, instruction->GetFieldInfo()); + __ Bind(&finish); +} + void InstructionCodeGeneratorX86_64::VisitInstanceFieldGet(HInstanceFieldGet* instruction) { HandleFieldGet(instruction, instruction->GetFieldInfo()); } |