summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
author Ulyana Trafimovich <skvadrik@google.com> 2021-07-28 14:33:34 +0000
committer Ulyana Trafimovich <skvadrik@google.com> 2021-08-31 16:13:39 +0000
commit98f01d1deac3a938e49f0725c58798e38ef59277 (patch)
treedcbf841ef87fdb1baf21f231e20cc9bd9f3cb0df /compiler/optimizing/instruction_simplifier.cc
parent96dadefd24331f6808cb287048269ba772423c33 (diff)
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
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc60
1 files changed, 57 insertions, 3 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index a6104effd7..1a7544da55 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 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
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 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
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 @@ void InstructionSimplifierVisitor::VisitNullCheck(HNullCheck* null_check) {
}
}
-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::SimplifyAllocationIntrinsic(HInvoke* invoke)
}
}
+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 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
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: