summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2023-11-13 16:40:52 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2023-11-15 14:10:36 +0000
commit1fde65ece2163c459069a8f3a42bd2663994c88c (patch)
tree596d52ac52354eef1e52d9e5f684d11c54d2d436 /compiler/optimizing
parent9d2e5d7ec5af45b40e59aaa021bb577fb4ecfff1 (diff)
Constant fold Reverse/ReverseBytes
Bug: 309886589 Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing Change-Id: Ibdf60f579b44b5d2609e0e89b98a41dd0a8b7a89
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/constant_folding.cc59
1 files changed, 59 insertions, 0 deletions
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc
index 686ecf08d2..e2bfffb8ec 100644
--- a/compiler/optimizing/constant_folding.cc
+++ b/compiler/optimizing/constant_folding.cc
@@ -19,6 +19,7 @@
#include <algorithm>
#include "base/bit_utils.h"
+#include "base/casts.h"
#include "base/logging.h"
#include "dex/dex_file-inl.h"
#include "intrinsics_enum.h"
@@ -56,6 +57,8 @@ class HConstantFoldingVisitor final : public HGraphDelegateVisitor {
void PropagateValue(HBasicBlock* starting_block, HInstruction* variable, HConstant* constant);
// Intrinsics foldings
+ void FoldReverseIntrinsic(HInvoke* invoke);
+ void FoldReverseBytesIntrinsic(HInvoke* invoke);
void FoldHighestOneBitIntrinsic(HInvoke* invoke);
void FoldLowestOneBitIntrinsic(HInvoke* invoke);
void FoldNumberOfLeadingZerosIntrinsic(HInvoke* invoke);
@@ -362,6 +365,15 @@ void HConstantFoldingVisitor::VisitIf(HIf* inst) {
void HConstantFoldingVisitor::VisitInvoke(HInvoke* inst) {
switch (inst->GetIntrinsic()) {
+ case Intrinsics::kIntegerReverse:
+ case Intrinsics::kLongReverse:
+ FoldReverseIntrinsic(inst);
+ break;
+ case Intrinsics::kIntegerReverseBytes:
+ case Intrinsics::kLongReverseBytes:
+ case Intrinsics::kShortReverseBytes:
+ FoldReverseBytesIntrinsic(inst);
+ break;
case Intrinsics::kIntegerHighestOneBit:
case Intrinsics::kLongHighestOneBit:
FoldHighestOneBitIntrinsic(inst);
@@ -383,6 +395,53 @@ void HConstantFoldingVisitor::VisitInvoke(HInvoke* inst) {
}
}
+void HConstantFoldingVisitor::FoldReverseIntrinsic(HInvoke* inst) {
+ DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerReverse ||
+ inst->GetIntrinsic() == Intrinsics::kLongReverse);
+
+ HInstruction* input = inst->InputAt(0);
+ if (!input->IsConstant()) {
+ return;
+ }
+
+ // Integer and Long intrinsics have different return types.
+ if (inst->GetIntrinsic() == Intrinsics::kIntegerReverse) {
+ DCHECK(input->IsIntConstant());
+ inst->ReplaceWith(
+ GetGraph()->GetIntConstant(ReverseBits32(input->AsIntConstant()->GetValue())));
+ } else {
+ DCHECK(input->IsLongConstant());
+ inst->ReplaceWith(
+ GetGraph()->GetLongConstant(ReverseBits64(input->AsLongConstant()->GetValue())));
+ }
+ inst->GetBlock()->RemoveInstruction(inst);
+}
+
+void HConstantFoldingVisitor::FoldReverseBytesIntrinsic(HInvoke* inst) {
+ DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerReverseBytes ||
+ inst->GetIntrinsic() == Intrinsics::kLongReverseBytes ||
+ inst->GetIntrinsic() == Intrinsics::kShortReverseBytes);
+
+ HInstruction* input = inst->InputAt(0);
+ if (!input->IsConstant()) {
+ return;
+ }
+
+ // Integer, Long, and Short intrinsics have different return types.
+ if (inst->GetIntrinsic() == Intrinsics::kIntegerReverseBytes) {
+ DCHECK(input->IsIntConstant());
+ inst->ReplaceWith(GetGraph()->GetIntConstant(BSWAP(input->AsIntConstant()->GetValue())));
+ } else if (inst->GetIntrinsic() == Intrinsics::kLongReverseBytes) {
+ DCHECK(input->IsLongConstant());
+ inst->ReplaceWith(GetGraph()->GetLongConstant(BSWAP(input->AsLongConstant()->GetValue())));
+ } else {
+ DCHECK(input->IsIntConstant());
+ inst->ReplaceWith(GetGraph()->GetIntConstant(
+ BSWAP(dchecked_integral_cast<int16_t>(input->AsIntConstant()->GetValue()))));
+ }
+ inst->GetBlock()->RemoveInstruction(inst);
+}
+
void HConstantFoldingVisitor::FoldHighestOneBitIntrinsic(HInvoke* inst) {
DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerHighestOneBit ||
inst->GetIntrinsic() == Intrinsics::kLongHighestOneBit);