diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/constant_folding.cc | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc index e20d9e83e6..5506604e9e 100644 --- a/compiler/optimizing/constant_folding.cc +++ b/compiler/optimizing/constant_folding.cc @@ -19,6 +19,7 @@ #include <algorithm> #include "dex/dex_file-inl.h" +#include "intrinsics_enum.h" #include "optimizing/data_type.h" #include "optimizing/nodes.h" @@ -47,10 +48,15 @@ class HConstantFoldingVisitor final : public HGraphDelegateVisitor { void VisitArrayLength(HArrayLength* inst) override; void VisitDivZeroCheck(HDivZeroCheck* inst) override; void VisitIf(HIf* inst) override; + void VisitInvoke(HInvoke* inst) override; void VisitTypeConversion(HTypeConversion* inst) override; void PropagateValue(HBasicBlock* starting_block, HInstruction* variable, HConstant* constant); + // Intrinsics foldings + void FoldNumberOfLeadingZerosIntrinsic(HInvoke* invoke); + void FoldNumberOfTrailingZerosIntrinsic(HInvoke* invoke); + // Use all optimizations without restrictions. bool use_all_optimizations_; @@ -350,6 +356,63 @@ void HConstantFoldingVisitor::VisitIf(HIf* inst) { } } +void HConstantFoldingVisitor::VisitInvoke(HInvoke* inst) { + switch (inst->GetIntrinsic()) { + case Intrinsics::kIntegerNumberOfLeadingZeros: + case Intrinsics::kLongNumberOfLeadingZeros: + FoldNumberOfLeadingZerosIntrinsic(inst); + break; + case Intrinsics::kIntegerNumberOfTrailingZeros: + case Intrinsics::kLongNumberOfTrailingZeros: + FoldNumberOfTrailingZerosIntrinsic(inst); + break; + default: + break; + } +} + +void HConstantFoldingVisitor::FoldNumberOfLeadingZerosIntrinsic(HInvoke* inst) { + DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfLeadingZeros || + inst->GetIntrinsic() == Intrinsics::kLongNumberOfLeadingZeros); + + if (!inst->InputAt(0)->IsConstant()) { + return; + } + + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfLeadingZeros, + inst->InputAt(0)->IsIntConstant()); + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kLongNumberOfLeadingZeros, + inst->InputAt(0)->IsLongConstant()); + + // Note that both the Integer and Long intrinsics return an int as a result. + int result = inst->InputAt(0)->IsIntConstant() ? + JAVASTYLE_CLZ(inst->InputAt(0)->AsIntConstant()->GetValue()) : + JAVASTYLE_CLZ(inst->InputAt(0)->AsLongConstant()->GetValue()); + inst->ReplaceWith(GetGraph()->GetIntConstant(result)); + inst->GetBlock()->RemoveInstruction(inst); +} + +void HConstantFoldingVisitor::FoldNumberOfTrailingZerosIntrinsic(HInvoke* inst) { + DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfTrailingZeros || + inst->GetIntrinsic() == Intrinsics::kLongNumberOfTrailingZeros); + + if (!inst->InputAt(0)->IsConstant()) { + return; + } + + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfTrailingZeros, + inst->InputAt(0)->IsIntConstant()); + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kLongNumberOfTrailingZeros, + inst->InputAt(0)->IsLongConstant()); + + // Note that both the Integer and Long intrinsics return an int as a result. + int result = inst->InputAt(0)->IsIntConstant() ? + JAVASTYLE_CTZ(inst->InputAt(0)->AsIntConstant()->GetValue()) : + JAVASTYLE_CTZ(inst->InputAt(0)->AsLongConstant()->GetValue()); + inst->ReplaceWith(GetGraph()->GetIntConstant(result)); + inst->GetBlock()->RemoveInstruction(inst); +} + void HConstantFoldingVisitor::VisitArrayLength(HArrayLength* inst) { HInstruction* input = inst->InputAt(0); if (input->IsLoadString()) { |