summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2023-11-24 12:02:13 +0100
committer VladimĂ­r Marko <vmarko@google.com> 2023-11-27 11:43:58 +0000
commit7f515181fdbe88a139d973d3481964d9cb7ed118 (patch)
treedcd9802bb4eed26591d69972e605d27c68164f98 /compiler/optimizing/instruction_simplifier.cc
parentdb8d042c6dc12d9d1ba5ff2526ccc86a077570ca (diff)
Simplify boxing followed by unboxing.
Also mark boxing `valueOf()` intrinsics as never null to avoid creating unnecessary `HNullCheck` instructions. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Change-Id: I86e7721e3af6c59407aa2ddfc1bd11bd2fdac83c
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc32
1 files changed, 32 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index fb6d53b9da..3328f3babe 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -22,6 +22,7 @@
#include "data_type-inl.h"
#include "driver/compiler_options.h"
#include "escape.h"
+#include "intrinsic_objects.h"
#include "intrinsics.h"
#include "intrinsics_utils.h"
#include "mirror/class-inl.h"
@@ -30,6 +31,7 @@
#include "scoped_thread_state_change-inl.h"
#include "sharpening.h"
#include "string_builder_append.h"
+#include "well_known_classes.h"
namespace art HIDDEN {
@@ -114,6 +116,7 @@ class InstructionSimplifierVisitor final : public HGraphDelegateVisitor {
void VisitDeoptimize(HDeoptimize* deoptimize) override;
void VisitVecMul(HVecMul* instruction) override;
void VisitPredicatedInstanceFieldGet(HPredicatedInstanceFieldGet* instruction) override;
+ void SimplifyBoxUnbox(HInvoke* instruction, ArtField* field, DataType::Type type);
void SimplifySystemArrayCopy(HInvoke* invoke);
void SimplifyStringEquals(HInvoke* invoke);
void SimplifyFP2Int(HInvoke* invoke);
@@ -2407,6 +2410,29 @@ void InstructionSimplifierVisitor::VisitXor(HXor* instruction) {
TryHandleAssociativeAndCommutativeOperation(instruction);
}
+void InstructionSimplifierVisitor::SimplifyBoxUnbox(
+ HInvoke* instruction, ArtField* field, DataType::Type type) {
+ DCHECK(instruction->GetIntrinsic() == Intrinsics::kByteValueOf ||
+ instruction->GetIntrinsic() == Intrinsics::kShortValueOf ||
+ instruction->GetIntrinsic() == Intrinsics::kCharacterValueOf ||
+ instruction->GetIntrinsic() == Intrinsics::kIntegerValueOf);
+ const HUseList<HInstruction*>& uses = instruction->GetUses();
+ for (auto it = uses.begin(), end = uses.end(); it != end;) {
+ HInstruction* user = it->GetUser();
+ ++it; // Increment the iterator before we potentially remove the node from the list.
+ if (user->IsInstanceFieldGet() &&
+ user->AsInstanceFieldGet()->GetFieldInfo().GetField() == field &&
+ // Note: Due to other simplifications, we may have an `HInstanceFieldGet` with
+ // a different type (Int8 vs. Uint8, Int16 vs. Uint16) for the same field.
+ // Do not optimize that case for now. (We would need to insert a `HTypeConversion`.)
+ user->GetType() == type) {
+ user->ReplaceWith(instruction->InputAt(0));
+ RecordSimplification();
+ // Do not remove `user` while we're iterating over the block's instructions. Let DCE do it.
+ }
+ }
+}
+
void InstructionSimplifierVisitor::SimplifyStringEquals(HInvoke* instruction) {
HInstruction* argument = instruction->InputAt(1);
HInstruction* receiver = instruction->InputAt(0);
@@ -3058,6 +3084,12 @@ bool InstructionSimplifierVisitor::CanUseKnownBootImageVarHandle(HInvoke* invoke
void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
switch (instruction->GetIntrinsic()) {
+#define SIMPLIFY_BOX_UNBOX(name, low, high, type, start_index) \
+ case Intrinsics::k ## name ## ValueOf: \
+ SimplifyBoxUnbox(instruction, WellKnownClasses::java_lang_##name##_value, type); \
+ break;
+ BOXED_TYPES(SIMPLIFY_BOX_UNBOX)
+#undef SIMPLIFY_BOX_UNBOX
case Intrinsics::kStringEquals:
SimplifyStringEquals(instruction);
break;