blob: ca1223f9dba9caec03c781a8c408a13f803d143a [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.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.SingleNumberValue;
import com.android.tools.r8.ir.analysis.value.arithmetic.AbstractCalculator;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.IterableUtils;
import java.util.Objects;
/**
* Encodes the `x | const` abstract function. This is currently used as part of the modeling of
* updateChangedFlags, since the updateChangedFlags function is invoked with `changedFlags | 1` as
* an argument.
*/
public class OrAbstractFunction implements AbstractFunction {
public final BaseInFlow inFlow;
public final SingleNumberValue constant;
public OrAbstractFunction(BaseInFlow inFlow, SingleNumberValue constant) {
this.inFlow = inFlow;
this.constant = constant;
}
@Override
public ValueState apply(
AppView<AppInfoWithLiveness> appView,
FlowGraphStateProvider flowGraphStateProvider,
ConcreteValueState inState) {
ConcretePrimitiveTypeValueState inPrimitiveState = inState.asPrimitiveState();
AbstractValue result =
AbstractCalculator.orIntegers(appView, inPrimitiveState.getAbstractValue(), constant);
return ConcretePrimitiveTypeValueState.create(result, inPrimitiveState.copyInFlow());
}
@Override
public boolean containsBaseInFlow(BaseInFlow otherInFlow) {
if (inFlow.isAbstractFunction()) {
return inFlow.asAbstractFunction().containsBaseInFlow(otherInFlow);
}
assert inFlow.isBaseInFlow();
return inFlow.equals(otherInFlow);
}
@Override
public Iterable<BaseInFlow> getBaseInFlow() {
if (inFlow.isAbstractFunction()) {
return inFlow.asAbstractFunction().getBaseInFlow();
}
return IterableUtils.singleton(inFlow);
}
@Override
@SuppressWarnings("EqualsGetClass")
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
OrAbstractFunction fn = (OrAbstractFunction) obj;
return inFlow.equals(fn.inFlow) && constant.equals(fn.constant);
}
@Override
public int hashCode() {
return Objects.hash(getClass(), inFlow, constant);
}
}