diff options
Diffstat (limited to 'compiler')
4 files changed, 53 insertions, 2 deletions
diff --git a/compiler/optimizing/instruction_simplifier_arm.cc b/compiler/optimizing/instruction_simplifier_arm.cc index be4371f734..aefa27628b 100644 --- a/compiler/optimizing/instruction_simplifier_arm.cc +++ b/compiler/optimizing/instruction_simplifier_arm.cc @@ -278,9 +278,15 @@ void InstructionSimplifierArmVisitor::VisitSub(HSub* instruction) { if (IsSubRightSubLeftShl(instruction)) { HInstruction* shl = instruction->GetRight()->InputAt(0); if (shl->InputAt(1)->IsConstant() && TryReplaceSubSubWithSubAdd(instruction)) { - TryMergeIntoUsersShifterOperand(shl); + if (TryMergeIntoUsersShifterOperand(shl)) { + return; + } } } + + if (TryMergeWithAnd(instruction)) { + return; + } } void InstructionSimplifierArmVisitor::VisitTypeConversion(HTypeConversion* instruction) { diff --git a/compiler/optimizing/instruction_simplifier_arm64.cc b/compiler/optimizing/instruction_simplifier_arm64.cc index 2c191dc3f4..d0fbe1382b 100644 --- a/compiler/optimizing/instruction_simplifier_arm64.cc +++ b/compiler/optimizing/instruction_simplifier_arm64.cc @@ -249,9 +249,15 @@ void InstructionSimplifierArm64Visitor::VisitSub(HSub* instruction) { if (IsSubRightSubLeftShl(instruction)) { HInstruction* shl = instruction->GetRight()->InputAt(0); if (shl->InputAt(1)->IsConstant() && TryReplaceSubSubWithSubAdd(instruction)) { - TryMergeIntoUsersShifterOperand(shl); + if (TryMergeIntoUsersShifterOperand(shl)) { + return; + } } } + + if (TryMergeWithAnd(instruction)) { + return; + } } void InstructionSimplifierArm64Visitor::VisitTypeConversion(HTypeConversion* instruction) { diff --git a/compiler/optimizing/instruction_simplifier_shared.cc b/compiler/optimizing/instruction_simplifier_shared.cc index 50ea2b929b..deb8f93492 100644 --- a/compiler/optimizing/instruction_simplifier_shared.cc +++ b/compiler/optimizing/instruction_simplifier_shared.cc @@ -18,6 +18,7 @@ #include "code_generator.h" #include "mirror/array-inl.h" +#include "nodes.h" namespace art HIDDEN { @@ -229,6 +230,35 @@ bool TryMergeNegatedInput(HBinaryOperation* op) { return false; } +bool TryMergeWithAnd(HSub* instruction) { + HAnd* and_instr = instruction->GetRight()->AsAndOrNull(); + if (and_instr == nullptr) { + return false; + } + + HInstruction* value = instruction->GetLeft(); + + HInstruction* left = and_instr->GetLeft(); + const bool left_is_equal = left == value; + HInstruction* right = and_instr->GetRight(); + const bool right_is_equal = right == value; + if (!left_is_equal && !right_is_equal) { + return false; + } + + HBitwiseNegatedRight* bnr = new (instruction->GetBlock()->GetGraph()->GetAllocator()) + HBitwiseNegatedRight(instruction->GetType(), + HInstruction::InstructionKind::kAnd, + value, + left_is_equal ? right : left, + instruction->GetDexPc()); + instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, bnr); + // Since we don't run DCE after this phase, try to manually remove the And instruction. + if (!and_instr->HasUses()) { + and_instr->GetBlock()->RemoveInstruction(and_instr); + } + return true; +} bool TryExtractArrayAccessAddress(CodeGenerator* codegen, HInstruction* access, diff --git a/compiler/optimizing/instruction_simplifier_shared.h b/compiler/optimizing/instruction_simplifier_shared.h index 68148cff7e..ca6d5286c5 100644 --- a/compiler/optimizing/instruction_simplifier_shared.h +++ b/compiler/optimizing/instruction_simplifier_shared.h @@ -66,6 +66,15 @@ bool TryCombineMultiplyAccumulate(HMul* mul, InstructionSet isa); // a negated bitwise instruction. bool TryMergeNegatedInput(HBinaryOperation* op); +// Convert +// i1: AND a, b +// SUB a, i1 +// into: +// BIC a, a, b +// +// It also works if `i1` is AND b, a +bool TryMergeWithAnd(HSub* instruction); + bool TryExtractArrayAccessAddress(CodeGenerator* codegen, HInstruction* access, HInstruction* array, |