diff options
author | 2021-01-25 14:11:05 +0000 | |
---|---|---|
committer | 2021-01-25 07:01:32 -0800 | |
commit | 3a73ffb70151dbc99fa41f300a237f8c29783e0e (patch) | |
tree | 8debef1b372e5bea27d5265a9019446229955e3d /compiler/optimizing/instruction_simplifier.cc | |
parent | e585964df42e9fd2fab6f209810cb03e1b261ab1 (diff) |
Revert^4 "Partial Load Store Elimination"
This reverts commit 791df7a161ecfa28eb69862a4bc285282463b960.
This unreverts commit fc1ce4e8be0d977e3d41699f5ec746d68f63c024.
This unreverts commit b8686ce4c93eba7192ed7ef89e7ffd9f3aa6cd07.
We incorrectly failed to include PredicatedInstanceFieldGet in a few
conditions, including a DCHECK. This caused tests to fail under the
read-barrier-table-lookup configuration.
Reason for revert: Fixed 2 incorrect checks
Bug: 67037140
Test: ./art/test/testrunner/run_build_test_target.py -j70 art-gtest-read-barrier-table-lookup
Change-Id: I32b01b29fb32077fb5074e7c77a0226bd1fcaab4
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 8886f14726..71376178b1 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -23,6 +23,7 @@ #include "escape.h" #include "intrinsics.h" #include "mirror/class-inl.h" +#include "optimizing/nodes.h" #include "scoped_thread_state_change-inl.h" #include "sharpening.h" #include "string_builder_append.h" @@ -109,6 +110,7 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor { void VisitInvoke(HInvoke* invoke) override; void VisitDeoptimize(HDeoptimize* deoptimize) override; void VisitVecMul(HVecMul* instruction) override; + void VisitPredicatedInstanceFieldGet(HPredicatedInstanceFieldGet* instruction) override; bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const; @@ -915,6 +917,42 @@ static HInstruction* AllowInMinMax(IfCondition cmp, return nullptr; } +// TODO This should really be done by LSE itself since there is significantly +// more information available there. +void InstructionSimplifierVisitor::VisitPredicatedInstanceFieldGet( + HPredicatedInstanceFieldGet* pred_get) { + HInstruction* target = pred_get->GetTarget(); + HInstruction* default_val = pred_get->GetDefaultValue(); + // TODO Technically we could end up with a case where the target isn't a phi + // (allowing us to eliminate the instruction and replace with either a + // InstanceFieldGet or the default) but due to the ordering of compilation + // passes this can't happen in ART. + if (!target->IsPhi() || !default_val->IsPhi() || default_val->GetBlock() != target->GetBlock()) { + // Already reduced the target or the phi selection will differ between the + // target and default. + return; + } + DCHECK_EQ(default_val->InputCount(), target->InputCount()); + // In the same block both phis only one non-null we can remove the phi from default_val. + HInstruction* single_value = nullptr; + auto inputs = target->GetInputs(); + for (auto [input, idx] : ZipCount(MakeIterationRange(inputs))) { + if (input->CanBeNull()) { + if (single_value == nullptr) { + single_value = default_val->InputAt(idx); + } else if (single_value != default_val->InputAt(idx) && + !single_value->Equals(default_val->InputAt(idx))) { + // Multiple values, can't combine. + return; + } + } + } + if (single_value->StrictlyDominates(pred_get)) { + // Combine all the maybe null values into one. + pred_get->ReplaceInput(single_value, 0); + } +} + void InstructionSimplifierVisitor::VisitSelect(HSelect* select) { HInstruction* replace_with = nullptr; HInstruction* condition = select->GetCondition(); @@ -1098,6 +1136,9 @@ static inline bool TryReplaceFieldOrArrayGetType(HInstruction* maybe_get, DataTy if (maybe_get->IsInstanceFieldGet()) { maybe_get->AsInstanceFieldGet()->SetType(new_type); return true; + } else if (maybe_get->IsPredicatedInstanceFieldGet()) { + maybe_get->AsPredicatedInstanceFieldGet()->SetType(new_type); + return true; } else if (maybe_get->IsStaticFieldGet()) { maybe_get->AsStaticFieldGet()->SetType(new_type); return true; |