From 1fde65ece2163c459069a8f3a42bd2663994c88c Mon Sep 17 00:00:00 2001 From: Santiago Aboy Solanes Date: Mon, 13 Nov 2023 16:40:52 +0000 Subject: Constant fold Reverse/ReverseBytes Bug: 309886589 Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing Change-Id: Ibdf60f579b44b5d2609e0e89b98a41dd0a8b7a89 --- compiler/optimizing/constant_folding.cc | 59 +++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'compiler/optimizing/constant_folding.cc') 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 #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(input->AsIntConstant()->GetValue())))); + } + inst->GetBlock()->RemoveInstruction(inst); +} + void HConstantFoldingVisitor::FoldHighestOneBitIntrinsic(HInvoke* inst) { DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerHighestOneBit || inst->GetIntrinsic() == Intrinsics::kLongHighestOneBit); -- cgit v1.2.3-59-g8ed1b