| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_SHARED_H_ |
| #define ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_SHARED_H_ |
| |
| #include "nodes.h" |
| |
| namespace art { |
| |
| namespace helpers { |
| |
| inline bool CanFitInShifterOperand(HInstruction* instruction) { |
| if (instruction->IsTypeConversion()) { |
| HTypeConversion* conversion = instruction->AsTypeConversion(); |
| DataType::Type result_type = conversion->GetResultType(); |
| DataType::Type input_type = conversion->GetInputType(); |
| // We don't expect to see the same type as input and result. |
| return DataType::IsIntegralType(result_type) && DataType::IsIntegralType(input_type) && |
| (result_type != input_type); |
| } else { |
| return (instruction->IsShl() && instruction->AsShl()->InputAt(1)->IsIntConstant()) || |
| (instruction->IsShr() && instruction->AsShr()->InputAt(1)->IsIntConstant()) || |
| (instruction->IsUShr() && instruction->AsUShr()->InputAt(1)->IsIntConstant()); |
| } |
| } |
| |
| inline bool HasShifterOperand(HInstruction* instr, InstructionSet isa) { |
| // On ARM64 `neg` instructions are an alias of `sub` using the zero register |
| // as the first register input. |
| bool res = instr->IsAdd() || instr->IsAnd() || |
| (isa == InstructionSet::kArm64 && instr->IsNeg()) || |
| instr->IsOr() || instr->IsSub() || instr->IsXor(); |
| return res; |
| } |
| |
| // Check the specified sub is the last operation of the sequence: |
| // t1 = Shl |
| // t2 = Sub(t1, *) |
| // t3 = Sub(*, t2) |
| inline bool IsSubRightSubLeftShl(HSub *sub) { |
| HInstruction* right = sub->GetRight(); |
| return right->IsSub() && right->AsSub()->GetLeft()->IsShl();; |
| } |
| |
| } // namespace helpers |
| |
| bool TryCombineMultiplyAccumulate(HMul* mul, InstructionSet isa); |
| // For bitwise operations (And/Or/Xor) with a negated input, try to use |
| // a negated bitwise instruction. |
| bool TryMergeNegatedInput(HBinaryOperation* op); |
| |
| bool TryExtractArrayAccessAddress(HInstruction* access, |
| HInstruction* array, |
| HInstruction* index, |
| size_t data_offset); |
| |
| bool TryExtractVecArrayAccessAddress(HVecMemoryOperation* access, HInstruction* index); |
| |
| // Try to replace |
| // Sub(c, Sub(a, b)) |
| // with |
| // Add(c, Sub(b, a)) |
| bool TryReplaceSubSubWithSubAdd(HSub* last_sub); |
| |
| } // namespace art |
| |
| #endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_SHARED_H_ |