summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/constant_folding.cc25
1 files changed, 25 insertions, 0 deletions
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc
index e2bfffb8ec..29f5d5caee 100644
--- a/compiler/optimizing/constant_folding.cc
+++ b/compiler/optimizing/constant_folding.cc
@@ -59,6 +59,7 @@ class HConstantFoldingVisitor final : public HGraphDelegateVisitor {
// Intrinsics foldings
void FoldReverseIntrinsic(HInvoke* invoke);
void FoldReverseBytesIntrinsic(HInvoke* invoke);
+ void FoldBitCountIntrinsic(HInvoke* invoke);
void FoldHighestOneBitIntrinsic(HInvoke* invoke);
void FoldLowestOneBitIntrinsic(HInvoke* invoke);
void FoldNumberOfLeadingZerosIntrinsic(HInvoke* invoke);
@@ -374,6 +375,10 @@ void HConstantFoldingVisitor::VisitInvoke(HInvoke* inst) {
case Intrinsics::kShortReverseBytes:
FoldReverseBytesIntrinsic(inst);
break;
+ case Intrinsics::kIntegerBitCount:
+ case Intrinsics::kLongBitCount:
+ FoldBitCountIntrinsic(inst);
+ break;
case Intrinsics::kIntegerHighestOneBit:
case Intrinsics::kLongHighestOneBit:
FoldHighestOneBitIntrinsic(inst);
@@ -442,6 +447,26 @@ void HConstantFoldingVisitor::FoldReverseBytesIntrinsic(HInvoke* inst) {
inst->GetBlock()->RemoveInstruction(inst);
}
+void HConstantFoldingVisitor::FoldBitCountIntrinsic(HInvoke* inst) {
+ DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerBitCount ||
+ inst->GetIntrinsic() == Intrinsics::kLongBitCount);
+
+ HInstruction* input = inst->InputAt(0);
+ if (!input->IsConstant()) {
+ return;
+ }
+
+ DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kIntegerBitCount, input->IsIntConstant());
+ DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kLongBitCount, input->IsLongConstant());
+
+ // Note that both the Integer and Long intrinsics return an int as a result.
+ int result = inst->GetIntrinsic() == Intrinsics::kIntegerBitCount ?
+ POPCOUNT(input->AsIntConstant()->GetValue()) :
+ POPCOUNT(input->AsLongConstant()->GetValue());
+ inst->ReplaceWith(GetGraph()->GetIntConstant(result));
+ inst->GetBlock()->RemoveInstruction(inst);
+}
+
void HConstantFoldingVisitor::FoldHighestOneBitIntrinsic(HInvoke* inst) {
DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerHighestOneBit ||
inst->GetIntrinsic() == Intrinsics::kLongHighestOneBit);