diff options
author | 2015-11-17 11:16:56 -0500 | |
---|---|---|
committer | 2015-11-20 16:48:04 +0000 | |
commit | f652917de5634b30c974c81d35a72871915b352a (patch) | |
tree | c50bcaf37c246df633d42a166334c9b6332e5394 /compiler/optimizing/nodes.cc | |
parent | 60c4c6ad2b892bb00a6016a147b1cc089ba6bcb5 (diff) |
Simplify boolean condition compared to 0
CaffeineMarkRR Logic has some boolean flipping which can be helped by
some simplification.
Simplify non-FP (A COND_OP B) != 0 to A OPPOSITE_COND_OP B.
This is better than the original code, which would use a HBooleanNot
after the condition.
Also simplify non-FP (A COND_OP B) == 1 to A OPPOSITE_COND_OP B.
Move GetOppositeCondition to nodes.h/nodes.cc to share with Boolean
Simplification, renaming it to InsertOppositeCondition, as it inserts
the new HInstruction (unless it is a constant).
Change-Id: I34ded7758836e375de0d6fdba9239d2d451928d0
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 0a39ff31bf..1680c07776 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2090,4 +2090,43 @@ void HInstruction::RemoveEnvironmentUsers() { env_uses_.Clear(); } +// Returns an instruction with the opposite boolean value from 'cond'. +HInstruction* HGraph::InsertOppositeCondition(HInstruction* cond, HInstruction* cursor) { + ArenaAllocator* allocator = GetArena(); + + if (cond->IsCondition() && + !Primitive::IsFloatingPointType(cond->InputAt(0)->GetType())) { + // Can't reverse floating point conditions. We have to use HBooleanNot in that case. + HInstruction* lhs = cond->InputAt(0); + HInstruction* rhs = cond->InputAt(1); + HInstruction* replacement; + switch (cond->AsCondition()->GetOppositeCondition()) { // get *opposite* + case kCondEQ: replacement = new (allocator) HEqual(lhs, rhs); break; + case kCondNE: replacement = new (allocator) HNotEqual(lhs, rhs); break; + case kCondLT: replacement = new (allocator) HLessThan(lhs, rhs); break; + case kCondLE: replacement = new (allocator) HLessThanOrEqual(lhs, rhs); break; + case kCondGT: replacement = new (allocator) HGreaterThan(lhs, rhs); break; + case kCondGE: replacement = new (allocator) HGreaterThanOrEqual(lhs, rhs); break; + case kCondB: replacement = new (allocator) HBelow(lhs, rhs); break; + case kCondBE: replacement = new (allocator) HBelowOrEqual(lhs, rhs); break; + case kCondA: replacement = new (allocator) HAbove(lhs, rhs); break; + case kCondAE: replacement = new (allocator) HAboveOrEqual(lhs, rhs); break; + } + cursor->GetBlock()->InsertInstructionBefore(replacement, cursor); + return replacement; + } else if (cond->IsIntConstant()) { + HIntConstant* int_const = cond->AsIntConstant(); + if (int_const->IsZero()) { + return GetIntConstant(1); + } else { + DCHECK(int_const->IsOne()); + return GetIntConstant(0); + } + } else { + HInstruction* replacement = new (allocator) HBooleanNot(cond); + cursor->GetBlock()->InsertInstructionBefore(replacement, cursor); + return replacement; + } +} + } // namespace art |