diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2015-04-27 08:53:46 +0000 |
---|---|---|
committer | Mark Mendell <mark.p.mendell@intel.com> | 2015-04-27 20:06:50 -0400 |
commit | 0d22184ec9e5b1e958c031ac92c7f053de3a13a2 (patch) | |
tree | 4055eda9986916dc86b39d023082a57e60c804f4 /compiler/optimizing/instruction_simplifier.cc | |
parent | 97c96f5aab22f75dd54089bdc194588a4b5a2e8d (diff) | |
download | art-0d22184ec9e5b1e958c031ac92c7f053de3a13a2.tar.gz art-0d22184ec9e5b1e958c031ac92c7f053de3a13a2.tar.bz2 art-0d22184ec9e5b1e958c031ac92c7f053de3a13a2.zip |
Revert "Revert "[optimizing] Replace FP divide by power of 2""
This reverts commit 067cae2c86627d2edcf01b918ee601774bc76aeb.
Change-Id: Iaaa8772500ea7d3dce6ae0829dc0dc3bbc9c14ca
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 2df7c166d8..e79d4f4bdc 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -377,15 +377,42 @@ void InstructionSimplifierVisitor::VisitDiv(HDiv* instruction) { return; } - if ((input_cst != nullptr) && input_cst->IsMinusOne() && - (Primitive::IsFloatingPointType(type) || Primitive::IsIntOrLongType(type))) { + if ((input_cst != nullptr) && input_cst->IsMinusOne()) { // Replace code looking like // DIV dst, src, -1 // with // NEG dst, src instruction->GetBlock()->ReplaceAndRemoveInstructionWith( - instruction, (new (GetGraph()->GetArena()) HNeg(type, input_other))); + instruction, new (GetGraph()->GetArena()) HNeg(type, input_other)); RecordSimplification(); + return; + } + + if ((input_cst != nullptr) && Primitive::IsFloatingPointType(type)) { + // Try replacing code looking like + // DIV dst, src, constant + // with + // MUL dst, src, 1 / constant + HConstant* reciprocal = nullptr; + if (type == Primitive::Primitive::kPrimDouble) { + double value = input_cst->AsDoubleConstant()->GetValue(); + if (CanDivideByReciprocalMultiplyDouble(bit_cast<int64_t, double>(value))) { + reciprocal = GetGraph()->GetDoubleConstant(1.0 / value); + } + } else { + DCHECK_EQ(type, Primitive::kPrimFloat); + float value = input_cst->AsFloatConstant()->GetValue(); + if (CanDivideByReciprocalMultiplyFloat(bit_cast<int32_t, float>(value))) { + reciprocal = GetGraph()->GetFloatConstant(1.0f / value); + } + } + + if (reciprocal != nullptr) { + instruction->GetBlock()->ReplaceAndRemoveInstructionWith( + instruction, new (GetGraph()->GetArena()) HMul(type, input_other, reciprocal)); + RecordSimplification(); + return; + } } } |