blob: 2258b2784d3cea07ecccc61962ca6521ff79f8c7 [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.ir.optimize;
import static com.android.tools.r8.utils.ConsumerUtils.emptyConsumer;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Value;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class AffectedValues implements Set<Value> {
private static final AffectedValues EMPTY = new AffectedValues(ImmutableSet.of());
private final Set<Value> affectedValues;
public AffectedValues() {
this(Sets.newIdentityHashSet());
}
private AffectedValues(Set<Value> affectedValues) {
this.affectedValues = affectedValues;
}
public static AffectedValues empty() {
return EMPTY;
}
public void narrowingWithAssumeRemoval(AppView<?> appView, IRCode code) {
narrowingWithAssumeRemoval(appView, code, emptyConsumer());
}
public void narrowingWithAssumeRemoval(
AppView<?> appView, IRCode code, Consumer<TypeAnalysis> typeAnalysisConsumer) {
if (hasNext()) {
TypeAnalysis typeAnalysis = new TypeAnalysis(appView, code);
typeAnalysisConsumer.accept(typeAnalysis);
typeAnalysis.narrowingWithAssumeRemoval(this);
clear();
}
}
public void propagateWithAssumeRemoval(
AppView<?> appView, IRCode code, Consumer<TypeAnalysis> typeAnalysisConsumer) {
if (hasNext()) {
TypeAnalysis typeAnalysis = new TypeAnalysis(appView, code);
typeAnalysisConsumer.accept(typeAnalysis);
typeAnalysis.propagateWithAssumeRemoval(this);
clear();
}
}
public void widening(AppView<?> appView, IRCode code) {
if (hasNext()) {
new TypeAnalysis(appView, code).widening(this);
}
}
@Override
public boolean add(Value value) {
return affectedValues.add(value);
}
@Override
public boolean addAll(Collection<? extends Value> c) {
return affectedValues.addAll(c);
}
public void addLiveAffectedValuesOf(Value value, Predicate<BasicBlock> removedBlocks) {
for (Value affectedValue : value.affectedValues()) {
if (affectedValue.hasBlock() && !removedBlocks.test(affectedValue.getBlock())) {
add(affectedValue);
}
}
}
@Override
public void clear() {
affectedValues.clear();
}
@Override
public boolean contains(Object o) {
return affectedValues.contains(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return affectedValues.containsAll(c);
}
public boolean hasNext() {
return !isEmpty();
}
@Override
public boolean isEmpty() {
return affectedValues.isEmpty();
}
@Override
public Iterator<Value> iterator() {
return affectedValues.iterator();
}
@Override
public boolean remove(Object o) {
return affectedValues.remove(o);
}
@Override
public boolean removeAll(Collection<?> c) {
return affectedValues.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
return affectedValues.retainAll(c);
}
@Override
public int size() {
return affectedValues.size();
}
@Override
public Object[] toArray() {
return affectedValues.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return affectedValues.toArray(a);
}
}