summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.h
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2023-12-08 14:01:44 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2024-01-19 11:42:17 +0000
commit7c1dd6e2d1893f288214413c4b97273980f3aa4a (patch)
treed2912acfaed1cee70670d3497236a4b0d81baff3 /compiler/optimizing/nodes.h
parent921cc7db943144fe8a45f00527ad4950570637d0 (diff)
Revert "Disable write-barrier elimination pass"
This reverts commit 5a3271d7caafefd10a20f5a5db09d2c178838b76. Reason for revert: This CL has two fixes (codegen not doing a null check if a write barrier is being relied on, and codegen not recomputing skipping write barriers), regression tests, a new runtime check which runs in debug mode for the CC GC to ensure that the card table is set correctly for skipped write barriers, and new compile time (graph checker) tests to ensure graph consistency. This patchset updates the WriteBarrierKind to be {emit being relied on, emit not being relied on, dont emit}, which leaves the null check skip implementation to codegen. Test 2247- is removed from knownfailures.json but still skipped in MTS due to SLO requirements. Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Bug: 301833859 Bug: 310755375 Bug: 260843353 Change-Id: I025597e284b2765986e2091538680ee629fb5ae7
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r--compiler/optimizing/nodes.h46
1 files changed, 25 insertions, 21 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 0efe8f4335..8dd89fa4e4 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2903,6 +2903,10 @@ class HBackwardInstructionIterator : public ValueObject {
next_ = Done() ? nullptr : instruction_->GetPrevious();
}
+ explicit HBackwardInstructionIterator(HInstruction* instruction) : instruction_(instruction) {
+ next_ = Done() ? nullptr : instruction_->GetPrevious();
+ }
+
bool Done() const { return instruction_ == nullptr; }
HInstruction* Current() const { return instruction_; }
void Advance() {
@@ -6369,19 +6373,13 @@ class HInstanceFieldGet final : public HExpression<1> {
};
enum class WriteBarrierKind {
- // Emit the write barrier, with a runtime optimization which checks if the value that it is being
- // set is null.
- kEmitWithNullCheck,
- // Emit the write barrier, without the runtime null check optimization. This could be set because:
- // A) It is a write barrier for an ArraySet (which does the optimization with the type check, so
- // it never does the optimization at the write barrier stage)
- // B) We know that the input can't be null
- // C) This write barrier is actually several write barriers coalesced into one. Potentially we
- // could ask if every value is null for a runtime optimization at the cost of compile time / code
- // size. At the time of writing it was deemed not worth the effort.
- kEmitNoNullCheck,
+ // Emit the write barrier. This write barrier is not being relied on so e.g. codegen can decide to
+ // skip it if the value stored is null. This is the default behavior.
+ kEmitNotBeingReliedOn,
+ // Emit the write barrier. This write barrier is being relied on and must be emitted.
+ kEmitBeingReliedOn,
// Skip emitting the write barrier. This could be set because:
- // A) The write barrier is not needed (e.g. it is not a reference, or the value is the null
+ // A) The write barrier is not needed (i.e. it is not a reference, or the value is the null
// constant)
// B) This write barrier was coalesced into another one so there's no need to emit it.
kDontEmit,
@@ -6412,7 +6410,7 @@ class HInstanceFieldSet final : public HExpression<2> {
declaring_class_def_index,
dex_file) {
SetPackedFlag<kFlagValueCanBeNull>(true);
- SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitWithNullCheck);
+ SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitNotBeingReliedOn);
SetRawInputAt(0, object);
SetRawInputAt(1, value);
}
@@ -6433,8 +6431,11 @@ class HInstanceFieldSet final : public HExpression<2> {
void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); }
WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); }
void SetWriteBarrierKind(WriteBarrierKind kind) {
- DCHECK(kind != WriteBarrierKind::kEmitWithNullCheck)
+ DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn)
<< "We shouldn't go back to the original value.";
+ DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit,
+ GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn)
+ << "If a write barrier was relied on by other write barriers, we cannot skip emitting it.";
SetPackedField<WriteBarrierKindField>(kind);
}
@@ -6576,8 +6577,7 @@ class HArraySet final : public HExpression<3> {
SetPackedFlag<kFlagNeedsTypeCheck>(value->GetType() == DataType::Type::kReference);
SetPackedFlag<kFlagValueCanBeNull>(true);
SetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(false);
- // ArraySets never do the null check optimization at the write barrier stage.
- SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitNoNullCheck);
+ SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitNotBeingReliedOn);
SetRawInputAt(0, array);
SetRawInputAt(1, index);
SetRawInputAt(2, value);
@@ -6653,10 +6653,11 @@ class HArraySet final : public HExpression<3> {
WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); }
void SetWriteBarrierKind(WriteBarrierKind kind) {
- DCHECK(kind != WriteBarrierKind::kEmitNoNullCheck)
+ DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn)
<< "We shouldn't go back to the original value.";
- DCHECK(kind != WriteBarrierKind::kEmitWithNullCheck)
- << "We never do the null check optimization for ArraySets.";
+ DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit,
+ GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn)
+ << "If a write barrier was relied on by other write barriers, we cannot skip emitting it.";
SetPackedField<WriteBarrierKindField>(kind);
}
@@ -7516,7 +7517,7 @@ class HStaticFieldSet final : public HExpression<2> {
declaring_class_def_index,
dex_file) {
SetPackedFlag<kFlagValueCanBeNull>(true);
- SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitWithNullCheck);
+ SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitNotBeingReliedOn);
SetRawInputAt(0, cls);
SetRawInputAt(1, value);
}
@@ -7534,8 +7535,11 @@ class HStaticFieldSet final : public HExpression<2> {
WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); }
void SetWriteBarrierKind(WriteBarrierKind kind) {
- DCHECK(kind != WriteBarrierKind::kEmitWithNullCheck)
+ DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn)
<< "We shouldn't go back to the original value.";
+ DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit,
+ GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn)
+ << "If a write barrier was relied on by other write barriers, we cannot skip emitting it.";
SetPackedField<WriteBarrierKindField>(kind);
}