diff options
Diffstat (limited to 'compiler/optimizing/instruction_simplifier_shared.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier_shared.cc | 30 |
1 files changed, 30 insertions, 0 deletions
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, |