blob: be9f7874fb87797918b8302a12993489ed24d247 [file] [log] [blame]
// Copyright (c) 2023, 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 com.android.tools.r8.classmerging.Policy;
import com.android.tools.r8.classmerging.PolicyExecutor;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
public class HorizontalClassMergerPolicyExecutor extends PolicyExecutor<HorizontalMergeGroup> {
@Override
protected LinkedList<HorizontalMergeGroup> apply(
Policy policy, LinkedList<HorizontalMergeGroup> linkedGroups, ExecutorService executorService)
throws ExecutionException {
if (policy.isSingleClassPolicy()) {
applySingleClassPolicy(policy.asSingleClassPolicy(), linkedGroups);
} else {
if (policy.isMultiClassPolicy()) {
linkedGroups = applyMultiClassPolicy(policy.asMultiClassPolicy(), linkedGroups);
} else {
assert policy.isMultiClassPolicyWithPreprocessing();
linkedGroups =
applyMultiClassPolicyWithPreprocessing(
policy.asMultiClassPolicyWithPreprocessing(), linkedGroups, executorService);
}
}
return linkedGroups;
}
void applySingleClassPolicy(SingleClassPolicy policy, LinkedList<HorizontalMergeGroup> groups) {
Iterator<HorizontalMergeGroup> i = groups.iterator();
while (i.hasNext()) {
HorizontalMergeGroup group = i.next();
boolean isInterfaceGroup = group.isInterfaceGroup();
int previousGroupSize = group.size();
group.removeIf(clazz -> !policy.canMerge(clazz));
assert policy.recordRemovedClassesForDebugging(
isInterfaceGroup, previousGroupSize, ImmutableList.of(group));
if (group.isTrivial()) {
i.remove();
}
}
}
// TODO(b/270398965): Replace LinkedList.
@SuppressWarnings("JdkObsolete")
private LinkedList<HorizontalMergeGroup> applyMultiClassPolicy(
MultiClassPolicy policy, LinkedList<HorizontalMergeGroup> groups) {
// For each group apply the multi class policy and add all the new groups together.
LinkedList<HorizontalMergeGroup> newGroups = new LinkedList<>();
groups.forEach(
group -> {
boolean isInterfaceGroup = group.isInterfaceGroup();
int previousGroupSize = group.size();
Collection<HorizontalMergeGroup> policyGroups = policy.apply(group);
policyGroups.forEach(newGroup -> newGroup.applyMetadataFrom(group));
assert policy.recordRemovedClassesForDebugging(
isInterfaceGroup, previousGroupSize, policyGroups);
newGroups.addAll(policyGroups);
});
return newGroups;
}
// TODO(b/270398965): Replace LinkedList.
@SuppressWarnings("JdkObsolete")
private <T> LinkedList<HorizontalMergeGroup> applyMultiClassPolicyWithPreprocessing(
MultiClassPolicyWithPreprocessing<T> policy,
LinkedList<HorizontalMergeGroup> groups,
ExecutorService executorService)
throws ExecutionException {
// For each group apply the multi class policy and add all the new groups together.
T data = policy.preprocess(groups, executorService);
LinkedList<HorizontalMergeGroup> newGroups = new LinkedList<>();
groups.forEach(
group -> {
boolean isInterfaceGroup = group.isInterfaceGroup();
int previousGroupSize = group.size();
Collection<HorizontalMergeGroup> policyGroups = policy.apply(group, data);
policyGroups.forEach(newGroup -> newGroup.applyMetadataFrom(group));
assert policy.recordRemovedClassesForDebugging(
isInterfaceGroup, previousGroupSize, policyGroups);
newGroups.addAll(policyGroups);
});
return newGroups;
}
}