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); 143d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko if (bitfield_op->GetUses().empty()) { 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. 163d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko for (const HUseListNode<HInstruction*>& use : uses) { 164d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko HInstruction* user = use.GetUser(); 165d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko if (!HasShifterOperand(user)) { 1668626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames return false; 1678626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 168d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko if (!CanMergeIntoShifterOperand(user, bitfield_op)) { 1698626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames return false; 1708626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 1718626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 1728626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 1738626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames // Merge the instruction into its uses. 174d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko for (auto it = uses.begin(), end = uses.end(); it != end; /* ++it below */) { 175d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko HInstruction* user = it->GetUser(); 176d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko // Increment `it` now because `*it` will disappear thanks to MergeIntoShifterOperand(). 177d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko ++it; 178d59f3b1b7f5c1ab9f0731ff9dc60611e8d9a6edeVladimir Marko bool merged = MergeIntoShifterOperand(user, bitfield_op); 1798626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames DCHECK(merged); 1808626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 1818626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 1828626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames return true; 1838626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames} 1848626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 1859ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodskyvoid InstructionSimplifierArm64Visitor::VisitAnd(HAnd* instruction) { 1867fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov if (TryMergeNegatedInput(instruction)) { 1877fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov RecordSimplification(); 1887fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov } 1899ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky} 1909ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky 191e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitArrayGet(HArrayGet* instruction) { 192e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames TryExtractArrayAccessAddress(instruction, 193e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames instruction->GetArray(), 194e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames instruction->GetIndex(), 195e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames Primitive::ComponentSize(instruction->GetType())); 196e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames} 197e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames 198e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitArraySet(HArraySet* instruction) { 199e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames TryExtractArrayAccessAddress(instruction, 200e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames instruction->GetArray(), 201e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames instruction->GetIndex(), 202e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames Primitive::ComponentSize(instruction->GetComponentType())); 203e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames} 204e6dbf48d7a549e58a3d798bbbdc391e4d091b432Alexandre Rames 205418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitMul(HMul* instruction) { 2064a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko if (TryCombineMultiplyAccumulate(instruction, kArm64)) { 2074a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko RecordSimplification(); 208418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames } 209418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames} 210418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames 2119ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodskyvoid InstructionSimplifierArm64Visitor::VisitOr(HOr* instruction) { 2127fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov if (TryMergeNegatedInput(instruction)) { 2137fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov RecordSimplification(); 2147fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov } 2159ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky} 2169ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky 2178626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitShl(HShl* instruction) { 2188626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames if (instruction->InputAt(1)->IsConstant()) { 2198626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames TryMergeIntoUsersShifterOperand(instruction); 2208626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 2218626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames} 2228626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 2238626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitShr(HShr* instruction) { 2248626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames if (instruction->InputAt(1)->IsConstant()) { 2258626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames TryMergeIntoUsersShifterOperand(instruction); 2268626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 2278626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames} 2288626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 2298626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitTypeConversion(HTypeConversion* instruction) { 2308626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames Primitive::Type result_type = instruction->GetResultType(); 2318626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames Primitive::Type input_type = instruction->GetInputType(); 2328626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 2338626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames if (input_type == result_type) { 2348626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames // We let the arch-independent code handle this. 2358626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames return; 2368626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 2378626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 2388626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames if (Primitive::IsIntegralType(result_type) && Primitive::IsIntegralType(input_type)) { 2398626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames TryMergeIntoUsersShifterOperand(instruction); 2408626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 2418626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames} 2428626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 2438626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Ramesvoid InstructionSimplifierArm64Visitor::VisitUShr(HUShr* instruction) { 2448626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames if (instruction->InputAt(1)->IsConstant()) { 2458626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames TryMergeIntoUsersShifterOperand(instruction); 2468626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames } 2478626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames} 2488626b741716390a0119ffeb88b5b9fcf08e13010Alexandre Rames 2499ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodskyvoid InstructionSimplifierArm64Visitor::VisitXor(HXor* instruction) { 2507fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov if (TryMergeNegatedInput(instruction)) { 2517fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov RecordSimplification(); 2527fc6350f6f1ab04b52b9cd7542e0790528296cbeArtem Serov } 2539ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky} 2549ff0d205fd60cba6753a91f613b198ca2d67f04dKevin Brodsky 25544b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames} // namespace arm64 25644b9cf937836bb33139123e15ca8b586b5853268Alexandre Rames} // namespace art 257