summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_x86.cc
diff options
context:
space:
mode:
authorAlex Light <allight@google.com>2021-01-22 14:05:13 +0000
committerAlex Light <allight@google.com>2021-01-22 07:15:51 -0800
commitfc1ce4e8be0d977e3d41699f5ec746d68f63c024 (patch)
treeb656aa7c9e62aa181dfbf7fd4f2a0d32b8bf0704 /compiler/optimizing/code_generator_x86.cc
parentc6da1be58086e873c9695f8c4c1a3a8ca718696e (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.cc')
-rw-r--r--compiler/optimizing/code_generator_x86.cc65
1 files changed, 54 insertions, 11 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index f6c0270804..4fc29fcb0c 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -489,6 +489,7 @@ class ReadBarrierMarkSlowPathX86 : public SlowPathCode {
DCHECK(locations->CanCall());
DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(ref_reg)) << ref_reg;
DCHECK(instruction_->IsInstanceFieldGet() ||
+ instruction_->IsPredicatedInstanceFieldGet() ||
instruction_->IsStaticFieldGet() ||
instruction_->IsArrayGet() ||
instruction_->IsArraySet() ||
@@ -749,6 +750,7 @@ class ReadBarrierForHeapReferenceSlowPathX86 : public SlowPathCode {
DCHECK(locations->CanCall());
DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(reg_out));
DCHECK(instruction_->IsInstanceFieldGet() ||
+ instruction_->IsPredicatedInstanceFieldGet() ||
instruction_->IsStaticFieldGet() ||
instruction_->IsArrayGet() ||
instruction_->IsInstanceOf() ||
@@ -5642,10 +5644,13 @@ void CodeGeneratorX86::MarkGCCard(Register temp,
}
void LocationsBuilderX86::HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info) {
- 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,
kEmitCompilerReadBarrier
@@ -5654,21 +5659,30 @@ void LocationsBuilderX86::HandleFieldGet(HInstruction* instruction, const FieldI
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 in case of long: we don't want the low move
// to overwrite the object's location. Likewise, in the case of
// an object field get with read barriers 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 || instruction->GetType() == DataType::Type::kInt64) ?
- Location::kOutputOverlap :
- Location::kNoOutputOverlap);
+ locations->SetOut(is_predicated ? Location::SameAsFirstInput() : Location::RequiresRegister(),
+ (object_field_get_with_read_barrier ||
+ instruction->GetType() == DataType::Type::kInt64 ||
+ is_predicated)
+ ? Location::kOutputOverlap
+ : Location::kNoOutputOverlap);
}
if (field_info.IsVolatile() && (field_info.GetFieldType() == DataType::Type::kInt64)) {
@@ -5682,10 +5696,12 @@ void LocationsBuilderX86::HandleFieldGet(HInstruction* instruction, const FieldI
void InstructionCodeGeneratorX86::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);
Register base = base_loc.AsRegister<Register>();
Location out = locations->Out();
bool is_volatile = field_info.IsVolatile();
@@ -5979,9 +5995,17 @@ void InstructionCodeGeneratorX86::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();
Address field_addr(base, offset);
+ NearLabel pred_is_null;
+ if (is_predicated) {
+ __ testl(base, base);
+ __ j(kEqual, &pred_is_null);
+ }
+
HandleFieldSet(instruction,
/* value_index= */ 1,
field_type,
@@ -5989,6 +6013,10 @@ void InstructionCodeGeneratorX86::HandleFieldSet(HInstruction* instruction,
base,
is_volatile,
value_can_be_null);
+
+ if (is_predicated) {
+ __ Bind(&pred_is_null);
+ }
}
void LocationsBuilderX86::VisitStaticFieldGet(HStaticFieldGet* instruction) {
@@ -6015,10 +6043,25 @@ void InstructionCodeGeneratorX86::VisitInstanceFieldSet(HInstanceFieldSet* instr
HandleFieldSet(instruction, instruction->GetFieldInfo(), instruction->GetValueCanBeNull());
}
+void LocationsBuilderX86::VisitPredicatedInstanceFieldGet(
+ HPredicatedInstanceFieldGet* instruction) {
+ HandleFieldGet(instruction, instruction->GetFieldInfo());
+}
+
void LocationsBuilderX86::VisitInstanceFieldGet(HInstanceFieldGet* instruction) {
HandleFieldGet(instruction, instruction->GetFieldInfo());
}
+void InstructionCodeGeneratorX86::VisitPredicatedInstanceFieldGet(
+ HPredicatedInstanceFieldGet* instruction) {
+ NearLabel finish;
+ LocationSummary* locations = instruction->GetLocations();
+ Register recv = locations->InAt(1).AsRegister<Register>();
+ __ testl(recv, recv);
+ __ j(kZero, &finish);
+ HandleFieldGet(instruction, instruction->GetFieldInfo());
+ __ Bind(&finish);
+}
void InstructionCodeGeneratorX86::VisitInstanceFieldGet(HInstanceFieldGet* instruction) {
HandleFieldGet(instruction, instruction->GetFieldInfo());
}