instruction_simplifier_arm64.cc revision 4a0dad67867f389e01a5a6c0fe381d210f687c0d
144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames/*
244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * Copyright (C) 2015 The Android Open Source Project
344b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *
444b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * Licensed under the Apache License, Version 2.0 (the "License");
544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * you may not use this file except in compliance with the License.
644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * You may obtain a copy of the License at
744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *
844b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *      http://www.apache.org/licenses/LICENSE-2.0
944b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames *
1044b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * Unless required by applicable law or agreed to in writing, software
1144b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * distributed under the License is distributed on an "AS IS" BASIS,
1244b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1344b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * See the License for the specific language governing permissions and
1444b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames * limitations under the License.
1544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames */
1644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
1744b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames#include "instruction_simplifier_arm64.h"
1844b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
198626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames#include "common_arm64.h"
204a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko#include "instruction_simplifier_shared.h"
21e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames#include "mirror/array-inl.h"
22e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
2344b9cf937836bb33139123e15ca8b586b5853268Alexandre Ramesnamespace art {
2444b9cf937836bb33139123e15ca8b586b5853268Alexandre Ramesnamespace arm64 {
2544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames
268626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesusing helpers::CanFitInShifterOperand;
278626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesusing helpers::HasShifterOperand;
288626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesusing helpers::ShifterOperandSupportsExtension;
298626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
30e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Ramesvoid InstructionSimplifierArm64Visitor::TryExtractArrayAccessAddress(HInstruction* access,
31e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                                                                     HInstruction* array,
32e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                                                                     HInstruction* index,
33e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                                                                     int access_size) {
34cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain  if (kEmitCompilerReadBarrier) {
35cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain    // The read barrier instrumentation does not support the
36cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain    // HArm64IntermediateAddress instruction yet.
37cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain    //
38cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain    // TODO: Handle this case properly in the ARM64 code generator and
39cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain    // re-enable this optimization; otherwise, remove this TODO.
40cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain    // b/26601270
41cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain    return;
42cd3d0fb5a4c113cfdb610454d133762a2ab0e6deRoland Levillain  }
43e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  if (index->IsConstant() ||
44e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames      (index->IsBoundsCheck() && index->AsBoundsCheck()->GetIndex()->IsConstant())) {
45e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames    // When the index is a constant all the addressing can be fitted in the
46e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames    // memory access instruction, so do not split the access.
47e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames    return;
48e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  }
49e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  if (access->IsArraySet() &&
50e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames      access->AsArraySet()->GetValue()->GetType() == Primitive::kPrimNot) {
51e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames    // The access may require a runtime call or the original array pointer.
52e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames    return;
53e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  }
54e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
55e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // Proceed to extract the base address computation.
56e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  ArenaAllocator* arena = GetGraph()->GetArena();
57e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
58e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  HIntConstant* offset =
59e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames      GetGraph()->GetIntConstant(mirror::Array::DataOffset(access_size).Uint32Value());
60e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  HArm64IntermediateAddress* address =
61e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames      new (arena) HArm64IntermediateAddress(array, offset, kNoDexPc);
62295abc1a3aec98868544dfd4e0eeab797c3d60c2David Brazdil  address->SetReferenceTypeInfo(array->GetReferenceTypeInfo());
63e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  access->GetBlock()->InsertInstructionBefore(address, access);
64e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  access->ReplaceInput(address, 0);
65e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // Both instructions must depend on GC to prevent any instruction that can
66e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // trigger GC to be inserted between the two.
67e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  access->AddSideEffects(SideEffects::DependsOnGC());
68e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  DCHECK(address->GetSideEffects().Includes(SideEffects::DependsOnGC()));
69e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  DCHECK(access->GetSideEffects().Includes(SideEffects::DependsOnGC()));
70e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // TODO: Code generation for HArrayGet and HArraySet will check whether the input address
71e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // is an HArm64IntermediateAddress and generate appropriate code.
72e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // We would like to replace the `HArrayGet` and `HArraySet` with custom instructions (maybe
73e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // `HArm64Load` and `HArm64Store`). We defer these changes because these new instructions would
74e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // not bring any advantages yet.
75e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // Also see the comments in
76e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // `InstructionCodeGeneratorARM64::VisitArrayGet()` and
77e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  // `InstructionCodeGeneratorARM64::VisitArraySet()`.
78e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  RecordSimplification();
79e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames}
80e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
818626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesbool InstructionSimplifierArm64Visitor::TryMergeIntoShifterOperand(HInstruction* use,
828626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                                                   HInstruction* bitfield_op,
838626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                                                   bool do_merge) {
848626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  DCHECK(HasShifterOperand(use));
858626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  DCHECK(use->IsBinaryOperation() || use->IsNeg());
868626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  DCHECK(CanFitInShifterOperand(bitfield_op));
878626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  DCHECK(!bitfield_op->HasEnvironmentUses());
888626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
898626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  Primitive::Type type = use->GetType();
908626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (type != Primitive::kPrimInt && type != Primitive::kPrimLong) {
918626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    return false;
928626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
938626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
948626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  HInstruction* left;
958626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  HInstruction* right;
968626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (use->IsBinaryOperation()) {
978626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    left = use->InputAt(0);
988626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    right = use->InputAt(1);
998626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  } else {
1008626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    DCHECK(use->IsNeg());
1018626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    right = use->AsNeg()->InputAt(0);
1028626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    left = GetGraph()->GetConstant(right->GetType(), 0);
1038626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1048626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  DCHECK(left == bitfield_op || right == bitfield_op);
1058626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1068626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (left == right) {
1078626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    // TODO: Handle special transformations in this situation?
1088626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    // For example should we transform `(x << 1) + (x << 1)` into `(x << 2)`?
1098626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    // Or should this be part of a separate transformation logic?
1108626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    return false;
1118626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1128626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1138626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  bool is_commutative = use->IsBinaryOperation() && use->AsBinaryOperation()->IsCommutative();
1148626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  HInstruction* other_input;
1158626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (bitfield_op == right) {
1168626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    other_input = left;
1178626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  } else {
1188626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    if (is_commutative) {
1198626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames      other_input = right;
1208626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    } else {
1218626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames      return false;
1228626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    }
1238626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1248626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1258626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  HArm64DataProcWithShifterOp::OpKind op_kind;
1268626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  int shift_amount = 0;
1278626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  HArm64DataProcWithShifterOp::GetOpInfoFromInstruction(bitfield_op, &op_kind, &shift_amount);
1288626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1298626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (HArm64DataProcWithShifterOp::IsExtensionOp(op_kind) &&
1308626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames      !ShifterOperandSupportsExtension(use)) {
1318626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    return false;
1328626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1338626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1348626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (do_merge) {
1358626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    HArm64DataProcWithShifterOp* alu_with_op =
1368626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames        new (GetGraph()->GetArena()) HArm64DataProcWithShifterOp(use,
1378626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                                                 other_input,
1388626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                                                 bitfield_op->InputAt(0),
1398626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                                                 op_kind,
1408626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                                                 shift_amount,
1418626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames                                                                 use->GetDexPc());
1428626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    use->GetBlock()->ReplaceAndRemoveInstructionWith(use, alu_with_op);
1438626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    if (bitfield_op->GetUses().IsEmpty()) {
1448626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames      bitfield_op->GetBlock()->RemoveInstruction(bitfield_op);
1458626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    }
1468626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    RecordSimplification();
1478626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1488626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1498626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  return true;
1508626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames}
1518626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1528626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames// Merge a bitfield move instruction into its uses if it can be merged in all of them.
1538626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesbool InstructionSimplifierArm64Visitor::TryMergeIntoUsersShifterOperand(HInstruction* bitfield_op) {
1548626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  DCHECK(CanFitInShifterOperand(bitfield_op));
1558626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1568626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (bitfield_op->HasEnvironmentUses()) {
1578626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    return false;
1588626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1598626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1608626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  const HUseList<HInstruction*>& uses = bitfield_op->GetUses();
1618626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1628626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  // Check whether we can merge the instruction in all its users' shifter operand.
1638626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  for (HUseIterator<HInstruction*> it_use(uses); !it_use.Done(); it_use.Advance()) {
1648626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    HInstruction* use = it_use.Current()->GetUser();
1658626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    if (!HasShifterOperand(use)) {
1668626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames      return false;
1678626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    }
1688626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    if (!CanMergeIntoShifterOperand(use, bitfield_op)) {
1698626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames      return false;
1708626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    }
1718626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1728626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1738626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  // Merge the instruction into its uses.
1748626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  for (HUseIterator<HInstruction*> it_use(uses); !it_use.Done(); it_use.Advance()) {
1758626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    HInstruction* use = it_use.Current()->GetUser();
1768626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    bool merged = MergeIntoShifterOperand(use, bitfield_op);
1778626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    DCHECK(merged);
1788626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
1798626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
1808626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  return true;
1818626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames}
1828626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
183e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitArrayGet(HArrayGet* instruction) {
184e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  TryExtractArrayAccessAddress(instruction,
185e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                               instruction->GetArray(),
186e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                               instruction->GetIndex(),
187e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                               Primitive::ComponentSize(instruction->GetType()));
188e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames}
189e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
190e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitArraySet(HArraySet* instruction) {
191e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames  TryExtractArrayAccessAddress(instruction,
192e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                               instruction->GetArray(),
193e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                               instruction->GetIndex(),
194e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames                               Primitive::ComponentSize(instruction->GetComponentType()));
195e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames}
196e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames
197418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitMul(HMul* instruction) {
1984a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  if (TryCombineMultiplyAccumulate(instruction, kArm64)) {
1994a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko    RecordSimplification();
200418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
201418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames}
202418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
2038626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitShl(HShl* instruction) {
2048626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (instruction->InputAt(1)->IsConstant()) {
2058626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    TryMergeIntoUsersShifterOperand(instruction);
2068626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
2078626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames}
2088626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
2098626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitShr(HShr* instruction) {
2108626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (instruction->InputAt(1)->IsConstant()) {
2118626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    TryMergeIntoUsersShifterOperand(instruction);
2128626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
2138626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames}
2148626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
2158626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitTypeConversion(HTypeConversion* instruction) {
2168626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  Primitive::Type result_type = instruction->GetResultType();
2178626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  Primitive::Type input_type = instruction->GetInputType();
2188626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
2198626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (input_type == result_type) {
2208626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    // We let the arch-independent code handle this.
2218626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    return;
2228626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
2238626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
2248626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (Primitive::IsIntegralType(result_type) && Primitive::IsIntegralType(input_type)) {
2258626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    TryMergeIntoUsersShifterOperand(instruction);
2268626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
2278626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames}
2288626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
2298626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitUShr(HUShr* instruction) {
2308626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  if (instruction->InputAt(1)->IsConstant()) {
2318626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames    TryMergeIntoUsersShifterOperand(instruction);
2328626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames  }
2338626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames}
2348626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames
23544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames}  // namespace arm64
23644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames}  // namespace art
237