summaryrefslogtreecommitdiff
path: root/compiler/optimizing/constant_folding.cc
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2023-11-10 11:13:53 +0000
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2023-11-13 11:45:29 +0000
commit0d3cf53ae0d400f7850d96798116dd3d4b963530 (patch)
tree2a2a5a46320f0e8b697412ffe8150c681fb150fe /compiler/optimizing/constant_folding.cc
parentd79f980d213c135b1171bd2d20bbc0ff0842badc (diff)
Constant fold Highest/LowestOneBit
Bug: 309886589 Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing Change-Id: I64b8889bcef2e4c65d85bffec560f4078a17648c
Diffstat (limited to 'compiler/optimizing/constant_folding.cc')
-rw-r--r--compiler/optimizing/constant_folding.cc80
1 files changed, 68 insertions, 12 deletions
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc
index 5506604e9e..686ecf08d2 100644
--- a/compiler/optimizing/constant_folding.cc
+++ b/compiler/optimizing/constant_folding.cc
@@ -18,6 +18,8 @@
#include <algorithm>
+#include "base/bit_utils.h"
+#include "base/logging.h"
#include "dex/dex_file-inl.h"
#include "intrinsics_enum.h"
#include "optimizing/data_type.h"
@@ -54,6 +56,8 @@ class HConstantFoldingVisitor final : public HGraphDelegateVisitor {
void PropagateValue(HBasicBlock* starting_block, HInstruction* variable, HConstant* constant);
// Intrinsics foldings
+ void FoldHighestOneBitIntrinsic(HInvoke* invoke);
+ void FoldLowestOneBitIntrinsic(HInvoke* invoke);
void FoldNumberOfLeadingZerosIntrinsic(HInvoke* invoke);
void FoldNumberOfTrailingZerosIntrinsic(HInvoke* invoke);
@@ -358,6 +362,14 @@ void HConstantFoldingVisitor::VisitIf(HIf* inst) {
void HConstantFoldingVisitor::VisitInvoke(HInvoke* inst) {
switch (inst->GetIntrinsic()) {
+ case Intrinsics::kIntegerHighestOneBit:
+ case Intrinsics::kLongHighestOneBit:
+ FoldHighestOneBitIntrinsic(inst);
+ break;
+ case Intrinsics::kIntegerLowestOneBit:
+ case Intrinsics::kLongLowestOneBit:
+ FoldLowestOneBitIntrinsic(inst);
+ break;
case Intrinsics::kIntegerNumberOfLeadingZeros:
case Intrinsics::kLongNumberOfLeadingZeros:
FoldNumberOfLeadingZerosIntrinsic(inst);
@@ -371,23 +383,67 @@ void HConstantFoldingVisitor::VisitInvoke(HInvoke* inst) {
}
}
+void HConstantFoldingVisitor::FoldHighestOneBitIntrinsic(HInvoke* inst) {
+ DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerHighestOneBit ||
+ inst->GetIntrinsic() == Intrinsics::kLongHighestOneBit);
+
+ HInstruction* input = inst->InputAt(0);
+ if (!input->IsConstant()) {
+ return;
+ }
+
+ // Integer and Long intrinsics have different return types.
+ if (inst->GetIntrinsic() == Intrinsics::kIntegerHighestOneBit) {
+ DCHECK(input->IsIntConstant());
+ inst->ReplaceWith(
+ GetGraph()->GetIntConstant(HighestOneBitValue(input->AsIntConstant()->GetValue())));
+ } else {
+ DCHECK(input->IsLongConstant());
+ inst->ReplaceWith(
+ GetGraph()->GetLongConstant(HighestOneBitValue(input->AsLongConstant()->GetValue())));
+ }
+ inst->GetBlock()->RemoveInstruction(inst);
+}
+
+void HConstantFoldingVisitor::FoldLowestOneBitIntrinsic(HInvoke* inst) {
+ DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerLowestOneBit ||
+ inst->GetIntrinsic() == Intrinsics::kLongLowestOneBit);
+
+ HInstruction* input = inst->InputAt(0);
+ if (!input->IsConstant()) {
+ return;
+ }
+
+ // Integer and Long intrinsics have different return types.
+ if (inst->GetIntrinsic() == Intrinsics::kIntegerLowestOneBit) {
+ DCHECK(input->IsIntConstant());
+ inst->ReplaceWith(
+ GetGraph()->GetIntConstant(LowestOneBitValue(input->AsIntConstant()->GetValue())));
+ } else {
+ DCHECK(input->IsLongConstant());
+ inst->ReplaceWith(
+ GetGraph()->GetLongConstant(LowestOneBitValue(input->AsLongConstant()->GetValue())));
+ }
+ inst->GetBlock()->RemoveInstruction(inst);
+}
+
void HConstantFoldingVisitor::FoldNumberOfLeadingZerosIntrinsic(HInvoke* inst) {
DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfLeadingZeros ||
inst->GetIntrinsic() == Intrinsics::kLongNumberOfLeadingZeros);
- if (!inst->InputAt(0)->IsConstant()) {
+ HInstruction* input = inst->InputAt(0);
+ if (!input->IsConstant()) {
return;
}
DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfLeadingZeros,
- inst->InputAt(0)->IsIntConstant());
+ input->IsIntConstant());
DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kLongNumberOfLeadingZeros,
- inst->InputAt(0)->IsLongConstant());
+ input->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());
+ int result = input->IsIntConstant() ? JAVASTYLE_CLZ(input->AsIntConstant()->GetValue()) :
+ JAVASTYLE_CLZ(input->AsLongConstant()->GetValue());
inst->ReplaceWith(GetGraph()->GetIntConstant(result));
inst->GetBlock()->RemoveInstruction(inst);
}
@@ -396,19 +452,19 @@ void HConstantFoldingVisitor::FoldNumberOfTrailingZerosIntrinsic(HInvoke* inst)
DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfTrailingZeros ||
inst->GetIntrinsic() == Intrinsics::kLongNumberOfTrailingZeros);
- if (!inst->InputAt(0)->IsConstant()) {
+ HInstruction* input = inst->InputAt(0);
+ if (!input->IsConstant()) {
return;
}
DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfTrailingZeros,
- inst->InputAt(0)->IsIntConstant());
+ input->IsIntConstant());
DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kLongNumberOfTrailingZeros,
- inst->InputAt(0)->IsLongConstant());
+ input->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());
+ int result = input->IsIntConstant() ? JAVASTYLE_CTZ(input->AsIntConstant()->GetValue()) :
+ JAVASTYLE_CTZ(input->AsLongConstant()->GetValue());
inst->ReplaceWith(GetGraph()->GetIntConstant(result));
inst->GetBlock()->RemoveInstruction(inst);
}