Merge "Towards using AppView globally"
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index a47351c..af3c140 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -436,7 +436,6 @@
application,
appViewWithLiveness,
executorService,
- options,
timing,
mainDexClasses);
appView.setGraphLense(verticalClassMerger.run());
diff --git a/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java b/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java
index 9effd30..5f198c0 100644
--- a/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java
@@ -7,6 +7,8 @@
import com.android.tools.r8.cf.TypeVerificationHelper.TypeInfo;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.DebugLocalWrite;
import com.android.tools.r8.ir.code.Dup;
@@ -56,8 +58,8 @@
*/
public class CfRegisterAllocator implements RegisterAllocator {
+ private final AppView<? extends AppInfo> appView;
private final IRCode code;
- private final InternalOptions options;
private final TypeVerificationHelper typeHelper;
// Mapping from basic blocks to the set of values live at entry to that basic block.
@@ -112,9 +114,9 @@
private int maxArgumentRegisterNumber = -1;
public CfRegisterAllocator(
- IRCode code, InternalOptions options, TypeVerificationHelper typeHelper) {
+ AppView<? extends AppInfo> appView, IRCode code, TypeVerificationHelper typeHelper) {
+ this.appView = appView;
this.code = code;
- this.options = options;
this.typeHelper = typeHelper;
}
@@ -143,7 +145,7 @@
@Override
public InternalOptions getOptions() {
- return options;
+ return appView.options();
}
@Override
@@ -155,7 +157,7 @@
// register allocation. We just treat the method as being in debug mode in order to keep
// locals alive for their entire live range. In release mode the liveness is all that matters
// and we do not actually want locals information in the output.
- if (options.debug) {
+ if (appView.options().debug) {
LinearScanRegisterAllocator.computeDebugInfo(blocks, liveIntervals, this, liveAtEntrySets);
}
}
@@ -176,7 +178,8 @@
private ImmutableList<BasicBlock> computeLivenessInformation() {
ImmutableList<BasicBlock> blocks = code.numberInstructions();
liveAtEntrySets = code.computeLiveAtEntrySets();
- LinearScanRegisterAllocator.computeLiveRanges(options, code, liveAtEntrySets, liveIntervals);
+ LinearScanRegisterAllocator.computeLiveRanges(
+ appView.options(), code, liveAtEntrySets, liveIntervals);
return blocks;
}
diff --git a/src/main/java/com/android/tools/r8/cf/LoadStoreHelper.java b/src/main/java/com/android/tools/r8/cf/LoadStoreHelper.java
index c5cb84e..9a73ab1 100644
--- a/src/main/java/com/android/tools/r8/cf/LoadStoreHelper.java
+++ b/src/main/java/com/android/tools/r8/cf/LoadStoreHelper.java
@@ -5,6 +5,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
@@ -31,17 +32,18 @@
public class LoadStoreHelper {
+ private final AppView<? extends AppInfo> appView;
private final IRCode code;
private final TypeVerificationHelper typesHelper;
- private final AppInfo appInfo;
private Map<Value, ConstInstruction> clonableConstants = null;
private ListIterator<BasicBlock> blockIterator = null;
- public LoadStoreHelper(IRCode code, TypeVerificationHelper typesHelper, AppInfo appInfo) {
+ public LoadStoreHelper(
+ AppView<? extends AppInfo> appView, IRCode code, TypeVerificationHelper typesHelper) {
+ this.appView = appView;
this.code = code;
this.typesHelper = typesHelper;
- this.appInfo = appInfo;
}
private static boolean hasLocalInfoOrUsersOutsideThisBlock(Value value, BasicBlock block) {
@@ -140,11 +142,11 @@
}
private StackValue createStackValue(Value value, int height) {
- return StackValue.create(typesHelper.getTypeInfo(value), height, appInfo);
+ return StackValue.create(typesHelper.getTypeInfo(value), height, appView);
}
private StackValue createStackValue(DexType type, int height) {
- return StackValue.create(typesHelper.createInitializedType(type), height, appInfo);
+ return StackValue.create(typesHelper.createInitializedType(type), height, appView);
}
public void loadInValues(Instruction instruction, InstructionListIterator it) {
diff --git a/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java b/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
index 2349a3b..4bf9e04 100644
--- a/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
+++ b/src/main/java/com/android/tools/r8/cf/TypeVerificationHelper.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
@@ -103,9 +104,8 @@
private final TypeInfo LONG;
private final TypeInfo DOUBLE;
+ private final AppView<? extends AppInfo> appView;
private final IRCode code;
- private final DexItemFactory factory;
- private final AppInfo appInfo;
private Map<Value, TypeInfo> types;
private Map<NewInstance, NewInstanceInfo> newInstanceInfos = new IdentityHashMap<>();
@@ -113,18 +113,15 @@
// Flag to indicate that we are computing types in the fixed point.
private boolean computingVerificationTypes = false;
- public TypeVerificationHelper(IRCode code, DexItemFactory factory, AppInfo appInfo) {
+ public TypeVerificationHelper(AppView<? extends AppInfo> appView, IRCode code) {
+ this.appView = appView;
this.code = code;
- this.factory = factory;
- this.appInfo = appInfo;
- INT = new InitializedTypeInfo(factory.intType);
- FLOAT = new InitializedTypeInfo(factory.floatType);
- LONG = new InitializedTypeInfo(factory.longType);
- DOUBLE = new InitializedTypeInfo(factory.doubleType);
- }
- public DexItemFactory getFactory() {
- return factory;
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
+ INT = new InitializedTypeInfo(dexItemFactory.intType);
+ FLOAT = new InitializedTypeInfo(dexItemFactory.floatType);
+ LONG = new InitializedTypeInfo(dexItemFactory.longType);
+ DOUBLE = new InitializedTypeInfo(dexItemFactory.doubleType);
}
public TypeInfo createInitializedType(DexType type) {
@@ -188,13 +185,13 @@
Iterator<DexType> iterator = types.iterator();
TypeLatticeElement result = getLatticeElement(iterator.next());
while (iterator.hasNext()) {
- result = result.join(getLatticeElement(iterator.next()), appInfo);
+ result = result.join(getLatticeElement(iterator.next()), appView.appInfo());
}
// All types are reference types so the join is either a class or an array.
if (result.isClassType()) {
return result.asClassTypeLatticeElement().getClassType();
} else if (result.isArrayType()) {
- return result.asArrayTypeLatticeElement().getArrayType(factory);
+ return result.asArrayTypeLatticeElement().getArrayType(appView.dexItemFactory());
}
throw new CompilationError("Unexpected join " + result + " of types: " +
String.join(", ",
@@ -220,7 +217,7 @@
}
private TypeLatticeElement getLatticeElement(DexType type) {
- return TypeLatticeElement.fromDexType(type, Nullability.maybeNull(), appInfo);
+ return TypeLatticeElement.fromDexType(type, Nullability.maybeNull(), appView.appInfo());
}
public Map<Value, TypeInfo> computeVerificationTypes() {
@@ -273,7 +270,7 @@
nullsUsedInPhis.add(instruction.asConstNumber());
}
}
- DexType type = instruction.computeVerificationType(this);
+ DexType type = instruction.computeVerificationType(appView, this);
types.put(outValue, createInitializedType(type));
addUsers(outValue, worklist);
}
@@ -316,7 +313,7 @@
private DexType computeVerificationType(Value value) {
return value.isPhi()
? value.asPhi().computeVerificationType(this)
- : value.definition.computeVerificationType(this);
+ : value.definition.computeVerificationType(appView, this);
}
private static void addUsers(Value value, Set<Value> worklist) {
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
index ec38ea9..0674bf2 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
@@ -33,6 +33,7 @@
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
Slot array = state.pop();
assert array.type.isObject();
- builder.addArrayLength(state.push(builder.getFactory().intType).register, array.register);
+ builder.addArrayLength(
+ state.push(builder.appView.dexItemFactory().intType).register, array.register);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
index 9f38741..e77a59e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -75,7 +75,7 @@
assert array.type.isObject();
ValueType memberType = ValueType.fromMemberType(type);
if (array.preciseType != null) {
- value = state.push(array.preciseType.toArrayElementType(builder.getFactory()));
+ value = state.push(array.preciseType.toArrayElementType(builder.appView.dexItemFactory()));
assert state.peek().type == memberType;
} else {
value = state.push(memberType);
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index 4da0b5c..6719e3f 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -74,6 +74,6 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
- builder.addConstClass(state.push(builder.getFactory().classType).register, type);
+ builder.addConstClass(state.push(builder.appView.dexItemFactory().classType).register, type);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
index c36bd57..7f23c58 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
@@ -50,6 +50,6 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
builder.addConstMethodHandle(
- state.push(builder.getFactory().methodHandleType).register, handle);
+ state.push(builder.appView.dexItemFactory().methodHandleType).register, handle);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
index ebbaf21..1d12726 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
@@ -49,6 +49,7 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
- builder.addConstMethodType(state.push(builder.getFactory().methodTypeType).register, type);
+ builder.addConstMethodType(
+ state.push(builder.appView.dexItemFactory().methodTypeType).register, type);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
index 0467fcd..30a3aaf 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
@@ -55,6 +55,7 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
- builder.addConstString(state.push(builder.getFactory().stringType).register, string);
+ builder.addConstString(
+ state.push(builder.appView.dexItemFactory().stringType).register, string);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
index 8ba58b7..9c0fee6 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
@@ -70,6 +70,7 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
- builder.addDexItemBasedConstString(state.push(builder.getFactory().stringType).register, item);
+ builder.addDexItemBasedConstString(
+ state.push(builder.appView.dexItemFactory().stringType).register, item);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
index 6a093df..cbfc0fb 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
@@ -48,6 +48,7 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
int value = state.pop().register;
- builder.addInstanceOf(state.push(builder.getFactory().booleanType).register, value, type);
+ builder.addInstanceOf(
+ state.push(builder.appView.dexItemFactory().booleanType).register, value, type);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index a84b916..c8749fe 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -113,7 +113,8 @@
}
case Opcodes.INVOKEVIRTUAL:
{
- canonicalMethod = builder.getFactory().polymorphicMethods.canonicalize(method);
+ canonicalMethod =
+ builder.appView.dexItemFactory().polymorphicMethods.canonicalize(method);
if (canonicalMethod == null) {
type = Type.VIRTUAL;
canonicalMethod = method;
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
index 0eed4a6..e2f7336 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.ir.conversion.CfState;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.utils.InternalOptions;
import org.objectweb.asm.MethodVisitor;
public class CfMultiANewArray extends CfInstruction {
@@ -53,7 +54,8 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
- if (!builder.isGeneratingClassFiles()) {
+ InternalOptions options = builder.appView.options();
+ if (options.isGeneratingDex()) {
// TODO(b/109789539): Implement this case (see JarSourceCode.buildPrelude()/buildPostlude()).
throw new Unimplemented("CfMultiANewArray to DEX backend");
}
diff --git a/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java b/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
index 630f25d..000e8e6 100644
--- a/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
+++ b/src/main/java/com/android/tools/r8/dex/ResourceAdapter.java
@@ -97,7 +97,7 @@
// Returns true for files in META-INF/services/ that are never used by the application.
public boolean shouldBeDeleted(DataEntryResource file) {
- if (appView != null && appView.appInfo().hasLiveness()) {
+ if (appView.appInfo().hasLiveness()) {
AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
if (file.getName().startsWith(AppServices.SERVICE_DIRECTORY_NAME)) {
String serviceName = file.getName().substring(AppServices.SERVICE_DIRECTORY_NAME.length());
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index 8690894..eee4acd 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -10,36 +10,34 @@
public class AppView<T extends AppInfo> implements DexDefinitionSupplier {
+ private enum WholeProgramOptimizations {
+ ON,
+ OFF
+ }
+
private T appInfo;
private AppServices appServices;
private final DexItemFactory dexItemFactory;
- private final boolean enableWholeProgramOptimizations;
+ private final WholeProgramOptimizations wholeProgramOptimizations;
private GraphLense graphLense;
private final InternalOptions options;
private VerticallyMergedClasses verticallyMergedClasses;
private AppView(
- T appInfo,
- boolean enableWholeProgramOptimizations,
- GraphLense graphLense,
- InternalOptions options) {
+ T appInfo, WholeProgramOptimizations wholeProgramOptimizations, InternalOptions options) {
this.appInfo = appInfo;
this.dexItemFactory = appInfo != null ? appInfo.dexItemFactory : null;
- this.enableWholeProgramOptimizations = enableWholeProgramOptimizations;
- this.graphLense = graphLense;
+ this.wholeProgramOptimizations = wholeProgramOptimizations;
+ this.graphLense = GraphLense.getIdentityLense();
this.options = options;
}
public static <T extends AppInfo> AppView<T> createForD8(T appInfo, InternalOptions options) {
- boolean enableWholeProgramOptimizations = false;
- return new AppView<>(
- appInfo, enableWholeProgramOptimizations, GraphLense.getIdentityLense(), options);
+ return new AppView<>(appInfo, WholeProgramOptimizations.OFF, options);
}
public static <T extends AppInfo> AppView<T> createForR8(T appInfo, InternalOptions options) {
- boolean enableWholeProgramOptimizations = true;
- return new AppView<>(
- appInfo, enableWholeProgramOptimizations, GraphLense.getIdentityLense(), options);
+ return new AppView<>(appInfo, WholeProgramOptimizations.ON, options);
}
public T appInfo() {
@@ -84,7 +82,7 @@
}
public boolean enableWholeProgramOptimizations() {
- return enableWholeProgramOptimizations;
+ return wholeProgramOptimizations == WholeProgramOptimizations.ON;
}
public GraphLense graphLense() {
@@ -116,7 +114,7 @@
private class AppViewWithLiveness extends AppView<AppInfoWithLiveness> {
private AppViewWithLiveness() {
- super(null, false, null, null);
+ super(null, null, null);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index 6abc3fd..344f79f 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -215,23 +215,16 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
- Origin origin) {
+ DexEncodedMethod encodedMethod, AppView<? extends AppInfo> appView, Origin origin) {
assert getOwner() == encodedMethod;
- return internalBuild(
- encodedMethod, encodedMethod, appInfo, graphLense, options, null, null, origin);
+ return internalBuild(encodedMethod, encodedMethod, appView, null, null, origin);
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
@@ -239,27 +232,18 @@
assert valueNumberGenerator != null;
assert callerPosition != null;
return internalBuild(
- context,
- encodedMethod,
- appInfo,
- graphLense,
- options,
- valueNumberGenerator,
- callerPosition,
- origin);
+ context, encodedMethod, appView, valueNumberGenerator, callerPosition, origin);
}
private IRCode internalBuild(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator generator,
Position callerPosition,
Origin origin) {
// TODO(b/109789541): Implement CF->IR->DEX for synchronized methods.
- if (options.isGeneratingDex() && encodedMethod.accessFlags.isSynchronized()) {
+ if (appView.options().isGeneratingDex() && encodedMethod.accessFlags.isSynchronized()) {
throw new Unimplemented(
"Converting CfCode to IR not supported for DEX output of synchronized methods.");
}
@@ -267,12 +251,11 @@
new CfSourceCode(
this,
encodedMethod,
- graphLense.getOriginalMethodSignature(encodedMethod.method),
+ appView.graphLense().getOriginalMethodSignature(encodedMethod.method),
callerPosition,
origin,
- options.getInternalOutputMode());
- return new IRBuilder(encodedMethod, appInfo, source, options, origin, generator, graphLense)
- .build(context);
+ appView.options().getInternalOutputMode());
+ return new IRBuilder(encodedMethod, appView, source, origin, generator).build(context);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/Code.java b/src/main/java/com/android/tools/r8/graph/Code.java
index 4962fac..728ec2e 100644
--- a/src/main/java/com/android/tools/r8/graph/Code.java
+++ b/src/main/java/com/android/tools/r8/graph/Code.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.ir.optimize.Outliner.OutlineCode;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.InternalOptions;
public abstract class Code extends CachedHashValueDexItem {
@@ -29,18 +28,12 @@
}
public abstract IRCode buildIR(
- DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
- Origin origin);
+ DexEncodedMethod encodedMethod, AppView<? extends AppInfo> appView, Origin origin);
public IRCode buildInliningIR(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index f5935d4..f303c74 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -542,12 +542,12 @@
return null;
}
- public boolean hasMissingSuperType(AppInfo appInfo) {
- if (superType != null && superType.isMissingOrHasMissingSuperType(appInfo)) {
+ public boolean hasMissingSuperType(DexDefinitionSupplier definitions) {
+ if (superType != null && superType.isMissingOrHasMissingSuperType(definitions)) {
return true;
}
for (DexType interfaceType : interfaces.values) {
- if (interfaceType.isMissingOrHasMissingSuperType(appInfo)) {
+ if (interfaceType.isMissingOrHasMissingSuperType(definitions)) {
return true;
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexCode.java b/src/main/java/com/android/tools/r8/graph/DexCode.java
index cea5e4d..c3b240a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -18,7 +18,6 @@
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.base.Strings;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
@@ -215,28 +214,16 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
- Origin origin) {
+ DexEncodedMethod encodedMethod, AppView<? extends AppInfo> appView, Origin origin) {
assert getOwner() == encodedMethod;
DexSourceCode source =
new DexSourceCode(
this,
encodedMethod,
- graphLense.getOriginalMethodSignature(encodedMethod.method),
- null,
- appInfo);
+ appView.graphLense().getOriginalMethodSignature(encodedMethod.method),
+ null);
IRBuilder builder =
- new IRBuilder(
- encodedMethod,
- appInfo,
- source,
- options,
- origin,
- new ValueNumberGenerator(),
- graphLense);
+ new IRBuilder(encodedMethod, appView, source, origin, new ValueNumberGenerator());
return builder.build(encodedMethod);
}
@@ -244,9 +231,7 @@
public IRCode buildInliningIR(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
@@ -255,12 +240,9 @@
new DexSourceCode(
this,
encodedMethod,
- graphLense.getOriginalMethodSignature(encodedMethod.method),
- callerPosition,
- appInfo);
- IRBuilder builder =
- new IRBuilder(
- encodedMethod, appInfo, source, options, origin, valueNumberGenerator, graphLense);
+ appView.graphLense().getOriginalMethodSignature(encodedMethod.method),
+ callerPosition);
+ IRBuilder builder = new IRBuilder(encodedMethod, appView, source, origin, valueNumberGenerator);
return builder.build(context);
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 46719ca..9fa16f1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -317,36 +317,20 @@
compilationState = CompilationState.NOT_PROCESSED;
}
- public IRCode buildIR(
- AppInfo appInfo, GraphLense graphLense, InternalOptions options, Origin origin) {
+ public IRCode buildIR(AppView<? extends AppInfo> appView, Origin origin) {
checkIfObsolete();
- return code == null ? null : code.buildIR(this, appInfo, graphLense, options, origin);
- }
-
- public IRCode buildInliningIRForTesting(
- InternalOptions options, ValueNumberGenerator valueNumberGenerator, AppInfo appInfo) {
- checkIfObsolete();
- return buildInliningIR(
- this,
- appInfo,
- GraphLense.getIdentityLense(),
- options,
- valueNumberGenerator,
- null,
- Origin.unknown());
+ return code == null ? null : code.buildIR(this, appView, origin);
}
public IRCode buildInliningIR(
DexEncodedMethod context,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
checkIfObsolete();
return code.buildInliningIR(
- context, this, appInfo, graphLense, options, valueNumberGenerator, callerPosition, origin);
+ context, this, appView, valueNumberGenerator, callerPosition, origin);
}
public void setCode(Code code) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index 035b472..5ef8072 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -1065,7 +1065,7 @@
}
public ReferenceTypeLatticeElement createReferenceTypeLatticeElement(
- DexType type, Nullability nullability, AppInfo appInfo) {
+ DexType type, Nullability nullability, DexDefinitionSupplier definitions) {
ReferenceTypeLatticeElement primary = referenceTypeLatticeElements.get(type);
if (primary != null) {
return nullability == primary.nullability()
@@ -1083,13 +1083,13 @@
// It is expensive to walk through type hierarchy; collect implemented interfaces; and
// compute the least upper bound of two interface sets. Hence, lazy computations.
// Most likely during lattice join. See {@link ClassTypeLatticeElement#getInterfaces}.
- primary = new ClassTypeLatticeElement(type, maybeNull(), appInfo);
+ primary = new ClassTypeLatticeElement(type, maybeNull(), definitions);
}
} else {
assert type.isArrayType();
DexType elementType = type.toArrayElementType(this);
TypeLatticeElement elementTypeLattice =
- TypeLatticeElement.fromDexType(elementType, maybeNull(), appInfo, true);
+ TypeLatticeElement.fromDexType(elementType, maybeNull(), definitions, true);
primary = new ArrayTypeLatticeElement(elementTypeLattice, maybeNull());
}
referenceTypeLatticeElements.put(type, primary);
diff --git a/src/main/java/com/android/tools/r8/graph/DexType.java b/src/main/java/com/android/tools/r8/graph/DexType.java
index 4f90719..efd4a2b 100644
--- a/src/main/java/com/android/tools/r8/graph/DexType.java
+++ b/src/main/java/com/android/tools/r8/graph/DexType.java
@@ -105,9 +105,9 @@
setLevel(INTERFACE_LEVEL);
}
- public boolean isMissingOrHasMissingSuperType(AppInfo appInfo) {
- DexClass clazz = appInfo.definitionFor(this);
- return clazz == null || clazz.hasMissingSuperType(appInfo);
+ public boolean isMissingOrHasMissingSuperType(DexDefinitionSupplier definitions) {
+ DexClass clazz = definitions.definitionFor(this);
+ return clazz == null || clazz.hasMissingSuperType(definitions);
}
public boolean isInterface() {
@@ -286,37 +286,38 @@
/**
* Collect all interfaces that this type directly or indirectly implements.
- * @param appInfo where the definition of a certain {@link DexType} is looked up.
+ *
+ * @param definitions where the definition of a certain {@link DexType} is looked up.
* @return a set of interfaces of {@link DexType}.
*/
- public Set<DexType> implementedInterfaces(AppInfo appInfo) {
+ public Set<DexType> implementedInterfaces(DexDefinitionSupplier definitions) {
if (implementedInterfaces != null) {
return implementedInterfaces;
}
synchronized (this) {
if (implementedInterfaces == null) {
Set<DexType> interfaces = Sets.newIdentityHashSet();
- implementedInterfaces(appInfo, interfaces);
+ implementedInterfaces(definitions, interfaces);
implementedInterfaces = interfaces;
}
}
return implementedInterfaces;
}
- private void implementedInterfaces(AppInfo appInfo, Set<DexType> interfaces) {
- DexClass dexClass = appInfo.definitionFor(this);
+ private void implementedInterfaces(DexDefinitionSupplier definitions, Set<DexType> interfaces) {
+ DexClass dexClass = definitions.definitionFor(this);
// Loop to traverse the super type hierarchy of the current type.
while (dexClass != null) {
if (dexClass.isInterface()) {
interfaces.add(dexClass.type);
}
for (DexType itf : dexClass.interfaces.values) {
- itf.implementedInterfaces(appInfo, interfaces);
+ itf.implementedInterfaces(definitions, interfaces);
}
if (dexClass.superType == null) {
break;
}
- dexClass = appInfo.definitionFor(dexClass.superType);
+ dexClass = definitions.definitionFor(dexClass.superType);
}
}
@@ -623,11 +624,11 @@
return type.directSubtypes.contains(this);
}
- public DexType computeLeastUpperBoundOfClasses(AppInfo appInfo, DexType other) {
+ public DexType computeLeastUpperBoundOfClasses(DexDefinitionSupplier definitions, DexType other) {
if (this == other) {
return this;
}
- DexType objectType = appInfo.dexItemFactory.objectType;
+ DexType objectType = definitions.dexItemFactory().objectType;
// If we have no definition for either class, stop proceeding.
if (hierarchyLevel == UNKNOWN_LEVEL || other.hierarchyLevel == UNKNOWN_LEVEL) {
return objectType;
@@ -648,7 +649,7 @@
DexClass dexClass;
// Make both of other and this in the same level.
while (t2.hierarchyLevel > t1.hierarchyLevel) {
- dexClass = appInfo.definitionFor(t2);
+ dexClass = definitions.definitionFor(t2);
if (dexClass == null || dexClass.superType == null) {
return objectType;
}
@@ -660,13 +661,13 @@
// (It will stop at anytime when either one's definition is not found.)
DexType lubType = t1;
while (t2 != lubType) {
- dexClass = appInfo.definitionFor(t2);
+ dexClass = definitions.definitionFor(t2);
if (dexClass == null) {
lubType = objectType;
break;
}
t2 = dexClass.superType;
- dexClass = appInfo.definitionFor(lubType);
+ dexClass = definitions.definitionFor(lubType);
if (dexClass == null) {
lubType = objectType;
break;
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLense.java
index aa8523e..5dd36c6 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLense.java
@@ -388,14 +388,14 @@
public abstract DexMethod getRenamedMethodSignature(DexMethod originalMethod);
public DexEncodedMethod mapDexEncodedMethod(
- DexEncodedMethod originalEncodedMethod, AppInfo appInfo) {
+ DexEncodedMethod originalEncodedMethod, DexDefinitionSupplier definitions) {
DexMethod newMethod = getRenamedMethodSignature(originalEncodedMethod.method);
// Note that:
// * Even if `newMethod` is the same as `originalEncodedMethod.method`, we still need to look it
// up, since `originalEncodedMethod` may be obsolete.
// * We can't directly use AppInfo#definitionFor(DexMethod) since definitions may not be
// updated either yet.
- DexClass newHolder = appInfo.definitionFor(newMethod.holder);
+ DexClass newHolder = definitions.definitionFor(newMethod.holder);
assert newHolder != null;
DexEncodedMethod newEncodedMethod = newHolder.lookupMethod(newMethod);
assert newEncodedMethod != null;
diff --git a/src/main/java/com/android/tools/r8/graph/JarCode.java b/src/main/java/com/android/tools/r8/graph/JarCode.java
index 26264a5..732f35b 100644
--- a/src/main/java/com/android/tools/r8/graph/JarCode.java
+++ b/src/main/java/com/android/tools/r8/graph/JarCode.java
@@ -124,67 +124,52 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
- Origin origin) {
- return internalBuildPossiblyWithLocals(
- encodedMethod, encodedMethod, appInfo, graphLense, options, null, null);
+ DexEncodedMethod encodedMethod, AppView<? extends AppInfo> appView, Origin origin) {
+ return internalBuildPossiblyWithLocals(encodedMethod, encodedMethod, appView, null, null);
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator generator,
Position callerPosition,
Origin origin) {
assert generator != null;
return internalBuildPossiblyWithLocals(
- context, encodedMethod, appInfo, graphLense, options, generator, callerPosition);
+ context, encodedMethod, appView, generator, callerPosition);
}
private IRCode internalBuildPossiblyWithLocals(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator generator,
Position callerPosition) {
assert getOwner() == encodedMethod;
triggerDelayedParsingIfNeccessary();
- if (!keepLocals(encodedMethod, options)) {
+ if (!keepLocals(encodedMethod, appView.options())) {
// We strip locals here because we will not be able to recover from invalid info.
node.localVariables.clear();
- return internalBuild(
- context, encodedMethod, appInfo, graphLense, options, generator, callerPosition);
+ return internalBuild(context, encodedMethod, appView, generator, callerPosition);
} else {
- return internalBuildWithLocals(
- context, encodedMethod, appInfo, graphLense, options, generator, callerPosition);
+ return internalBuildWithLocals(context, encodedMethod, appView, generator, callerPosition);
}
}
private IRCode internalBuildWithLocals(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator generator,
Position callerPosition) {
try {
- return internalBuild(
- context, encodedMethod, appInfo, graphLense, options, generator, callerPosition);
+ return internalBuild(context, encodedMethod, appView, generator, callerPosition);
} catch (InvalidDebugInfoException e) {
- options.warningInvalidDebugInfo(encodedMethod, origin, e);
+ appView.options().warningInvalidDebugInfo(encodedMethod, origin, e);
node.localVariables.clear();
- return internalBuild(
- context, encodedMethod, appInfo, graphLense, options, generator, callerPosition);
+ return internalBuild(context, encodedMethod, appView, generator, callerPosition);
}
}
@@ -201,21 +186,18 @@
private IRCode internalBuild(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator generator,
Position callerPosition) {
- assert node.localVariables.isEmpty() || keepLocals(encodedMethod, options);
+ assert node.localVariables.isEmpty() || keepLocals(encodedMethod, appView.options());
JarSourceCode source =
new JarSourceCode(
method.getHolder(),
node,
application,
- graphLense.getOriginalMethodSignature(encodedMethod.method),
+ appView.graphLense().getOriginalMethodSignature(encodedMethod.method),
callerPosition);
- IRBuilder builder =
- new IRBuilder(encodedMethod, appInfo, source, options, origin, generator, graphLense);
+ IRBuilder builder = new IRBuilder(encodedMethod, appView, source, origin, generator);
return builder.build(context);
}
@@ -246,7 +228,7 @@
DexType invocationContext) {
InliningConstraintVisitor visitor =
new InliningConstraintVisitor(
- application, appView.appInfo(), graphLense, encodedMethod, invocationContext);
+ application, appView, graphLense, encodedMethod, invocationContext);
if (appView.options().enableDesugaring
&& appView.options().interfaceMethodDesugaring == OffOrAuto.Auto
diff --git a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
index 42a427c..d1e1c5c 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -58,7 +58,6 @@
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.InternalOptions;
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
import java.util.ArrayList;
@@ -176,36 +175,23 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
- Origin origin) {
+ DexEncodedMethod encodedMethod, AppView<? extends AppInfo> appView, Origin origin) {
assert getOwner() == encodedMethod;
- return asCfCode().buildIR(encodedMethod, appInfo, graphLense, options, origin);
+ return asCfCode().buildIR(encodedMethod, appView, origin);
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
assert getOwner() == encodedMethod;
return asCfCode()
.buildInliningIR(
- context,
- encodedMethod,
- appInfo,
- graphLense,
- options,
- valueNumberGenerator,
- callerPosition,
- origin);
+ context, encodedMethod, appView, valueNumberGenerator, callerPosition, origin);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
index 4e08835..120a099 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
@@ -73,8 +73,6 @@
}
public ClassInitializationAnalysis(AppView<? extends AppInfoWithLiveness> appView, IRCode code) {
- assert appView != null;
- assert code != null;
this.appView = appView;
this.code = code;
this.dexItemFactory = appView.dexItemFactory();
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java
index a88a71d..1c16837 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java
@@ -6,7 +6,7 @@
import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
-import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
@@ -77,8 +77,8 @@
}
@Override
- public boolean isBasedOnMissingClass(AppInfo appInfo) {
- return memberTypeLattice.isBasedOnMissingClass(appInfo);
+ public boolean isBasedOnMissingClass(DexDefinitionSupplier definitions) {
+ return memberTypeLattice.isBasedOnMissingClass(definitions);
}
@Override
@@ -119,7 +119,8 @@
return (isNullable() ? 1 : -1) * memberTypeLattice.hashCode();
}
- ReferenceTypeLatticeElement join(ArrayTypeLatticeElement other, AppInfo appInfo) {
+ ReferenceTypeLatticeElement join(
+ ArrayTypeLatticeElement other, DexDefinitionSupplier definitions) {
TypeLatticeElement aMember = getArrayMemberTypeAsMemberType();
TypeLatticeElement bMember = other.getArrayMemberTypeAsMemberType();
if (aMember.equals(bMember)) {
@@ -129,18 +130,22 @@
Nullability nullability = nullability().join(other.nullability());
if (aMember.isArrayType() && bMember.isArrayType()) {
ReferenceTypeLatticeElement join =
- aMember.asArrayTypeLatticeElement().join(bMember.asArrayTypeLatticeElement(), appInfo);
+ aMember
+ .asArrayTypeLatticeElement()
+ .join(bMember.asArrayTypeLatticeElement(), definitions);
return join == null ? null : new ArrayTypeLatticeElement(join, nullability);
}
if (aMember.isClassType() && bMember.isClassType()) {
ClassTypeLatticeElement join =
- aMember.asClassTypeLatticeElement().join(bMember.asClassTypeLatticeElement(), appInfo);
+ aMember
+ .asClassTypeLatticeElement()
+ .join(bMember.asClassTypeLatticeElement(), definitions);
return join == null ? null : new ArrayTypeLatticeElement(join, nullability);
}
if (aMember.isPrimitive() || bMember.isPrimitive()) {
- return objectClassType(appInfo, nullability);
+ return objectClassType(definitions, nullability);
}
- return objectArrayType(appInfo, nullability);
+ return objectArrayType(definitions, nullability);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/BottomTypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/BottomTypeLatticeElement.java
index c44aa34..78c4e56 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/BottomTypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/BottomTypeLatticeElement.java
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.analysis.type;
-import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexType;
public class BottomTypeLatticeElement extends TypeLatticeElement {
@@ -24,7 +24,7 @@
}
@Override
- public TypeLatticeElement checkCast(AppInfo appInfo, DexType castType) {
+ public TypeLatticeElement checkCast(DexDefinitionSupplier definitions, DexType castType) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeLatticeElement.java
index 34ef919..09dda42 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/ClassTypeLatticeElement.java
@@ -6,8 +6,8 @@
import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
-import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexType;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayDeque;
@@ -21,7 +21,7 @@
public class ClassTypeLatticeElement extends ReferenceTypeLatticeElement {
private Set<DexType> lazyInterfaces;
- private AppInfo appInfoForLazyInterfacesComputation;
+ private DexDefinitionSupplier definitionsForLazyInterfacesComputation;
public ClassTypeLatticeElement(
DexType classType, Nullability nullability, Set<DexType> interfaces) {
@@ -29,18 +29,18 @@
}
public ClassTypeLatticeElement(
- DexType classType, Nullability nullability, AppInfo appInfo) {
- this(classType, nullability, null, appInfo);
+ DexType classType, Nullability nullability, DexDefinitionSupplier definitions) {
+ this(classType, nullability, null, definitions);
}
private ClassTypeLatticeElement(
DexType classType,
Nullability nullability,
Set<DexType> interfaces,
- AppInfo appInfo) {
+ DexDefinitionSupplier definitions) {
super(nullability, classType);
assert classType.isClassType();
- appInfoForLazyInterfacesComputation = appInfo;
+ definitionsForLazyInterfacesComputation = definitions;
lazyInterfaces = interfaces;
}
@@ -55,10 +55,10 @@
}
synchronized (this) {
if (lazyInterfaces == null) {
- Set<DexType> itfs = type.implementedInterfaces(appInfoForLazyInterfacesComputation);
+ Set<DexType> itfs = type.implementedInterfaces(definitionsForLazyInterfacesComputation);
lazyInterfaces =
- computeLeastUpperBoundOfInterfaces(appInfoForLazyInterfacesComputation, itfs, itfs);
- appInfoForLazyInterfacesComputation = null;
+ computeLeastUpperBoundOfInterfaces(definitionsForLazyInterfacesComputation, itfs, itfs);
+ definitionsForLazyInterfacesComputation = null;
}
}
return lazyInterfaces;
@@ -70,7 +70,7 @@
return this;
}
return new ClassTypeLatticeElement(
- type, nullability, lazyInterfaces, appInfoForLazyInterfacesComputation);
+ type, nullability, lazyInterfaces, definitionsForLazyInterfacesComputation);
}
@Override
@@ -84,9 +84,10 @@
}
@Override
- public boolean isBasedOnMissingClass(AppInfo appInfo) {
- return getClassType().isMissingOrHasMissingSuperType(appInfo)
- || getInterfaces().stream().anyMatch(type -> type.isMissingOrHasMissingSuperType(appInfo));
+ public boolean isBasedOnMissingClass(DexDefinitionSupplier definitions) {
+ return getClassType().isMissingOrHasMissingSuperType(definitions)
+ || getInterfaces().stream()
+ .anyMatch(type -> type.isMissingOrHasMissingSuperType(definitions));
}
@Override
@@ -116,8 +117,9 @@
return (isNullable() ? 1 : -1) * type.hashCode();
}
- ClassTypeLatticeElement join(ClassTypeLatticeElement other, AppInfo appInfo) {
- DexType lubType = getClassType().computeLeastUpperBoundOfClasses(appInfo, other.getClassType());
+ ClassTypeLatticeElement join(ClassTypeLatticeElement other, DexDefinitionSupplier definitions) {
+ DexType lubType =
+ getClassType().computeLeastUpperBoundOfClasses(definitions, other.getClassType());
Set<DexType> c1lubItfs = getInterfaces();
Set<DexType> c2lubItfs = other.getInterfaces();
Set<DexType> lubItfs = null;
@@ -125,7 +127,7 @@
lubItfs = c1lubItfs;
}
if (lubItfs == null) {
- lubItfs = computeLeastUpperBoundOfInterfaces(appInfo, c1lubItfs, c2lubItfs);
+ lubItfs = computeLeastUpperBoundOfInterfaces(definitions, c1lubItfs, c2lubItfs);
}
Nullability nullability = nullability().join(other.nullability());
return new ClassTypeLatticeElement(lubType, nullability, lubItfs);
@@ -147,12 +149,12 @@
}
static Set<DexType> computeLeastUpperBoundOfInterfaces(
- AppInfo appInfo, Set<DexType> s1, Set<DexType> s2) {
- Set<DexType> cached = appInfo.dexItemFactory.leastUpperBoundOfInterfacesTable.get(s1, s2);
+ DexDefinitionSupplier definitions, Set<DexType> s1, Set<DexType> s2) {
+ Set<DexType> cached = definitions.dexItemFactory().leastUpperBoundOfInterfacesTable.get(s1, s2);
if (cached != null) {
return cached;
}
- cached = appInfo.dexItemFactory.leastUpperBoundOfInterfacesTable.get(s2, s1);
+ cached = definitions.dexItemFactory().leastUpperBoundOfInterfacesTable.get(s2, s1);
if (cached != null) {
return cached;
}
@@ -181,7 +183,7 @@
// Otherwise, this type is freshly visited.
markers.add(marker);
// Put super interfaces into the worklist.
- DexClass itfClass = appInfo.definitionFor(itf);
+ DexClass itfClass = definitions.definitionFor(itf);
if (itfClass != null) {
for (DexType superItf : itfClass.interfaces.values) {
markers = seen.computeIfAbsent(superItf, k -> new HashSet<>());
@@ -207,7 +209,7 @@
// If there is a strict sub interface of this interface, it is not the least element.
boolean notTheLeast = false;
for (DexType other : commonlyVisited) {
- if (other.isStrictSubtypeOf(itf, appInfo)) {
+ if (other.isStrictSubtypeOf(itf, definitions)) {
notTheLeast = true;
break;
}
@@ -220,8 +222,8 @@
Set<DexType> lub = lubBuilder.build();
// Cache the computation result only if the given two sets of interfaces are different.
if (s1.size() != s2.size() || !s1.containsAll(s2)) {
- synchronized (appInfo.dexItemFactory.leastUpperBoundOfInterfacesTable) {
- appInfo.dexItemFactory.leastUpperBoundOfInterfacesTable.put(s1, s2, lub);
+ synchronized (definitions.dexItemFactory().leastUpperBoundOfInterfacesTable) {
+ definitions.dexItemFactory().leastUpperBoundOfInterfacesTable.put(s1, s2, lub);
}
}
return lub;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TopTypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TopTypeLatticeElement.java
index d0d0c79..6531bff 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TopTypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TopTypeLatticeElement.java
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.analysis.type;
-import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexType;
public class TopTypeLatticeElement extends TypeLatticeElement {
@@ -24,7 +24,7 @@
}
@Override
- public TypeLatticeElement checkCast(AppInfo appInfo, DexType castType) {
+ public TypeLatticeElement checkCast(DexDefinitionSupplier definitions, DexType castType) {
return this;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
index 0e15644..e5ea8b7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeAnalysis.java
@@ -8,7 +8,8 @@
import static com.android.tools.r8.ir.analysis.type.TypeLatticeElement.fromDexType;
import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -35,20 +36,22 @@
private Mode mode = Mode.UNSET;
- private final AppInfo appInfo;
+ private final AppView<? extends AppInfo> appView;
private final DexEncodedMethod context;
private final Deque<Value> worklist = new ArrayDeque<>();
- public TypeAnalysis(
- AppInfo appInfo, DexEncodedMethod encodedMethod, boolean mayHaveImpreciseTypes) {
- this.appInfo = appInfo;
- this.context = encodedMethod;
- this.mayHaveImpreciseTypes = mayHaveImpreciseTypes;
+ public TypeAnalysis(AppView<? extends AppInfo> appView, DexEncodedMethod encodedMethod) {
+ this(appView, encodedMethod, false);
}
- public TypeAnalysis(AppInfo appInfo, DexEncodedMethod encodedMethod) {
- this(appInfo, encodedMethod, false);
+ public TypeAnalysis(
+ AppView<? extends AppInfo> appView,
+ DexEncodedMethod encodedMethod,
+ boolean mayHaveImpreciseTypes) {
+ this.appView = appView;
+ this.context = encodedMethod;
+ this.mayHaveImpreciseTypes = mayHaveImpreciseTypes;
}
private void analyze() {
@@ -101,18 +104,21 @@
TypeLatticeElement derived;
if (argumentsSeen < 0) {
// Receiver
- derived = fromDexType(encodedMethod.method.holder,
- // Now we try inlining even when the receiver could be null.
- encodedMethod == context ? definitelyNotNull() : maybeNull(), appInfo);
+ derived =
+ fromDexType(
+ encodedMethod.method.holder,
+ // Now we try inlining even when the receiver could be null.
+ encodedMethod == context ? definitelyNotNull() : maybeNull(),
+ appView);
} else {
DexType argType = encodedMethod.method.proto.parameters.values[argumentsSeen];
- derived = fromDexType(argType, maybeNull(), appInfo);
+ derived = fromDexType(argType, maybeNull(), appView);
}
argumentsSeen++;
updateTypeOfValue(outValue, derived);
// Note that we don't need to enqueue the out value of arguments here because it's constant.
} else if (instruction.hasInvariantOutType()) {
- TypeLatticeElement derived = instruction.evaluate(appInfo);
+ TypeLatticeElement derived = instruction.evaluate(appView);
updateTypeOfValue(outValue, derived);
} else {
enqueue(outValue);
@@ -126,9 +132,7 @@
private void analyzeValue(Value value) {
TypeLatticeElement previous = value.getTypeLattice();
TypeLatticeElement derived =
- value.isPhi()
- ? value.asPhi().computePhiType(appInfo)
- : value.definition.evaluate(appInfo);
+ value.isPhi() ? value.asPhi().computePhiType(appView) : value.definition.evaluate(appView);
assert mayHaveImpreciseTypes || derived.isPreciseType();
assert !previous.isPreciseType() || derived.isPreciseType();
updateTypeOfValue(value, derived);
@@ -146,10 +150,10 @@
return;
}
if (mode == Mode.WIDENING) {
- value.widening(appInfo, type);
+ value.widening(appView, type);
} else {
assert mode == Mode.NARROWING;
- value.narrowing(appInfo, type);
+ value.narrowing(appView, type);
}
// propagate the type change to (instruction) users if any.
@@ -166,12 +170,12 @@
}
public static DexType getRefinedReceiverType(
- AppInfoWithSubtyping appInfo, InvokeMethodWithReceiver invoke) {
+ DexDefinitionSupplier definitions, InvokeMethodWithReceiver invoke) {
DexType receiverType = invoke.getInvokedMethod().getHolder();
TypeLatticeElement lattice = invoke.getReceiver().getTypeLattice();
if (lattice.isClassType()) {
DexType refinedType = lattice.asClassTypeLatticeElement().getClassType();
- if (refinedType.isSubtypeOf(receiverType, appInfo)) {
+ if (refinedType.isSubtypeOf(receiverType, definitions)) {
return refinedType;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java
index 3ef167c..6384088 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.ir.analysis.type;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.Value;
@@ -56,10 +56,10 @@
* Computes the least upper bound of the current and the other elements.
*
* @param other {@link TypeLatticeElement} to join.
- * @param appInfo {@link AppInfo}.
+ * @param definitions {@link DexDefinitionSupplier}.
* @return {@link TypeLatticeElement}, a least upper bound of {@param this} and {@param other}.
*/
- public TypeLatticeElement join(TypeLatticeElement other, AppInfo appInfo) {
+ public TypeLatticeElement join(TypeLatticeElement other, DexDefinitionSupplier definitions) {
if (this == other) {
return this;
}
@@ -91,36 +91,27 @@
assert isReference() && other.isReference();
assert isPreciseType() && other.isPreciseType();
if (getClass() != other.getClass()) {
- return objectClassType(appInfo, nullability().join(other.nullability()));
+ return objectClassType(definitions, nullability().join(other.nullability()));
}
// From now on, getClass() == other.getClass()
if (isArrayType()) {
assert other.isArrayType();
TypeLatticeElement join =
- asArrayTypeLatticeElement().join(other.asArrayTypeLatticeElement(), appInfo);
+ asArrayTypeLatticeElement().join(other.asArrayTypeLatticeElement(), definitions);
return join != null ? join : (isNullable() ? this : other);
}
if (isClassType()) {
assert other.isClassType();
- return asClassTypeLatticeElement().join(other.asClassTypeLatticeElement(), appInfo);
+ return asClassTypeLatticeElement().join(other.asClassTypeLatticeElement(), definitions);
}
throw new Unreachable("unless a new type lattice is introduced.");
}
public static TypeLatticeElement join(
- Iterable<TypeLatticeElement> typeLattices, AppInfo appInfo) {
+ Iterable<TypeLatticeElement> typeLattices, DexDefinitionSupplier definitions) {
TypeLatticeElement result = BOTTOM;
for (TypeLatticeElement other : typeLattices) {
- result = result.join(other, appInfo);
- }
- return result;
- }
-
- public static TypeLatticeElement joinTypes(
- Iterable<DexType> types, Nullability nullability, AppInfo appInfo) {
- TypeLatticeElement result = BOTTOM;
- for (DexType type : types) {
- result = result.join(fromDexType(type, nullability, appInfo), appInfo);
+ result = result.join(other, definitions);
}
return result;
}
@@ -129,14 +120,15 @@
* Determines the strict partial order of the given {@link TypeLatticeElement}s.
*
* @param other expected to be *strictly* bigger than {@param this}
- * @param appInfo {@link AppInfo} to compute the least upper bound of {@link TypeLatticeElement}
+ * @param definitions {@link DexDefinitionSupplier} to compute the least upper bound of {@link
+ * TypeLatticeElement}
* @return {@code true} if {@param this} is strictly less than {@param other}.
*/
- public boolean strictlyLessThan(TypeLatticeElement other, AppInfo appInfo) {
+ public boolean strictlyLessThan(TypeLatticeElement other, DexDefinitionSupplier definitions) {
if (equals(other)) {
return false;
}
- TypeLatticeElement lub = join(other, appInfo);
+ TypeLatticeElement lub = join(other, definitions);
return !equals(lub) && other.equals(lub);
}
@@ -144,11 +136,12 @@
* Determines the partial order of the given {@link TypeLatticeElement}s.
*
* @param other expected to be bigger than or equal to {@param this}
- * @param appInfo {@link AppInfo} to compute the least upper bound of {@link TypeLatticeElement}
+ * @param definitions {@link DexDefinitionSupplier} to compute the least upper bound of {@link
+ * TypeLatticeElement}
* @return {@code true} if {@param this} is less than or equal to {@param other}.
*/
- public boolean lessThanOrEqual(TypeLatticeElement other, AppInfo appInfo) {
- return equals(other) || strictlyLessThan(other, appInfo);
+ public boolean lessThanOrEqual(TypeLatticeElement other, DexDefinitionSupplier definitions) {
+ return equals(other) || strictlyLessThan(other, definitions);
}
/**
@@ -156,7 +149,7 @@
*
* @return {@code} true if this type is based on a missing class.
*/
- public boolean isBasedOnMissingClass(AppInfo appInfo) {
+ public boolean isBasedOnMissingClass(DexDefinitionSupplier definitions) {
return false;
}
@@ -290,38 +283,41 @@
return isWide() ? 2 : 1;
}
- public static ClassTypeLatticeElement objectClassType(AppInfo appInfo, Nullability nullability) {
- return fromDexType(appInfo.dexItemFactory.objectType, nullability, appInfo)
+ public static ClassTypeLatticeElement objectClassType(
+ DexDefinitionSupplier definitions, Nullability nullability) {
+ return fromDexType(definitions.dexItemFactory().objectType, nullability, definitions)
.asClassTypeLatticeElement();
}
- static ArrayTypeLatticeElement objectArrayType(AppInfo appInfo, Nullability nullability) {
+ static ArrayTypeLatticeElement objectArrayType(
+ DexDefinitionSupplier definitions, Nullability nullability) {
+ DexItemFactory dexItemFactory = definitions.dexItemFactory();
return fromDexType(
- appInfo.dexItemFactory.createArrayType(1, appInfo.dexItemFactory.objectType),
- nullability,
- appInfo)
+ dexItemFactory.createArrayType(1, dexItemFactory.objectType), nullability, definitions)
.asArrayTypeLatticeElement();
}
- public static ClassTypeLatticeElement classClassType(AppInfo appInfo, Nullability nullability) {
- return fromDexType(appInfo.dexItemFactory.classType, nullability, appInfo)
+ public static ClassTypeLatticeElement classClassType(
+ DexDefinitionSupplier definitions, Nullability nullability) {
+ return fromDexType(definitions.dexItemFactory().classType, nullability, definitions)
.asClassTypeLatticeElement();
}
- public static ClassTypeLatticeElement stringClassType(AppInfo appInfo, Nullability nullability) {
- return fromDexType(appInfo.dexItemFactory.stringType, nullability, appInfo)
+ public static ClassTypeLatticeElement stringClassType(
+ DexDefinitionSupplier definitions, Nullability nullability) {
+ return fromDexType(definitions.dexItemFactory().stringType, nullability, definitions)
.asClassTypeLatticeElement();
}
public static TypeLatticeElement fromDexType(
- DexType type, Nullability nullability, AppInfo appInfo) {
- return fromDexType(type, nullability, appInfo, false);
+ DexType type, Nullability nullability, DexDefinitionSupplier definitions) {
+ return fromDexType(type, nullability, definitions, false);
}
public static TypeLatticeElement fromDexType(
DexType type,
Nullability nullability,
- AppInfo appInfo,
+ DexDefinitionSupplier definitions,
boolean asArrayElementType) {
if (type == DexItemFactory.nullValueType) {
assert !nullability.isDefinitelyNotNull();
@@ -330,7 +326,9 @@
if (type.isPrimitiveType()) {
return PrimitiveTypeLatticeElement.fromDexType(type, asArrayElementType);
}
- return appInfo.dexItemFactory.createReferenceTypeLatticeElement(type, nullability, appInfo);
+ return definitions
+ .dexItemFactory()
+ .createReferenceTypeLatticeElement(type, nullability, definitions);
}
public boolean isValueTypeCompatible(TypeLatticeElement other) {
@@ -339,9 +337,9 @@
|| (isWide() && other.isWide());
}
- public TypeLatticeElement checkCast(AppInfo appInfo, DexType castType) {
- TypeLatticeElement castTypeLattice = fromDexType(castType, nullability(), appInfo);
- if (lessThanOrEqual(castTypeLattice, appInfo)) {
+ public TypeLatticeElement checkCast(DexDefinitionSupplier definitions, DexType castType) {
+ TypeLatticeElement castTypeLattice = fromDexType(castType, nullability(), definitions);
+ if (lessThanOrEqual(castTypeLattice, definitions)) {
return this;
}
return castTypeLattice;
diff --git a/src/main/java/com/android/tools/r8/ir/code/Argument.java b/src/main/java/com/android/tools/r8/ir/code/Argument.java
index 997f1c5..8cbf90d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Argument.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Argument.java
@@ -77,7 +77,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
throw new Unreachable();
}
@@ -87,7 +88,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return outValue.getTypeLattice();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
index 3879639..f5e6e6c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.ArrayTypeLatticeElement;
@@ -147,7 +148,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
// This method is not called for ArrayGet on primitive array.
assert this.outValue.getTypeLattice().isReference();
DexType arrayType = helper.getDexType(array());
@@ -155,7 +157,7 @@
// JVM 8 §4.10.1.9.aaload: Array component type of null is null.
return arrayType;
}
- return arrayType.toArrayElementType(helper.getFactory());
+ return arrayType.toArrayElementType(appView.dexItemFactory());
}
@Override
@@ -170,7 +172,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
ArrayTypeLatticeElement arrayTypeLattice = array().getTypeLattice().isArrayType()
? array().getTypeLattice().asArrayTypeLatticeElement()
: null;
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java b/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java
index 7049c25..97a610f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.cf.code.CfArrayLength;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -100,7 +101,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return TypeLatticeElement.INT;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
index 47013dd..a3a230d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DebugLocalInfo.PrintLevel;
import com.android.tools.r8.graph.DexItemFactory;
@@ -79,9 +80,8 @@
return true;
}
- public boolean verifyTypes(AppInfo appInfo, GraphLense graphLense) {
- assert instructions.stream()
- .allMatch(instruction -> instruction.verifyTypes(appInfo, graphLense));
+ public boolean verifyTypes(AppView<? extends AppInfo> appView) {
+ assert instructions.stream().allMatch(instruction -> instruction.verifyTypes(appView));
return true;
}
@@ -1305,14 +1305,15 @@
}
public static BasicBlock createRethrowBlock(
- IRCode code, Position position, DexType guard, AppInfo appInfo, InternalOptions options) {
+ IRCode code, Position position, DexType guard, AppView<? extends AppInfo> appView) {
TypeLatticeElement guardTypeLattice =
- TypeLatticeElement.fromDexType(guard, Nullability.definitelyNotNull(), appInfo);
+ TypeLatticeElement.fromDexType(guard, Nullability.definitelyNotNull(), appView.appInfo());
BasicBlock block = new BasicBlock();
- MoveException moveException = new MoveException(
- new Value(code.valueNumberGenerator.next(), guardTypeLattice, null),
- guard,
- options);
+ MoveException moveException =
+ new MoveException(
+ new Value(code.valueNumberGenerator.next(), guardTypeLattice, null),
+ guard,
+ appView.options());
moveException.setPosition(position);
Throw throwInstruction = new Throw(moveException.outValue);
throwInstruction.setPosition(position);
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
index 1ab0670..d45a368 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.ir.code.DominatorTree.Assumption.MAY_HAVE_UNREACHABLE_BLOCKS;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -333,7 +334,7 @@
@Override
public BasicBlock inlineInvoke(
- AppInfo appInfo,
+ AppView<? extends AppInfo> appView,
IRCode code,
IRCode inlinee,
ListIterator<BasicBlock> blocksIterator,
@@ -372,7 +373,7 @@
Value receiver = invoke.inValues().get(0);
TypeLatticeElement castTypeLattice =
TypeLatticeElement.fromDexType(
- downcast, receiver.getTypeLattice().nullability(), appInfo);
+ downcast, receiver.getTypeLattice().nullability(), appView);
CheckCast castInstruction =
new CheckCast(code.createValue(castTypeLattice), receiver, downcast);
castInstruction.setPosition(invoke.getPosition());
@@ -422,7 +423,7 @@
assert entryBlock.getInstructions().stream().noneMatch(Instruction::isArgument);
// Actual arguments are flown to the inlinee.
- new TypeAnalysis(appInfo, inlinee.method).narrowing(argumentUsers);
+ new TypeAnalysis(appView, inlinee.method).narrowing(argumentUsers);
// The inline entry is the first block now the argument instructions are gone.
BasicBlock inlineEntry = inlinee.entryBlock();
@@ -432,7 +433,7 @@
if (!normalExits.isEmpty()) {
// Ensure and locate the single return instruction of the inlinee.
InstructionListIterator inlineeIterator =
- ensureSingleReturnInstruction(appInfo, inlinee, normalExits);
+ ensureSingleReturnInstruction(appView, inlinee, normalExits);
// Replace the invoke value with the return value if non-void.
assert inlineeIterator.peekNext().isReturn();
@@ -441,8 +442,10 @@
Return returnInstruction = inlineeIterator.peekNext().asReturn();
invoke.outValue().replaceUsers(returnInstruction.returnValue());
// The return type is flown to the original context.
- new TypeAnalysis(appInfo, code.method).narrowing(
- Iterables.concat(ImmutableList.of(returnInstruction.returnValue()), affectedValues));
+ new TypeAnalysis(appView, code.method)
+ .narrowing(
+ Iterables.concat(
+ ImmutableList.of(returnInstruction.returnValue()), affectedValues));
}
// Split before return and unlink return.
@@ -517,7 +520,7 @@
}
private InstructionListIterator ensureSingleReturnInstruction(
- AppInfo appInfo, IRCode code, List<BasicBlock> normalExits) {
+ AppView<? extends AppInfo> appView, IRCode code, List<BasicBlock> normalExits) {
if (normalExits.size() == 1) {
InstructionListIterator it = normalExits.get(0).listIterator();
it.nextUntil(Instruction::isReturn);
@@ -550,7 +553,7 @@
null,
RegisterReadType.NORMAL);
phi.addOperands(operands);
- new TypeAnalysis(appInfo, code.method).widening(ImmutableSet.of(phi));
+ new TypeAnalysis(appView, code.method).widening(ImmutableSet.of(phi));
value = phi;
}
newReturn = new Return(value);
diff --git a/src/main/java/com/android/tools/r8/ir/code/Binop.java b/src/main/java/com/android/tools/r8/ir/code/Binop.java
index 54567b5..78827cd 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Binop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Binop.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.PrimitiveTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -135,7 +136,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return PrimitiveTypeLatticeElement.fromNumericType(type);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
index b13e356..6c7112f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
+++ b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
@@ -11,8 +11,8 @@
import com.android.tools.r8.code.MoveObjectFrom16;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -106,13 +106,13 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return object().getTypeLattice().checkCast(appInfo, type);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return object().getTypeLattice().checkCast(appView, type);
}
@Override
- public boolean verifyTypes(AppInfo appInfo, GraphLense graphLense) {
- assert super.verifyTypes(appInfo, graphLense);
+ public boolean verifyTypes(AppView<? extends AppInfo> appView) {
+ assert super.verifyTypes(appView);
TypeLatticeElement inType = object().getTypeLattice();
@@ -120,12 +120,12 @@
TypeLatticeElement outType = outValue().getTypeLattice();
TypeLatticeElement castType =
- TypeLatticeElement.fromDexType(getType(), inType.nullability(), appInfo);
+ TypeLatticeElement.fromDexType(getType(), inType.nullability(), appView);
- if (inType.lessThanOrEqual(castType, appInfo)) {
+ if (inType.lessThanOrEqual(castType, appView)) {
// Cast can be removed. Check that it is sound to replace all users of the out-value by the
// in-value.
- assert inType.lessThanOrEqual(outType, appInfo);
+ assert inType.lessThanOrEqual(outType, appView);
// TODO(b/72693244): Consider checking equivalence. This requires that the types are always
// as precise as possible, though, meaning that almost all changes to the IR must be followed
@@ -163,7 +163,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return type;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Cmp.java b/src/main/java/com/android/tools/r8/ir/code/Cmp.java
index 2f346a5..8ad8d4b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Cmp.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Cmp.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.analysis.constant.Bottom;
import com.android.tools.r8.ir.analysis.constant.ConstLatticeElement;
import com.android.tools.r8.ir.analysis.constant.LatticeElement;
@@ -225,7 +226,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return TypeLatticeElement.INT;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
index b3ab484..83bbb0f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
@@ -136,13 +136,14 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.classClassType(appInfo, Nullability.definitelyNotNull());
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.classClassType(appView, Nullability.definitelyNotNull());
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
- return helper.getFactory().classType;
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
+ return appView.dexItemFactory().classType;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java b/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
index ebc61d0..40c879f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.cf.code.CfConstMethodHandle;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
@@ -106,14 +107,15 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return TypeLatticeElement.fromDexType(
- appInfo.dexItemFactory.methodHandleType, Nullability.definitelyNotNull(), appInfo);
+ appView.dexItemFactory().methodHandleType, Nullability.definitelyNotNull(), appView);
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
- return helper.getFactory().methodHandleType;
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
+ return appView.dexItemFactory().methodHandleType;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java b/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
index 47aa1c4..f9eee1b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.cf.code.CfConstMethodType;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
@@ -98,14 +99,15 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return TypeLatticeElement.fromDexType(
- appInfo.dexItemFactory.methodTypeType, Nullability.definitelyNotNull(), appInfo);
+ appView.dexItemFactory().methodTypeType, Nullability.definitelyNotNull(), appView);
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
- return helper.getFactory().methodTypeType;
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
+ return appView.dexItemFactory().methodTypeType;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
index 3976889..0847cb7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
@@ -17,8 +17,8 @@
import com.android.tools.r8.code.ConstWideHigh16;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.constant.Bottom;
import com.android.tools.r8.ir.analysis.constant.ConstLatticeElement;
import com.android.tools.r8.ir.analysis.constant.LatticeElement;
@@ -279,9 +279,10 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
assert outType().isObject();
- return helper.getFactory().nullValueType;
+ return appView.dexItemFactory().nullValueType;
}
@Override
@@ -293,13 +294,13 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return outValue().getTypeLattice();
}
@Override
- public boolean verifyTypes(AppInfo appInfo, GraphLense graphLense) {
- assert super.verifyTypes(appInfo, graphLense);
+ public boolean verifyTypes(AppView<? extends AppInfo> appView) {
+ assert super.verifyTypes(appView);
assert !isZero()
|| outValue().getTypeLattice().isPrimitive()
|| outValue().getTypeLattice().isNullType();
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstString.java b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
index f6f1ccf..27577c0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
@@ -131,12 +131,13 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
- return helper.getFactory().stringType;
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
+ return appView.dexItemFactory().stringType;
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.stringClassType(appInfo, Nullability.definitelyNotNull());
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.stringClassType(appView, Nullability.definitelyNotNull());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java b/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java
index 2a5aebc..de1b6fb 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java
@@ -6,6 +6,8 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.cf.code.CfStore;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -50,7 +52,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return helper.getDexType(src());
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java b/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
index 7d0d44f..d5c8c82 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
@@ -126,12 +126,13 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
- return helper.getFactory().stringType;
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
+ return appView.dexItemFactory().stringType;
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.stringClassType(appInfo, Nullability.definitelyNotNull());
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.stringClassType(appView, Nullability.definitelyNotNull());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 0d8826b..c4c130f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.TypeChecker;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.IRBuilder;
@@ -486,14 +485,13 @@
return true;
}
- public boolean verifyTypes(
- AppInfo appInfo, AppView<? extends AppInfo> appView, GraphLense graphLense) {
+ public boolean verifyTypes(AppView<? extends AppInfo> appView) {
// We can only type check the program if we have subtyping information. Therefore, we do not
// require that the program type checks in D8.
- if (appView != null && appView.enableWholeProgramOptimizations()) {
+ if (appView.enableWholeProgramOptimizations()) {
assert new TypeChecker(appView).check(this);
}
- assert blocks.stream().allMatch(block -> block.verifyTypes(appInfo, graphLense));
+ assert blocks.stream().allMatch(block -> block.verifyTypes(appView));
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
index 44cc6a1..3634edf 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
@@ -112,7 +112,7 @@
// * NullPointerException (null receiver).
// TODO(b/123857022): Should be possible to use definitionFor().
AppInfo appInfo = appView.appInfo();
- DexEncodedField resolvedField = appInfo.resolveFieldOn(getField().getHolder(), getField());
+ DexEncodedField resolvedField = appInfo.resolveField(getField());
if (resolvedField == null) {
return false;
}
@@ -167,12 +167,13 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.fromDexType(getField().type, Nullability.maybeNull(), appInfo);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.fromDexType(getField().type, Nullability.maybeNull(), appView);
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return getField().type;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
index 47e229b..e2cfeb3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.cf.code.CfInstanceOf;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -80,7 +81,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return TypeLatticeElement.INT;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index b05cd55..9c28e92 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
import com.android.tools.r8.ir.analysis.constant.Bottom;
@@ -1195,7 +1194,8 @@
public abstract void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper);
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
assert outValue == null || !outValue.getTypeLattice().isReference();
throw new Unreachable("Instruction without object outValue cannot compute verification type");
}
@@ -1210,13 +1210,13 @@
}
// TODO(b/72693244): maybe rename to computeOutType once TypeVerificationHelper is gone?
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
assert outValue == null;
throw new Unimplemented(
"Implement type lattice evaluation for: " + getInstructionName());
}
- public boolean verifyTypes(AppInfo appInfo, GraphLense graphLense) {
+ public boolean verifyTypes(AppView<? extends AppInfo> appView) {
// TODO(b/72693244): for instructions with invariant out type, we can verify type directly here.
if (outValue != null) {
TypeLatticeElement outTypeLatticeElement = outValue.getTypeLattice();
@@ -1224,12 +1224,12 @@
DexType outBaseType =
outTypeLatticeElement
.asArrayTypeLatticeElement()
- .getArrayType(appInfo.dexItemFactory)
- .toBaseType(appInfo.dexItemFactory);
- assert graphLense.lookupType(outBaseType) == outBaseType;
+ .getArrayType(appView.dexItemFactory())
+ .toBaseType(appView.dexItemFactory());
+ assert appView.graphLense().lookupType(outBaseType) == outBaseType;
} else if (outTypeLatticeElement.isClassType()) {
DexType outType = outTypeLatticeElement.asClassTypeLatticeElement().getClassType();
- assert graphLense.lookupType(outType) == outType;
+ assert appView.graphLense().lookupType(outType) == outType;
}
}
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
index c232d3f..0a1bf67 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.ir.code;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import java.util.ArrayList;
import java.util.List;
@@ -100,30 +101,31 @@
* Inline the code in {@code inlinee} into {@code code}, replacing the invoke instruction at the
* position after the cursor.
*
- * The instruction at the position after cursor must be an invoke that matches the signature for
- * the code in {@code inlinee}.
+ * <p>The instruction at the position after cursor must be an invoke that matches the signature
+ * for the code in {@code inlinee}.
*
- * With one exception (see below) both the calling code and the inlinee can have catch handlers.
+ * <p>With one exception (see below) both the calling code and the inlinee can have catch
+ * handlers.
*
- * <strong>EXCEPTION:</strong> If the invoke instruction is covered by catch handlers, and the
+ * <p><strong>EXCEPTION:</strong> If the invoke instruction is covered by catch handlers, and the
* code for {@code inlinee} always throws (does not have a normal return) inlining is currently
* <strong>NOT</strong> supported.
*
- * @param appInfo {@link AppInfo} to retrieve class definition.
+ * @param appView {@link AppView} to retrieve class definition.
* @param code the IR code for the block this iterator originates from.
* @param inlinee the IR code for the block this iterator originates from.
* @param blockIterator basic block iterator used to iterate the blocks. This must be positioned
- * just after the block for which this is the instruction iterator. After this method returns it
- * will be positioned just after the basic block returned.
+ * just after the block for which this is the instruction iterator. After this method returns
+ * it will be positioned just after the basic block returned.
* @param blocksToRemove list passed where blocks that where detached from the graph, but not
- * removed are added. When inlining an inlinee that always throws blocks in the <code>code</code>
- * can be detached, and not simply removed unsing the passed <code>blockIterator</code>. When
- * iterating using <code>blockIterator</code> after then method returns the blocks in this list
- * must be skipped when iterating with the active <code>blockIterator</code> and ultimately
- * removed.
+ * removed are added. When inlining an inlinee that always throws blocks in the <code>code
+ * </code> can be detached, and not simply removed unsing the passed <code>blockIterator
+ * </code>. When iterating using <code>blockIterator</code> after then method returns the
+ * blocks in this list must be skipped when iterating with the active <code>blockIterator
+ * </code> and ultimately removed.
* @param downcast tells the inliner to issue a check cast operation.
* @return the basic block with the instructions right after the inlining. This can be a block
- * which can also be in the <code>blocksToRemove</code> list.
+ * which can also be in the <code>blocksToRemove</code> list.
*/
// TODO(sgjesse): Refactor to avoid the need for passing code.
// TODO(sgjesse): Refactor to avoid the need for passing blocksToRemove.
@@ -131,19 +133,17 @@
// TODO(sgjesse): Maybe find a better place for this method.
// TODO(sgjesse): Support inlinee with throwing instructions for invokes with existing handlers.
BasicBlock inlineInvoke(
- AppInfo appInfo,
+ AppView<? extends AppInfo> appView,
IRCode code,
IRCode inlinee,
ListIterator<BasicBlock> blockIterator,
List<BasicBlock> blocksToRemove,
DexType downcast);
- /**
- * See {@link #inlineInvoke(AppInfo, IRCode, IRCode, ListIterator, List, DexType)}.
- */
- default BasicBlock inlineInvoke(AppInfo appInfo, IRCode code, IRCode inlinee) {
+ /** See {@link #inlineInvoke(AppView, IRCode, IRCode, ListIterator, List, DexType)}. */
+ default BasicBlock inlineInvoke(AppView<? extends AppInfo> appView, IRCode code, IRCode inlinee) {
List<BasicBlock> blocksToRemove = new ArrayList<>();
- BasicBlock result = inlineInvoke(appInfo, code, inlinee, null, blocksToRemove, null);
+ BasicBlock result = inlineInvoke(appView, code, inlinee, null, blocksToRemove, null);
code.removeBlocks(blocksToRemove);
return result;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Invoke.java b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
index 48e2659..03beffd 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Invoke.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItem;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -262,11 +263,11 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
DexType returnType = getReturnType();
if (returnType.isVoidType()) {
throw new Unreachable("void methods have no type.");
}
- return TypeLatticeElement.fromDexType(returnType, Nullability.maybeNull(), appInfo);
+ return TypeLatticeElement.fromDexType(returnType, Nullability.maybeNull(), appView);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java b/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
index bb42328..3d13f750 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
@@ -7,6 +7,8 @@
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.cf.code.CfInvokeDynamic;
import com.android.tools.r8.code.InvokeCustomRange;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -121,7 +123,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return getCallSite().methodProto.returnType;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
index d203184..ce3fcb3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
@@ -5,7 +5,9 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.cf.TypeVerificationHelper;
+import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
@@ -87,7 +89,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return getReturnType();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
index f994058..1ca8df7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
@@ -4,10 +4,10 @@
package com.android.tools.r8.ir.code;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.optimize.Inliner.InlineAction;
@@ -48,8 +48,8 @@
}
@Override
- public boolean verifyTypes(AppInfo appInfo, GraphLense graphLense) {
- assert super.verifyTypes(appInfo, graphLense);
+ public boolean verifyTypes(AppView<? extends AppInfo> appView) {
+ assert super.verifyTypes(appView);
TypeLatticeElement receiverType = getReceiver().getTypeLattice();
assert receiverType.isPreciseType();
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java
index 0c0171f..13a8473 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.cf.code.CfMultiANewArray;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -67,8 +68,8 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.fromDexType(type, Nullability.definitelyNotNull(), appInfo);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.fromDexType(type, Nullability.definitelyNotNull(), appView);
}
@Override
@@ -77,7 +78,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return type;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java b/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java
index fbb7307..f89ccf6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.code.FilledNewArrayRange;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -97,8 +98,8 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.fromDexType(type, Nullability.definitelyNotNull(), appInfo);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.fromDexType(type, Nullability.definitelyNotNull(), appView);
}
@Override
@@ -107,7 +108,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
throw cfUnsupported();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java b/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
index 4b9ff7d..cbc0e7c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
@@ -80,7 +80,7 @@
@Override
public void buildCf(CfBuilder builder) {
DexMethod dexMethod = getInvokedMethod();
- DexItemFactory factory = builder.getFactory();
+ DexItemFactory factory = builder.appView.dexItemFactory();
// When we translate InvokeVirtual on MethodHandle/VarHandle into InvokePolymorphic,
// we translate the invoked prototype into a generic prototype that simply accepts Object[].
// To translate InvokePolymorphic back into InvokeVirtual, use the original prototype
diff --git a/src/main/java/com/android/tools/r8/ir/code/LinearFlowInstructionIterator.java b/src/main/java/com/android/tools/r8/ir/code/LinearFlowInstructionIterator.java
index e8bbd69..01c66a8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/LinearFlowInstructionIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/LinearFlowInstructionIterator.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.ir.code;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import java.util.List;
import java.util.ListIterator;
@@ -46,14 +47,14 @@
@Override
public BasicBlock inlineInvoke(
- AppInfo appInfo,
+ AppView<? extends AppInfo> appView,
IRCode code,
IRCode inlinee,
ListIterator<BasicBlock> blockIterator,
List<BasicBlock> blocksToRemove,
DexType downcast) {
return currentBlockIterator.inlineInvoke(
- appInfo, code, inlinee, blockIterator, blocksToRemove, downcast);
+ appView, code, inlinee, blockIterator, blocksToRemove, downcast);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Load.java b/src/main/java/com/android/tools/r8/ir/code/Load.java
index 0b93773..4229b41 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Load.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Load.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -69,7 +70,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return helper.getDexType(src());
}
@@ -79,7 +81,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return src().getTypeLattice();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Move.java b/src/main/java/com/android/tools/r8/ir/code/Move.java
index 8892a52..53c0134 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Move.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Move.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -94,7 +95,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return src().getTypeLattice();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/MoveException.java b/src/main/java/com/android/tools/r8/ir/code/MoveException.java
index 96d5186..3ccd8b0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/MoveException.java
+++ b/src/main/java/com/android/tools/r8/ir/code/MoveException.java
@@ -97,14 +97,14 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return exceptionType;
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.fromDexType(
- exceptionType, Nullability.definitelyNotNull(), appInfo);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.fromDexType(exceptionType, Nullability.definitelyNotNull(), appView);
}
public DexType getExceptionType() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
index a8bcea2..641b77e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
@@ -108,7 +108,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return type;
}
@@ -125,7 +126,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.fromDexType(type, Nullability.definitelyNotNull(), appInfo);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.fromDexType(type, Nullability.definitelyNotNull(), appView);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
index b5401b0..13263d9 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
@@ -100,13 +100,14 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return clazz;
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.fromDexType(clazz, Nullability.definitelyNotNull(), appInfo);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.fromDexType(clazz, Nullability.definitelyNotNull(), appView);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/NonNull.java b/src/main/java/com/android/tools/r8/ir/code/NonNull.java
index 6b016b7..81e69f1 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NonNull.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NonNull.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -98,7 +99,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return src().getTypeLattice().asNonNullable();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java b/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
index 4e1e0ed..2b38cba 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.code.LongToInt;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.analysis.type.PrimitiveTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -142,7 +143,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return PrimitiveTypeLatticeElement.fromNumericType(to);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index 812f928..5e2160f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -6,8 +6,8 @@
import com.android.tools.r8.cf.TypeVerificationHelper;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.InvalidDebugInfoException;
-import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DebugLocalInfo;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.BasicBlock.EdgeType;
@@ -410,10 +410,10 @@
}
// Type of phi(v1, v2, ..., vn) is the least upper bound of all those n operands.
- public TypeLatticeElement computePhiType(AppInfo appInfo) {
+ public TypeLatticeElement computePhiType(DexDefinitionSupplier definitions) {
TypeLatticeElement result = TypeLatticeElement.BOTTOM;
for (Value operand : getOperands()) {
- result = result.join(operand.getTypeLattice(), appInfo);
+ result = result.join(operand.getTypeLattice(), definitions);
}
return result;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/StackValue.java b/src/main/java/com/android/tools/r8/ir/code/StackValue.java
index 20f10a4..18019dc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StackValue.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StackValue.java
@@ -5,6 +5,7 @@
import com.android.tools.r8.cf.TypeVerificationHelper.TypeInfo;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
@@ -20,10 +21,13 @@
assert height >= 0;
}
- public static StackValue create(TypeInfo typeInfo, int height, AppInfo appInfo) {
+ public static StackValue create(
+ TypeInfo typeInfo, int height, AppView<? extends AppInfo> appView) {
return new StackValue(
- typeInfo, TypeLatticeElement.fromDexType(
- typeInfo.getDexType(), Nullability.maybeNull(), appInfo), height);
+ typeInfo,
+ TypeLatticeElement.fromDexType(
+ typeInfo.getDexType(), Nullability.maybeNull(), appView.appInfo()),
+ height);
}
public int getHeight() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
index f4b0beb..6358853 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
@@ -175,13 +175,14 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return getField().type;
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
- return TypeLatticeElement.fromDexType(getField().type, Nullability.maybeNull(), appInfo);
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
+ return TypeLatticeElement.fromDexType(getField().type, Nullability.maybeNull(), appView);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Store.java b/src/main/java/com/android/tools/r8/ir/code/Store.java
index f09107f..2058ba0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Store.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Store.java
@@ -70,7 +70,8 @@
}
@Override
- public DexType computeVerificationType(TypeVerificationHelper helper) {
+ public DexType computeVerificationType(
+ AppView<? extends AppInfo> appView, TypeVerificationHelper helper) {
return helper.getDexType(src());
}
@@ -80,7 +81,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return src().getTypeLattice();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Unop.java b/src/main/java/com/android/tools/r8/ir/code/Unop.java
index 5ac4668..98083c8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Unop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Unop.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -58,7 +59,7 @@
}
@Override
- public TypeLatticeElement evaluate(AppInfo appInfo) {
+ public TypeLatticeElement evaluate(AppView<? extends AppInfo> appView) {
return source().getTypeLattice();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 3b783d9..9cbdd34 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -892,7 +892,7 @@
&& getConstInstruction().asConstNumber().isZero();
}
- public void widening(AppInfo appInfo, TypeLatticeElement newType) {
+ public void widening(AppView<? extends AppInfo> appView, TypeLatticeElement newType) {
// TODO(b/72693244): Enable assertion.
// During WIDENING (due to fix-point iteration), type update is monotonically upwards,
// i.e., towards something wider.
@@ -902,7 +902,7 @@
typeLattice = newType;
}
- public void narrowing(AppInfo appInfo, TypeLatticeElement newType) {
+ public void narrowing(AppView<? extends AppInfo> appView, TypeLatticeElement newType) {
// TODO(b/72693244): Enable assertion.
// During NARROWING (e.g., after inlining), type update is monotonically downwards,
// i.e., towards something narrower, with more specific type info.
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
index e9c825d..ab1e319 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
@@ -567,7 +567,7 @@
private void processFieldAccess(DexField field) {
// Any field access implicitly calls the class initializer.
if (field.clazz.isClassType()) {
- DexEncodedField encodedField = appInfo.resolveFieldOn(field.clazz, field);
+ DexEncodedField encodedField = appInfo.resolveField(field);
if (encodedField != null && encodedField.isStatic()) {
addClassInitializerTarget(field.getHolder());
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index 743f2a5..c9e30e2 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -19,16 +19,16 @@
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -52,7 +52,6 @@
import com.android.tools.r8.ir.optimize.PeepholeOptimizer;
import com.android.tools.r8.ir.optimize.PhiOptimizations;
import com.android.tools.r8.ir.optimize.peepholes.BasicBlockMuncher;
-import com.android.tools.r8.utils.InternalOptions;
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap.Entry;
@@ -76,11 +75,10 @@
private static final int SUFFIX_SHARING_OVERHEAD = 30;
private static final int IINC_PATTERN_SIZE = 4;
- private final DexItemFactory factory;
+ public final AppView<? extends AppInfo> appView;
private final DexEncodedMethod method;
private final IRCode code;
- private TypeVerificationHelper typeVerificationHelper;
private Map<BasicBlock, CfLabel> labels;
private Set<CfLabel> emittedLabels;
private List<CfInstruction> instructions;
@@ -97,14 +95,10 @@
private final Int2ReferenceMap<LocalVariableInfo> openLocalVariables =
new Int2ReferenceOpenHashMap<>();
- private AppInfo appInfo;
-
private Map<NewInstance, List<InvokeDirect>> initializers;
private List<InvokeDirect> thisInitializers;
private Map<NewInstance, CfLabel> newInstanceLabels;
- private InternalOptions options;
-
// Internal structure maintaining the stack height.
private static class StackHeightTracker {
int maxHeight = 0;
@@ -131,32 +125,22 @@
}
}
- public CfBuilder(DexEncodedMethod method, IRCode code, DexItemFactory factory) {
+ public CfBuilder(AppView<? extends AppInfo> appView, DexEncodedMethod method, IRCode code) {
+ this.appView = appView;
this.method = method;
this.code = code;
- this.factory = factory;
}
- public DexItemFactory getFactory() {
- return factory;
- }
-
- public CfCode build(
- CodeRewriter rewriter,
- GraphLense graphLense,
- InternalOptions options,
- AppInfo appInfo) {
- this.options = options;
- this.appInfo = appInfo;
+ public CfCode build(CodeRewriter rewriter) {
computeInitializers();
- typeVerificationHelper = new TypeVerificationHelper(code, factory, appInfo);
+ TypeVerificationHelper typeVerificationHelper = new TypeVerificationHelper(appView, code);
typeVerificationHelper.computeVerificationTypes();
rewriter.converter.deadCodeRemover.run(code);
rewriteNots();
- LoadStoreHelper loadStoreHelper = new LoadStoreHelper(code, typeVerificationHelper, appInfo);
+ LoadStoreHelper loadStoreHelper = new LoadStoreHelper(appView, code, typeVerificationHelper);
loadStoreHelper.insertLoadsAndStores();
// Run optimizations on phis and basic blocks in a fixpoint.
- if (!options.testing.disallowLoadStoreOptimization) {
+ if (!appView.options().testing.disallowLoadStoreOptimization) {
PhiOptimizations phiOptimizations = new PhiOptimizations();
boolean reachedFixpoint = false;
phiOptimizations.optimize(code);
@@ -166,7 +150,7 @@
}
}
assert code.isConsistentSSA();
- registerAllocator = new CfRegisterAllocator(code, options, typeVerificationHelper);
+ registerAllocator = new CfRegisterAllocator(appView, code, typeVerificationHelper);
registerAllocator.allocateRegisters();
loadStoreHelper.insertPhiMoves(registerAllocator);
@@ -181,16 +165,16 @@
CodeRewriter.collapseTrivialGotos(method, code);
DexBuilder.removeRedundantDebugPositions(code);
CfCode code = buildCfCode();
- assert verifyInvokeInterface(code, appInfo);
+ assert verifyInvokeInterface(code, appView);
return code;
}
- private static boolean verifyInvokeInterface(CfCode code, AppInfo appInfo) {
+ private static boolean verifyInvokeInterface(CfCode code, DexDefinitionSupplier definitions) {
for (CfInstruction instruction : code.instructions) {
if (instruction instanceof CfInvoke) {
CfInvoke invoke = (CfInvoke) instruction;
if (invoke.getMethod().holder.isClassType()) {
- DexClass holder = appInfo.definitionFor(invoke.getMethod().holder);
+ DexClass holder = definitions.definitionFor(invoke.getMethod().holder);
assert holder == null || holder.isInterface() == invoke.isInterface();
}
}
@@ -199,7 +183,7 @@
}
public DexField resolveField(DexField field) {
- DexEncodedField resolvedField = appInfo.resolveFieldOn(field.clazz, field);
+ DexEncodedField resolvedField = appView.appInfo().resolveField(field);
return resolvedField == null ? field : resolvedField.field;
}
@@ -229,7 +213,8 @@
for (Instruction user : value.uniqueUsers()) {
if (user instanceof InvokeDirect
&& user.inValues().get(0) == value
- && user.asInvokeDirect().getInvokedMethod().name == factory.constructorMethodName) {
+ && user.asInvokeDirect().getInvokedMethod().name
+ == appView.dexItemFactory().constructorMethodName) {
initializers.add(user.asInvokeDirect());
}
}
@@ -488,7 +473,7 @@
// Ignore synthetic positions prior to any actual position, except when inlined
// (that is, callerPosition != null).
&& !(currentPosition.isNone() && position.synthetic && position.callerPosition == null)
- && (options.debug || instruction.instructionTypeCanThrow());
+ && (appView.options().debug || instruction.instructionTypeCanThrow());
if (!didLocalsChange && !didPositionChange) {
return;
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
index 661d3e9..25d1b39 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
@@ -15,6 +15,8 @@
import com.android.tools.r8.cf.code.CfSwitch;
import com.android.tools.r8.cf.code.CfThrow;
import com.android.tools.r8.cf.code.CfTryCatch;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
import com.android.tools.r8.graph.DebugLocalInfo;
@@ -265,9 +267,11 @@
@Override
public int traceInstruction(int instructionIndex, IRBuilder builder) {
CfInstruction instruction = code.getInstructions().get(instructionIndex);
- assert builder.isGeneratingClassFiles() == internalOutputMode.isGeneratingClassFiles();
+ AppView<? extends AppInfo> appView = builder.appView;
+ assert appView.options().isGeneratingClassFiles()
+ == internalOutputMode.isGeneratingClassFiles();
if (canThrowHelper(instruction)) {
- TryHandlerList tryHandlers = getTryHandlers(instructionIndex, builder.getFactory());
+ TryHandlerList tryHandlers = getTryHandlers(instructionIndex, appView.dexItemFactory());
if (!tryHandlers.isEmpty()) {
// Ensure the block starts at the start of the try-range (don't enqueue, not a target).
builder.ensureBlockWithoutEnqueuing(tryHandlers.startOffset);
@@ -366,8 +370,7 @@
builder.addBooleanNonThisArgument(argumentRegister++);
} else {
TypeLatticeElement typeLattice =
- TypeLatticeElement.fromDexType(
- type, Nullability.maybeNull(), builder.getAppInfo());
+ TypeLatticeElement.fromDexType(type, Nullability.maybeNull(), builder.appView);
builder.addNonThisArgument(argumentRegister, typeLattice);
argumentRegister += typeLattice.requiredRegisters();
}
@@ -442,7 +445,7 @@
if (canThrowHelper(instruction)) {
Snapshot exceptionTransfer =
- state.getSnapshot().exceptionTransfer(builder.getFactory().throwableType);
+ state.getSnapshot().exceptionTransfer(builder.appView.dexItemFactory().throwableType);
for (int target : currentBlockInfo.exceptionalSuccessors) {
recordStateForTarget(target, exceptionTransfer);
}
@@ -626,7 +629,8 @@
@Override
public CatchHandlers<Integer> getCurrentCatchHandlers(IRBuilder builder) {
TryHandlerList tryHandlers =
- getTryHandlers(instructionOffset(currentInstructionIndex), builder.getFactory());
+ getTryHandlers(
+ instructionOffset(currentInstructionIndex), builder.appView.dexItemFactory());
if (tryHandlers.isEmpty()) {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
index 0790018..373949e 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
@@ -27,7 +27,6 @@
import com.android.tools.r8.code.MoveResultWide;
import com.android.tools.r8.code.SwitchPayload;
import com.android.tools.r8.code.Throw;
-import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexCode.Try;
@@ -79,11 +78,7 @@
private final DexMethod originalMethod;
public DexSourceCode(
- DexCode code,
- DexEncodedMethod method,
- DexMethod originalMethod,
- Position callerPosition,
- AppInfo appInfo) {
+ DexCode code, DexEncodedMethod method, DexMethod originalMethod, Position callerPosition) {
this.code = code;
this.method = method;
this.originalMethod = originalMethod;
@@ -172,7 +167,7 @@
if (nextRemovedArgument != null && nextRemovedArgument.getArgumentIndex() == argumentIndex) {
type =
TypeLatticeElement.fromDexType(
- nextRemovedArgument.getType(), Nullability.maybeNull(), builder.getAppInfo());
+ nextRemovedArgument.getType(), Nullability.maybeNull(), builder.appView);
builder.addConstantOrUnusedArgument(register);
nextRemovedArgument =
removedArgumentIterator.hasNext() ? removedArgumentIterator.next() : null;
@@ -181,7 +176,7 @@
TypeLatticeElement.fromDexType(
method.method.proto.parameters.values[usedArgumentIndex++],
Nullability.maybeNull(),
- builder.getAppInfo());
+ builder.appView);
builder.addNonThisArgument(register, type);
}
register += type.requiredRegisters();
@@ -203,7 +198,7 @@
@Override
public void buildInstruction(
IRBuilder builder, int instructionIndex, boolean firstBlockInstruction) {
- updateCurrentCatchHandlers(instructionIndex, builder.getFactory());
+ updateCurrentCatchHandlers(instructionIndex, builder.appView.dexItemFactory());
updateDebugPosition(instructionIndex, builder);
currentDexInstruction = code.instructions[instructionIndex];
currentDexInstruction.buildIR(builder);
@@ -390,7 +385,8 @@
}
builder.ensureBlockWithoutEnqueuing(tryRangeStartAddress);
// Edge to exceptional successors.
- for (Integer handlerOffset : getUniqueTryHandlerOffsets(tryRange, builder.getFactory())) {
+ for (Integer handlerOffset :
+ getUniqueTryHandlerOffsets(tryRange, builder.appView.dexItemFactory())) {
builder.ensureExceptionalSuccessorBlock(offset, handlerOffset);
}
// If the following instruction is a move-result include it in this (the invokes) block.
@@ -470,12 +466,7 @@
private List<Integer> getTryHandlerOffsets(Try tryRange, DexItemFactory factory) {
List<Integer> handlerOffsets = new ArrayList<>();
- forEachTryRange(
- tryRange,
- factory,
- (type, addr) -> {
- handlerOffsets.add(addr);
- });
+ forEachTryRange(tryRange, factory, (type, addr) -> handlerOffsets.add(addr));
return handlerOffsets;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 2e22480..0d7f6e1 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -13,12 +13,12 @@
import com.android.tools.r8.errors.InvalidDebugInfoException;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItem;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProto;
@@ -102,7 +102,6 @@
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.IteratorUtils;
import com.android.tools.r8.utils.Pair;
import com.google.common.collect.Sets;
@@ -136,6 +135,7 @@
* http://compilers.cs.uni-saarland.de/papers/bbhlmz13cc.pdf
*/
public class IRBuilder {
+
private static final TypeLatticeElement INT = TypeLatticeElement.INT;
private static final TypeLatticeElement FLOAT = TypeLatticeElement.FLOAT;
private static final TypeLatticeElement LONG = TypeLatticeElement.LONG;
@@ -170,16 +170,8 @@
}
}
- public DexItemFactory getFactory() {
- return options.itemFactory;
- }
-
- public AppInfo getAppInfo() {
- return appInfo;
- }
-
public TypeLatticeElement getTypeLattice(DexType type, Nullability nullability) {
- return TypeLatticeElement.fromDexType(type, nullability, appInfo);
+ return TypeLatticeElement.fromDexType(type, nullability, appView);
}
// SSA construction uses a worklist of basic blocks reachable from the entry and their
@@ -394,7 +386,7 @@
final private ValueNumberGenerator valueNumberGenerator;
private final DexEncodedMethod method;
private DexEncodedMethod context;
- private final AppInfo appInfo;
+ public final AppView<? extends AppInfo> appView;
private final Origin origin;
final RewrittenPrototypeDescription prototypeChanges;
private ListIterator<RemovedArgumentInfo> removedArgumentsIterator;
@@ -406,7 +398,6 @@
private SourceCode source;
private boolean throwingInstructionInCurrentBlock = false;
- private final InternalOptions options;
// Pending local reads.
private Value previousLocalValue = null;
@@ -431,44 +422,33 @@
public IRBuilder(
DexEncodedMethod method,
- AppInfo appInfo,
+ AppView<? extends AppInfo> appView,
SourceCode source,
- InternalOptions options,
Origin origin) {
- this(
- method,
- appInfo,
- source,
- options,
- origin,
- new ValueNumberGenerator(),
- GraphLense.getIdentityLense());
+ this(method, appView, source, origin, new ValueNumberGenerator());
}
public IRBuilder(
DexEncodedMethod method,
- AppInfo appInfo,
+ AppView<? extends AppInfo> appView,
SourceCode source,
- InternalOptions options,
Origin origin,
- ValueNumberGenerator valueNumberGenerator,
- GraphLense graphLense) {
+ ValueNumberGenerator valueNumberGenerator) {
assert source != null;
this.method = method;
- this.appInfo = appInfo;
+ this.appView = appView;
this.source = source;
this.valueNumberGenerator =
valueNumberGenerator != null ? valueNumberGenerator : new ValueNumberGenerator();
- this.options = options;
this.origin = origin;
if (method.isProcessed()) {
// NOTE: This is currently assuming that we never remove additional arguments from methods
// after they have already been processed once.
- assert verifyMethodSignature(method, graphLense);
+ assert verifyMethodSignature(method, appView.graphLense());
this.prototypeChanges = RewrittenPrototypeDescription.none();
} else {
- this.prototypeChanges = graphLense.lookupPrototypeChanges(method.method);
+ this.prototypeChanges = appView.graphLense().lookupPrototypeChanges(method.method);
if (Log.ENABLED && prototypeChanges.getRemovedArgumentsInfo().hasRemovedArguments()) {
Log.info(
@@ -490,12 +470,8 @@
return true;
}
- public boolean isGeneratingClassFiles() {
- return options.isGeneratingClassFiles();
- }
-
public boolean isDebugMode() {
- return options.debug || method.getOptimizationInfo().isReachabilitySensitive();
+ return appView.options().debug || method.getOptimizationInfo().isReachabilitySensitive();
}
public Int2ReferenceSortedMap<BlockInfo> getCFG() {
@@ -618,7 +594,7 @@
// Package up the IR code.
IRCode ir =
new IRCode(
- options,
+ appView.options(),
method,
blocks,
valueNumberGenerator,
@@ -641,10 +617,9 @@
if (hasImpreciseValues || impreciseInstructions != null) {
// In DEX we may need to constrain all values and instructions to precise types.
assert source instanceof DexSourceCode;
- new TypeConstraintResolver(this, options.reporter)
- .resolve(impreciseInstructions, ir, appInfo, method, context);
+ new TypeConstraintResolver(appView, this).resolve(impreciseInstructions, ir, method, context);
} else {
- new TypeAnalysis(appInfo, context).widening(method, ir);
+ new TypeAnalysis(appView, context).widening(method, ir);
}
assert ir.isConsistentSSA();
@@ -656,7 +631,7 @@
}
public void constrainType(Value value, ValueTypeConstraint constraint) {
- value.constrainType(constraint, method.method, origin, options.reporter);
+ value.constrainType(constraint, method.method, origin, appView.options().reporter);
}
private void addImpreciseInstruction(ImpreciseMemberTypeInstruction instruction) {
@@ -819,9 +794,10 @@
Position position = source.getCanonicalDebugPositionAtOffset(moveExceptionItem.targetOffset);
if (moveExceptionDest >= 0) {
TypeLatticeElement typeLattice =
- TypeLatticeElement.fromDexType(moveExceptionItem.guard, definitelyNotNull(), appInfo);
+ TypeLatticeElement.fromDexType(moveExceptionItem.guard, definitelyNotNull(), appView);
Value out = writeRegister(moveExceptionDest, typeLattice, ThrowingInfo.NO_THROW, null);
- MoveException moveException = new MoveException(out, moveExceptionItem.guard, options);
+ MoveException moveException =
+ new MoveException(out, moveExceptionItem.guard, appView.options());
moveException.setPosition(position);
currentBlock.add(moveException);
}
@@ -882,7 +858,7 @@
boolean receiverCouldBeNull = context != null && context != method;
Nullability nullability = receiverCouldBeNull ? maybeNull() : definitelyNotNull();
TypeLatticeElement receiver =
- TypeLatticeElement.fromDexType(method.method.getHolder(), nullability, appInfo);
+ TypeLatticeElement.fromDexType(method.method.getHolder(), nullability, appView);
Value value = writeRegister(register, receiver, ThrowingInfo.NO_THROW, local);
addInstruction(new Argument(value));
value.markAsThis();
@@ -1065,7 +1041,7 @@
public void addCheckCast(int value, DexType type) {
Value in = readRegister(value, ValueTypeConstraint.OBJECT);
TypeLatticeElement castTypeLattice =
- TypeLatticeElement.fromDexType(type, in.getTypeLattice().nullability(), appInfo);
+ TypeLatticeElement.fromDexType(type, in.getTypeLattice().nullability(), appView);
Value out = writeRegister(value, castTypeLattice, ThrowingInfo.CAN_THROW);
CheckCast instruction = new CheckCast(out, in, type);
assert instruction.instructionTypeCanThrow();
@@ -1110,7 +1086,7 @@
public void addConstClass(int dest, DexType type) {
TypeLatticeElement typeLattice =
- TypeLatticeElement.classClassType(appInfo, definitelyNotNull());
+ TypeLatticeElement.classClassType(appView, definitelyNotNull());
Value out = writeRegister(dest, typeLattice, ThrowingInfo.CAN_THROW);
ConstClass instruction = new ConstClass(out, type);
assert instruction.instructionTypeCanThrow();
@@ -1118,7 +1094,7 @@
}
public void addConstMethodHandle(int dest, DexMethodHandle methodHandle) {
- if (!options.canUseConstantMethodHandle()) {
+ if (!appView.options().canUseConstantMethodHandle()) {
throw new ApiLevelException(
AndroidApiLevel.P,
"Const-method-handle",
@@ -1126,14 +1102,14 @@
}
TypeLatticeElement typeLattice =
TypeLatticeElement.fromDexType(
- appInfo.dexItemFactory.methodHandleType, definitelyNotNull(), appInfo);
+ appView.dexItemFactory().methodHandleType, definitelyNotNull(), appView);
Value out = writeRegister(dest, typeLattice, ThrowingInfo.CAN_THROW);
ConstMethodHandle instruction = new ConstMethodHandle(out, methodHandle);
add(instruction);
}
public void addConstMethodType(int dest, DexProto methodType) {
- if (!options.canUseConstantMethodType()) {
+ if (!appView.options().canUseConstantMethodType()) {
throw new ApiLevelException(
AndroidApiLevel.P,
"Const-method-type",
@@ -1141,19 +1117,21 @@
}
TypeLatticeElement typeLattice =
TypeLatticeElement.fromDexType(
- appInfo.dexItemFactory.methodTypeType, definitelyNotNull(), appInfo);
+ appView.dexItemFactory().methodTypeType, definitelyNotNull(), appView);
Value out = writeRegister(dest, typeLattice, ThrowingInfo.CAN_THROW);
ConstMethodType instruction = new ConstMethodType(out, methodType);
add(instruction);
}
private ThrowingInfo throwingInfoForConstStrings() {
- return options.isGeneratingClassFiles() ? ThrowingInfo.NO_THROW : ThrowingInfo.CAN_THROW;
+ return appView.options().isGeneratingClassFiles()
+ ? ThrowingInfo.NO_THROW
+ : ThrowingInfo.CAN_THROW;
}
public void addConstString(int dest, DexString string) {
TypeLatticeElement typeLattice =
- TypeLatticeElement.stringClassType(appInfo, definitelyNotNull());
+ TypeLatticeElement.stringClassType(appView, definitelyNotNull());
ThrowingInfo throwingInfo = throwingInfoForConstStrings();
add(new ConstString(writeRegister(dest, typeLattice, throwingInfo), string, throwingInfo));
}
@@ -1161,7 +1139,7 @@
public void addDexItemBasedConstString(int dest, DexReference item) {
assert method.getOptimizationInfo().useIdentifierNameString();
TypeLatticeElement typeLattice =
- TypeLatticeElement.stringClassType(appInfo, definitelyNotNull());
+ TypeLatticeElement.stringClassType(appView, definitelyNotNull());
ThrowingInfo throwingInfo = throwingInfoForConstStrings();
Value out = writeRegister(dest, typeLattice, throwingInfo);
DexItemBasedConstString instruction = new DexItemBasedConstString(out, item, throwingInfo);
@@ -1347,11 +1325,12 @@
public void addInstanceGet(int dest, int object, DexField field) {
Value in = readRegister(object, ValueTypeConstraint.OBJECT);
- Value out = writeRegister(
- dest,
- TypeLatticeElement.fromDexType(field.type, maybeNull(), appInfo),
- ThrowingInfo.CAN_THROW);
- out.setKnownToBeBoolean(field.type == getFactory().booleanType);
+ Value out =
+ writeRegister(
+ dest,
+ TypeLatticeElement.fromDexType(field.type, maybeNull(), appView),
+ ThrowingInfo.CAN_THROW);
+ out.setKnownToBeBoolean(field.type == appView.dexItemFactory().booleanType);
InstanceGet instruction = new InstanceGet(out, in, field);
assert instruction.instructionTypeCanThrow();
addInstruction(instruction);
@@ -1376,27 +1355,27 @@
Type type, DexItem item, DexProto callSiteProto, List<Value> arguments, boolean itf) {
if (type == Type.POLYMORPHIC) {
assert item instanceof DexMethod;
- if (!options.canUseInvokePolymorphic()) {
+ if (!appView.options().canUseInvokePolymorphic()) {
throw new ApiLevelException(
AndroidApiLevel.O,
"MethodHandle.invoke and MethodHandle.invokeExact",
null /* sourceString */);
- } else if (!options.canUseInvokePolymorphicOnVarHandle()
- && ((DexMethod) item).getHolder() == options.itemFactory.varHandleType) {
+ } else if (!appView.options().canUseInvokePolymorphicOnVarHandle()
+ && ((DexMethod) item).getHolder() == appView.dexItemFactory().varHandleType) {
throw new ApiLevelException(
AndroidApiLevel.P,
"Call to polymorphic signature of VarHandle",
null /* sourceString */);
}
}
- if (appInfo != null && type == Type.VIRTUAL) {
+ if (type == Type.VIRTUAL) {
// If an invoke-virtual targets a private method in the current class overriding will
// not apply (see jvm spec on method resolution 5.4.3.3 and overriding 5.4.5) and
// therefore we use an invoke-direct instead. We need to do this as the Android Runtime
// will not allow invoke-virtual of a private method.
DexMethod invocationMethod = (DexMethod) item;
if (invocationMethod.holder == method.method.holder) {
- DexEncodedMethod directTarget = appInfo.lookupDirectTarget(invocationMethod);
+ DexEncodedMethod directTarget = appView.appInfo().lookupDirectTarget(invocationMethod);
if (directTarget != null && invocationMethod.holder == directTarget.method.holder) {
type = Type.DIRECT;
}
@@ -1506,7 +1485,7 @@
}
checkInvokeArgumentRegisters(registerIndex, argumentRegisterCount);
// Note: We only call this register variant from DEX inputs where isInterface does not matter.
- assert !isGeneratingClassFiles();
+ assert appView.options().isGeneratingDex();
addInvoke(type, method, callSiteProto, arguments, false /* isInterface */);
}
@@ -1531,7 +1510,7 @@
}
public void addMultiNewArray(DexType type, int dest, int[] dimensions) {
- assert isGeneratingClassFiles();
+ assert appView.options().isGeneratingClassFiles();
List<Value> arguments = new ArrayList<>(dimensions.length);
for (int dimension : dimensions) {
arguments.add(readRegister(dimension, ValueTypeConstraint.INT));
@@ -1571,7 +1550,7 @@
}
checkInvokeArgumentRegisters(register, firstArgumentRegister + argumentCount);
// Note: We only call this register variant from DEX inputs where isInterface does not matter.
- assert !isGeneratingClassFiles();
+ assert appView.options().isGeneratingDex();
addInvoke(type, method, callSiteProto, arguments, false /* isInterface */);
}
@@ -1589,7 +1568,7 @@
}
checkInvokeArgumentRegisters(register, firstArgumentRegister + argumentCount);
// Note: We only call this register variant from DEX inputs where isInterface does not matter.
- assert !isGeneratingClassFiles();
+ assert appView.options().isGeneratingDex();
addInvoke(Invoke.Type.NEW_ARRAY, type, null, arguments, false /* isInterface */);
}
@@ -1630,7 +1609,7 @@
Value outValue =
writeRegister(
dest,
- TypeLatticeElement.fromDexType(outType, maybeNull(), appInfo),
+ TypeLatticeElement.fromDexType(outType, maybeNull(), appView),
ThrowingInfo.CAN_THROW);
outValue.setKnownToBeBoolean(outType.isBooleanType());
invoke.setOutValue(outValue);
@@ -1648,7 +1627,7 @@
Value in = readNumericRegister(value, type);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
Instruction instruction;
- if (options.canUseNotInstruction()) {
+ if (appView.options().canUseNotInstruction()) {
instruction = new Not(type, out, in);
} else {
Value minusOne = readLiteral(ValueTypeConstraint.fromNumericType(type), -1);
@@ -1662,7 +1641,7 @@
assert type.isArrayType();
Value in = readRegister(size, ValueTypeConstraint.INT);
TypeLatticeElement arrayTypeLattice =
- TypeLatticeElement.fromDexType(type, definitelyNotNull(), appInfo);
+ TypeLatticeElement.fromDexType(type, definitelyNotNull(), appView);
Value out = writeRegister(dest, arrayTypeLattice, ThrowingInfo.CAN_THROW);
NewArrayEmpty instruction = new NewArrayEmpty(out, in, type);
assert instruction.instructionTypeCanThrow();
@@ -1679,7 +1658,7 @@
public void addNewInstance(int dest, DexType type) {
TypeLatticeElement instanceType =
- TypeLatticeElement.fromDexType(type, definitelyNotNull(), appInfo);
+ TypeLatticeElement.fromDexType(type, definitelyNotNull(), appView);
Value out = writeRegister(dest, instanceType, ThrowingInfo.CAN_THROW);
NewInstance instruction = new NewInstance(type, out);
assert instruction.instructionTypeCanThrow();
@@ -1687,7 +1666,7 @@
}
public void addReturn(int value) {
- if (method.method.proto.returnType == appInfo.dexItemFactory.voidType) {
+ if (method.method.proto.returnType == appView.dexItemFactory().voidType) {
assert prototypeChanges.hasBeenChangedToReturnVoid();
addReturn();
} else {
@@ -1710,11 +1689,12 @@
}
public void addStaticGet(int dest, DexField field) {
- Value out = writeRegister(
- dest,
- TypeLatticeElement.fromDexType(field.type, maybeNull(), appInfo),
- ThrowingInfo.CAN_THROW);
- out.setKnownToBeBoolean(field.type == getFactory().booleanType);
+ Value out =
+ writeRegister(
+ dest,
+ TypeLatticeElement.fromDexType(field.type, maybeNull(), appView),
+ ThrowingInfo.CAN_THROW);
+ out.setKnownToBeBoolean(field.type == appView.dexItemFactory().booleanType);
StaticGet instruction = new StaticGet(out, field);
assert instruction.instructionTypeCanThrow();
addInstruction(instruction);
@@ -1932,9 +1912,9 @@
Value in2 = readNumericRegister(right, type);
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
Instruction instruction;
- if (options.canUseNotInstruction() &&
- in2.isConstNumber() &&
- in2.getConstInstruction().asConstNumber().isIntegerNegativeOne(type)) {
+ if (appView.options().canUseNotInstruction()
+ && in2.isConstNumber()
+ && in2.getConstInstruction().asConstNumber().isIntegerNegativeOne(type)) {
instruction = new Not(type, out, in1);
} else {
instruction = new Xor(type, out, in1, in2);
@@ -1947,7 +1927,7 @@
assert isNonLongIntegerType(type);
Value in1 = readNumericRegister(value, type);
Instruction instruction;
- if (options.canUseNotInstruction() && constant == -1) {
+ if (appView.options().canUseNotInstruction() && constant == -1) {
Value out = writeNumericRegister(dest, type, ThrowingInfo.NO_THROW);
instruction = new Not(type, out, in1);
} else {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 7900d16..85d9a2f 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -193,19 +193,22 @@
AppView<? extends AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
AppInfoWithLiveness appInfoWithLiveness = appViewWithLiveness.appInfo();
assert rootSet != null;
+ this.classInliner =
+ options.enableClassInlining && options.enableInlining
+ ? new ClassInliner(appViewWithLiveness, lambdaRewriter)
+ : null;
this.classStaticizer =
options.enableClassStaticizer ? new ClassStaticizer(appViewWithLiveness, this) : null;
this.nonNullTracker =
new NonNullTracker(
- appInfoWithLiveness, libraryMethodsReturningNonNull(appView.dexItemFactory()));
- this.inliner = new Inliner(appViewWithLiveness, this, options, mainDexClasses);
- this.outliner = new Outliner(appInfoWithLiveness, options, this);
+ appViewWithLiveness, libraryMethodsReturningNonNull(appView.dexItemFactory()));
+ this.inliner = new Inliner(appViewWithLiveness, mainDexClasses);
+ this.outliner = new Outliner(appViewWithLiveness, this);
this.memberValuePropagation =
options.enableValuePropagation ? new MemberValuePropagation(appViewWithLiveness) : null;
this.lensCodeRewriter = new LensCodeRewriter(appViewWithLiveness);
if (!appInfoWithLiveness.identifierNameStrings.isEmpty() && options.enableMinification) {
- this.identifierNameStringMarker =
- new IdentifierNameStringMarker(appInfoWithLiveness, options);
+ this.identifierNameStringMarker = new IdentifierNameStringMarker(appViewWithLiveness);
} else {
this.identifierNameStringMarker = null;
}
@@ -217,6 +220,7 @@
: null;
this.typeChecker = new TypeChecker(appView);
} else {
+ this.classInliner = null;
this.classStaticizer = null;
this.nonNullTracker = null;
this.inliner = null;
@@ -228,20 +232,11 @@
this.uninstantiatedTypeOptimization = null;
this.typeChecker = null;
}
- this.classInliner =
- (options.enableClassInlining && options.enableInlining && inliner != null)
- ? new ClassInliner(
- appView.dexItemFactory(), lambdaRewriter, options.classInliningInstructionLimit)
- : null;
this.deadCodeRemover = new DeadCodeRemover(appView, codeRewriter);
this.idempotentFunctionCallCanonicalizer =
new IdempotentFunctionCallCanonicalizer(appView.dexItemFactory());
}
- public GraphLense graphLense() {
- return appView != null ? appView.graphLense() : GraphLense.getIdentityLense();
- }
-
public Set<DexCallSite> getDesugaredCallSites() {
if (lambdaRewriter != null) {
return lambdaRewriter.getDesugaredCallSites();
@@ -309,12 +304,11 @@
}
}
- private Set<DexEncodedMethod> staticizeClasses(
- OptimizationFeedback feedback, ExecutorService executorService) throws ExecutionException {
+ private void staticizeClasses(OptimizationFeedback feedback, ExecutorService executorService)
+ throws ExecutionException {
if (classStaticizer != null) {
- return classStaticizer.staticizeCandidates(feedback, executorService);
+ classStaticizer.staticizeCandidates(feedback, executorService);
}
- return ImmutableSet.of();
}
private void collectStaticizerCandidates(DexApplication application) {
@@ -519,7 +513,7 @@
printPhase("Primary optimization pass");
// Process the application identifying outlining candidates.
- GraphLense graphLenseForIR = graphLense();
+ GraphLense graphLenseForIR = appView.graphLense();
OptimizationFeedbackDelayed feedback = delayedOptimizationFeedback;
{
timing.begin("Build call graph");
@@ -535,16 +529,16 @@
this::waveDone,
executorService);
timing.end();
- assert graphLenseForIR == graphLense();
+ assert graphLenseForIR == appView.graphLense();
}
// Second inlining pass for dealing with double inline callers.
if (inliner != null) {
printPhase("Double caller inlining");
- assert graphLenseForIR == graphLense();
+ assert graphLenseForIR == appView.graphLense();
inliner.processDoubleInlineCallers(this, executorService, feedback);
feedback.updateVisibleOptimizationInfo();
- assert graphLenseForIR == graphLense();
+ assert graphLenseForIR == appView.graphLense();
}
// TODO(b/112831361): Implement support for staticizeClasses in CF backend.
@@ -654,7 +648,6 @@
private void forEachSelectedOutliningMethod(
ExecutorService executorService, BiConsumer<IRCode, DexEncodedMethod> consumer)
throws ExecutionException {
- assert appView != null;
assert !options.skipIR;
Set<DexEncodedMethod> methods = outliner.getMethodsSelectedForOutlining();
List<Future<?>> futures = new ArrayList<>();
@@ -663,11 +656,7 @@
executorService.submit(
() -> {
IRCode code =
- method.buildIR(
- appView.appInfo(),
- appView.graphLense(),
- options,
- appView.appInfo().originFor(method.method.holder));
+ method.buildIR(appView, appView.appInfo().originFor(method.method.holder));
assert code != null;
assert !method.getCode().isOutlineCode();
// Instead of repeating all the optimizations of rewriteCode(), only run the
@@ -685,7 +674,7 @@
private void collectLambdaMergingCandidates(DexApplication application) {
if (lambdaMerger != null) {
- lambdaMerger.collectGroupCandidates(application, appView.appInfo().withLiveness(), options);
+ lambdaMerger.collectGroupCandidates(application, appView.withLiveness());
}
}
@@ -846,9 +835,7 @@
feedback.markProcessed(method, ConstraintWithTarget.NEVER);
return;
}
- AppInfo appInfo = appView.appInfo();
- IRCode code =
- method.buildIR(appInfo, graphLense(), options, appInfo.originFor(method.method.holder));
+ IRCode code = method.buildIR(appView, appView.appInfo().originFor(method.method.holder));
if (code == null) {
feedback.markProcessed(method, ConstraintWithTarget.NEVER);
return;
@@ -878,7 +865,7 @@
if (lensCodeRewriter != null) {
lensCodeRewriter.rewrite(code, method);
} else {
- assert graphLense().isIdentityLense();
+ assert appView.graphLense().isIdentityLense();
}
}
@@ -899,7 +886,7 @@
// assert fails, then the types that we have inferred are unsound, or the method does not type
// check. In the latter case, the type checker should be extended to detect the issue such that
// we will return with finalizeEmptyThrowingCode() above.
- assert code.verifyTypes(appInfo, appView, graphLense());
+ assert code.verifyTypes(appView);
if (classStaticizer != null) {
classStaticizer.fixupMethodCode(method, code);
@@ -917,11 +904,12 @@
memberValuePropagation.rewriteWithConstantValues(
code, method.method.holder, isProcessedConcurrently);
}
- if (options.enableSwitchMapRemoval && appInfo.hasLiveness()) {
+ if (options.enableSwitchMapRemoval) {
+ assert appView.enableWholeProgramOptimizations();
codeRewriter.removeSwitchMaps(code);
}
if (options.disableAssertions) {
- codeRewriter.disableAssertions(appInfo, method, code, feedback);
+ codeRewriter.disableAssertions(appView, method, code, feedback);
}
previous = printMethod(code, "IR after disable assertions (SSA)", previous);
@@ -939,9 +927,9 @@
previous = printMethod(code, "IR after inlining (SSA)", previous);
- if (appInfo.hasLiveness()) {
+ if (appView.appInfo().hasLiveness()) {
// Reflection optimization 1. getClass() -> const-class
- ReflectionOptimizer.rewriteGetClass(appInfo.withLiveness(), code);
+ ReflectionOptimizer.rewriteGetClass(appView.withLiveness(), code);
}
if (!isDebugMode) {
@@ -957,14 +945,14 @@
}
if (devirtualizer != null) {
- assert code.verifyTypes(appInfo, appView, graphLense());
+ assert code.verifyTypes(appView);
devirtualizer.devirtualizeInvokeInterface(code, method.method.getHolder());
}
if (uninstantiatedTypeOptimization != null) {
uninstantiatedTypeOptimization.rewrite(method, code);
}
- assert code.verifyTypes(appInfo, appView, graphLense());
+ assert code.verifyTypes(appView);
codeRewriter.removeTrivialCheckCastAndInstanceOfInstructions(
code, appView.enableWholeProgramOptimizations());
@@ -979,8 +967,7 @@
codeRewriter.simplifyIf(code);
// TODO(b/123284765) This produces a runtime-crash in Q. Activate again when fixed.
// codeRewriter.redundantConstNumberRemoval(code);
- new RedundantFieldLoadElimination(appInfo, code, appView.enableWholeProgramOptimizations())
- .run();
+ new RedundantFieldLoadElimination(appView, code).run();
if (options.testing.invertConditionals) {
invertConditionalsForTesting(code);
@@ -1022,7 +1009,7 @@
previous = printMethod(code, "IR after lambda desugaring (SSA)", previous);
- assert code.verifyTypes(appInfo, appView, graphLense());
+ assert code.verifyTypes(appView);
previous = printMethod(code, "IR before class inlining (SSA)", previous);
@@ -1031,7 +1018,7 @@
// lambda, it does not get collected by merger.
assert options.enableInlining && inliner != null;
classInliner.processMethodCode(
- appInfo.withLiveness(),
+ appView.withLiveness(),
codeRewriter,
stringOptimizer,
method,
@@ -1169,9 +1156,9 @@
// These hints are on the original holder. To find the original holder, we first find the
// original method signature (this could have changed as a result of, for example, class
// merging). Then, we find the type that now corresponds to the the original holder.
- DexMethod originalSignature = graphLense().getOriginalMethodSignature(method.method);
+ DexMethod originalSignature = appView.graphLense().getOriginalMethodSignature(method.method);
DexClass originalHolder =
- appView.definitionFor(graphLense().lookupType(originalSignature.holder));
+ appView.definitionFor(appView.graphLense().lookupType(originalSignature.holder));
if (originalHolder.hasKotlinInfo()) {
KotlinInfo kotlinInfo = originalHolder.getKotlinInfo();
if (kotlinInfo.hasNonNullParameterHints()) {
@@ -1232,15 +1219,15 @@
private void finalizeToCf(DexEncodedMethod method, IRCode code, OptimizationFeedback feedback) {
assert !method.getCode().isDexCode();
- CfBuilder builder = new CfBuilder(method, code, options.itemFactory);
- CfCode result = builder.build(codeRewriter, graphLense(), options, appView.appInfo());
+ CfBuilder builder = new CfBuilder(appView, method, code);
+ CfCode result = builder.build(codeRewriter);
method.setCode(result);
markProcessed(method, code, feedback);
}
private void finalizeToDex(DexEncodedMethod method, IRCode code, OptimizationFeedback feedback) {
// Workaround massive dex2oat memory use for self-recursive methods.
- CodeRewriter.disableDex2OatInliningForSelfRecursiveMethods(code, options, appView.appInfo());
+ CodeRewriter.disableDex2OatInliningForSelfRecursiveMethods(appView, code);
// Perform register allocation.
RegisterAllocator registerAllocator = performRegisterAllocation(code, method);
method.setCode(code, registerAllocator, options);
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
index 6574551..722866a 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
@@ -6,6 +6,8 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexField;
@@ -2843,7 +2845,8 @@
for (int i = 0; i < insn.dims; i++) {
dimensions[i] = slots[i].register;
}
- if (builder.isGeneratingClassFiles()) {
+ AppView<? extends AppInfo> appView = builder.appView;
+ if (appView.options().isGeneratingClassFiles()) {
int result = state.push(arrayType);
builder.addMultiNewArray(dexArrayType, result, dimensions);
return;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index b88a262..e8cf039 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -58,7 +58,6 @@
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.shaking.VerticalClassMerger.VerticallyMergedClasses;
-import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.HashSet;
@@ -71,13 +70,11 @@
public class LensCodeRewriter {
private final AppView<? extends AppInfo> appView;
- private final InternalOptions options;
private final Map<DexProto, DexProto> protoFixupCache = new ConcurrentHashMap<>();
public LensCodeRewriter(AppView<? extends AppInfoWithSubtyping> appView) {
this.appView = appView;
- this.options = appView.options();
}
private Value makeOutValue(Instruction insn, IRCode code, Set<Value> collector) {
@@ -102,7 +99,7 @@
boolean mayHaveUnreachableBlocks = false;
while (blocks.hasNext()) {
BasicBlock block = blocks.next();
- if (block.hasCatchHandlers() && options.enableVerticalClassMerging) {
+ if (block.hasCatchHandlers() && appView.options().enableVerticalClassMerging) {
boolean anyGuardsRenamed = block.renameGuardsInCatchHandlers(graphLense);
if (anyGuardsRenamed) {
mayHaveUnreachableBlocks |= unlinkDeadCatchHandlers(block);
@@ -341,7 +338,9 @@
if (newExceptionType != moveException.getExceptionType()) {
iterator.replaceCurrentInstruction(
new MoveException(
- makeOutValue(moveException, code, newSSAValues), newExceptionType, options));
+ makeOutValue(moveException, code, newSSAValues),
+ newExceptionType,
+ appView.options()));
}
} else if (current.isNewArrayEmpty()) {
NewArrayEmpty newArrayEmpty = current.asNewArrayEmpty();
@@ -366,7 +365,7 @@
code.removeUnreachableBlocks();
}
if (!newSSAValues.isEmpty()) {
- new TypeAnalysis(appInfo, method).widening(newSSAValues);
+ new TypeAnalysis(appView, method).widening(newSSAValues);
}
assert code.isConsistentSSA();
}
@@ -400,17 +399,20 @@
if (newInstance.clazz != invokedMethod.holder
&& verticallyMergedClasses.hasBeenMergedIntoSubtype(invokedMethod.holder)) {
// Generated code will not work. Fail with a compilation error.
- throw options.reporter.fatalError(
- String.format(
- "Unable to rewrite `invoke-direct %s.<init>(new %s, ...)` in method `%s` after "
- + "type `%s` was merged into `%s`. Please add the following rule to your "
- + "Proguard configuration file: `-keep,allowobfuscation class %s`.",
- invokedMethod.holder.toSourceString(),
- newInstance.clazz,
- method.toSourceString(),
- invokedMethod.holder,
- verticallyMergedClasses.getTargetFor(invokedMethod.holder),
- invokedMethod.holder.toSourceString()));
+ throw appView
+ .options()
+ .reporter
+ .fatalError(
+ String.format(
+ "Unable to rewrite `invoke-direct %s.<init>(new %s, ...)` in method `%s` after "
+ + "type `%s` was merged into `%s`. Please add the following rule to your "
+ + "Proguard configuration file: `-keep,allowobfuscation class %s`.",
+ invokedMethod.holder.toSourceString(),
+ newInstance.clazz,
+ method.toSourceString(),
+ invokedMethod.holder,
+ verticallyMergedClasses.getTargetFor(invokedMethod.holder),
+ invokedMethod.holder.toSourceString()));
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java b/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
index 1ed85c4..363db4a 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/TypeConstraintResolver.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.analysis.type.ArrayTypeLatticeElement;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
@@ -21,7 +22,6 @@
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.code.ValueTypeConstraint;
import com.android.tools.r8.position.MethodPosition;
-import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
@@ -52,13 +52,13 @@
*/
public class TypeConstraintResolver {
+ private final AppView<? extends AppInfo> appView;
private final IRBuilder builder;
- private final Reporter reporter;
private final Map<Value, Value> unificationParents = new HashMap<>();
- public TypeConstraintResolver(IRBuilder builder, Reporter reporter) {
+ public TypeConstraintResolver(AppView<? extends AppInfo> appView, IRBuilder builder) {
+ this.appView = appView;
this.builder = builder;
- this.reporter = reporter;
}
public static ValueTypeConstraint constraintForType(TypeLatticeElement type) {
@@ -96,14 +96,13 @@
public void resolve(
List<ImpreciseMemberTypeInstruction> impreciseInstructions,
IRCode code,
- AppInfo appInfo,
DexEncodedMethod method,
DexEncodedMethod context) {
// Round one will resolve at least all object vs single types.
List<Value> remainingImpreciseValues = resolveRoundOne(code);
// Round two will resolve any remaining single and wide types. These can depend on the types
// of array instructions, thus we need to complete the type fixed point prior to resolving.
- new TypeAnalysis(appInfo, context, true).widening(method, code);
+ new TypeAnalysis(appView, context, true).widening(method, code);
// Round two resolves any remaining imprecision and finally selects a final precise type for
// any unconstrained imprecise type.
resolveRoundTwo(code, impreciseInstructions, remainingImpreciseValues);
@@ -150,14 +149,17 @@
}
ArrayList<Value> stillImprecise = constrainValues(true, remainingImpreciseValues);
if (!stillImprecise.isEmpty()) {
- throw reporter.fatalError(
- new StringDiagnostic(
- "Cannot determine precise type for value: "
- + stillImprecise.get(0)
- + ", its imprecise type is: "
- + stillImprecise.get(0).getTypeLattice(),
- code.origin,
- new MethodPosition(code.method.method)));
+ throw appView
+ .options()
+ .reporter
+ .fatalError(
+ new StringDiagnostic(
+ "Cannot determine precise type for value: "
+ + stillImprecise.get(0)
+ + ", its imprecise type is: "
+ + stillImprecise.get(0).getTypeLattice(),
+ code.origin,
+ new MethodPosition(code.method.method)));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 3551a7c..fb5fac8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -494,7 +494,7 @@
return;
}
DexMethod originalReferencedFrom =
- converter.graphLense().getOriginalMethodSignature(referencedFrom);
+ appView.graphLense().getOriginalMethodSignature(referencedFrom);
StringBuilder builder = new StringBuilder();
builder
.append("Type `")
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index c89019c..e91f1cc 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -32,7 +32,6 @@
import com.android.tools.r8.ir.synthetic.ForwardMethodSourceCode;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import com.android.tools.r8.origin.SynthesizedOrigin;
-import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
@@ -308,8 +307,7 @@
// also be kept (such a situation can happen if the vertical class merger merges two interfaces).
private boolean interfaceMethodRemovalChangesApi(DexEncodedMethod method, DexClass iface) {
if (appView.enableWholeProgramOptimizations()) {
- AppInfoWithLiveness appInfoWithLiveness = appView.appInfo().withLiveness();
- if (appInfoWithLiveness.isPinned(method.method)) {
+ if (appView.appInfo().withLiveness().isPinned(method.method)) {
return true;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
index 9b096a2..01c94da 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
@@ -71,7 +71,7 @@
}
InvokeStatic invoke = instruction.asInvokeStatic();
- MethodGenerator generator = getMethodGeneratorOrNull(converter, invoke.getInvokedMethod());
+ MethodGenerator generator = getMethodGeneratorOrNull(invoke.getInvokedMethod());
if (generator == null) {
continue;
}
@@ -151,8 +151,8 @@
}
}
- private MethodGenerator getMethodGeneratorOrNull(IRConverter converter, DexMethod method) {
- DexMethod original = converter.graphLense().getOriginalMethodSignature(method);
+ private MethodGenerator getMethodGeneratorOrNull(DexMethod method) {
+ DexMethod original = appView.graphLense().getOriginalMethodSignature(method);
assert original != null;
return rewritableMethods.getGenerator(
original.holder.descriptor, original.name, original.proto);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
index 29b6aa7..ff903f3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
@@ -202,7 +202,7 @@
// If we are in R8, and we have removed all static-put instructions to some field, then record
// that the field is no longer written.
- if (appView != null && appView.enableWholeProgramOptimizations() && converter.isInWave()) {
+ if (appView.enableWholeProgramOptimizations() && converter.isInWave()) {
if (appView.appInfo().hasLiveness()) {
AppView<? extends AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
AppInfoWithLiveness appInfoWithLiveness = appViewWithLiveness.appInfo();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 304c86d..0015e17 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -293,8 +293,8 @@
// For method with many self-recursive calls, insert a try-catch to disable inlining.
// Marshmallow dex2oat aggressively inlines and eats up all the memory on devices.
public static void disableDex2OatInliningForSelfRecursiveMethods(
- IRCode code, InternalOptions options, AppInfo appInfo) {
- if (!options.canHaveDex2OatInliningIssue() || code.hasCatchHandlers()) {
+ AppView<? extends AppInfo> appView, IRCode code) {
+ if (!appView.options().canHaveDex2OatInliningIssue() || code.hasCatchHandlers()) {
// Catch handlers disables inlining, so if the method already has catch handlers
// there is nothing to do.
return;
@@ -317,13 +317,9 @@
splitIterator.previous();
BasicBlock newBlock = splitIterator.split(code, 1);
// Generate rethrow block.
- DexType guard = options.itemFactory.throwableType;
- BasicBlock rethrowBlock = BasicBlock.createRethrowBlock(
- code,
- lastSelfRecursiveCall.getPosition(),
- guard,
- appInfo,
- options);
+ DexType guard = appView.dexItemFactory().throwableType;
+ BasicBlock rethrowBlock =
+ BasicBlock.createRethrowBlock(code, lastSelfRecursiveCall.getPosition(), guard, appView);
code.blocks.add(rethrowBlock);
// Add catch handler to the block containing the last recursive call.
newBlock.addCatchHandler(rethrowBlock, guard);
@@ -1606,8 +1602,7 @@
if (options.isGeneratingClassFiles()) {
return;
}
- AppInfo appInfo = appView.appInfo();
- AppInfoWithLiveness appInfoWithLiveness = appInfo.withLiveness();
+ AppInfoWithLiveness appInfoWithLiveness = appView.appInfo().withLiveness();
Set<Value> needToWidenValues = Sets.newIdentityHashSet();
Set<Value> needToNarrowValues = Sets.newIdentityHashSet();
InstructionIterator iterator = code.instructionIterator();
@@ -1647,15 +1642,16 @@
if (target != null) {
DexMethod invokedMethod = target.method;
// Check if the invoked method is known to return one of its arguments.
- DexEncodedMethod definition = appInfo.definitionFor(invokedMethod);
+ DexEncodedMethod definition = appView.definitionFor(invokedMethod);
if (definition != null && definition.getOptimizationInfo().returnsArgument()) {
int argumentIndex = definition.getOptimizationInfo().getReturnedArgument();
// Replace the out value of the invoke with the argument and ignore the out value.
if (argumentIndex >= 0 && checkArgumentType(invoke, argumentIndex)) {
Value argument = invoke.arguments().get(argumentIndex);
assert outValue.verifyCompatible(argument.outType());
- if (argument.getTypeLattice().lessThanOrEqual(
- outValue.getTypeLattice(), appInfo)) {
+ if (argument
+ .getTypeLattice()
+ .lessThanOrEqual(outValue.getTypeLattice(), appView)) {
needToNarrowValues.addAll(outValue.affectedValues());
} else {
needToWidenValues.addAll(outValue.affectedValues());
@@ -1670,7 +1666,7 @@
}
}
if (!needToWidenValues.isEmpty() || !needToNarrowValues.isEmpty()) {
- TypeAnalysis analysis = new TypeAnalysis(appInfo, code.method);
+ TypeAnalysis analysis = new TypeAnalysis(appView, code.method);
// If out value of invoke < argument (e.g., losing non-null info), widen users type.
if (!needToWidenValues.isEmpty()) {
analysis.widening(needToWidenValues);
@@ -1684,10 +1680,11 @@
}
/**
- * For supporting assert javac adds the static field $assertionsDisabled to all classes which
- * have methods with assertions. This is used to support the Java VM -ea flag.
+ * For supporting assert javac adds the static field $assertionsDisabled to all classes which have
+ * methods with assertions. This is used to support the Java VM -ea flag.
*
- * The class:
+ * <p>The class:
+ *
* <pre>
* class A {
* void m() {
@@ -1695,7 +1692,9 @@
* }
* }
* </pre>
+ *
* Is compiled into:
+ *
* <pre>
* class A {
* static boolean $assertionsDisabled;
@@ -1713,7 +1712,9 @@
* }
* }
* </pre>
+ *
* With the rewriting below (and other rewritings) the resulting code is:
+ *
* <pre>
* class A {
* void m() {
@@ -1722,7 +1723,10 @@
* </pre>
*/
public void disableAssertions(
- AppInfo appInfo, DexEncodedMethod method, IRCode code, OptimizationFeedback feedback) {
+ AppView<? extends AppInfo> appView,
+ DexEncodedMethod method,
+ IRCode code,
+ OptimizationFeedback feedback) {
if (method.isClassInitializer()) {
if (!hasJavacClinitAssertionCode(code)) {
return;
@@ -1732,7 +1736,7 @@
} else {
// If the clinit of this class did not have have code to turn on assertions don't try to
// remove assertion code from the method.
- DexClass clazz = appInfo.definitionFor(method.method.holder);
+ DexClass clazz = appView.definitionFor(method.method.holder);
if (clazz == null) {
return;
}
@@ -2931,7 +2935,7 @@
}
Set<Value> affectedValues = code.removeUnreachableBlocks();
if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appView.appInfo(), code.method).narrowing(affectedValues);
+ new TypeAnalysis(appView, code.method).narrowing(affectedValues);
}
assert code.isConsistentSSA();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index 019c3ac..3f1b066 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -40,7 +40,6 @@
private final CallSiteInformation callSiteInformation;
private final Predicate<DexEncodedMethod> isProcessedConcurrently;
private final InliningInfo info;
- private final InternalOptions options;
private final int inliningInstructionLimit;
private int instructionAllowance;
@@ -51,7 +50,6 @@
IRCode code,
CallSiteInformation callSiteInformation,
Predicate<DexEncodedMethod> isProcessedConcurrently,
- InternalOptions options,
int inliningInstructionLimit,
int inliningInstructionAllowance) {
this.appView = appView;
@@ -61,7 +59,6 @@
this.callSiteInformation = callSiteInformation;
this.isProcessedConcurrently = isProcessedConcurrently;
info = Log.ENABLED ? new InliningInfo(method) : null;
- this.options = options;
this.inliningInstructionLimit = inliningInstructionLimit;
this.instructionAllowance = inliningInstructionAllowance;
}
@@ -185,6 +182,7 @@
return false;
}
+ InternalOptions options = appView.options();
if (options.testing.validInliningReasons != null
&& !options.testing.validInliningReasons.contains(reason)) {
return false;
@@ -433,7 +431,7 @@
// Abort if inlining could lead to an explosion in the number of control flow
// resolution blocks that setup the register state before the actual catch handler.
if (estimatedNumberOfControlFlowResolutionBlocks
- >= options.inliningControlFlowResolutionBlocksThreshold) {
+ >= appView.options().inliningControlFlowResolutionBlocksThreshold) {
return true;
}
}
@@ -450,7 +448,7 @@
@Override
public void updateTypeInformationIfNeeded(
IRCode inlinee, ListIterator<BasicBlock> blockIterator, BasicBlock block) {
- if (inliner.options.enableNonNullTracking) {
+ if (appView.options().enableNonNullTracking) {
BasicBlock state = IteratorUtils.peekNext(blockIterator);
// Move the cursor back to where the first inlinee block was added.
while (blockIterator.hasPrevious() && blockIterator.previous() != block) {
@@ -459,8 +457,8 @@
assert IteratorUtils.peekNext(blockIterator) == block;
// Kick off the tracker to add non-null IRs only to the inlinee blocks.
- new NonNullTracker(appView.appInfo(),
- IRConverter.libraryMethodsReturningNonNull(appView.dexItemFactory()))
+ new NonNullTracker(
+ appView, IRConverter.libraryMethodsReturningNonNull(appView.dexItemFactory()))
.addNonNullInPart(code, blockIterator, inlinee.blocks::contains);
assert !blockIterator.hasNext();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
index 930ac78..d0f3599 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
@@ -221,7 +221,7 @@
}
}
if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appView.appInfo(), code.method).narrowing(affectedValues);
+ new TypeAnalysis(appView, code.method).narrowing(affectedValues);
}
assert code.isConsistentSSA();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
index fd387a3..aa3b405 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
@@ -8,14 +8,12 @@
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionIterator;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
-import com.android.tools.r8.utils.InternalOptions;
import it.unimi.dsi.fastutil.objects.Reference2IntArrayMap;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import java.util.IdentityHashMap;
@@ -31,26 +29,22 @@
*/
public class EnumOrdinalMapCollector {
- private final AppInfoWithLiveness appInfo;
- private final GraphLense graphLense;
- private final InternalOptions options;
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final Map<DexType, Reference2IntMap<DexField>> ordinalsMaps = new IdentityHashMap<>();
public EnumOrdinalMapCollector(AppView<? extends AppInfoWithLiveness> appView) {
- this.appInfo = appView.appInfo();
- this.graphLense = appView.graphLense();
- this.options = appView.options();
+ this.appView = appView;
}
public AppInfoWithLiveness run() {
- for (DexProgramClass clazz : appInfo.classes()) {
+ for (DexProgramClass clazz : appView.appInfo().classes()) {
processClasses(clazz);
}
if (!ordinalsMaps.isEmpty()) {
- return appInfo.addEnumOrdinalMaps(ordinalsMaps);
+ return appView.appInfo().addEnumOrdinalMaps(ordinalsMaps);
}
- return appInfo;
+ return appView.appInfo();
}
private void processClasses(DexProgramClass clazz) {
@@ -59,8 +53,7 @@
return;
}
DexEncodedMethod initializer = clazz.getClassInitializer();
- IRCode code =
- initializer.getCode().buildIR(initializer, appInfo, graphLense, options, clazz.origin);
+ IRCode code = initializer.getCode().buildIR(initializer, appView, clazz.origin);
Reference2IntMap<DexField> ordinalsMap = new Reference2IntArrayMap<>();
ordinalsMap.defaultReturnValue(-1);
InstructionIterator it = code.instructionIterator();
@@ -83,7 +76,7 @@
continue;
}
InvokeDirect invoke = ctorCall.asInvokeDirect();
- if (!appInfo.dexItemFactory.isConstructor(invoke.getInvokedMethod())
+ if (!appView.dexItemFactory().isConstructor(invoke.getInvokedMethod())
|| invoke.arguments().size() < 3) {
continue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 299181e..9a50518 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -4,15 +4,16 @@
package com.android.tools.r8.ir.optimize;
import com.android.tools.r8.graph.AccessFlags;
-import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
@@ -49,8 +50,6 @@
public class Inliner {
protected final AppView<? extends AppInfoWithLiveness> appView;
- private final IRConverter converter;
- final InternalOptions options;
final MainDexClasses mainDexClasses;
// State for inlining methods which are known to be called twice.
@@ -63,12 +62,8 @@
public Inliner(
AppView<? extends AppInfoWithLiveness> appView,
- IRConverter converter,
- InternalOptions options,
MainDexClasses mainDexClasses) {
this.appView = appView;
- this.converter = converter;
- this.options = options;
this.mainDexClasses = mainDexClasses;
fillInBlackList(appView.appInfo());
}
@@ -96,7 +91,8 @@
public ConstraintWithTarget computeInliningConstraint(IRCode code, DexEncodedMethod method) {
ConstraintWithTarget result = ConstraintWithTarget.ALWAYS;
- InliningConstraints inliningConstraints = new InliningConstraints(appView.appInfo());
+ InliningConstraints inliningConstraints =
+ new InliningConstraints(appView, GraphLense.getIdentityLense());
InstructionIterator it = code.instructionIterator();
while (it.hasNext()) {
Instruction instruction = it.next();
@@ -281,7 +277,7 @@
DexType contextHolder,
DexType targetHolder,
AccessFlags flags,
- AppInfo appInfo) {
+ DexDefinitionSupplier definitions) {
if (flags.isPublic()) {
return ALWAYS;
} else if (flags.isPrivate()) {
@@ -291,7 +287,7 @@
if (targetHolder.isSamePackage(contextHolder)) {
// Even though protected, this is visible via the same package from the context.
return new ConstraintWithTarget(Constraint.PACKAGE, targetHolder);
- } else if (contextHolder.isSubtypeOf(targetHolder, appInfo)) {
+ } else if (contextHolder.isSubtypeOf(targetHolder, definitions)) {
return new ConstraintWithTarget(Constraint.SUBCLASS, targetHolder);
}
return NEVER;
@@ -303,27 +299,29 @@
}
public static ConstraintWithTarget classIsVisible(
- DexType context, DexType clazz, AppInfo appInfo) {
+ DexType context, DexType clazz, DexDefinitionSupplier definitions) {
if (clazz.isArrayType()) {
- return classIsVisible(context, clazz.toArrayElementType(appInfo.dexItemFactory), appInfo);
+ return classIsVisible(
+ context, clazz.toArrayElementType(definitions.dexItemFactory()), definitions);
}
if (clazz.isPrimitiveType()) {
return ALWAYS;
}
- DexClass definition = appInfo.definitionFor(clazz);
- return definition == null ? NEVER
- : deriveConstraint(context, clazz, definition.accessFlags, appInfo);
+ DexClass definition = definitions.definitionFor(clazz);
+ return definition == null
+ ? NEVER
+ : deriveConstraint(context, clazz, definition.accessFlags, definitions);
}
public static ConstraintWithTarget meet(
- ConstraintWithTarget one, ConstraintWithTarget other, AppInfo appInfo) {
+ ConstraintWithTarget one, ConstraintWithTarget other, DexDefinitionSupplier definitions) {
if (one.equals(other)) {
return one;
}
if (other.constraint.ordinal() < one.constraint.ordinal()) {
- return meet(other, one, appInfo);
+ return meet(other, one, definitions);
}
// From now on, one.constraint.ordinal() <= other.constraint.ordinal()
if (one == NEVER) {
@@ -349,7 +347,7 @@
return NEVER;
}
assert other.constraint == Constraint.SUBCLASS;
- if (one.targetHolder.isSubtypeOf(other.targetHolder, appInfo)) {
+ if (one.targetHolder.isSubtypeOf(other.targetHolder, definitions)) {
return one;
}
return NEVER;
@@ -379,10 +377,10 @@
assert Constraint.SUBCLASS.isSet(constraint);
assert one.constraint == other.constraint;
assert one.targetHolder != other.targetHolder;
- if (one.targetHolder.isSubtypeOf(other.targetHolder, appInfo)) {
+ if (one.targetHolder.isSubtypeOf(other.targetHolder, definitions)) {
return one;
}
- if (other.targetHolder.isSubtypeOf(one.targetHolder, appInfo)) {
+ if (other.targetHolder.isSubtypeOf(one.targetHolder, definitions)) {
return other;
}
// SUBCLASS of x and SUBCLASS of y while x and y are not a subtype of each other.
@@ -425,18 +423,10 @@
DexEncodedMethod context,
ValueNumberGenerator generator,
AppView<? extends AppInfoWithSubtyping> appView,
- InternalOptions options,
Position callerPosition) {
// Build the IR for a yet not processed method, and perform minimal IR processing.
Origin origin = appView.appInfo().originFor(target.method.holder);
- IRCode code = target.buildInliningIR(
- context,
- appView.appInfo(),
- appView.graphLense(),
- options,
- generator,
- callerPosition,
- origin);
+ IRCode code = target.buildInliningIR(context, appView, generator, callerPosition, origin);
if (!target.isProcessed()) {
new LensCodeRewriter(appView).rewrite(code, target);
}
@@ -565,7 +555,7 @@
IRCode code,
Predicate<DexEncodedMethod> isProcessedConcurrently,
CallSiteInformation callSiteInformation) {
-
+ InternalOptions options = appView.options();
DefaultInliningOracle oracle =
createDefaultOracle(
method,
@@ -574,7 +564,6 @@
callSiteInformation,
options.inliningInstructionLimit,
options.inliningInstructionAllowance - numberOfInstructions(code));
-
performInliningImpl(oracle, oracle, method, code);
}
@@ -585,7 +574,6 @@
CallSiteInformation callSiteInformation,
int inliningInstructionLimit,
int inliningInstructionAllowance) {
-
return new DefaultInliningOracle(
appView,
this,
@@ -593,7 +581,6 @@
code,
callSiteInformation,
isProcessedConcurrently,
- options,
inliningInstructionLimit,
inliningInstructionAllowance);
}
@@ -628,10 +615,10 @@
}
assert invokePosition.callerPosition == null
|| invokePosition.getOutermostCaller().method
- == converter.graphLense().getOriginalMethodSignature(context.method);
+ == appView.graphLense().getOriginalMethodSignature(context.method);
- InlineeWithReason inlinee = result.buildInliningIR(
- context, code.valueNumberGenerator, appView, options, invokePosition);
+ InlineeWithReason inlinee =
+ result.buildInliningIR(context, code.valueNumberGenerator, appView, invokePosition);
if (inlinee != null) {
if (strategy.willExceedBudget(inlinee, block)) {
continue;
@@ -652,7 +639,7 @@
iterator.previous();
strategy.markInlined(inlinee);
iterator.inlineInvoke(
- appView.appInfo(), code, inlinee.code, blockIterator, blocksToRemove, downcast);
+ appView, code, inlinee.code, blockIterator, blocksToRemove, downcast);
classInitializationAnalysis.notifyCodeHasChanged();
strategy.updateTypeInformationIfNeeded(inlinee.code, blockIterator, block);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
index 873eb20..afb2e0f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo.ResolutionResult;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
@@ -22,7 +23,7 @@
// Computes the inlining constraint for a given instruction.
public class InliningConstraints {
- private AppInfoWithLiveness appInfo;
+ private AppView<? extends AppInfoWithLiveness> appView;
private boolean allowStaticInterfaceMethodCalls = true;
@@ -38,14 +39,12 @@
// type A to B, to create a temporary view of what the world would look like after class merging.
private GraphLense graphLense;
- public InliningConstraints(AppInfoWithLiveness appInfo) {
- this(appInfo, GraphLense.getIdentityLense());
- }
-
- public InliningConstraints(AppInfoWithLiveness appInfo, GraphLense graphLense) {
+ public InliningConstraints(
+ AppView<? extends AppInfoWithLiveness> appView, GraphLense graphLense) {
assert graphLense.isContextFreeForMethods();
- this.appInfo = appInfo;
- this.graphLense = graphLense;
+ assert appView.graphLense() != graphLense || graphLense.isIdentityLense();
+ this.appView = appView;
+ this.graphLense = graphLense; // Note: Intentionally *not* appView.graphLense().
}
public void disallowStaticInterfaceMethodCalls() {
@@ -77,11 +76,11 @@
}
public ConstraintWithTarget forCheckCast(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appInfo);
+ return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
}
public ConstraintWithTarget forConstClass(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appInfo);
+ return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
}
public ConstraintWithTarget forConstInstruction() {
@@ -111,17 +110,17 @@
public ConstraintWithTarget forInstanceGet(DexField field, DexType invocationContext) {
DexField lookup = graphLense.lookupField(field);
return forFieldInstruction(
- lookup, appInfo.lookupInstanceTarget(lookup.clazz, lookup), invocationContext);
+ lookup, appView.appInfo().lookupInstanceTarget(lookup.clazz, lookup), invocationContext);
}
public ConstraintWithTarget forInstanceOf(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appInfo);
+ return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
}
public ConstraintWithTarget forInstancePut(DexField field, DexType invocationContext) {
DexField lookup = graphLense.lookupField(field);
return forFieldInstruction(
- lookup, appInfo.lookupInstanceTarget(lookup.clazz, lookup), invocationContext);
+ lookup, appView.appInfo().lookupInstanceTarget(lookup.clazz, lookup), invocationContext);
}
public ConstraintWithTarget forInvoke(DexMethod method, Type type, DexType invocationContext) {
@@ -151,20 +150,22 @@
public ConstraintWithTarget forInvokeDirect(DexMethod method, DexType invocationContext) {
DexMethod lookup = graphLense.lookupMethod(method);
- return forSingleTargetInvoke(lookup, appInfo.lookupDirectTarget(lookup), invocationContext);
+ return forSingleTargetInvoke(
+ lookup, appView.appInfo().lookupDirectTarget(lookup), invocationContext);
}
public ConstraintWithTarget forInvokeInterface(DexMethod method, DexType invocationContext) {
DexMethod lookup = graphLense.lookupMethod(method);
- return forVirtualInvoke(lookup, appInfo.lookupInterfaceTargets(lookup), invocationContext);
+ return forVirtualInvoke(
+ lookup, appView.appInfo().lookupInterfaceTargets(lookup), invocationContext);
}
public ConstraintWithTarget forInvokeMultiNewArray(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appInfo);
+ return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
}
public ConstraintWithTarget forInvokeNewArray(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appInfo);
+ return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
}
public ConstraintWithTarget forInvokePolymorphic(DexMethod method, DexType invocationContext) {
@@ -173,7 +174,8 @@
public ConstraintWithTarget forInvokeStatic(DexMethod method, DexType invocationContext) {
DexMethod lookup = graphLense.lookupMethod(method);
- return forSingleTargetInvoke(lookup, appInfo.lookupStaticTarget(lookup), invocationContext);
+ return forSingleTargetInvoke(
+ lookup, appView.appInfo().lookupStaticTarget(lookup), invocationContext);
}
public ConstraintWithTarget forInvokeSuper(DexMethod method, DexType invocationContext) {
@@ -183,7 +185,8 @@
public ConstraintWithTarget forInvokeVirtual(DexMethod method, DexType invocationContext) {
DexMethod lookup = graphLense.lookupMethod(method);
- return forVirtualInvoke(lookup, appInfo.lookupVirtualTargets(lookup), invocationContext);
+ return forVirtualInvoke(
+ lookup, appView.appInfo().lookupVirtualTargets(lookup), invocationContext);
}
public ConstraintWithTarget forJumpInstruction() {
@@ -208,7 +211,7 @@
}
public ConstraintWithTarget forNewArrayEmpty(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appInfo);
+ return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
}
public ConstraintWithTarget forNewArrayFilledData() {
@@ -216,7 +219,7 @@
}
public ConstraintWithTarget forNewInstance(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appInfo);
+ return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
}
public ConstraintWithTarget forNonNull() {
@@ -234,13 +237,13 @@
public ConstraintWithTarget forStaticGet(DexField field, DexType invocationContext) {
DexField lookup = graphLense.lookupField(field);
return forFieldInstruction(
- lookup, appInfo.lookupStaticTarget(lookup.clazz, lookup), invocationContext);
+ lookup, appView.appInfo().lookupStaticTarget(lookup.clazz, lookup), invocationContext);
}
public ConstraintWithTarget forStaticPut(DexField field, DexType invocationContext) {
DexField lookup = graphLense.lookupField(field);
return forFieldInstruction(
- lookup, appInfo.lookupStaticTarget(lookup.clazz, lookup), invocationContext);
+ lookup, appView.appInfo().lookupStaticTarget(lookup.clazz, lookup), invocationContext);
}
public ConstraintWithTarget forStore() {
@@ -267,16 +270,16 @@
DexField field, DexEncodedField target, DexType invocationContext) {
// Resolve the field if possible and decide whether the instruction can inlined.
DexType fieldHolder = graphLense.lookupType(field.clazz);
- DexClass fieldClass = appInfo.definitionFor(fieldHolder);
+ DexClass fieldClass = appView.definitionFor(fieldHolder);
if (target != null && fieldClass != null) {
ConstraintWithTarget fieldConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, fieldHolder, target.accessFlags, appInfo);
+ invocationContext, fieldHolder, target.accessFlags, appView);
ConstraintWithTarget classConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, fieldHolder, fieldClass.accessFlags, appInfo);
+ invocationContext, fieldHolder, fieldClass.accessFlags, appView);
return ConstraintWithTarget.meet(
- fieldConstraintWithTarget, classConstraintWithTarget, appInfo);
+ fieldConstraintWithTarget, classConstraintWithTarget, appView);
}
return ConstraintWithTarget.NEVER;
}
@@ -288,7 +291,7 @@
}
if (target != null) {
DexType methodHolder = graphLense.lookupType(target.method.holder);
- DexClass methodClass = appInfo.definitionFor(methodHolder);
+ DexClass methodClass = appView.definitionFor(methodHolder);
if (methodClass != null) {
if (!allowStaticInterfaceMethodCalls && methodClass.isInterface() && target.hasCode()) {
// See b/120121170.
@@ -297,13 +300,13 @@
ConstraintWithTarget methodConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, target.accessFlags, appInfo);
+ invocationContext, methodHolder, target.accessFlags, appView);
// We also have to take the constraint of the enclosing class into account.
ConstraintWithTarget classConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, methodClass.accessFlags, appInfo);
+ invocationContext, methodHolder, methodClass.accessFlags, appView);
return ConstraintWithTarget.meet(
- methodConstraintWithTarget, classConstraintWithTarget, appInfo);
+ methodConstraintWithTarget, classConstraintWithTarget, appView);
}
}
return ConstraintWithTarget.NEVER;
@@ -320,7 +323,7 @@
// Perform resolution and derive inlining constraints based on the accessibility of the
// resolution result.
- ResolutionResult resolutionResult = appInfo.resolveMethod(method.holder, method);
+ ResolutionResult resolutionResult = appView.appInfo().resolveMethod(method.holder, method);
DexEncodedMethod resolutionTarget = resolutionResult.asResultOfResolve();
if (resolutionTarget == null) {
// This will fail at runtime.
@@ -328,11 +331,11 @@
}
DexType methodHolder = graphLense.lookupType(resolutionTarget.method.holder);
- DexClass methodClass = appInfo.definitionFor(methodHolder);
+ DexClass methodClass = appView.definitionFor(methodHolder);
assert methodClass != null;
ConstraintWithTarget methodConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, resolutionTarget.accessFlags, appInfo);
+ invocationContext, methodHolder, resolutionTarget.accessFlags, appView);
// We also have to take the constraint of the enclosing class of the resolution result
// into account. We do not allow inlining this method if it is calling something that
// is inaccessible. Inlining in that case could move the code to another package making a
@@ -340,9 +343,9 @@
// we have to make sure that inlining cannot make it inaccessible.
ConstraintWithTarget classConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, methodClass.accessFlags, appInfo);
+ invocationContext, methodHolder, methodClass.accessFlags, appView);
ConstraintWithTarget result =
- ConstraintWithTarget.meet(methodConstraintWithTarget, classConstraintWithTarget, appInfo);
+ ConstraintWithTarget.meet(methodConstraintWithTarget, classConstraintWithTarget, appView);
if (result == ConstraintWithTarget.NEVER) {
return result;
}
@@ -351,11 +354,11 @@
// of the method itself.
for (DexEncodedMethod target : targets) {
methodHolder = graphLense.lookupType(target.method.holder);
- assert appInfo.definitionFor(methodHolder) != null;
+ assert appView.definitionFor(methodHolder) != null;
methodConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, target.accessFlags, appInfo);
- result = ConstraintWithTarget.meet(result, methodConstraintWithTarget, appInfo);
+ invocationContext, methodHolder, target.accessFlags, appView);
+ result = ConstraintWithTarget.meet(result, methodConstraintWithTarget, appView);
if (result == ConstraintWithTarget.NEVER) {
return result;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index 002461f..0d5a895 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -220,7 +220,7 @@
&& current.outValue().canBeNull()) {
Value knownToBeNonNullValue = current.outValue();
TypeLatticeElement typeLattice = knownToBeNonNullValue.getTypeLattice();
- knownToBeNonNullValue.narrowing(appView.appInfo(), typeLattice.asNonNullable());
+ knownToBeNonNullValue.narrowing(appView, typeLattice.asNonNullable());
affectedValues.addAll(knownToBeNonNullValue.affectedValues());
}
if (target.getOptimizationInfo().returnsConstant()) {
@@ -310,7 +310,7 @@
&& outValue.getTypeLattice().isReference()
&& outValue.canBeNull()) {
TypeLatticeElement typeLattice = outValue.getTypeLattice();
- outValue.narrowing(appView.appInfo(), typeLattice.asNonNullable());
+ outValue.narrowing(appView, typeLattice.asNonNullable());
affectedValues.addAll(outValue.affectedValues());
}
}
@@ -367,7 +367,7 @@
}
}
if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appView.appInfo(), code.method).narrowing(affectedValues);
+ new TypeAnalysis(appView, code.method).narrowing(affectedValues);
}
assert code.isConsistentSSA();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
index 9a0a550..2a1092e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.ir.code.DominatorTree.Assumption.MAY_HAVE_UNREACHABLE_BLOCKS;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
@@ -40,13 +41,13 @@
public class NonNullTracker {
- private final AppInfoWithLiveness appInfo;
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final Set<DexMethod> libraryMethodsReturningNonNull;
public NonNullTracker(
- AppInfoWithLiveness appInfo,
+ AppView<? extends AppInfoWithLiveness> appView,
Set<DexMethod> libraryMethodsReturningNonNull) {
- this.appInfo = appInfo;
+ this.appView = appView;
this.libraryMethodsReturningNonNull = libraryMethodsReturningNonNull;
}
@@ -121,7 +122,9 @@
}
if (current.isInvokeMethod() && !current.isInvokePolymorphic()) {
DexEncodedMethod singleTarget =
- current.asInvokeMethod().lookupSingleTarget(appInfo, code.method.method.getHolder());
+ current
+ .asInvokeMethod()
+ .lookupSingleTarget(appView.appInfo(), code.method.method.getHolder());
if (singleTarget != null
&& singleTarget.getOptimizationInfo().getNonNullParamOnNormalExits() != null) {
BitSet facts = singleTarget.getOptimizationInfo().getNonNullParamOnNormalExits();
@@ -218,7 +221,7 @@
}
}
if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appInfo, code.method).narrowing(affectedValues);
+ new TypeAnalysis(appView, code.method).narrowing(affectedValues);
}
}
@@ -500,7 +503,7 @@
// Since z is defined as "z = (T) x", and x is nullable, it is no longer sound to have that z
// is not nullable. This is fixed by rerunning the type analysis for the affected values.
if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appInfo, code.method).widening(affectedValues);
+ new TypeAnalysis(appView, code.method).widening(affectedValues);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 5ba7eb1..a7ec086 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -10,13 +10,13 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
@@ -103,7 +103,6 @@
*/
public class Outliner {
- private final InternalOptions options;
/** Result of first step (see {@link Outliner#identifyCandidateMethods()}. */
private final List<List<DexEncodedMethod>> candidateMethodLists = new ArrayList<>();
/** Result of second step (see {@link Outliner#selectMethodsForOutlining()}. */
@@ -115,9 +114,7 @@
static final int MAX_IN_SIZE = 5; // Avoid using ranged calls for outlined code.
- final private AppInfoWithLiveness appInfo;
- final private DexItemFactory dexItemFactory;
- final private IRConverter converter;
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final InliningConstraints inliningConstraints;
private abstract static class OutlineInstruction {
@@ -360,7 +357,7 @@
@Override
public int createInstruction(IRBuilder builder, Outline outline, int argumentMapIndex) {
TypeLatticeElement latticeElement =
- TypeLatticeElement.fromDexType(clazz, definitelyNotNull(), builder.getAppInfo());
+ TypeLatticeElement.fromDexType(clazz, definitelyNotNull(), builder.appView);
Value outValue =
builder.writeRegister(outline.argumentCount(), latticeElement, ThrowingInfo.CAN_THROW);
Instruction newInstruction = new NewInstance(clazz, outValue);
@@ -496,8 +493,7 @@
Value outValue = null;
if (hasOutValue) {
TypeLatticeElement latticeElement =
- TypeLatticeElement.fromDexType(
- method.proto.returnType, maybeNull(), builder.getAppInfo());
+ TypeLatticeElement.fromDexType(method.proto.returnType, maybeNull(), builder.appView);
outValue =
builder.writeRegister(outline.argumentCount(), latticeElement, ThrowingInfo.CAN_THROW);
}
@@ -571,14 +567,14 @@
DexProto buildProto() {
if (proto == null) {
DexType[] argumentTypesArray = argumentTypes.toArray(new DexType[argumentTypes.size()]);
- proto = dexItemFactory.createProto(returnType, argumentTypesArray);
+ proto = appView.dexItemFactory().createProto(returnType, argumentTypesArray);
}
return proto;
}
// Build the DexMethod for this outline.
DexMethod buildMethod(DexType clazz, DexString name) {
- return dexItemFactory.createMethod(clazz, buildProto(), name);
+ return appView.dexItemFactory().createMethod(clazz, buildProto(), name);
}
@Override
@@ -695,7 +691,7 @@
builder.append(instruction.getDetailsString());
builder.append("\n");
}
- if (returnType == dexItemFactory.voidType) {
+ if (returnType == appView.dexItemFactory().voidType) {
builder.append("Return-Void");
} else {
StringUtils.appendRightPadded(builder, "Return", 20);
@@ -798,7 +794,7 @@
// Add this instruction.
includeInstruction(instruction);
// Check if this instruction ends the outline.
- if (actualInstructions >= options.outline.maxSize) {
+ if (actualInstructions >= appView.options().outline.maxSize) {
candidate(start, index + 1);
} else {
index++;
@@ -848,7 +844,7 @@
return false;
}
InvokeMethod invoke = instruction.asInvokeMethod();
- boolean constructor = dexItemFactory.isConstructor(invoke.getInvokedMethod());
+ boolean constructor = appView.dexItemFactory().isConstructor(invoke.getInvokedMethod());
// See whether we could move this invoke somewhere else. We reuse the logic from inlining
// here, as the constraints are the same.
@@ -932,7 +928,7 @@
}
if (returnValueUsersLeft == 0) {
returnValue = null;
- returnType = dexItemFactory.voidType;
+ returnType = appView.dexItemFactory().voidType;
}
}
}
@@ -961,7 +957,7 @@
DexType receiverType = argumentTypeFromInvoke(invoke, i);
// Ensure that the outline argument type is specific enough.
if (receiverType.isClassType()) {
- if (receiverType.isSubtypeOf(argumentTypes.get(argumentIndex), appInfo)) {
+ if (receiverType.isSubtypeOf(argumentTypes.get(argumentIndex), appView)) {
argumentTypes.set(argumentIndex, receiverType);
}
}
@@ -978,7 +974,8 @@
argumentTypes
.add(instruction.asInvokeMethod().getInvokedMethod().proto.parameters.values[i]);
} else {
- argumentTypes.add(instruction.asBinop().getNumericType().dexTypeFor(dexItemFactory));
+ argumentTypes.add(
+ instruction.asBinop().getNumericType().dexTypeFor(appView.dexItemFactory()));
}
argumentsMap.add(argumentTypes.size() - 1);
}
@@ -993,7 +990,7 @@
} else {
updateReturnValueState(
instruction.outValue(),
- instruction.asBinop().getNumericType().dexTypeFor(dexItemFactory));
+ instruction.asBinop().getNumericType().dexTypeFor(appView.dexItemFactory()));
}
}
}
@@ -1003,7 +1000,7 @@
// If the return value is not used don't track it.
if (returnValueUsersLeft == 0) {
returnValue = null;
- returnType = dexItemFactory.voidType;
+ returnType = appView.dexItemFactory().voidType;
} else {
returnValue = newReturnValue;
returnType = newReturnType;
@@ -1039,7 +1036,7 @@
nonConstInstructions++;
}
}
- if (nonConstInstructions < options.outline.minSize) {
+ if (nonConstInstructions < appView.options().outline.minSize) {
reset(start + 1);
return;
}
@@ -1061,7 +1058,7 @@
argumentTypes = new ArrayList<>(MAX_IN_SIZE);
argumentsMap = new ArrayList<>(MAX_IN_SIZE);
argumentRegisters = 0;
- returnType = dexItemFactory.voidType;
+ returnType = appView.dexItemFactory().voidType;
returnValue = null;
returnValueUsersLeft = 0;
pendingNewInstanceIndex = -1;
@@ -1202,12 +1199,9 @@
}
}
- public Outliner(AppInfoWithLiveness appInfo, InternalOptions options, IRConverter converter) {
- this.appInfo = appInfo;
- this.dexItemFactory = appInfo.dexItemFactory;
- this.converter = converter;
- this.inliningConstraints = new InliningConstraints(appInfo);
- this.options = options;
+ public Outliner(AppView<? extends AppInfoWithLiveness> appView, IRConverter converter) {
+ this.appView = appView;
+ this.inliningConstraints = new InliningConstraints(appView, GraphLense.getIdentityLense());
}
public BiConsumer<IRCode, DexEncodedMethod> identifyCandidateMethods() {
@@ -1236,12 +1230,10 @@
assert methodsSelectedForOutlining.size() == 0;
assert outlineSites.size() == 0;
for (List<DexEncodedMethod> outlineMethods : candidateMethodLists) {
- if (outlineMethods.size() >= options.outline.threshold) {
+ if (outlineMethods.size() >= appView.options().outline.threshold) {
for (DexEncodedMethod outlineMethod : outlineMethods) {
methodsSelectedForOutlining.add(
- converter
- .graphLense()
- .mapDexEncodedMethod(outlineMethod, appInfo));
+ appView.graphLense().mapDexEncodedMethod(outlineMethod, appView));
}
}
}
@@ -1265,7 +1257,8 @@
MethodAccessFlags methodAccess =
MethodAccessFlags.fromSharedAccessFlags(
Constants.ACC_PUBLIC | Constants.ACC_STATIC, false);
- DexString methodName = dexItemFactory.createString(OutlineOptions.METHOD_PREFIX + count);
+ DexString methodName =
+ appView.dexItemFactory().createString(OutlineOptions.METHOD_PREFIX + count);
DexMethod method = outline.buildMethod(type, methodName);
List<DexEncodedMethod> sites = outlineSites.get(outline);
assert !sites.isEmpty();
@@ -1276,7 +1269,7 @@
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
new OutlineCode(outline));
- if (options.isGeneratingClassFiles()) {
+ if (appView.options().isGeneratingClassFiles()) {
direct[count].upgradeClassFileVersion(sites.get(0).getClassFileVersion());
}
generatedOutlines.put(outline, method);
@@ -1285,9 +1278,9 @@
// No need to sort the direct methods as they are generated in sorted order.
// Build the outliner class.
- DexType superType = dexItemFactory.createType("Ljava/lang/Object;");
+ DexType superType = appView.dexItemFactory().createType("Ljava/lang/Object;");
DexTypeList interfaces = DexTypeList.empty();
- DexString sourceFile = dexItemFactory.createString("outline");
+ DexString sourceFile = appView.dexItemFactory().createString("outline");
ClassAccessFlags accessFlags = ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC);
DexProgramClass clazz =
new DexProgramClass(
@@ -1306,7 +1299,7 @@
DexEncodedField.EMPTY_ARRAY, // Instance fields.
direct,
DexEncodedMethod.EMPTY_ARRAY, // Virtual methods.
- options.itemFactory.getSkipNameValidationForTesting());
+ appView.dexItemFactory().getSkipNameValidationForTesting());
return clazz;
}
@@ -1315,7 +1308,7 @@
assert candidateMethodLists.isEmpty();
List<Outline> result = new ArrayList<>();
for (Entry<Outline, List<DexEncodedMethod>> entry : outlineSites.entrySet()) {
- if (entry.getValue().size() >= options.outline.threshold) {
+ if (entry.getValue().size() >= appView.options().outline.threshold) {
result.add(entry.getKey());
}
}
@@ -1404,7 +1397,7 @@
// Fill in the Argument instructions in the argument block.
for (int i = 0; i < outline.argumentTypes.size(); i++) {
TypeLatticeElement typeLattice =
- TypeLatticeElement.fromDexType(outline.argumentTypes.get(i), maybeNull(), appInfo);
+ TypeLatticeElement.fromDexType(outline.argumentTypes.get(i), maybeNull(), appView);
builder.addNonThisArgument(i, typeLattice);
}
builder.flushArgumentInstructions();
@@ -1425,7 +1418,7 @@
public void buildInstruction(
IRBuilder builder, int instructionIndex, boolean firstBlockInstruction) {
if (instructionIndex == outline.templateInstructions.size()) {
- if (outline.returnType == dexItemFactory.voidType) {
+ if (outline.returnType == appView.dexItemFactory().voidType) {
builder.addReturn();
} else {
builder.addReturn(outline.argumentCount());
@@ -1520,14 +1513,10 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
- Origin origin) {
+ DexEncodedMethod encodedMethod, AppView<? extends AppInfo> appView, Origin origin) {
assert getOwner() == encodedMethod;
OutlineSourceCode source = new OutlineSourceCode(outline, encodedMethod.method);
- return new IRBuilder(encodedMethod, appInfo, source, options, origin).build(encodedMethod);
+ return new IRBuilder(encodedMethod, appView, source, origin).build(encodedMethod);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
index 9b0ab04..e298873 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.ir.optimize;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -29,10 +30,9 @@
// TODO(ager): Evaluate speed/size for computing active field sets in a fixed-point computation.
public class RedundantFieldLoadElimination {
- private final AppInfo appInfo;
+ private final AppView<? extends AppInfo> appView;
private final DexEncodedMethod method;
private final IRCode code;
- private final boolean enableWholeProgramOptimizations;
private final DominatorTree dominatorTree;
// Maps keeping track of fields that have an already loaded value at basic block entry.
@@ -46,12 +46,10 @@
private HashMap<FieldAndObject, Instruction> activeInstanceFields;
private HashMap<DexField, Instruction> activeStaticFields;
- public RedundantFieldLoadElimination(
- AppInfo appInfo, IRCode code, boolean enableWholeProgramOptimizations) {
- this.appInfo = appInfo;
+ public RedundantFieldLoadElimination(AppView<? extends AppInfo> appView, IRCode code) {
+ this.appView = appView;
this.method = code.method;
this.code = code;
- this.enableWholeProgramOptimizations = enableWholeProgramOptimizations;
dominatorTree = new DominatorTree(code);
}
@@ -80,10 +78,11 @@
}
private boolean couldBeVolatile(DexField field) {
- if (!enableWholeProgramOptimizations && field.getHolder() != method.method.getHolder()) {
+ if (!appView.enableWholeProgramOptimizations()
+ && field.getHolder() != method.method.getHolder()) {
return true;
}
- DexEncodedField definition = appInfo.definitionFor(field);
+ DexEncodedField definition = appView.definitionFor(field);
return definition == null || definition.accessFlags.isVolatile();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java
index 9d41edc..bd0fdea 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java
@@ -9,6 +9,7 @@
import static com.android.tools.r8.utils.DescriptorUtils.getSimpleClassNameFromDescriptor;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -75,8 +76,9 @@
}
// Rewrite getClass() call to const-class if the type of the given instance is effectively final.
- public static void rewriteGetClass(AppInfoWithLiveness appInfo, IRCode code) {
+ public static void rewriteGetClass(AppView<? extends AppInfoWithLiveness> appView, IRCode code) {
InstructionIterator it = code.instructionIterator();
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
while (it.hasNext()) {
Instruction current = it.next();
// Conservatively bail out if the containing block has catch handlers.
@@ -90,7 +92,7 @@
InvokeVirtual invoke = current.asInvokeVirtual();
DexMethod invokedMethod = invoke.getInvokedMethod();
// Class<?> Object#getClass() is final and cannot be overridden.
- if (invokedMethod != appInfo.dexItemFactory.objectMethods.getClass) {
+ if (invokedMethod != dexItemFactory.objectMethods.getClass) {
continue;
}
Value in = invoke.getReceiver();
@@ -103,31 +105,32 @@
|| inType.isNullable()) {
continue;
}
- DexType type = inType.isClassType()
- ? inType.asClassTypeLatticeElement().getClassType()
- : inType.asArrayTypeLatticeElement().getArrayType(appInfo.dexItemFactory);
- DexType baseType = type.toBaseType(appInfo.dexItemFactory);
+ DexType type =
+ inType.isClassType()
+ ? inType.asClassTypeLatticeElement().getClassType()
+ : inType.asArrayTypeLatticeElement().getArrayType(dexItemFactory);
+ DexType baseType = type.toBaseType(dexItemFactory);
// Make sure base type is a class type.
if (!baseType.isClassType()) {
continue;
}
// Only consider program class, e.g., platform can introduce sub types in different versions.
- DexClass clazz = appInfo.definitionFor(baseType);
+ DexClass clazz = appView.definitionFor(baseType);
if (clazz == null || !clazz.isProgramClass()) {
continue;
}
// Only consider effectively final class. Exception: new Base().getClass().
if (!baseType.hasSubtypes()
- || !appInfo.isInstantiatedIndirectly(baseType)
+ || !appView.appInfo().isInstantiatedIndirectly(baseType)
|| (!in.isPhi() && in.definition.isCreatingInstanceOrArray())) {
// Make sure the target (base) type is visible.
ConstraintWithTarget constraints =
- ConstraintWithTarget.classIsVisible(code.method.method.getHolder(), baseType, appInfo);
+ ConstraintWithTarget.classIsVisible(code.method.method.getHolder(), baseType, appView);
if (constraints == ConstraintWithTarget.NEVER) {
continue;
}
TypeLatticeElement typeLattice =
- TypeLatticeElement.classClassType(appInfo, definitelyNotNull());
+ TypeLatticeElement.classClassType(appView, definitelyNotNull());
Value value = code.createValue(typeLattice, invoke.getLocalInfo());
ConstClass constClass = new ConstClass(value, type);
it.replaceCurrentInstruction(constClass);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
index 47284cc..a20539c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
@@ -10,13 +10,11 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionIterator;
import com.android.tools.r8.ir.code.InvokeVirtual;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
-import com.android.tools.r8.utils.InternalOptions;
import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import java.util.Arrays;
@@ -62,30 +60,26 @@
*/
public class SwitchMapCollector {
- private final AppInfoWithLiveness appInfo;
- private final GraphLense graphLense;
- private final InternalOptions options;
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final DexString switchMapPrefix;
private final DexType intArrayType;
private final Map<DexField, Int2ReferenceMap<DexField>> switchMaps = new IdentityHashMap<>();
public SwitchMapCollector(AppView<? extends AppInfoWithLiveness> appView) {
- this.appInfo = appView.appInfo();
- this.graphLense = appView.graphLense();
- this.options = appView.options();
- switchMapPrefix = appInfo.dexItemFactory.createString("$SwitchMap$");
- intArrayType = appInfo.dexItemFactory.createType("[I");
+ this.appView = appView;
+ switchMapPrefix = appView.dexItemFactory().createString("$SwitchMap$");
+ intArrayType = appView.dexItemFactory().createType("[I");
}
public AppInfoWithLiveness run() {
- for (DexProgramClass clazz : appInfo.classes()) {
+ for (DexProgramClass clazz : appView.appInfo().classes()) {
processClasses(clazz);
}
if (!switchMaps.isEmpty()) {
- return appInfo.addSwitchMaps(switchMaps);
+ return appView.appInfo().addSwitchMaps(switchMaps);
}
- return appInfo;
+ return appView.appInfo();
}
private void processClasses(DexProgramClass clazz) {
@@ -96,8 +90,7 @@
List<DexEncodedField> switchMapFields = Arrays.stream(clazz.staticFields())
.filter(this::maybeIsSwitchMap).collect(Collectors.toList());
if (!switchMapFields.isEmpty()) {
- IRCode initializer =
- clazz.getClassInitializer().buildIR(appInfo, graphLense, options, clazz.origin);
+ IRCode initializer = clazz.getClassInitializer().buildIR(appView, clazz.origin);
switchMapFields.forEach(field -> extractSwitchMap(field, initializer));
}
}
@@ -121,9 +114,10 @@
return;
}
InvokeVirtual invoke = value.asInvokeVirtual();
- DexClass holder = appInfo.definitionFor(invoke.getInvokedMethod().holder);
- if (holder == null ||
- (!holder.accessFlags.isEnum() && holder.type != appInfo.dexItemFactory.enumType)) {
+ DexClass holder = appView.definitionFor(invoke.getInvokedMethod().holder);
+ if (holder == null
+ || (!holder.accessFlags.isEnum()
+ && holder.type != appView.dexItemFactory().enumType)) {
return;
}
Instruction enumGet = invoke.arguments().get(0).definition;
@@ -131,7 +125,7 @@
return;
}
DexField enumField = enumGet.asStaticGet().getField();
- if (!appInfo.definitionFor(enumField.getHolder()).accessFlags.isEnum()) {
+ if (!appView.definitionFor(enumField.getHolder()).accessFlags.isEnum()) {
return;
}
if (switchMap.put(integerIndex, enumField) != null) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
index 1f4c1c3..da18d38 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.optimize.classinliner;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
@@ -25,16 +26,15 @@
import java.util.stream.Collectors;
public final class ClassInliner {
- private final DexItemFactory factory;
+
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final LambdaRewriter lambdaRewriter;
- private final int totalMethodInstructionLimit;
private final ConcurrentHashMap<DexClass, Boolean> knownClasses = new ConcurrentHashMap<>();
- public ClassInliner(DexItemFactory factory,
- LambdaRewriter lambdaRewriter, int totalMethodInstructionLimit) {
- this.factory = factory;
+ public ClassInliner(
+ AppView<? extends AppInfoWithLiveness> appView, LambdaRewriter lambdaRewriter) {
+ this.appView = appView;
this.lambdaRewriter = lambdaRewriter;
- this.totalMethodInstructionLimit = totalMethodInstructionLimit;
}
// Process method code and inline eligible class instantiations, in short:
@@ -115,7 +115,7 @@
// }
//
public final void processMethodCode(
- AppInfoWithLiveness appInfo,
+ AppView<? extends AppInfoWithLiveness> appView,
CodeRewriter codeRewriter,
StringOptimizer stringOptimizer,
DexEncodedMethod method,
@@ -144,11 +144,10 @@
Instruction root = rootsIterator.next();
InlineCandidateProcessor processor =
new InlineCandidateProcessor(
- factory,
- appInfo,
+ appView,
lambdaRewriter,
inliner,
- clazz -> isClassEligible(appInfo, clazz),
+ clazz -> isClassEligible(appView, clazz),
isProcessedConcurrently,
method,
root);
@@ -169,7 +168,8 @@
}
// Is inlining allowed.
- if (processor.getEstimatedCombinedSizeForInlining() >= totalMethodInstructionLimit) {
+ if (processor.getEstimatedCombinedSizeForInlining()
+ >= appView.options().classInliningInstructionLimit) {
continue;
}
@@ -201,10 +201,10 @@
}
}
- private boolean isClassEligible(AppInfoWithLiveness appInfo, DexClass clazz) {
+ private boolean isClassEligible(AppView<? extends AppInfoWithLiveness> appView, DexClass clazz) {
Boolean eligible = knownClasses.get(clazz);
if (eligible == null) {
- Boolean computed = computeClassEligible(appInfo, clazz);
+ Boolean computed = computeClassEligible(appView, clazz);
Boolean existing = knownClasses.putIfAbsent(clazz, computed);
assert existing == null || existing == computed;
eligible = existing == null ? computed : existing;
@@ -216,24 +216,26 @@
// - is not an abstract class or interface
// - does not declare finalizer
// - does not trigger any static initializers except for its own
- private boolean computeClassEligible(AppInfoWithLiveness appInfo, DexClass clazz) {
+ private boolean computeClassEligible(
+ AppView<? extends AppInfoWithLiveness> appView, DexClass clazz) {
if (clazz == null
|| clazz.isLibraryClass()
|| clazz.accessFlags.isAbstract()
|| clazz.accessFlags.isInterface()
- || appInfo.neverClassInline.contains(clazz.type)) {
+ || appView.appInfo().neverClassInline.contains(clazz.type)) {
return false;
}
// Class must not define finalizer.
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
for (DexEncodedMethod method : clazz.virtualMethods()) {
- if (method.method.name == factory.finalizeMethodName &&
- method.method.proto == factory.objectMethods.finalize.proto) {
+ if (method.method.name == dexItemFactory.finalizeMethodName
+ && method.method.proto == dexItemFactory.objectMethods.finalize.proto) {
return false;
}
}
// Check for static initializers in this class or any of interfaces it implements.
- return !clazz.initializationOfParentTypesMayHaveSideEffects(appInfo);
+ return !clazz.initializationOfParentTypesMayHaveSideEffects(appView.appInfo());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java
index 425ce11..bbbb3e8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -29,17 +30,18 @@
private final DexField field;
private final IRCode code;
private final Instruction root;
- private final AppInfo appInfo;
+ private final AppView<? extends AppInfo> appView;
private Value defaultValue = null;
private final Map<BasicBlock, Value> ins = new IdentityHashMap<>();
private final Map<BasicBlock, Value> outs = new IdentityHashMap<>();
- FieldValueHelper(DexField field, IRCode code, Instruction root, AppInfo appInfo) {
+ FieldValueHelper(
+ DexField field, IRCode code, Instruction root, AppView<? extends AppInfo> appView) {
this.field = field;
this.code = code;
this.root = root;
- this.appInfo = appInfo;
+ this.appView = appView;
}
void replaceValue(Value oldValue, Value newValue) {
@@ -94,7 +96,7 @@
new Phi(
code.valueNumberGenerator.next(),
block,
- TypeLatticeElement.fromDexType(field.type, maybeNull(), appInfo),
+ TypeLatticeElement.fromDexType(field.type, maybeNull(), appView),
null,
RegisterReadType.NORMAL);
ins.put(block, phi);
@@ -142,8 +144,8 @@
assert root == valueProducingInsn;
if (defaultValue == null) {
// If we met newInstance it means that default value is supposed to be used.
- defaultValue = code.createValue(
- TypeLatticeElement.fromDexType(field.type, maybeNull(), appInfo));
+ defaultValue =
+ code.createValue(TypeLatticeElement.fromDexType(field.type, maybeNull(), appView));
ConstNumber defaultValueInsn = new ConstNumber(defaultValue, 0);
defaultValueInsn.setPosition(root.getPosition());
LinkedList<Instruction> instructions = block.getInstructions();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index ec61b42..f36a132 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo.ResolutionResult;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
@@ -13,7 +14,6 @@
import com.android.tools.r8.graph.DexEncodedMethod.TrivialInitializer.TrivialClassInitializer;
import com.android.tools.r8.graph.DexEncodedMethod.TrivialInitializer.TrivialInstanceInitializer;
import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.OptimizationInfo;
@@ -58,8 +58,7 @@
private static final ImmutableSet<If.Type> ALLOWED_ZERO_TEST_TYPES =
ImmutableSet.of(If.Type.EQ, If.Type.NE);
- private final DexItemFactory factory;
- private final AppInfoWithLiveness appInfo;
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final LambdaRewriter lambdaRewriter;
private final Inliner inliner;
private final Predicate<DexClass> isClassEligible;
@@ -82,21 +81,19 @@
private int estimatedCombinedSizeForInlining = 0;
InlineCandidateProcessor(
- DexItemFactory factory,
- AppInfoWithLiveness appInfo,
+ AppView<? extends AppInfoWithLiveness> appView,
LambdaRewriter lambdaRewriter,
Inliner inliner,
Predicate<DexClass> isClassEligible,
Predicate<DexEncodedMethod> isProcessedConcurrently,
DexEncodedMethod method,
Instruction root) {
- this.factory = factory;
+ this.appView = appView;
this.lambdaRewriter = lambdaRewriter;
this.inliner = inliner;
this.isClassEligible = isClassEligible;
this.method = method;
this.root = root;
- this.appInfo = appInfo;
this.isProcessedConcurrently = isProcessedConcurrently;
}
@@ -123,7 +120,7 @@
isDesugaredLambda = eligibleClassDefinition != null;
}
if (eligibleClassDefinition == null) {
- eligibleClassDefinition = appInfo.definitionFor(eligibleClass);
+ eligibleClassDefinition = appView.definitionFor(eligibleClass);
}
return eligibleClassDefinition != null;
}
@@ -229,9 +226,11 @@
assert info == null || info instanceof TrivialClassInitializer;
DexField instanceField = root.asStaticGet().getField();
// Singleton instance field must NOT be pinned.
- return info != null &&
- ((TrivialClassInitializer) info).field == instanceField &&
- !appInfo.isPinned(eligibleClassDefinition.lookupStaticField(instanceField).field);
+ return info != null
+ && ((TrivialClassInitializer) info).field == instanceField
+ && !appView
+ .appInfo()
+ .isPinned(eligibleClassDefinition.lookupStaticField(instanceField).field);
}
/**
@@ -273,7 +272,7 @@
// Eligible constructor call (for new instance roots only).
if (user.isInvokeDirect()) {
InvokeDirect invoke = user.asInvokeDirect();
- if (factory.isConstructor(invoke.getInvokedMethod())) {
+ if (appView.dexItemFactory().isConstructor(invoke.getInvokedMethod())) {
boolean isCorrespondingConstructorCall =
root.isNewInstance()
&& !invoke.inValues().isEmpty()
@@ -414,10 +413,10 @@
boolean needToRemoveUnreachableBlocks = false;
for (Instruction user : eligibleInstance.uniqueUsers()) {
// Remove the call to superclass constructor.
- if (root.isNewInstance() &&
- user.isInvokeDirect() &&
- factory.isConstructor(user.asInvokeDirect().getInvokedMethod()) &&
- user.asInvokeDirect().getInvokedMethod().holder == eligibleClassDefinition.superType) {
+ if (root.isNewInstance()
+ && user.isInvokeDirect()
+ && appView.dexItemFactory().isConstructor(user.asInvokeDirect().getInvokedMethod())
+ && user.asInvokeDirect().getInvokedMethod().holder == eligibleClassDefinition.superType) {
removeInstruction(user);
continue;
}
@@ -491,14 +490,14 @@
if (value != null) {
FieldValueHelper helper =
fieldHelpers.computeIfAbsent(
- fieldRead.getField(), field -> new FieldValueHelper(field, code, root, appInfo));
+ fieldRead.getField(), field -> new FieldValueHelper(field, code, root, appView));
Value newValue = helper.getValueForFieldRead(fieldRead.getBlock(), fieldRead);
value.replaceUsers(newValue);
for (FieldValueHelper fieldValueHelper : fieldHelpers.values()) {
fieldValueHelper.replaceValue(value, newValue);
}
assert value.numberOfAllUsers() == 0;
- new TypeAnalysis(appInfo, code.method).widening(code.method, code);
+ new TypeAnalysis(appView, code.method).widening(code.method, code);
}
removeInstruction(fieldRead);
}
@@ -525,7 +524,7 @@
private InliningInfo isEligibleConstructorCall(
InvokeDirect invoke, DexEncodedMethod singleTarget, Supplier<InliningOracle> defaultOracle) {
- assert factory.isConstructor(invoke.getInvokedMethod());
+ assert appView.dexItemFactory().isConstructor(invoke.getInvokedMethod());
assert isEligibleSingleTarget(singleTarget);
// Must be a constructor called on the receiver.
@@ -559,7 +558,7 @@
// NOTE: since we already classified the class as eligible, it does not have
// any class initializers in superclass chain or in superinterfaces, see
// details in ClassInliner::computeClassEligible(...).
- if (eligibleClassDefinition.superType != factory.objectType) {
+ if (eligibleClassDefinition.superType != appView.dexItemFactory().objectType) {
TrivialInitializer info = singleTarget.getOptimizationInfo().getTrivialInitializerInfo();
if (!(info instanceof TrivialInstanceInitializer)) {
return null;
@@ -650,7 +649,7 @@
// We should not inline a method if the invocation has type interface or virtual and the
// signature of the invocation resolves to a private or static method.
- ResolutionResult resolutionResult = appInfo.resolveMethod(callee.holder, callee);
+ ResolutionResult resolutionResult = appView.appInfo().resolveMethod(callee.holder, callee);
if (resolutionResult.hasSingleTarget()
&& !resolutionResult.asSingleTarget().isVirtualMethod()) {
return null;
@@ -686,7 +685,8 @@
}
private boolean isExtraMethodCall(InvokeMethod invoke) {
- if (invoke.isInvokeDirect() && factory.isConstructor(invoke.getInvokedMethod())) {
+ if (invoke.isInvokeDirect()
+ && appView.dexItemFactory().isConstructor(invoke.getInvokedMethod())) {
return false;
}
if (invoke.isInvokeMethodWithReceiver()
@@ -845,10 +845,10 @@
}
private boolean isTrivialInitializer(DexMethod method) {
- if (method == appInfo.dexItemFactory.objectMethods.constructor) {
+ if (method == appView.dexItemFactory().objectMethods.constructor) {
return true;
}
- DexEncodedMethod encodedMethod = appInfo.definitionFor(method);
+ DexEncodedMethod encodedMethod = appView.definitionFor(method);
return encodedMethod != null
&& encodedMethod.getOptimizationInfo().getTrivialInitializerInfo() != null;
}
@@ -858,10 +858,10 @@
if (isDesugaredLambda && inlineeHolder == eligibleClass) {
return true;
}
- if (appInfo.isPinned(inlineeHolder)) {
+ if (appView.appInfo().isPinned(inlineeHolder)) {
return false;
}
- DexClass inlineeClass = appInfo.definitionFor(inlineeHolder);
+ DexClass inlineeClass = appView.definitionFor(inlineeHolder);
assert inlineeClass != null;
KotlinInfo kotlinInfo = inlineeClass.getKotlinInfo();
@@ -879,7 +879,7 @@
private DexEncodedMethod findSingleTarget(InvokeMethod invoke) {
if (isExtraMethodCall(invoke)) {
DexType invocationContext = method.method.holder;
- return invoke.lookupSingleTarget(appInfo, invocationContext);
+ return invoke.lookupSingleTarget(appView.appInfo(), invocationContext);
}
// We don't use computeSingleTarget(...) on invoke since it sometimes fails to
// find the single target, while this code may be more successful since we exactly
@@ -908,7 +908,7 @@
// return false.
return true;
}
- if (!singleTarget.isInliningCandidate(method, Reason.SIMPLE, appInfo)) {
+ if (!singleTarget.isInliningCandidate(method, Reason.SIMPLE, appView.appInfo())) {
// If `singleTarget` is not an inlining candidate, we won't be able to inline it here.
//
// Note that there may be some false negatives here since the method may
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
index 3538e8c..66ae73a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
@@ -34,7 +34,6 @@
import com.android.tools.r8.ir.optimize.lambda.kotlin.KotlinLambdaGroupIdFactory;
import com.android.tools.r8.kotlin.Kotlin;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
-import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.ThrowingConsumer;
@@ -147,29 +146,35 @@
// We do this before methods are being processed to guarantee stable order of
// lambdas inside each group.
public final void collectGroupCandidates(
- DexApplication app, AppInfoWithLiveness infoWithLiveness, InternalOptions options) {
- assert infoWithLiveness != null;
+ DexApplication app, AppView<? extends AppInfoWithLiveness> appView) {
// Collect lambda groups.
app.classes().stream()
- .filter(cls -> !infoWithLiveness.isPinned(cls.type))
- .filter(cls -> cls.hasKotlinInfo() &&
- cls.getKotlinInfo().isSyntheticClass() &&
- cls.getKotlinInfo().asSyntheticClass().isLambda())
+ .filter(cls -> !appView.appInfo().isPinned(cls.type))
+ .filter(
+ cls ->
+ cls.hasKotlinInfo()
+ && cls.getKotlinInfo().isSyntheticClass()
+ && cls.getKotlinInfo().asSyntheticClass().isLambda())
.sorted((a, b) -> a.type.slowCompareTo(b.type)) // Ensure stable ordering.
- .forEachOrdered(lambda -> {
- try {
- LambdaGroupId id = KotlinLambdaGroupIdFactory.create(kotlin, lambda, options);
- LambdaGroup group = groups.computeIfAbsent(id, LambdaGroupId::createGroup);
- group.add(lambda);
- lambdas.put(lambda.type, group);
- } catch (LambdaStructureError error) {
- if (error.reportable) {
- reporter.info(
- new StringDiagnostic("Unrecognized Kotlin lambda [" +
- lambda.type.toSourceString() + "]: " + error.getMessage()));
- }
- }
- });
+ .forEachOrdered(
+ lambda -> {
+ try {
+ LambdaGroupId id =
+ KotlinLambdaGroupIdFactory.create(kotlin, lambda, appView.options());
+ LambdaGroup group = groups.computeIfAbsent(id, LambdaGroupId::createGroup);
+ group.add(lambda);
+ lambdas.put(lambda.type, group);
+ } catch (LambdaStructureError error) {
+ if (error.reportable) {
+ reporter.info(
+ new StringDiagnostic(
+ "Unrecognized Kotlin lambda ["
+ + lambda.type.toSourceString()
+ + "]: "
+ + error.getMessage()));
+ }
+ }
+ });
// Remove trivial groups.
removeTrivialLambdaGroups();
@@ -233,9 +238,8 @@
// Then, there is a dilemma: other sub optimizations trigger subtype lookup that will throw
// NPE if it cannot find the holder for this synthesized lambda group.
// One hack here is to mark those methods `processed` so that the lense rewriter is skipped.
- synthesizedClass.forEachMethod(encodedMethod -> {
- encodedMethod.markProcessed(ConstraintWithTarget.NEVER);
- });
+ synthesizedClass.forEachMethod(
+ encodedMethod -> encodedMethod.markProcessed(ConstraintWithTarget.NEVER));
}
converter.optimizeSynthesizedClasses(lambdaGroupsClasses.values(), executorService);
@@ -324,7 +328,7 @@
}
Set<DexEncodedMethod> methods =
methodsToReprocess.stream()
- .map(method -> converter.graphLense().mapDexEncodedMethod(method, appView.appInfo()))
+ .map(method -> appView.graphLense().mapDexEncodedMethod(method, appView))
.collect(Collectors.toSet());
List<Future<?>> futures = new ArrayList<>();
for (DexEncodedMethod method : methods) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
index d69190f..9473341 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
@@ -534,10 +534,10 @@
// 2. Rewrite instance methods of classes being staticized into static ones
// 3. Rewrite methods referencing staticized members, also remove instance creation
//
- public final Set<DexEncodedMethod> staticizeCandidates(
+ public final void staticizeCandidates(
OptimizationFeedback feedback, ExecutorService executorService) throws ExecutionException {
phase = Phase.None; // We are done with processing/examining methods.
- return new StaticizingProcessor(this, executorService).run(feedback);
+ new StaticizingProcessor(appView, this, executorService).run(feedback);
}
public final void fixupMethodCode(DexEncodedMethod method, IRCode code) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
index 96bb394..5380baf 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerGraphLense.java
@@ -4,10 +4,10 @@
package com.android.tools.r8.ir.optimize.staticizer;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
import com.android.tools.r8.ir.code.Invoke.Type;
import com.google.common.collect.BiMap;
@@ -16,17 +16,17 @@
class ClassStaticizerGraphLense extends NestedGraphLense {
ClassStaticizerGraphLense(
- GraphLense previous,
- DexItemFactory factory,
+ AppView<? extends AppInfo> appView,
BiMap<DexField, DexField> fieldMapping,
BiMap<DexMethod, DexMethod> methodMapping) {
- super(ImmutableMap.of(),
+ super(
+ ImmutableMap.of(),
methodMapping,
fieldMapping,
fieldMapping.inverse(),
methodMapping.inverse(),
- previous,
- factory);
+ appView.graphLense(),
+ appView.dexItemFactory());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
index 7106005..6331d5f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
@@ -30,6 +31,7 @@
import com.android.tools.r8.ir.conversion.OptimizationFeedback;
import com.android.tools.r8.ir.optimize.Outliner;
import com.android.tools.r8.ir.optimize.staticizer.ClassStaticizer.CandidateInfo;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.utils.ThreadUtils;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
@@ -52,6 +54,7 @@
final class StaticizingProcessor {
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final ClassStaticizer classStaticizer;
private final ExecutorService executorService;
@@ -61,13 +64,16 @@
private final Map<DexField, CandidateInfo> singletonFields = new IdentityHashMap<>();
private final Map<DexType, DexType> candidateToHostMapping = new IdentityHashMap<>();
- StaticizingProcessor(ClassStaticizer classStaticizer, ExecutorService executorService) {
+ StaticizingProcessor(
+ AppView<? extends AppInfoWithLiveness> appView,
+ ClassStaticizer classStaticizer,
+ ExecutorService executorService) {
+ this.appView = appView;
this.classStaticizer = classStaticizer;
this.executorService = executorService;
}
- /** @return the set of methods that have been reprocessed as a result of staticizing. */
- final Set<DexEncodedMethod> run(OptimizationFeedback feedback) throws ExecutionException {
+ final void run(OptimizationFeedback feedback) throws ExecutionException {
// Filter out candidates based on the information we collected while examining methods.
finalEligibilityCheck();
@@ -90,8 +96,6 @@
methods.addAll(referencingExtraMethods);
methods.addAll(hostClassInits.keySet());
processMethodsConcurrently(methods, this::rewriteReferences, feedback);
-
- return methods;
}
private void finalEligibilityCheck() {
@@ -484,8 +488,7 @@
}
}
candidateClass.setVirtualMethods(DexEncodedMethod.EMPTY_ARRAY);
- candidateClass.setDirectMethods(
- newDirectMethods.toArray(new DexEncodedMethod[newDirectMethods.size()]));
+ candidateClass.setDirectMethods(newDirectMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
// Consider moving static members from candidate into host.
DexType hostType = candidate.hostType();
@@ -501,12 +504,7 @@
}
if (!methodMapping.isEmpty() || !fieldMapping.isEmpty()) {
- classStaticizer.converter.appView.setGraphLense(
- new ClassStaticizerGraphLense(
- classStaticizer.converter.graphLense(),
- classStaticizer.factory,
- fieldMapping,
- methodMapping));
+ appView.setGraphLense(new ClassStaticizerGraphLense(appView, fieldMapping, methodMapping));
}
return staticizedMethods;
}
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java
index faff2ac..21935b4 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java
@@ -6,9 +6,9 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Position;
@@ -17,7 +17,6 @@
import com.android.tools.r8.ir.conversion.SourceCode;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.InternalOptions;
import java.util.function.Consumer;
public abstract class AbstractSynthesizedCode extends Code {
@@ -37,21 +36,15 @@
@Override
public final IRCode buildIR(
- DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
- Origin origin) {
+ DexEncodedMethod encodedMethod, AppView<? extends AppInfo> appView, Origin origin) {
assert getOwner() == encodedMethod;
IRBuilder builder =
new IRBuilder(
encodedMethod,
- appInfo,
+ appView,
getSourceCodeProvider().get(null),
- options,
origin,
- new ValueNumberGenerator(),
- graphLense);
+ new ValueNumberGenerator());
return builder.build(encodedMethod);
}
@@ -59,9 +52,7 @@
public IRCode buildInliningIR(
DexEncodedMethod context,
DexEncodedMethod encodedMethod,
- AppInfo appInfo,
- GraphLense graphLense,
- InternalOptions options,
+ AppView<? extends AppInfo> appView,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
@@ -69,12 +60,10 @@
IRBuilder builder =
new IRBuilder(
encodedMethod,
- appInfo,
+ appView,
getSourceCodeProvider().get(callerPosition),
- options,
origin,
- valueNumberGenerator,
- graphLense);
+ valueNumberGenerator);
return builder.build(context);
}
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
index 031ae7e..a75b3bc 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
@@ -189,7 +189,7 @@
builder.writeRegister(
receiverRegister,
TypeLatticeElement.fromDexType(
- receiver, Nullability.definitelyNotNull(), builder.getAppInfo()),
+ receiver, Nullability.definitelyNotNull(), builder.appView),
NO_THROW);
builder.add(new Argument(receiverValue));
receiverValue.markAsThis();
@@ -200,8 +200,7 @@
for (int i = 0; i < parameters.length; i++) {
// TODO(zerny): Why does this not call builder.addNonThisArgument?
TypeLatticeElement typeLattice =
- TypeLatticeElement.fromDexType(
- parameters[i], Nullability.maybeNull(), builder.getAppInfo());
+ TypeLatticeElement.fromDexType(parameters[i], Nullability.maybeNull(), builder.appView);
Value paramValue = builder.writeRegister(paramRegisters[i], typeLattice, NO_THROW);
paramValues[i] = paramValue;
builder.add(new Argument(paramValue));
diff --git a/src/main/java/com/android/tools/r8/jar/InliningConstraintVisitor.java b/src/main/java/com/android/tools/r8/jar/InliningConstraintVisitor.java
index 4bfb5ce..d3cda4a 100644
--- a/src/main/java/com/android/tools/r8/jar/InliningConstraintVisitor.java
+++ b/src/main/java/com/android/tools/r8/jar/InliningConstraintVisitor.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -36,7 +37,7 @@
public class InliningConstraintVisitor extends MethodVisitor {
private final JarApplicationReader application;
- private final AppInfoWithLiveness appInfo;
+ private final AppView<? extends AppInfoWithLiveness> appView;
private final GraphLense graphLense;
private final InliningConstraints inliningConstraints;
private final DexEncodedMethod method;
@@ -46,16 +47,16 @@
public InliningConstraintVisitor(
JarApplicationReader application,
- AppInfoWithLiveness appInfo,
+ AppView<? extends AppInfoWithLiveness> appView,
GraphLense graphLense,
DexEncodedMethod method,
DexType invocationContext) {
super(ASM6);
assert graphLense.isContextFreeForMethods();
this.application = application;
- this.appInfo = appInfo;
+ this.appView = appView;
this.graphLense = graphLense;
- this.inliningConstraints = new InliningConstraints(appInfo, graphLense);
+ this.inliningConstraints = new InliningConstraints(appView, graphLense);
this.method = method;
this.invocationContext = invocationContext;
@@ -73,7 +74,7 @@
}
private void updateConstraint(ConstraintWithTarget other) {
- constraint = ConstraintWithTarget.meet(constraint, other, appInfo);
+ constraint = ConstraintWithTarget.meet(constraint, other, appView);
}
// Used to signal that the result is ready, such that we do not need to visit all instructions of
@@ -180,7 +181,7 @@
type = Invoke.Type.VIRTUAL;
// Instructions that target a private method in the same class translates to invoke-direct.
if (target.holder == method.method.holder) {
- DexClass clazz = appInfo.definitionFor(target.holder);
+ DexClass clazz = appView.definitionFor(target.holder);
if (clazz != null && clazz.lookupDirectMethod(target) != null) {
type = Invoke.Type.DIRECT;
}
diff --git a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
index 577da26..e5f9218 100644
--- a/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/FieldNameMinifier.java
@@ -134,20 +134,19 @@
return;
}
// Now, `field` is reference. Find its definition and check if it's renamed.
- DexType holderType = field.getHolder();
- DexClass holder = appInfo.definitionFor(holderType);
+ DexClass holder = appInfo.definitionFor(field.clazz);
// We don't care pruned types or library classes.
if (holder == null || holder.isLibraryClass()) {
return;
}
- definition = appInfo.resolveFieldOn(holderType, field);
+ definition = appInfo.resolveField(field);
if (definition == null) {
// The program is already broken in the sense that it has an unresolvable field reference.
// Leave it as-is.
return;
}
assert definition.field != field;
- assert definition.field.getHolder() != holderType;
+ assert definition.field.clazz != field.clazz;
// If the definition is renamed,
if (renaming.containsKey(definition.field)) {
// Assign the same, renamed name as the definition to the reference.
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
index 0638816..9479ab3 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
@@ -7,12 +7,11 @@
import static com.android.tools.r8.naming.IdentifierNameStringUtils.inferMemberOrTypeFromNameString;
import static com.android.tools.r8.naming.IdentifierNameStringUtils.isReflectionMethod;
-import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
@@ -36,7 +35,6 @@
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.TextPosition;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
-import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringDiagnostic;
import com.google.common.collect.Streams;
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
@@ -47,21 +45,18 @@
import java.util.stream.Collectors;
public class IdentifierNameStringMarker {
- private final AppInfo appInfo;
- private final DexItemFactory dexItemFactory;
- private final Object2BooleanMap<DexReference> identifierNameStrings;
- private final InternalOptions options;
- public IdentifierNameStringMarker(AppInfoWithLiveness appInfo, InternalOptions options) {
- this.appInfo = appInfo;
- this.dexItemFactory = appInfo.dexItemFactory;
+ private final AppView<? extends AppInfoWithLiveness> appView;
+ private final Object2BooleanMap<DexReference> identifierNameStrings;
+
+ public IdentifierNameStringMarker(AppView<? extends AppInfoWithLiveness> appView) {
+ this.appView = appView;
// Note that this info is only available at AppInfoWithLiveness.
- this.identifierNameStrings = appInfo.identifierNameStrings;
- this.options = options;
+ this.identifierNameStrings = appView.appInfo().identifierNameStrings;
}
public void decoupleIdentifierNameStringsInFields() {
- for (DexProgramClass clazz : appInfo.classes()) {
+ for (DexProgramClass clazz : appView.appInfo().classes()) {
for (DexEncodedField field : clazz.staticFields()) {
decoupleIdentifierNameStringInStaticField(field);
}
@@ -78,7 +73,7 @@
return;
}
DexString original = ((DexValueString) staticValue).getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appInfo, original);
+ DexReference itemBasedString = inferMemberOrTypeFromNameString(appView, original);
if (itemBasedString != null) {
encodedField.setStaticValue(new DexItemBasedValueString(itemBasedString));
}
@@ -88,8 +83,7 @@
if (!code.hasConstString) {
return;
}
- final ThrowingInfo throwingInfo =
- options.isGeneratingClassFiles() ? ThrowingInfo.NO_THROW : ThrowingInfo.NO_THROW;
+ ThrowingInfo throwingInfo = ThrowingInfo.defaultForConstString(appView.options());
DexType originHolder = code.method.method.getHolder();
ListIterator<BasicBlock> blocks = code.listIterator();
while (blocks.hasNext()) {
@@ -118,15 +112,13 @@
? instruction.asStaticPut().inValue()
: instruction.asInstancePut().value();
if (!in.isConstString()) {
- warnUndeterminedIdentifierIfNecessary(
- appInfo, options, field, originHolder, instruction, null);
+ warnUndeterminedIdentifierIfNecessary(field, originHolder, instruction, null);
continue;
}
DexString original = in.getConstInstruction().asConstString().getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appInfo, original);
+ DexReference itemBasedString = inferMemberOrTypeFromNameString(appView, original);
if (itemBasedString == null) {
- warnUndeterminedIdentifierIfNecessary(
- appInfo, options, field, originHolder, instruction, original);
+ warnUndeterminedIdentifierIfNecessary(field, originHolder, instruction, original);
continue;
}
// Move the cursor back to $fieldPut
@@ -176,18 +168,17 @@
}
List<Value> ins = invoke.arguments();
Value[] changes = new Value [ins.size()];
- if (isReflectionMethod(dexItemFactory, invokedMethod)) {
- DexReference itemBasedString = identifyIdentifier(appInfo, invoke);
+ if (isReflectionMethod(appView.dexItemFactory(), invokedMethod)) {
+ DexReference itemBasedString = identifyIdentifier(appView, invoke);
if (itemBasedString == null) {
- warnUndeterminedIdentifierIfNecessary(
- appInfo, options, invokedMethod, originHolder, instruction, null);
+ warnUndeterminedIdentifierIfNecessary(invokedMethod, originHolder, instruction, null);
continue;
}
DexType returnType = invoke.getReturnType();
boolean isClassForName =
- returnType.descriptor == dexItemFactory.classDescriptor;
+ returnType.descriptor == appView.dexItemFactory().classDescriptor;
boolean isReferenceFieldUpdater =
- returnType.descriptor == dexItemFactory.referenceFieldUpdaterDescriptor;
+ returnType.descriptor == appView.dexItemFactory().referenceFieldUpdaterDescriptor;
int positionOfIdentifier = isClassForName ? 0 : (isReferenceFieldUpdater ? 2 : 1);
Value in = invoke.arguments().get(positionOfIdentifier);
// Move the cursor back to $invoke
@@ -227,14 +218,14 @@
Value in = ins.get(i);
if (!in.isConstString()) {
warnUndeterminedIdentifierIfNecessary(
- appInfo, options, invokedMethod, originHolder, instruction, null);
+ invokedMethod, originHolder, instruction, null);
continue;
}
DexString original = in.getConstInstruction().asConstString().getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appInfo, original);
+ DexReference itemBasedString = inferMemberOrTypeFromNameString(appView, original);
if (itemBasedString == null) {
warnUndeterminedIdentifierIfNecessary(
- appInfo, options, invokedMethod, originHolder, instruction, original);
+ invokedMethod, originHolder, instruction, original);
continue;
}
// Move the cursor back to $invoke
@@ -291,8 +282,6 @@
}
private void warnUndeterminedIdentifierIfNecessary(
- AppInfo appInfo,
- InternalOptions options,
DexReference member,
DexType originHolder,
Instruction instruction,
@@ -303,16 +292,16 @@
if (!matchedByExplicitRule) {
return;
}
- DexClass originClass = appInfo.definitionFor(originHolder);
+ DexClass originClass = appView.definitionFor(originHolder);
// If the origin is a library class, it is out of developers' control.
if (originClass != null && originClass.isLibraryClass()) {
return;
}
// Undetermined identifiers matter only if minification is enabled.
- if (!options.getProguardConfiguration().isObfuscating()) {
+ if (!appView.options().getProguardConfiguration().isObfuscating()) {
return;
}
- Origin origin = appInfo.originFor(originHolder);
+ Origin origin = appView.appInfo().originFor(originHolder);
String kind = member instanceof DexField ? "field" : "method";
String originalMessage = original == null ? "what identifier string flows to "
: "what '" + original.toString() + "' refers to, which flows to ";
@@ -326,6 +315,6 @@
? new StringDiagnostic(message, origin,
new TextPosition(0L, instruction.getPosition().line, 1))
: new StringDiagnostic(message, origin);
- options.reporter.warning(diagnostic);
+ appView.options().reporter.warning(diagnostic);
}
}
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java
index 706620f..ba27d47 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringUtils.java
@@ -5,8 +5,8 @@
import static com.android.tools.r8.utils.DescriptorUtils.javaTypeToDescriptorIfValidJavaType;
-import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
@@ -140,19 +140,20 @@
* Returns a {@link DexReference} if one of the arguments to the invoke instruction is a constant
* string that corresponds to either a class or member name (i.e., an identifier).
*
- * @param appInfo {@link AppInfo} that gives access to {@link DexItemFactory}.
+ * @param definitions {@link DexDefinitionSupplier} that gives access to {@link DexItemFactory}.
* @param invoke {@link InvokeMethod} that is expected to have an identifier in its arguments.
* @return {@link DexReference} corresponding to the first constant string argument that matches a
* class or member name, or {@code null} if no such constant was found.
*/
- public static DexReference identifyIdentifier(AppInfo appInfo, InvokeMethod invoke) {
+ public static DexReference identifyIdentifier(
+ DexDefinitionSupplier definitions, InvokeMethod invoke) {
List<Value> ins = invoke.arguments();
// The only static call: Class#forName, which receives (String) as ins.
if (ins.size() == 1) {
Value in = ins.get(0);
if (in.isConstString()) {
ConstString constString = in.getConstInstruction().asConstString();
- return inferMemberOrTypeFromNameString(appInfo, constString.getValue());
+ return inferMemberOrTypeFromNameString(definitions, constString.getValue());
}
if (in.isDexItemBasedConstString()) {
DexItemBasedConstString constString = in.getConstInstruction().asDexItemBasedConstString();
@@ -162,7 +163,8 @@
}
// All the other cases receive either (Class, String) or (Class, String, Class[]) as ins.
boolean isReferenceFieldUpdater =
- invoke.getReturnType().descriptor == appInfo.dexItemFactory.referenceFieldUpdaterDescriptor;
+ invoke.getReturnType().descriptor
+ == definitions.dexItemFactory().referenceFieldUpdaterDescriptor;
int positionOfIdentifier = isReferenceFieldUpdater ? 2 : 1;
Value in = ins.get(positionOfIdentifier);
if (in.isConstString()) {
@@ -176,7 +178,7 @@
// declared in the library. Hence there is no need to handle this case.
return null;
}
- DexClass holder = appInfo.definitionFor(holderType);
+ DexClass holder = definitions.definitionFor(holderType);
if (holder == null) {
return null;
}
@@ -195,7 +197,7 @@
}
assert numOfParams == 3;
DexTypeList arguments =
- retrieveDexTypeListFromClassList(invoke, ins.get(2), appInfo.dexItemFactory);
+ retrieveDexTypeListFromClassList(invoke, ins.get(2), definitions.dexItemFactory());
if (arguments == null) {
return null;
}
@@ -208,21 +210,23 @@
return null;
}
- static DexReference inferMemberOrTypeFromNameString(AppInfo appInfo, DexString dexString) {
+ static DexReference inferMemberOrTypeFromNameString(
+ DexDefinitionSupplier definitions, DexString dexString) {
// "fully.qualified.ClassName.fieldOrMethodName"
// "fully.qualified.ClassName#fieldOrMethodName"
- DexReference itemBasedString = inferMemberFromNameString(appInfo, dexString);
+ DexReference itemBasedString = inferMemberFromNameString(definitions, dexString);
if (itemBasedString == null) {
// "fully.qualified.ClassName"
String maybeDescriptor = javaTypeToDescriptorIfValidJavaType(dexString.toString());
if (maybeDescriptor != null) {
- return appInfo.dexItemFactory.createType(maybeDescriptor);
+ return definitions.dexItemFactory().createType(maybeDescriptor);
}
}
return itemBasedString;
}
- private static DexReference inferMemberFromNameString(AppInfo appInfo, DexString dexString) {
+ private static DexReference inferMemberFromNameString(
+ DexDefinitionSupplier definitions, DexString dexString) {
String identifier = dexString.toString();
String typeIdentifier = null;
String memberIdentifier = null;
@@ -250,8 +254,8 @@
if (maybeDescriptor == null) {
return null;
}
- DexType type = appInfo.dexItemFactory.createType(maybeDescriptor);
- DexClass holder = appInfo.definitionFor(type);
+ DexType type = definitions.dexItemFactory().createType(maybeDescriptor);
+ DexClass holder = definitions.definitionFor(type);
if (holder == null) {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 8224503..b6aa517 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -311,8 +311,7 @@
if (!visited.add(staticFieldWritten)) {
continue;
}
- DexEncodedField encodedStaticFieldWritten =
- appInfo.resolveFieldOn(staticFieldWritten.clazz, staticFieldWritten);
+ DexEncodedField encodedStaticFieldWritten = appInfo.resolveField(staticFieldWritten);
if (encodedStaticFieldWritten != null
&& encodedStaticFieldWritten.isProgramField(appInfo)) {
result.add(encodedStaticFieldWritten.field);
@@ -614,7 +613,7 @@
Log.verbose(getClass(), "Register Sput `%s`.", field);
}
- DexEncodedField encodedField = appInfo.resolveFieldOn(field.clazz, field);
+ DexEncodedField encodedField = appInfo.resolveField(field);
if (encodedField != null && encodedField.isProgramField(appInfo)) {
boolean isWrittenOutsideEnclosingStaticInitializer =
currentMethod.method.holder != encodedField.field.clazz
@@ -1151,7 +1150,7 @@
}
private void markStaticFieldAsLive(DexField field, KeepReason reason) {
- markStaticFieldAsLive(field, reason, appInfo.resolveFieldOn(field.clazz, field));
+ markStaticFieldAsLive(field, reason, appInfo.resolveField(field));
}
private void markStaticFieldAsLive(
@@ -1281,7 +1280,7 @@
if (Log.ENABLED) {
Log.verbose(getClass(), "Marking instance field `%s` as reachable.", field);
}
- DexEncodedField encodedField = appInfo.resolveFieldOn(field.clazz, field);
+ DexEncodedField encodedField = appInfo.resolveField(field);
if (encodedField == null) {
reportMissingField(field);
return;
@@ -1760,7 +1759,7 @@
private void handleReflectiveBehavior(DexEncodedMethod method) {
DexType originHolder = method.method.holder;
Origin origin = appInfo.originFor(originHolder);
- IRCode code = method.buildIR(appInfo, appView.graphLense(), options, origin);
+ IRCode code = method.buildIR(appView, origin);
Iterator<Instruction> iterator = code.instructionIterator();
while (iterator.hasNext()) {
Instruction instruction = iterator.next();
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 613ec66..8f8b8c0 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -44,7 +44,6 @@
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.utils.FieldSignatureEquivalence;
-import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.MethodSignatureEquivalence;
import com.android.tools.r8.utils.Timing;
import com.google.common.base.Equivalence;
@@ -203,7 +202,6 @@
private final ExecutorService executorService;
private final GraphLense graphLense;
private final MethodPoolCollection methodPoolCollection;
- private final InternalOptions options;
private final Timing timing;
private Collection<DexMethod> invokes;
@@ -231,7 +229,6 @@
DexApplication application,
AppView<? extends AppInfoWithLiveness> appView,
ExecutorService executorService,
- InternalOptions options,
Timing timing,
MainDexClasses mainDexClasses) {
this.application = application;
@@ -240,7 +237,6 @@
this.executorService = executorService;
this.graphLense = appView.graphLense();
this.methodPoolCollection = new MethodPoolCollection(application);
- this.options = options;
this.renamedMembersLense = new VerticalClassMergerGraphLense.Builder();
this.timing = timing;
this.mainDexClasses = mainDexClasses;
@@ -1632,7 +1628,7 @@
}
private boolean disallowInlining(DexEncodedMethod method, DexType invocationContext) {
- if (options.enableInlining) {
+ if (appView.options().enableInlining) {
if (method.getCode().isJarCode()) {
JarCode jarCode = method.getCode().asJarCode();
ConstraintWithTarget constraint =
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 55071c1..3ccdc81 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -958,7 +958,7 @@
System.out.println(SmaliWriter.smali(app, options));
}
- protected DexEncodedMethod getMethod(
+ protected MethodSubject getMethodSubject(
CodeInspector inspector,
String className,
String returnType,
@@ -968,7 +968,21 @@
assertTrue(clazz.isPresent());
MethodSubject method = clazz.method(returnType, methodName, parameters);
assertTrue(method.isPresent());
- return method.getMethod();
+ return method;
+ }
+
+ protected MethodSubject getMethodSubject(
+ AndroidApp application,
+ String className,
+ String returnType,
+ String methodName,
+ List<String> parameters) {
+ try {
+ CodeInspector inspector = new CodeInspector(application);
+ return getMethodSubject(inspector, className, returnType, methodName, parameters);
+ } catch (Exception e) {
+ return null;
+ }
}
protected DexEncodedMethod getMethod(
@@ -977,12 +991,16 @@
String returnType,
String methodName,
List<String> parameters) {
- try {
- CodeInspector inspector = new CodeInspector(application);
- return getMethod(inspector, className, returnType, methodName, parameters);
- } catch (Exception e) {
- return null;
- }
+ return getMethodSubject(application, className, returnType, methodName, parameters).getMethod();
+ }
+
+ protected DexEncodedMethod getMethod(
+ CodeInspector inspector,
+ String className,
+ String returnType,
+ String methodName,
+ List<String> parameters) {
+ return getMethodSubject(inspector, className, returnType, methodName, parameters).getMethod();
}
protected static void checkInstructions(
diff --git a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
index 7e0bfec..0363c3e 100644
--- a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
@@ -33,7 +33,7 @@
public class TargetLookupTest extends SmaliTestBase {
@Test
- public void lookupDirect() throws Exception {
+ public void lookupDirect() {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
builder.addDefaultConstructor();
diff --git a/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java b/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java
index 656afc2..0a9696e 100644
--- a/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java
+++ b/src/test/java/com/android/tools/r8/ir/BasicBlockIteratorTest.java
@@ -6,18 +6,18 @@
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InstructionListIterator;
-import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.ListIterator;
@@ -52,17 +52,14 @@
);
AndroidApp application = buildApplication(builder);
+ InternalOptions options = new InternalOptions();
DexApplication dexApplication =
- new ApplicationReader(
- application, new InternalOptions(), new Timing("BasicBlockIteratorTest"))
- .read();
- AppInfo appInfo = new AppInfo(dexApplication);
+ new ApplicationReader(application, options, new Timing("BasicBlockIteratorTest")).read();
+ AppView<? extends AppInfo> appView = AppView.createForD8(new AppInfo(dexApplication), options);
// Build the code, and split the code into three blocks.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
+ IRCode code = methodSubject.buildIR();
ListIterator<BasicBlock> blocks = code.listIterator();
InstructionListIterator iter = blocks.next().listIterator();
iter.nextUntil(i -> !i.isArgument());
diff --git a/src/test/java/com/android/tools/r8/ir/InlineTest.java b/src/test/java/com/android/tools/r8/ir/InlineTest.java
index 68b466a..d7b2762 100644
--- a/src/test/java/com/android/tools/r8/ir/InlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InlineTest.java
@@ -6,27 +6,62 @@
import static org.junit.Assert.assertEquals;
-import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppInfoWithSubtyping;
+import com.android.tools.r8.graph.AppServices;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
-import com.android.tools.r8.ir.code.ValueNumberGenerator;
+import com.android.tools.r8.shaking.Enqueuer;
+import com.android.tools.r8.shaking.ProguardClassFilter;
+import com.android.tools.r8.shaking.ProguardKeepRule;
+import com.android.tools.r8.shaking.RootSetBuilder;
+import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.ThreadUtils;
+import com.android.tools.r8.utils.Timing;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
import org.junit.Test;
public class InlineTest extends IrInjectionTestBase {
- TestApplication codeForMethodReplaceTest(int a, int b) throws Exception {
+ public TestApplication buildTestApplication(
+ DexApplication application,
+ InternalOptions options,
+ MethodSubject method,
+ List<IRCode> additionalCode)
+ throws ExecutionException {
+ AppView<AppInfoWithSubtyping> appView =
+ AppView.createForR8(new AppInfoWithSubtyping(application), options);
+ appView.setAppServices(AppServices.builder(appView).build());
+ ExecutorService executorService = ThreadUtils.getExecutorService(options);
+ RootSet rootSet =
+ new RootSetBuilder(
+ appView,
+ application,
+ ImmutableList.of(ProguardKeepRule.defaultKeepAllRule(unused -> {})),
+ options)
+ .run(executorService);
+ Timing timing = new Timing(getClass().getSimpleName());
+ Enqueuer enqueuer = new Enqueuer(appView, options, null);
+ appView.setAppInfo(
+ enqueuer.traceApplication(rootSet, ProguardClassFilter.empty(), executorService, timing));
+
+ return new TestApplication(appView, rootSet, method, additionalCode);
+ }
+
+ private TestApplication codeForMethodReplaceTest(int a, int b) throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
MethodSignature signature = builder.addStaticMethod(
@@ -73,25 +108,22 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
- return new TestApplication(application, method, code,
- ImmutableList.of(codeA, codeB), valueNumberGenerator, options);
+ return buildTestApplication(
+ application, options, methodSubject, ImmutableList.of(codeA, codeB));
}
- public void runInlineTest(int a, int b, int expectedA, int expectedB) throws Exception {
+ private void runInlineTest(int a, int b, int expectedA, int expectedB) throws Exception {
// Run code without inlining.
TestApplication test = codeForMethodReplaceTest(a, b);
String result = test.run();
@@ -102,18 +134,18 @@
// Run code inlining a.
test = codeForMethodReplaceTest(a, b);
iterator = test.code.entryBlock().listIterator();
- iterator.nextUntil(instruction -> instruction.isInvoke());
+ iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(0));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(0));
result = test.run();
assertEquals(Integer.toString(expectedA), result);
// Run code inlining b (where a is actually called).
test = codeForMethodReplaceTest(a, b);
iterator = test.code.entryBlock().listIterator();
- iterator.nextUntil(instruction -> instruction.isInvoke());
+ iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(1));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(1));
result = test.run();
assertEquals(Integer.toString(expectedB), result);
}
@@ -124,7 +156,8 @@
runInlineTest(1, 2, 3, 1);
}
- TestApplication codeForMethodReplaceReturnVoidTest(int a, int b) throws Exception {
+ private TestApplication codeForMethodReplaceReturnVoidTest(int a, int b)
+ throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
MethodSignature signature = builder.addStaticMethod(
@@ -157,19 +190,15 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
- return new TestApplication(application, method, code,
- ImmutableList.of(codeA), valueNumberGenerator, options);
+ return buildTestApplication(application, options, methodSubject, ImmutableList.of(codeA));
}
@Test
@@ -184,14 +213,14 @@
// Run code inlining a.
test = codeForMethodReplaceReturnVoidTest(1, 2);
iterator = test.code.entryBlock().listIterator();
- iterator.nextUntil(instruction -> instruction.isInvoke());
+ iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(0));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(0));
result = test.run();
assertEquals(Integer.toString(1), result);
}
- TestApplication codeForMultipleMethodReplaceTest(int a, int b) throws Exception {
+ private TestApplication codeForMultipleMethodReplaceTest(int a, int b) throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
MethodSignature signature = builder.addStaticMethod(
@@ -238,33 +267,29 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
// Build three copies of a and b for inlining three times.
List<IRCode> additionalCode = new ArrayList<>();
for (int i = 0; i < 3; i++) {
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
additionalCode.add(codeA);
}
for (int i = 0; i < 3; i++) {
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
additionalCode.add(codeB);
}
- return new TestApplication(application, method, code,
- additionalCode, valueNumberGenerator, options);
+ return buildTestApplication(application, options, methodSubject, additionalCode);
}
- public void runInlineMultipleTest(int a, int b, int expectedA, int expectedB) throws Exception {
+ private void runInlineMultipleTest(int a, int b, int expectedA, int expectedB) throws Exception {
// Run code without inlining.
TestApplication test = codeForMultipleMethodReplaceTest(a, b);
String result = test.run();
@@ -280,11 +305,11 @@
while (blocksIterator.hasNext()) {
BasicBlock block = blocksIterator.next();
iterator = block.listIterator();
- Instruction invoke = iterator.nextUntil(instruction -> instruction.isInvoke());
+ Instruction invoke = iterator.nextUntil(Instruction::isInvoke);
if (invoke != null) {
iterator.previous();
iterator.inlineInvoke(
- test.appInfo, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
+ test.appView, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
assert blocksToRemove.isEmpty();
}
}
@@ -298,11 +323,11 @@
while (blocksIterator.hasNext()) {
BasicBlock block = blocksIterator.next();
iterator = block.listIterator();
- Instruction invoke = iterator.nextUntil(instruction -> instruction.isInvoke());
+ Instruction invoke = iterator.nextUntil(Instruction::isInvoke);
if (invoke != null) {
iterator.previous();
iterator.inlineInvoke(
- test.appInfo, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
+ test.appView, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
assert blocksToRemove.isEmpty();
}
}
@@ -316,8 +341,8 @@
runInlineMultipleTest(1, 2, 7, 8);
}
- TestApplication codeForMethodReplaceTestWithCatchHandler(int a, int b, boolean twoGuards)
- throws Exception {
+ private TestApplication codeForMethodReplaceTestWithCatchHandler(int a, int b, boolean twoGuards)
+ throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String secondGuard = twoGuards ?
@@ -375,25 +400,22 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
- return new TestApplication(application, method, code,
- ImmutableList.of(codeA, codeB), valueNumberGenerator, options);
+ return buildTestApplication(
+ application, options, methodSubject, ImmutableList.of(codeA, codeB));
}
- public void runInlineCallerHasCatchHandlersTest(
+ private void runInlineCallerHasCatchHandlersTest(
int a, int b, boolean twoGuards, int expectedA, int expectedB) throws Exception {
// Run code without inlining.
TestApplication test = codeForMethodReplaceTestWithCatchHandler(a, b, twoGuards);
@@ -405,18 +427,18 @@
// Run code inlining a.
test = codeForMethodReplaceTestWithCatchHandler(a, b, twoGuards);
iterator = test.code.blocks.get(1).listIterator();
- iterator.nextUntil(instruction -> instruction.isInvoke());
+ iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(0));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(0));
result = test.run();
assertEquals(Integer.toString(expectedA), result);
// Run code inlining b (where a is actually called).
test = codeForMethodReplaceTestWithCatchHandler(a, b, twoGuards);
iterator = test.code.blocks.get(1).listIterator();
- iterator.nextUntil(instruction -> instruction.isInvoke());
+ iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(1));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(1));
result = test.run();
assertEquals(Integer.toString(expectedB), result);
}
@@ -429,7 +451,8 @@
runInlineCallerHasCatchHandlersTest(1, 2, true, 3, 1);
}
- TestApplication codeForInlineCanThrow(int a, int b, boolean twoGuards) throws Exception {
+ private TestApplication codeForInlineCanThrow(int a, int b, boolean twoGuards)
+ throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String secondGuard = twoGuards ?
@@ -490,26 +513,23 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
- return new TestApplication(application, method, code,
- ImmutableList.of(codeA, codeB), valueNumberGenerator, options);
+ return buildTestApplication(
+ application, options, methodSubject, ImmutableList.of(codeA, codeB));
}
- public void runInlineCanThrow(
- int a, int b, boolean twoGuards, int expectedA, int expectedB) throws Exception {
+ private void runInlineCanThrow(int a, int b, boolean twoGuards, int expectedA, int expectedB)
+ throws Exception {
// Run code without inlining.
TestApplication test = codeForInlineCanThrow(a, b, twoGuards);
String result = test.run();
@@ -520,18 +540,18 @@
// Run code inlining a.
test = codeForInlineCanThrow(a, b, twoGuards);
iterator = test.code.entryBlock().listIterator();
- iterator.nextUntil(instruction -> instruction.isInvoke());
+ iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(0));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(0));
result = test.run();
assertEquals(Integer.toString(expectedA), result);
// Run code inlining b (where a is actually called).
test = codeForInlineCanThrow(a, b, twoGuards);
iterator = test.code.entryBlock().listIterator();
- iterator.nextUntil(instruction -> instruction.isInvoke());
+ iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(1));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(1));
result = test.run();
assertEquals(Integer.toString(expectedB), result);
}
@@ -544,7 +564,7 @@
runInlineCanThrow(2, 0, true, -2, -1);
}
- private TestApplication codeForInlineAlwaysThrows(boolean twoGuards) throws Exception {
+ private TestApplication codeForInlineAlwaysThrows(boolean twoGuards) throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String secondGuard = twoGuards ?
@@ -604,22 +624,19 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
- return new TestApplication(application, method, code,
- ImmutableList.of(codeA, codeB), valueNumberGenerator, options);
+ return buildTestApplication(
+ application, options, methodSubject, ImmutableList.of(codeA, codeB));
}
private void runInlineAlwaysThrows(boolean twoGuards, int expectedA, int expectedB)
@@ -636,7 +653,7 @@
iterator = test.code.entryBlock().listIterator();
iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(0));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(0));
result = test.run();
assertEquals(Integer.toString(expectedA), result);
@@ -646,7 +663,7 @@
iterator = test.code.entryBlock().listIterator();
iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(1));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(1));
result = test.run();
assertEquals(Integer.toString(expectedB), result);
}
@@ -657,7 +674,8 @@
runInlineAlwaysThrows(true, -2, -1);
}
- private TestApplication codeForInlineAlwaysThrowsMultiple(boolean twoGuards) throws Exception {
+ private TestApplication codeForInlineAlwaysThrowsMultiple(boolean twoGuards)
+ throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String secondGuard = twoGuards ?
@@ -719,30 +737,26 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
// Build three copies of a and b for inlining three times.
List<IRCode> additionalCode = new ArrayList<>();
for (int i = 0; i < 3; i++) {
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
additionalCode.add(codeA);
}
for (int i = 0; i < 3; i++) {
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
additionalCode.add(codeB);
}
- return new TestApplication(
- application, method, code, additionalCode, valueNumberGenerator, options);
+ return buildTestApplication(application, options, methodSubject, additionalCode);
}
private void runInlineAlwaysThrowsMultiple(boolean twoGuards, int expectedA, int expectedB)
@@ -770,7 +784,7 @@
if (invoke != null) {
iterator.previous();
iterator.inlineInvoke(
- test.appInfo, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
+ test.appView, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
}
}
test.code.removeBlocks(blocksToRemove);
@@ -794,7 +808,7 @@
if (invoke != null) {
iterator.previous();
iterator.inlineInvoke(
- test.appInfo, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
+ test.appView, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
}
}
test.code.removeBlocks(blocksToRemove);
@@ -809,8 +823,8 @@
runInlineAlwaysThrowsMultiple(true, -2, -1);
}
- private TestApplication codeForInlineAlwaysThrowsMultipleWithControlFlow(
- int a, boolean twoGuards) throws Exception {
+ private TestApplication codeForInlineAlwaysThrowsMultipleWithControlFlow(int a, boolean twoGuards)
+ throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String secondGuard = twoGuards ?
@@ -879,30 +893,26 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
// Build three copies of a and b for inlining three times.
List<IRCode> additionalCode = new ArrayList<>();
for (int i = 0; i < 3; i++) {
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
additionalCode.add(codeA);
}
for (int i = 0; i < 3; i++) {
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
additionalCode.add(codeB);
}
- return new TestApplication(
- application, method, code, additionalCode, valueNumberGenerator, options);
+ return buildTestApplication(application, options, methodSubject, additionalCode);
}
private void runInlineAlwaysThrowsMultipleWithControlFlow(
@@ -930,7 +940,7 @@
if (invoke != null) {
iterator.previous();
iterator.inlineInvoke(
- test.appInfo, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
+ test.appView, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
}
}
test.code.removeBlocks(blocksToRemove);
@@ -954,7 +964,7 @@
if (invoke != null) {
iterator.previous();
iterator.inlineInvoke(
- test.appInfo, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
+ test.appView, test.code, inlinee.next(), blocksIterator, blocksToRemove, null);
}
}
test.code.removeBlocks(blocksToRemove);
@@ -975,7 +985,7 @@
private TestApplication codeForInlineWithHandlersCanThrow(
int a, int b, int c, boolean twoGuards, boolean callerHasCatchAll, boolean inlineeHasCatchAll)
- throws Exception {
+ throws ExecutionException {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String secondGuard = "";
@@ -1129,22 +1139,19 @@
);
InternalOptions options = new InternalOptions();
- DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ DexApplication application = buildApplication(builder, options).toDirect();
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code = method.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
- DexEncodedMethod methodA = getMethod(application, signatureA);
- IRCode codeA = methodA.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodASubject = getMethodSubject(application, signatureA);
+ IRCode codeA = methodASubject.buildIR(options.itemFactory);
- DexEncodedMethod methodB = getMethod(application, signatureB);
- IRCode codeB = methodB.buildInliningIRForTesting(options, valueNumberGenerator, appInfo);
+ MethodSubject methodBSubject = getMethodSubject(application, signatureB);
+ IRCode codeB = methodBSubject.buildIR(options.itemFactory);
- return new TestApplication(application, method, code,
- ImmutableList.of(codeA, codeB), valueNumberGenerator, options);
+ return buildTestApplication(
+ application, options, methodSubject, ImmutableList.of(codeA, codeB));
}
private void runInlineWithHandlersCanThrow(int a, int b, int c,
@@ -1164,7 +1171,7 @@
iterator = test.code.blocks.get(1).listIterator();
iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(0));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(0));
result = test.run();
assertEquals(Integer.toString(expectedA), result);
@@ -1174,7 +1181,7 @@
iterator = test.code.blocks.get(1).listIterator();
iterator.nextUntil(Instruction::isInvoke);
iterator.previous();
- iterator.inlineInvoke(test.appInfo, test.code, test.additionalCode.get(1));
+ iterator.inlineInvoke(test.appView, test.code, test.additionalCode.get(1));
result = test.run();
assertEquals(Integer.toString(expectedB), result);
}
diff --git a/src/test/java/com/android/tools/r8/ir/InstructionIteratorTest.java b/src/test/java/com/android/tools/r8/ir/InstructionIteratorTest.java
index 6c7c2d3..5ab4a24 100644
--- a/src/test/java/com/android/tools/r8/ir/InstructionIteratorTest.java
+++ b/src/test/java/com/android/tools/r8/ir/InstructionIteratorTest.java
@@ -4,18 +4,15 @@
package com.android.tools.r8.ir;
-import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
-import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.ListIterator;
@@ -33,7 +30,7 @@
* <p>First block: Argument instructions Second block: Add instruction Third block: Return
* instruction
*/
- IRCode simpleCode() {
+ private IRCode simpleCode() {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String returnType = "int";
@@ -48,13 +45,10 @@
);
AndroidApp application = buildApplication(builder);
- AppInfo appInfo = getAppInfo(application);
// Build the code, and split the code into three blocks.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
+ IRCode code = methodSubject.buildIR();
ListIterator<BasicBlock> blocks = code.listIterator();
InstructionListIterator iter = blocks.next().listIterator();
iter.nextUntil(i -> !i.isArgument());
diff --git a/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java b/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
index 0251cf3..083f478 100644
--- a/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/IrInjectionTestBase.java
@@ -16,6 +16,8 @@
import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.shaking.MainDexClasses;
+import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.smali.SmaliTestBase;
@@ -24,6 +26,7 @@
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.io.IOException;
import java.util.List;
import java.util.ListIterator;
@@ -51,56 +54,54 @@
}
}
- protected DexEncodedMethod getMethod(DexApplication application, MethodSignature signature) {
- return getMethod(application,
- signature.clazz, signature.returnType, signature.name, signature.parameterTypes);
+ protected MethodSubject getMethodSubject(DexApplication application, MethodSignature signature) {
+ return getMethodSubject(
+ application,
+ signature.clazz,
+ signature.returnType,
+ signature.name,
+ signature.parameterTypes);
}
- protected DexEncodedMethod getMethod(
+ protected MethodSubject getMethodSubject(
DexApplication application,
String className,
String returnType,
String methodName,
List<String> parameters) {
CodeInspector inspector = new CodeInspector(application);
- return getMethod(inspector, className, returnType, methodName, parameters);
+ return getMethodSubject(inspector, className, returnType, methodName, parameters);
}
public class TestApplication {
public final DexApplication application;
- public final AppInfo appInfo;
+ public final AppView<? extends AppInfo> appView;
+ public final RootSet rootSet;
+
public final DexEncodedMethod method;
public final IRCode code;
public final List<IRCode> additionalCode;
- public final ValueNumberGenerator valueNumberGenerator;
- public final InternalOptions options;
public final AndroidAppConsumers consumers;
- public TestApplication(
- DexApplication application,
- DexEncodedMethod method,
- IRCode code,
- ValueNumberGenerator valueNumberGenerator,
- InternalOptions options) {
- this(application, method, code, null, valueNumberGenerator, options);
+ public final ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
+
+ public TestApplication(AppView<? extends AppInfo> appView, MethodSubject method) {
+ this(appView, null, method, null);
}
public TestApplication(
- DexApplication application,
- DexEncodedMethod method,
- IRCode code,
- List<IRCode> additionalCode,
- ValueNumberGenerator valueNumberGenerator,
- InternalOptions options) {
- this.application = application;
- this.appInfo = new AppInfo(application);
- this.method = method;
- this.code = code;
+ AppView<? extends AppInfo> appView,
+ RootSet rootSet,
+ MethodSubject method,
+ List<IRCode> additionalCode) {
+ this.application = appView.appInfo().app;
+ this.appView = appView;
+ this.rootSet = rootSet;
+ this.method = method.getMethod();
+ this.code = method.buildIR(appView.dexItemFactory());
this.additionalCode = additionalCode;
- this.valueNumberGenerator = valueNumberGenerator;
- this.options = options;
- consumers = new AndroidAppConsumers(options);
+ this.consumers = new AndroidAppConsumers(appView.options());
}
public int countArgumentInstructions() {
@@ -131,10 +132,10 @@
}
public String run() throws IOException {
- AppInfo appInfo = new AppInfo(application);
- IRConverter converter = new IRConverter(AppView.createForD8(appInfo, options));
+ Timing timing = new Timing(getClass().getSimpleName());
+ IRConverter converter = new IRConverter(appView, timing, null, MainDexClasses.NONE, rootSet);
converter.replaceCodeForTesting(method, code);
- AndroidApp app = writeDex(application, options);
+ AndroidApp app = writeDex(application, appView.options());
return runOnArtRaw(app, DEFAULT_MAIN_CLASS_NAME).stdout;
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/LinearFlowIteratorTest.java b/src/test/java/com/android/tools/r8/ir/LinearFlowIteratorTest.java
index 0a11f41..d33da76 100644
--- a/src/test/java/com/android/tools/r8/ir/LinearFlowIteratorTest.java
+++ b/src/test/java/com/android/tools/r8/ir/LinearFlowIteratorTest.java
@@ -5,18 +5,15 @@
package com.android.tools.r8.ir;
import com.android.tools.r8.TestBase;
-import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.LinearFlowInstructionIterator;
-import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.ListIterator;
import org.junit.Test;
@@ -53,12 +50,10 @@
appBuilder.addClassProgramData(jasminBuilder.buildClasses());
// Build the code, and split the code into three blocks.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
AndroidApp app = compileWithD8(appBuilder.build());
- AppInfo appInfo = getAppInfo(app);
- DexEncodedMethod method = getMethod(app, "foo", "void", "bar", ImmutableList.of("int"));
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
+ MethodSubject methodSubject =
+ getMethodSubject(app, "foo", "void", "bar", ImmutableList.of("int"));
+ IRCode code = methodSubject.buildIR();
ListIterator<BasicBlock> blocks = code.listIterator();
blocks.next();
InstructionListIterator iter = blocks.next().listIterator();
@@ -91,12 +86,9 @@
appBuilder.addClassProgramData(jasminBuilder.buildClasses());
// Build the code, and split the code into three blocks.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
AndroidApp app = compileWithD8(appBuilder.build());
- AppInfo appInfo = getAppInfo(app);
- DexEncodedMethod method = getMethod(app, "foo", "void", "bar", ImmutableList.of("int"));
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
+ MethodSubject method = getMethodSubject(app, "foo", "void", "bar", ImmutableList.of("int"));
+ IRCode code = method.buildIR();
ListIterator<BasicBlock> blocks = code.listIterator();
InstructionListIterator iter = blocks.next().listIterator();
iter.nextUntil(i -> !i.isArgument());
diff --git a/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java b/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java
index 2a6e8c8..006fc5b 100644
--- a/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java
+++ b/src/test/java/com/android/tools/r8/ir/SplitBlockTest.java
@@ -9,8 +9,8 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.Add;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -21,10 +21,10 @@
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
@@ -32,7 +32,7 @@
public class SplitBlockTest extends IrInjectionTestBase {
- TestApplication codeWithoutCatchHandlers() throws Exception {
+ private TestApplication codeWithoutCatchHandlers() {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String returnType = "int";
@@ -61,15 +61,11 @@
InternalOptions options = new InternalOptions();
DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ AppView<? extends AppInfo> appView = AppView.createForD8(new AppInfo(application), options);
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
-
- return new TestApplication(application, method, code, valueNumberGenerator, options);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
+ return new TestApplication(appView, methodSubject);
}
@Test
@@ -141,7 +137,7 @@
}
}
- TestApplication codeWithCatchHandlers(boolean shouldThrow, boolean twoGuards) throws Exception {
+ private TestApplication codeWithCatchHandlers(boolean shouldThrow, boolean twoGuards) {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String secondGuard = twoGuards ?
@@ -181,17 +177,14 @@
InternalOptions options = new InternalOptions();
DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ AppView<? extends AppInfo> appView = AppView.createForD8(new AppInfo(application), options);
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
- return new TestApplication(application, method, code, valueNumberGenerator, options);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
+ return new TestApplication(appView, methodSubject);
}
- public void hasCatchandlerIfThrowing(BasicBlock block) {
+ private void hasCatchandlerIfThrowing(BasicBlock block) {
boolean throwing = false;
for (Instruction instruction : block.getInstructions()) {
throwing |= instruction.instructionTypeCanThrow();
@@ -199,7 +192,7 @@
assertEquals(throwing, block.hasCatchHandlers());
}
- public void runCatchHandlerTest(boolean codeThrows, boolean twoGuards) throws Exception {
+ private void runCatchHandlerTest(boolean codeThrows, boolean twoGuards) throws Exception {
final int secondBlockInstructions = 4;
final int initialBlockCount = twoGuards ? 7 : 6;
// Try split between all instructions in second block.
@@ -237,7 +230,7 @@
runCatchHandlerTest(true, true);
}
- public void runCatchHandlerSplitThreeTest(boolean codeThrows, boolean twoGuards)
+ private void runCatchHandlerSplitThreeTest(boolean codeThrows, boolean twoGuards)
throws Exception {
final int secondBlockInstructions = 4;
final int initialBlockCount = twoGuards ? 7 : 6;
@@ -277,7 +270,7 @@
runCatchHandlerSplitThreeTest(true, true);
}
- TestApplication codeWithIf(boolean hitTrueBranch) throws Exception {
+ private TestApplication codeWithIf(boolean hitTrueBranch) {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String returnType = "int";
@@ -308,18 +301,14 @@
InternalOptions options = new InternalOptions();
DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ AppView<? extends AppInfo> appView = AppView.createForD8(new AppInfo(application), options);
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
-
- return new TestApplication(application, method, code, valueNumberGenerator, options);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
+ return new TestApplication(appView, methodSubject);
}
- public void runWithIfTest(boolean hitTrueBranch) throws Exception {
+ private void runWithIfTest(boolean hitTrueBranch) throws Exception {
final int initialBlockCount = 3;
final int argumentInstructions = 2;
final int firstBlockInstructions = 3;
@@ -358,7 +347,7 @@
runWithIfTest(true);
}
- public void splitBeforeReturn(boolean hitTrueBranch) throws Exception {
+ private void splitBeforeReturn(boolean hitTrueBranch) throws Exception {
TestApplication test = codeWithIf(hitTrueBranch);
IRCode code = test.code;
// Locate the exit blocks and split before the return.
@@ -397,7 +386,7 @@
splitBeforeReturn(true);
}
- TestApplication codeWithSwitch(boolean hitCase) throws Exception {
+ private TestApplication codeWithSwitch(boolean hitCase) {
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String returnType = "int";
@@ -436,18 +425,14 @@
InternalOptions options = new InternalOptions();
DexApplication application = buildApplication(builder, options);
- AppInfo appInfo = new AppInfo(application);
+ AppView<? extends AppInfo> appView = AppView.createForD8(new AppInfo(application), options);
// Return the processed method for inspection.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- IRCode code =
- method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
-
- return new TestApplication(application, method, code, valueNumberGenerator, options);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
+ return new TestApplication(appView, methodSubject);
}
- public void runWithSwitchTest(boolean hitCase) throws Exception {
+ private void runWithSwitchTest(boolean hitCase) throws Exception {
final int initialBlockCount = 5;
final int argumentInstructions = 1;
final int firstBlockInstructions = 2;
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/AnalysisTestBase.java b/src/test/java/com/android/tools/r8/ir/analysis/AnalysisTestBase.java
index e3ab0e7..b53d969 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/AnalysisTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/AnalysisTestBase.java
@@ -9,10 +9,8 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfo;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
-import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
@@ -55,11 +53,7 @@
public void buildAndCheckIR(String methodName, Consumer<IRCode> irInspector) throws Exception {
CodeInspector inspector = new CodeInspector(app);
MethodSubject methodSubject = inspector.clazz(className).uniqueMethodWithName(methodName);
- IRCode code =
- methodSubject
- .getMethod()
- .buildIR(appInfo, GraphLense.getIdentityLense(), options, Origin.unknown());
- irInspector.accept(code);
+ irInspector.accept(methodSubject.buildIR());
}
@SuppressWarnings("unchecked")
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
index eadec82..c5ac021 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
@@ -11,9 +11,9 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.ArrayGet;
import com.android.tools.r8.ir.code.IRCode;
@@ -32,10 +32,10 @@
import com.android.tools.r8.ir.optimize.nonnull.NonNullAfterFieldAccess;
import com.android.tools.r8.ir.optimize.nonnull.NonNullAfterInvoke;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
-import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Map;
@@ -49,16 +49,16 @@
boolean npeCaught,
BiConsumer<AppInfoWithLiveness, IRCode> inspector)
throws Exception {
- AppInfoWithLiveness appInfo = build(mainClass);
- CodeInspector codeInspector = new CodeInspector(appInfo.app);
+ AppView<? extends AppInfoWithLiveness> appView = build(mainClass);
+ CodeInspector codeInspector = new CodeInspector(appView.appInfo().app);
+ MethodSubject fooSubject = codeInspector.clazz(mainClass.getName()).method(signature);
DexEncodedMethod foo = codeInspector.clazz(mainClass.getName()).method(signature).getMethod();
- IRCode irCode =
- foo.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- NonNullTracker nonNullTracker = new NonNullTracker(appInfo, ImmutableSet.of());
+ IRCode irCode = fooSubject.buildIR();
+ NonNullTracker nonNullTracker = new NonNullTracker(appView, ImmutableSet.of());
nonNullTracker.addNonNull(irCode);
- TypeAnalysis analysis = new TypeAnalysis(appInfo, foo);
+ TypeAnalysis analysis = new TypeAnalysis(appView, foo);
analysis.widening(foo, irCode);
- inspector.accept(appInfo, irCode);
+ inspector.accept(appView.appInfo(), irCode);
verifyLastInvoke(irCode, npeCaught);
}
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
index d85b8dd..5ab424a 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
@@ -13,10 +13,10 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.ArrayLength;
import com.android.tools.r8.ir.code.CheckCast;
import com.android.tools.r8.ir.code.ConstString;
@@ -38,6 +38,7 @@
import com.android.tools.r8.utils.Smali;
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.nio.charset.StandardCharsets;
@@ -51,7 +52,6 @@
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
-import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -67,16 +67,17 @@
private final String dirName;
private final String smaliFileName;
- private final Consumer<AppInfo> inspection;
+ private final BiConsumer<AppView<? extends AppInfo>, CodeInspector> inspection;
- public TypeAnalysisTest(String test, Consumer<AppInfo> inspection) {
+ public TypeAnalysisTest(
+ String test, BiConsumer<AppView<? extends AppInfo>, CodeInspector> inspection) {
dirName = test.substring(0, test.lastIndexOf('/'));
smaliFileName = test.substring(test.lastIndexOf('/') + 1) + ".smali";
this.inspection = inspection;
}
@Parameters(name = "{0}")
- public static Collection<Object[]> data() throws Exception {
+ public static Collection<Object[]> data() {
List<String> tests = Arrays.asList(
"arithmetic/Arithmetic",
"fibonacci/Fibonacci",
@@ -88,7 +89,8 @@
"type-confusion-regression5/TestObject"
);
- Map<String, Consumer<AppInfo>> inspections = new HashMap<>();
+ Map<String, BiConsumer<AppView<? extends AppInfo>, CodeInspector>> inspections =
+ new HashMap<>();
inspections.put("arithmetic/Arithmetic", TypeAnalysisTest::arithmetic);
inspections.put("fibonacci/Fibonacci", TypeAnalysisTest::fibonacci);
inspections.put("fill-array-data/FillArrayData", TypeAnalysisTest::fillArrayData);
@@ -100,7 +102,7 @@
List<Object[]> testCases = new ArrayList<>();
for (String test : tests) {
- Consumer<AppInfo> inspection = inspections.get(test);
+ BiConsumer<AppView<? extends AppInfo>, CodeInspector> inspection = inspections.get(test);
testCases.add(new Object[]{test, inspection});
}
return testCases;
@@ -117,7 +119,9 @@
DexApplication dexApplication =
new ApplicationReader(app, TEST_OPTIONS, new Timing("TypeAnalysisTest.appReader"))
.read().toDirect();
- inspection.accept(new AppInfo(dexApplication));
+ inspection.accept(
+ AppView.createForR8(new AppInfo(dexApplication), TEST_OPTIONS),
+ new CodeInspector(dexApplication));
}
private static void forEachOutValue(
@@ -132,16 +136,15 @@
}
// Simple one path with a lot of arithmetic operations.
- private static void arithmetic(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod subtract =
- inspector.clazz("Test")
+ private static void arithmetic(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject subtractSubject =
+ inspector
+ .clazz("Test")
.method(
- new MethodSignature("subtractConstants8bitRegisters", "int", ImmutableList.of()))
- .getMethod();
- IRCode irCode =
- subtract.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, subtract);
+ new MethodSignature("subtractConstants8bitRegisters", "int", ImmutableList.of()));
+ DexEncodedMethod subtract = subtractSubject.getMethod();
+ IRCode irCode = subtractSubject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, subtract);
analysis.widening(subtract, irCode);
forEachOutValue(irCode, (v, l) -> {
// v9 <- 9 (INT_OR_FLOAT), which is never used later, hence imprecise.
@@ -150,31 +153,25 @@
}
// A couple branches, along with some recursive calls.
- private static void fibonacci(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod fib =
- inspector.clazz("Test")
- .method(new MethodSignature("fibonacci", "int", ImmutableList.of("int")))
- .getMethod();
- IRCode irCode =
- fib.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, fib);
+ private static void fibonacci(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject fibSubject =
+ inspector
+ .clazz("Test")
+ .method(new MethodSignature("fibonacci", "int", ImmutableList.of("int")));
+ DexEncodedMethod fib = fibSubject.getMethod();
+ IRCode irCode = fibSubject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, fib);
analysis.widening(fib, irCode);
- forEachOutValue(irCode, (v, l) -> {
- assertEither(l, INT, NULL);
- });
+ forEachOutValue(irCode, (v, l) -> assertEither(l, INT, NULL));
}
// fill-array-data
- private static void fillArrayData(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod test1 =
- inspector.clazz("Test")
- .method(new MethodSignature("test1", "int[]", ImmutableList.of()))
- .getMethod();
- IRCode irCode =
- test1.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, test1);
+ private static void fillArrayData(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject test1Subject =
+ inspector.clazz("Test").method(new MethodSignature("test1", "int[]", ImmutableList.of()));
+ DexEncodedMethod test1 = test1Subject.getMethod();
+ IRCode irCode = test1Subject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, test1);
analysis.widening(test1, irCode);
Value array = null;
InstructionIterator iterator = irCode.instructionIterator();
@@ -199,15 +196,12 @@
}
// filled-new-array
- private static void filledNewArray(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod test4 =
- inspector.clazz("Test")
- .method(new MethodSignature("test4", "int[]", ImmutableList.of()))
- .getMethod();
- IRCode irCode =
- test4.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, test4);
+ private static void filledNewArray(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject test4Subject =
+ inspector.clazz("Test").method(new MethodSignature("test4", "int[]", ImmutableList.of()));
+ DexEncodedMethod test4 = test4Subject.getMethod();
+ IRCode irCode = test4Subject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, test4);
analysis.widening(test4, irCode);
Value array = null;
InstructionIterator iterator = irCode.instructionIterator();
@@ -232,15 +226,12 @@
}
// Make sure the analysis does not hang.
- private static void infiniteLoop(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod loop2 =
- inspector.clazz("Test")
- .method(new MethodSignature("loop2", "void", ImmutableList.of()))
- .getMethod();
- IRCode irCode =
- loop2.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, loop2);
+ private static void infiniteLoop(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject loop2Subject =
+ inspector.clazz("Test").method(new MethodSignature("loop2", "void", ImmutableList.of()));
+ DexEncodedMethod loop2 = loop2Subject.getMethod();
+ IRCode irCode = loop2Subject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, loop2);
analysis.widening(loop2, irCode);
forEachOutValue(irCode, (v, l) -> {
if (l.isClassType()) {
@@ -253,15 +244,14 @@
}
// move-exception
- private static void tryCatch(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod test2 =
- inspector.clazz("Test")
- .method(new MethodSignature("test2_throw", "int", ImmutableList.of()))
- .getMethod();
- IRCode irCode =
- test2.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, test2);
+ private static void tryCatch(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject test2Subject =
+ inspector
+ .clazz("Test")
+ .method(new MethodSignature("test2_throw", "int", ImmutableList.of()));
+ DexEncodedMethod test2 = test2Subject.getMethod();
+ IRCode irCode = test2Subject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, test2);
analysis.widening(test2, irCode);
forEachOutValue(irCode, (v, l) -> {
if (l.isClassType()) {
@@ -273,23 +263,22 @@
}
// One very complicated example.
- private static void typeConfusion(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod method =
- inspector.clazz("TestObject")
+ private static void typeConfusion(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject methodSubject =
+ inspector
+ .clazz("TestObject")
.method(
- new MethodSignature("a", "void",
- ImmutableList.of("Test", "Test", "Test", "Test")))
- .getMethod();
- DexType test = appInfo.dexItemFactory.createType("LTest;");
- Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
- ArrayLength.class, INT,
- ConstString.class, TypeLatticeElement.stringClassType(appInfo, definitelyNotNull()),
- CheckCast.class, TypeLatticeElement.fromDexType(test, maybeNull(), appInfo),
- NewInstance.class, TypeLatticeElement.fromDexType(test, definitelyNotNull(), appInfo));
- IRCode irCode =
- method.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, method);
+ new MethodSignature("a", "void", ImmutableList.of("Test", "Test", "Test", "Test")));
+ DexEncodedMethod method = methodSubject.getMethod();
+ DexType test = appView.dexItemFactory().createType("LTest;");
+ Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices =
+ ImmutableMap.of(
+ ArrayLength.class, INT,
+ ConstString.class, TypeLatticeElement.stringClassType(appView, definitelyNotNull()),
+ CheckCast.class, TypeLatticeElement.fromDexType(test, maybeNull(), appView),
+ NewInstance.class, TypeLatticeElement.fromDexType(test, definitelyNotNull(), appView));
+ IRCode irCode = methodSubject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, method);
analysis.widening(method, irCode);
forEachOutValue(irCode, (v, l) -> {
verifyTypeEnvironment(expectedLattices, v, l);
@@ -306,21 +295,20 @@
}
// One more complicated example.
- private static void typeConfusion5(AppInfo appInfo) {
- CodeInspector inspector = new CodeInspector(appInfo.app);
- DexEncodedMethod method =
- inspector.clazz("TestObject")
- .method(
- new MethodSignature("onClick", "void", ImmutableList.of("Test")))
- .getMethod();
- DexType test = appInfo.dexItemFactory.createType("LTest;");
- Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices = ImmutableMap.of(
- ConstString.class, TypeLatticeElement.stringClassType(appInfo, definitelyNotNull()),
- InstanceOf.class, INT,
- StaticGet.class, TypeLatticeElement.fromDexType(test, maybeNull(), appInfo));
- IRCode irCode =
- method.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
- TypeAnalysis analysis = new TypeAnalysis(appInfo, method);
+ private static void typeConfusion5(AppView<? extends AppInfo> appView, CodeInspector inspector) {
+ MethodSubject methodSubject =
+ inspector
+ .clazz("TestObject")
+ .method(new MethodSignature("onClick", "void", ImmutableList.of("Test")));
+ DexEncodedMethod method = methodSubject.getMethod();
+ DexType test = appView.dexItemFactory().createType("LTest;");
+ Map<Class<? extends Instruction>, TypeLatticeElement> expectedLattices =
+ ImmutableMap.of(
+ ConstString.class, TypeLatticeElement.stringClassType(appView, definitelyNotNull()),
+ InstanceOf.class, INT,
+ StaticGet.class, TypeLatticeElement.fromDexType(test, maybeNull(), appView));
+ IRCode irCode = methodSubject.buildIR();
+ TypeAnalysis analysis = new TypeAnalysis(appView, method);
analysis.widening(method, irCode);
forEachOutValue(irCode, (v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java
index 09cb601..2f5740c 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java
@@ -7,8 +7,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
@@ -20,9 +19,9 @@
import com.android.tools.r8.ir.optimize.nonnull.NonNullAfterInvoke;
import com.android.tools.r8.ir.optimize.nonnull.NonNullAfterNullCheck;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
-import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableSet;
import java.util.function.Consumer;
import org.junit.Test;
@@ -35,14 +34,13 @@
int expectedNumberOfNonNull,
Consumer<IRCode> testAugmentedIRCode)
throws Exception {
- AppInfoWithLiveness appInfo = build(testClass);
- CodeInspector codeInspector = new CodeInspector(appInfo.app);
- DexEncodedMethod foo = codeInspector.clazz(testClass.getName()).method(signature).getMethod();
- IRCode irCode =
- foo.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
+ AppView<? extends AppInfoWithLiveness> appView = build(testClass);
+ CodeInspector codeInspector = new CodeInspector(appView.appInfo().app);
+ MethodSubject fooSubject = codeInspector.clazz(testClass.getName()).method(signature);
+ IRCode irCode = fooSubject.buildIR();
checkCountOfNonNull(irCode, 0);
- NonNullTracker nonNullTracker = new NonNullTracker(appInfo, ImmutableSet.of());
+ NonNullTracker nonNullTracker = new NonNullTracker(appView, ImmutableSet.of());
nonNullTracker.addNonNull(irCode);
assertTrue(irCode.isConsistentSSA());
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java
index ecdf9fd..e98eeb1 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTestBase.java
@@ -24,31 +24,26 @@
import java.util.concurrent.ExecutorService;
public abstract class NonNullTrackerTestBase extends TestBase {
- protected static final InternalOptions TEST_OPTIONS = new InternalOptions();
- protected AppInfoWithLiveness build(Class<?> mainClass) throws Exception {
+ protected AppView<? extends AppInfoWithLiveness> build(Class<?> mainClass) throws Exception {
Timing timing = new Timing(getClass().getSimpleName());
AndroidApp app = buildAndroidApp(ToolHelper.getClassAsBytes(mainClass));
- DexApplication dexApplication =
- new ApplicationReader(app, TEST_OPTIONS, timing).read().toDirect();
+ InternalOptions options = new InternalOptions();
+ DexApplication dexApplication = new ApplicationReader(app, options, timing).read().toDirect();
AppView<? extends AppInfoWithSubtyping> appView =
- AppView.createForR8(new AppInfoWithSubtyping(dexApplication), TEST_OPTIONS);
+ AppView.createForR8(new AppInfoWithSubtyping(dexApplication), options);
appView.setAppServices(AppServices.builder(appView).build());
- ExecutorService executorService = ThreadUtils.getExecutorService(TEST_OPTIONS);
+ ExecutorService executorService = ThreadUtils.getExecutorService(options);
RootSet rootSet =
new RootSetBuilder(
- appView,
- dexApplication,
- ImmutableList.of(ProguardKeepRule.defaultKeepAllRule(unused -> {})),
- TEST_OPTIONS)
- .run(executorService);
- Enqueuer enqueuer =
- new Enqueuer(appView, TEST_OPTIONS, null);
- return enqueuer.traceApplication(
- rootSet,
- ProguardClassFilter.empty(),
- executorService,
- timing);
+ appView,
+ dexApplication,
+ ImmutableList.of(ProguardKeepRule.defaultKeepAllRule(unused -> {})),
+ options)
+ .run(executorService);
+ Enqueuer enqueuer = new Enqueuer(appView, options, null);
+ return AppView.createForR8(
+ enqueuer.traceApplication(rootSet, ProguardClassFilter.empty(), executorService, timing),
+ options);
}
-
}
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java b/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
index 80a3285..9dd9def 100644
--- a/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/RegisterMoveSchedulerTest.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.Nullability;
@@ -106,7 +107,7 @@
@Override
public BasicBlock inlineInvoke(
- AppInfo appInfo,
+ AppView<? extends AppInfo> appView,
IRCode code,
IRCode inlinee,
ListIterator<BasicBlock> blockIterator,
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java b/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
index 1a463f2..a0e937d 100644
--- a/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
@@ -5,16 +5,15 @@
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.ir.code.ValueNumberGenerator;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.PriorityQueue;
import org.junit.Test;
@@ -48,11 +47,9 @@
1,
" return-void");
AndroidApp application = buildApplication(builder);
- AppInfo appInfo = getAppInfo(application);
// Build the code, and split the code into three blocks.
- ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
- DexEncodedMethod method = getMethod(application, signature);
- return method.buildInliningIRForTesting(new InternalOptions(), valueNumberGenerator, appInfo);
+ MethodSubject methodSubject = getMethodSubject(application, signature);
+ return methodSubject.buildIR();
}
@Test
diff --git a/src/test/java/com/android/tools/r8/jasmin/JasminTestBase.java b/src/test/java/com/android/tools/r8/jasmin/JasminTestBase.java
index cfc49fe..b7a60bc 100644
--- a/src/test/java/com/android/tools/r8/jasmin/JasminTestBase.java
+++ b/src/test/java/com/android/tools/r8/jasmin/JasminTestBase.java
@@ -275,10 +275,10 @@
return ToolHelper.runArtNoVerificationErrors(out.toString(), main);
}
- protected DexEncodedMethod getMethod(AndroidApp application, String clazz,
- MethodSignature signature) {
- return getMethod(application,
- clazz, signature.type, signature.name, Arrays.asList(signature.parameters));
+ protected DexEncodedMethod getMethod(
+ AndroidApp application, String clazz, MethodSignature signature) {
+ return getMethod(
+ application, clazz, signature.type, signature.name, Arrays.asList(signature.parameters));
}
protected MethodSubject getMethodSubject(
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index bdf815e..483b02e 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -29,6 +29,7 @@
import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DebugLocalInfo;
@@ -751,8 +752,7 @@
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
code);
- IRCode ir =
- code.buildIR(method, null, GraphLense.getIdentityLense(), options, Origin.unknown());
+ IRCode ir = code.buildIR(method, AppView.createForR8(null, options), Origin.unknown());
RegisterAllocator allocator = new LinearScanRegisterAllocator(appInfo, ir, options);
method.setCode(ir, allocator, options);
directMethods[i] = method;
diff --git a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
index 2673690..93e4a4f 100644
--- a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppServices;
@@ -65,6 +66,7 @@
ProguardConfiguration configuration =
ToolHelper.loadProguardConfiguration(dexItemFactory, configPaths);
InternalOptions options = new InternalOptions(configuration, new Reporter());
+ options.programConsumer = DexIndexedConsumer.emptyConsumer();
ExecutorService executor = ThreadUtils.getExecutorService(1);
diff --git a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
index 482cb9a..06ccf5a 100644
--- a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
+++ b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
@@ -6,11 +6,12 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Phi;
@@ -70,21 +71,19 @@
" return-void");
AndroidApp originalApplication = buildApplication(builder);
+
+ InternalOptions options = new InternalOptions();
+ options.programConsumer = DexIndexedConsumer.emptyConsumer();
+
DexApplication application =
new ApplicationReader(
- originalApplication,
- new InternalOptions(),
- new Timing("CatchSuccessorFallthroughTest"))
+ originalApplication, options, new Timing("CatchSuccessorFallthroughTest"))
.read();
DexEncodedMethod method = getMethod(originalApplication, methodSig);
// Get the IR pre-optimization.
IRCode code =
- method.buildIR(
- new AppInfo(application),
- GraphLense.getIdentityLense(),
- new InternalOptions(),
- Origin.unknown());
+ method.buildIR(AppView.createForD8(new AppInfo(application), options), Origin.unknown());
// Find the exit block and assert that the value is a phi merging the exceptional edge
// with the normal edge.
diff --git a/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java b/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
index dfab990..c528eb0 100644
--- a/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
+++ b/src/test/java/com/android/tools/r8/smali/SmaliTestBase.java
@@ -26,6 +26,7 @@
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
@@ -130,23 +131,39 @@
}
}
- protected DexEncodedMethod getMethod(Path appPath, MethodSignature signature) {
+ protected MethodSubject getMethodSubject(Path appPath, MethodSignature signature) {
try {
CodeInspector inspector = new CodeInspector(appPath);
- return getMethod(inspector, signature);
+ return getMethodSubject(inspector, signature);
} catch (IOException | ExecutionException e) {
throw new RuntimeException(e);
}
}
- protected DexEncodedMethod getMethod(CodeInspector inspector, MethodSignature signature) {
- return getMethod(
+ protected MethodSubject getMethodSubject(CodeInspector inspector, MethodSignature signature) {
+ return getMethodSubject(
inspector, signature.clazz, signature.returnType, signature.name, signature.parameterTypes);
}
+ protected MethodSubject getMethodSubject(AndroidApp application, MethodSignature signature) {
+ return getMethodSubject(
+ application,
+ signature.clazz,
+ signature.returnType,
+ signature.name,
+ signature.parameterTypes);
+ }
+
+ protected DexEncodedMethod getMethod(Path appPath, MethodSignature signature) {
+ return getMethodSubject(appPath, signature).getMethod();
+ }
+
+ protected DexEncodedMethod getMethod(CodeInspector inspector, MethodSignature signature) {
+ return getMethodSubject(inspector, signature).getMethod();
+ }
+
protected DexEncodedMethod getMethod(AndroidApp application, MethodSignature signature) {
- return getMethod(application,
- signature.clazz, signature.returnType, signature.name, signature.parameterTypes);
+ return getMethodSubject(application, signature).getMethod();
}
/**
@@ -220,8 +237,9 @@
assertEquals(1, getNumberOfProgramClasses(processdApplication));
// Return the processed method for inspection.
- return getMethod(
- processdApplication, DEFAULT_CLASS_NAME, returnType, DEFAULT_METHOD_NAME, parameters);
+ return getMethodSubject(
+ processdApplication, DEFAULT_CLASS_NAME, returnType, DEFAULT_METHOD_NAME, parameters)
+ .getMethod();
}
public String runArt(AndroidApp application) {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
index 87ae2ec..97de52dd 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.MemberNaming.Signature;
@@ -13,7 +14,7 @@
public class AbsentMethodSubject extends MethodSubject {
@Override
- public IRCode buildIR() {
+ public IRCode buildIR(DexItemFactory dexItemFactory) {
throw new Unreachable("Cannot build IR for an absent method");
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index 4d7c0fc..15b2977 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -4,12 +4,14 @@
package com.android.tools.r8.utils.codeinspector;
+import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfPosition;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexAnnotation;
@@ -18,8 +20,8 @@
import com.android.tools.r8.graph.DexDebugInfo;
import com.android.tools.r8.graph.DexDebugPositionState;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.JarCode;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.naming.MemberNaming;
@@ -27,6 +29,7 @@
import com.android.tools.r8.naming.signature.GenericSignatureParser;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Reporter;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import java.util.Arrays;
@@ -47,15 +50,16 @@
}
@Override
- public IRCode buildIR() {
+ public IRCode buildIR(DexItemFactory dexItemFactory) {
+ InternalOptions options = new InternalOptions(dexItemFactory, new Reporter());
+ options.programConsumer = DexIndexedConsumer.emptyConsumer();
+
DexEncodedMethod method = getMethod();
return method
.getCode()
.buildIR(
method,
- new AppInfo(codeInspector.application),
- GraphLense.getIdentityLense(),
- new InternalOptions(),
+ AppView.createForD8(new AppInfo(codeInspector.application), options),
Origin.unknown());
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
index 8fb4001..7979530 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.utils.codeinspector;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.google.common.collect.Streams;
@@ -14,7 +15,11 @@
public abstract class MethodSubject extends MemberSubject {
- public abstract IRCode buildIR();
+ public final IRCode buildIR() {
+ return buildIR(new DexItemFactory());
+ }
+
+ public abstract IRCode buildIR(DexItemFactory dexItemFactory);
public abstract boolean isAbstract();