summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2023-11-09 16:09:49 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2023-11-10 11:14:31 +0000
commit039154ecfaea7f7e61ba2bbcee8c0d77a57cd47d (patch)
treed30db24a126038f66e281c9076d992814d2c2511 /compiler/optimizing
parent7109d7fb2e2274c61d264afe3932c0e3e25f2477 (diff)
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
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/constant_folding.cc63
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()) {