From 039154ecfaea7f7e61ba2bbcee8c0d77a57cd47d Mon Sep 17 00:00:00 2001 From: Santiago Aboy Solanes Date: Thu, 9 Nov 2023 16:09:49 +0000 Subject: Constant fold NumberOfTrailing/LeadingZeros Recognize intrinsics in constant folding and optimize the invoke away if the value is known at compile time. Bug: 309886589 Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing Change-Id: I989af53c17f018eb6b3f790ee7d9d9e8255dfd41 --- compiler/optimizing/constant_folding.cc | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'compiler/optimizing/constant_folding.cc') 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 #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()) { -- cgit v1.2.3-59-g8ed1b