diff options
author | 2021-01-22 14:05:13 +0000 | |
---|---|---|
committer | 2021-01-22 07:15:51 -0800 | |
commit | fc1ce4e8be0d977e3d41699f5ec746d68f63c024 (patch) | |
tree | b656aa7c9e62aa181dfbf7fd4f2a0d32b8bf0704 /compiler/optimizing/instruction_simplifier.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/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; |