blob: bd97c0b7150832df8bc4b787924da34d1541f280 [file] [log] [blame]
// Copyright (c) 2024, 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.optimize.argumentpropagation.codescanner;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.Lists;
public class InstanceFieldReadAbstractFunction implements AbstractFunction {
private final BaseInFlow receiver;
private final DexField field;
public InstanceFieldReadAbstractFunction(BaseInFlow receiver, DexField field) {
this.receiver = receiver;
this.field = field;
}
@Override
public ValueState apply(
AppView<AppInfoWithLiveness> appView,
FlowGraphStateProvider flowGraphStateProvider,
ConcreteValueState predecessorState) {
ValueState state = flowGraphStateProvider.getState(receiver, () -> ValueState.bottom(field));
if (state.isBottom()) {
return ValueState.bottom(field);
}
if (!state.isClassState()) {
return getFallbackState(flowGraphStateProvider);
}
ConcreteClassTypeValueState classState = state.asClassState();
if (classState.getNullability().isDefinitelyNull()) {
return ValueState.bottom(field);
}
AbstractValue abstractValue = state.getAbstractValue(null);
if (!abstractValue.hasObjectState()) {
return getFallbackState(flowGraphStateProvider);
}
AbstractValue fieldValue = abstractValue.getObjectState().getAbstractFieldValue(field);
if (fieldValue.isUnknown()) {
return getFallbackState(flowGraphStateProvider);
}
return ConcreteValueState.create(field.getType(), fieldValue);
}
@Override
public boolean containsBaseInFlow(BaseInFlow inFlow) {
return inFlow.equals(receiver) || inFlow.isFieldValue(field);
}
@Override
public Iterable<BaseInFlow> getBaseInFlow() {
return Lists.newArrayList(receiver, new FieldValue(field));
}
private ValueState getFallbackState(FlowGraphStateProvider flowGraphStateProvider) {
ValueState valueState = flowGraphStateProvider.getState(new FieldValue(field), null);
assert !valueState.isConcrete() || !valueState.asConcrete().hasInFlow();
return valueState;
}
@Override
public boolean isInstanceFieldReadAbstractFunction() {
return true;
}
@Override
public InstanceFieldReadAbstractFunction asInstanceFieldReadAbstractFunction() {
return this;
}
}