summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier_shared.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/instruction_simplifier_shared.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier_shared.cc30
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,