| // Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| package com.android.tools.r8.horizontalclassmerging; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| |
| /** |
| * The super class of all horizontal class merging policies. Most classes will either implement |
| * {@link SingleClassPolicy} or {@link MultiClassPolicy}. |
| */ |
| public abstract class Policy { |
| |
| /** Counter keeping track of how many classes this policy has removed. For debugging only. */ |
| public int numberOfRemovedClasses; |
| |
| public int numberOfRemovedInterfaces; |
| |
| public void clear() {} |
| |
| public abstract String getName(); |
| |
| public boolean isIdentityForInterfaceGroups() { |
| return false; |
| } |
| |
| public boolean isSingleClassPolicy() { |
| return false; |
| } |
| |
| public SingleClassPolicy asSingleClassPolicy() { |
| return null; |
| } |
| |
| public boolean isMultiClassPolicy() { |
| return false; |
| } |
| |
| public MultiClassPolicy asMultiClassPolicy() { |
| return null; |
| } |
| |
| public boolean isMultiClassPolicyWithPreprocessing() { |
| return false; |
| } |
| |
| public MultiClassPolicyWithPreprocessing<?> asMultiClassPolicyWithPreprocessing() { |
| return null; |
| } |
| |
| public boolean shouldSkipPolicy() { |
| return false; |
| } |
| |
| /** |
| * Remove all groups containing no or only a single class, as there is no point in merging these. |
| */ |
| protected Collection<MergeGroup> removeTrivialGroups(Collection<MergeGroup> groups) { |
| assert !(groups instanceof ArrayList); |
| groups.removeIf(MergeGroup::isTrivial); |
| return groups; |
| } |
| |
| boolean recordRemovedClassesForDebugging( |
| boolean isInterfaceGroup, int previousGroupSize, Collection<MergeGroup> newGroups) { |
| assert previousGroupSize >= 2; |
| int previousNumberOfRemovedClasses = previousGroupSize - 1; |
| int newNumberOfRemovedClasses = 0; |
| for (MergeGroup newGroup : newGroups) { |
| if (newGroup.isNonTrivial()) { |
| newNumberOfRemovedClasses += newGroup.size() - 1; |
| } |
| } |
| assert previousNumberOfRemovedClasses >= newNumberOfRemovedClasses; |
| int change = previousNumberOfRemovedClasses - newNumberOfRemovedClasses; |
| if (isInterfaceGroup) { |
| numberOfRemovedInterfaces += change; |
| } else { |
| numberOfRemovedClasses += change; |
| } |
| return true; |
| } |
| } |