diff options
author | 2023-11-13 16:40:52 +0000 | |
---|---|---|
committer | 2023-11-15 14:10:36 +0000 | |
commit | 1fde65ece2163c459069a8f3a42bd2663994c88c (patch) | |
tree | 596d52ac52354eef1e52d9e5f684d11c54d2d436 /compiler/optimizing/constant_folding.cc | |
parent | 9d2e5d7ec5af45b40e59aaa021bb577fb4ecfff1 (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/constant_folding.cc')
-rw-r--r-- | compiler/optimizing/constant_folding.cc | 59 |
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); |