Add IR instruction builders
Change-Id: Id24bbb84bbc185a58283c687bd980d3c8af3015b
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 865d83b..5afa942 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
@@ -44,6 +44,10 @@
this.type = type;
}
+ public static Builder builder() {
+ return new Builder();
+ }
+
@Override
public int opcode() {
return Opcodes.ARRAY_GET;
@@ -299,4 +303,40 @@
public void buildLir(LirBuilder<Value, ?> builder) {
builder.addArrayGet(getMemberType(), array(), index());
}
+
+ public static class Builder extends BuilderBase<Builder, ArrayGet> {
+
+ private Value arrayValue;
+ private Value indexValue;
+ private MemberType memberType;
+
+ public Builder setArrayValue(Value arrayValue) {
+ this.arrayValue = arrayValue;
+ return this;
+ }
+
+ public Builder setIndexValue(Value indexValue) {
+ this.indexValue = indexValue;
+ return this;
+ }
+
+ public Builder setMemberType(MemberType memberType) {
+ this.memberType = memberType;
+ return this;
+ }
+
+ @Override
+ public ArrayGet build() {
+ if (memberType == null && outValue.getType().isReferenceType()) {
+ memberType = MemberType.OBJECT;
+ }
+ assert memberType != null;
+ return amend(new ArrayGet(memberType, outValue, arrayValue, indexValue));
+ }
+
+ @Override
+ public Builder self() {
+ return this;
+ }
+ }
}
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 126f23a..9b4fffb 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
@@ -45,6 +45,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.function.Consumer;
import java.util.function.Predicate;
public abstract class Instruction
@@ -1764,6 +1765,13 @@
protected Value outValue;
protected Position position;
+ public final B applyIf(boolean condition, Consumer<B> consumer) {
+ if (condition) {
+ consumer.accept(self());
+ }
+ return self();
+ }
+
public abstract I build();
public abstract B self();
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
index b60c42e..c448a2d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -52,6 +52,11 @@
}
@Override
+ public Builder newBuilder() {
+ return builder();
+ }
+
+ @Override
public int opcode() {
return Opcodes.INVOKE_DIRECT;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
index f677699..e4c26ae 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
@@ -32,6 +32,15 @@
super(target, result, arguments);
}
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public Builder newBuilder() {
+ return builder();
+ }
+
@Override
public boolean getInterfaceBit() {
return true;
@@ -147,4 +156,17 @@
public void buildLir(LirBuilder<Value, ?> builder) {
builder.addInvokeInterface(getInvokedMethod(), arguments());
}
+
+ public static class Builder extends InvokeMethod.Builder<Builder, InvokeInterface> {
+
+ @Override
+ public InvokeInterface build() {
+ return amend(new InvokeInterface(method, outValue, arguments));
+ }
+
+ @Override
+ public Builder self() {
+ return this;
+ }
+ }
}
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 e15b67c..c40827c 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
@@ -77,6 +77,8 @@
}
}
+ public abstract Builder<? extends Builder, ? extends InvokeMethod> newBuilder();
+
public Value getFirstNonReceiverArgument() {
return getArgument(getFirstNonReceiverArgumentIndex());
}
@@ -346,11 +348,12 @@
return false;
}
- abstract static class Builder<B extends Builder<B, I>, I extends InvokeMethod>
+ public abstract static class Builder<B extends Builder<B, I>, I extends InvokeMethod>
extends BuilderBase<B, I> {
protected DexMethod method;
protected List<Value> arguments = Collections.emptyList();
+ protected boolean isInterface = false;
public B setArguments(Value... arguments) {
return setArguments(Arrays.asList(arguments));
@@ -367,6 +370,11 @@
factory, TypeElement.fromDexType(method.getReturnType(), maybeNull(), appView));
}
+ public B setIsInterface(boolean isInterface) {
+ this.isInterface = isInterface;
+ return self();
+ }
+
public B setSingleArgument(Value argument) {
return setArguments(ImmutableList.of(argument));
}
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 9ef005e..601448c 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
@@ -37,6 +37,11 @@
}
@Override
+ public Builder<? extends Builder, ? extends InvokeMethod> newBuilder() {
+ throw new Unreachable();
+ }
+
+ @Override
public boolean getInterfaceBit() {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
index 8abaa2c..16f0c04 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
-
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.dex.code.DexInstruction;
import com.android.tools.r8.dex.code.DexInvokeStatic;
@@ -48,6 +47,11 @@
}
@Override
+ public Builder newBuilder() {
+ return builder();
+ }
+
+ @Override
public boolean getInterfaceBit() {
return isInterface;
}
@@ -229,7 +233,7 @@
assert method != null;
assert method.getArity() == arguments.size();
assert outValue == null || !method.getReturnType().isVoidType();
- return amend(new InvokeStatic(method, outValue, arguments));
+ return amend(new InvokeStatic(method, outValue, arguments, isInterface));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
index d1d9ad4..b5520a0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
@@ -34,6 +34,15 @@
this.isInterface = isInterface;
}
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ @Override
+ public Builder newBuilder() {
+ return builder();
+ }
+
@Override
public boolean getInterfaceBit() {
return isInterface;
@@ -132,4 +141,17 @@
public void buildLir(LirBuilder<Value, ?> builder) {
builder.addInvokeSuper(getInvokedMethod(), arguments(), isInterface);
}
+
+ public static class Builder extends InvokeMethod.Builder<Builder, InvokeSuper> {
+
+ @Override
+ public InvokeSuper build() {
+ return amend(new InvokeSuper(method, outValue, arguments, isInterface));
+ }
+
+ @Override
+ public Builder self() {
+ return this;
+ }
+ }
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
index 6d97ebe..b1cf3bd 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
@@ -37,6 +37,11 @@
}
@Override
+ public Builder newBuilder() {
+ return builder();
+ }
+
+ @Override
public boolean getInterfaceBit() {
return false;
}