Revert^2 "Compile time null checks for VarHandle intrinsics."
This reverts commit 4a889b7f1e58368f0ffd795eaa24f2f493ccab8d.
Reason for revert: relanding the original change after fixing the
baseline compiler.
Static checks for VarHandle intrinsics are now done in two places:
1) Simple static checks are done for both baseline and optimizing
compilers in `HInstructionBuilder::BuildInvokePolymorphic`.
2) More complex checks are done in instruction simplifier only for the
optimizing compiler. They can use information provided by preceding
optimization passes.
Bug: 191765508
Test: art/test.py --host -r
Change-Id: I92932f6fcf408c700e6db0101fe2fb1e8300a54a
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index a6104ef..1a7544d 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -22,6 +22,7 @@
#include "data_type-inl.h"
#include "escape.h"
#include "intrinsics.h"
+#include "intrinsics_utils.h"
#include "mirror/class-inl.h"
#include "optimizing/nodes.h"
#include "scoped_thread_state_change-inl.h"
@@ -112,8 +113,6 @@
void VisitVecMul(HVecMul* instruction) override;
void VisitPredicatedInstanceFieldGet(HPredicatedInstanceFieldGet* instruction) override;
- bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const;
-
void SimplifySystemArrayCopy(HInvoke* invoke);
void SimplifyStringEquals(HInvoke* invoke);
void SimplifyFP2Int(HInvoke* invoke);
@@ -123,6 +122,7 @@
void SimplifyNPEOnArgN(HInvoke* invoke, size_t);
void SimplifyReturnThis(HInvoke* invoke);
void SimplifyAllocationIntrinsic(HInvoke* invoke);
+ void SimplifyVarHandleIntrinsic(HInvoke* invoke);
CodeGenerator* codegen_;
OptimizingCompilerStats* stats_;
@@ -580,7 +580,7 @@
}
}
-bool InstructionSimplifierVisitor::CanEnsureNotNullAt(HInstruction* input, HInstruction* at) const {
+bool CanEnsureNotNullAt(HInstruction* input, HInstruction* at) {
if (!input->CanBeNull()) {
return true;
}
@@ -2762,6 +2762,27 @@
}
}
+void InstructionSimplifierVisitor::SimplifyVarHandleIntrinsic(HInvoke* invoke) {
+ DCHECK(invoke->IsInvokePolymorphic());
+ VarHandleOptimizations optimizations(invoke);
+
+ if (optimizations.GetDoNotIntrinsify()) {
+ // Preceding static checks disabled intrinsic, so no need to analyze further.
+ return;
+ }
+
+ size_t expected_coordinates_count = GetExpectedVarHandleCoordinatesCount(invoke);
+ if (expected_coordinates_count == 1u) {
+ HInstruction* object = invoke->InputAt(1);
+ // The following has been ensured by static checks in done in the instruction builder.
+ DCHECK(object->GetType() == DataType::Type::kReference && !object->IsNullConstant());
+ // Test whether we can avoid the null check on the object.
+ if (CanEnsureNotNullAt(object, invoke)) {
+ optimizations.SetSkipObjectNullCheck();
+ }
+ }
+}
+
void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
switch (instruction->GetIntrinsic()) {
case Intrinsics::kStringEquals:
@@ -2809,6 +2830,39 @@
case Intrinsics::kStringBuilderToString:
SimplifyAllocationIntrinsic(instruction);
break;
+ case Intrinsics::kVarHandleCompareAndExchange:
+ case Intrinsics::kVarHandleCompareAndExchangeAcquire:
+ case Intrinsics::kVarHandleCompareAndExchangeRelease:
+ case Intrinsics::kVarHandleCompareAndSet:
+ case Intrinsics::kVarHandleGet:
+ case Intrinsics::kVarHandleGetAcquire:
+ case Intrinsics::kVarHandleGetAndAdd:
+ case Intrinsics::kVarHandleGetAndAddAcquire:
+ case Intrinsics::kVarHandleGetAndAddRelease:
+ case Intrinsics::kVarHandleGetAndBitwiseAnd:
+ case Intrinsics::kVarHandleGetAndBitwiseAndAcquire:
+ case Intrinsics::kVarHandleGetAndBitwiseAndRelease:
+ case Intrinsics::kVarHandleGetAndBitwiseOr:
+ case Intrinsics::kVarHandleGetAndBitwiseOrAcquire:
+ case Intrinsics::kVarHandleGetAndBitwiseOrRelease:
+ case Intrinsics::kVarHandleGetAndBitwiseXor:
+ case Intrinsics::kVarHandleGetAndBitwiseXorAcquire:
+ case Intrinsics::kVarHandleGetAndBitwiseXorRelease:
+ case Intrinsics::kVarHandleGetAndSet:
+ case Intrinsics::kVarHandleGetAndSetAcquire:
+ case Intrinsics::kVarHandleGetAndSetRelease:
+ case Intrinsics::kVarHandleGetOpaque:
+ case Intrinsics::kVarHandleGetVolatile:
+ case Intrinsics::kVarHandleSet:
+ case Intrinsics::kVarHandleSetOpaque:
+ case Intrinsics::kVarHandleSetRelease:
+ case Intrinsics::kVarHandleSetVolatile:
+ case Intrinsics::kVarHandleWeakCompareAndSet:
+ case Intrinsics::kVarHandleWeakCompareAndSetAcquire:
+ case Intrinsics::kVarHandleWeakCompareAndSetPlain:
+ case Intrinsics::kVarHandleWeakCompareAndSetRelease:
+ SimplifyVarHandleIntrinsic(instruction);
+ break;
case Intrinsics::kIntegerRotateRight:
case Intrinsics::kLongRotateRight:
case Intrinsics::kIntegerRotateLeft: