Split return rewriter pass
Change-Id: Ib06bb796b6445dca1d6e359669ea0a59b6c498bb
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 0081d41..64dee4d 100644
--- a/src/main/java/com/android/tools/r8/cf/LoadStoreHelper.java
+++ b/src/main/java/com/android/tools/r8/cf/LoadStoreHelper.java
@@ -7,6 +7,7 @@
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.BasicBlockIterator;
import com.android.tools.r8.ir.code.ConstClass;
import com.android.tools.r8.ir.code.ConstInstruction;
import com.android.tools.r8.ir.code.ConstNumber;
@@ -25,7 +26,6 @@
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
-import java.util.ListIterator;
import java.util.Map;
public class LoadStoreHelper {
@@ -34,8 +34,12 @@
private final IRCode code;
private final TypeVerificationHelper typesHelper;
- private Map<Value, ConstInstruction> clonableConstants = null;
- private ListIterator<BasicBlock> blockIterator = null;
+ private Map<Value, ConstInstruction> clonableConstants;
+
+ // The active block and instruction iterator used by the pass. These are stored in fields to avoid
+ // needing to pass them back and forth through Instruction#insertLoadAndStores.
+ private BasicBlockIterator blockIterator;
+ private InstructionListIterator instructionIterator;
public LoadStoreHelper(AppView<?> appView, IRCode code, TypeVerificationHelper typesHelper) {
this.appView = appView;
@@ -99,9 +103,11 @@
clonableConstants = new IdentityHashMap<>();
blockIterator = code.listIterator();
while (blockIterator.hasNext()) {
- InstructionListIterator it = blockIterator.next().listIterator();
- while (it.hasNext()) {
- it.next().insertLoadAndStores(it, this);
+ BasicBlock block = blockIterator.next();
+ instructionIterator = block.listIterator();
+ while (instructionIterator.hasNext()) {
+ Instruction instruction = instructionIterator.next();
+ instruction.insertLoadAndStores(this);
}
clonableConstants.clear();
}
@@ -128,10 +134,10 @@
moves.add(new PhiMove(phi, value));
}
}
- InstructionListIterator it = pred.listIterator(pred.getInstructions().size());
- Instruction exit = it.previous();
+ instructionIterator = pred.listIterator(pred.getInstructions().size());
+ Instruction exit = instructionIterator.previous();
assert pred.exit() == exit;
- movePhis(moves, it, exit.getPosition());
+ movePhis(moves, exit.getPosition());
}
allocator.addToLiveAtEntrySet(block, block.getPhis());
}
@@ -147,9 +153,9 @@
return StackValue.create(typesHelper.createInitializedType(type), height, appView);
}
- public void loadInValues(Instruction instruction, InstructionListIterator it) {
+ public void loadInValues(Instruction instruction) {
int topOfStack = 0;
- it.previous();
+ instructionIterator.previous();
for (int i = 0; i < instruction.inValues().size(); i++) {
Value value = instruction.inValues().get(i);
StackValue stackValue = createStackValue(value, topOfStack++);
@@ -158,26 +164,25 @@
if (constInstruction != null) {
ConstInstruction clonedConstInstruction =
ConstInstruction.copyOf(stackValue, constInstruction);
- add(clonedConstInstruction, instruction, it);
+ add(clonedConstInstruction, instruction);
} else {
- add(load(stackValue, value), instruction, it);
+ add(load(stackValue, value), instruction);
}
instruction.replaceValue(i, stackValue);
}
- it.next();
+ instructionIterator.next();
}
- public void storeOrPopOutValue(
- DexType type, Instruction instruction, InstructionListIterator it) {
+ public void storeOrPopOutValue(DexType type, Instruction instruction) {
if (instruction.hasOutValue()) {
assert instruction.outValue().isUsed();
- storeOutValue(instruction, it);
+ storeOutValue(instruction);
} else {
- popOutType(type, instruction, it);
+ popOutType(type, instruction);
}
}
- public void storeOutValue(Instruction instruction, InstructionListIterator it) {
+ public void storeOutValue(Instruction instruction) {
assert instruction.hasOutValue();
assert !(instruction.outValue() instanceof StackValue);
if (instruction.isConstInstruction()) {
@@ -187,7 +192,7 @@
|| constInstruction.outValue().numberOfUsers() == 1;
clonableConstants.put(instruction.outValue(), constInstruction);
instruction.outValue().clearUsers();
- it.removeOrReplaceByDebugLocalRead();
+ instructionIterator.removeOrReplaceByDebugLocalRead();
return;
}
assert instruction.outValue().isUsed()
@@ -195,7 +200,7 @@
: "Expected instruction to be removed: " + instruction;
}
if (!instruction.outValue().isUsed()) {
- popOutValue(instruction.outValue(), instruction, it);
+ popOutValue(instruction.outValue(), instruction);
return;
}
StackValue newOutValue = createStackValue(instruction.outValue(), 0);
@@ -208,41 +213,40 @@
// instruction is throwing, the action should be moved to a new block - otherwise, the store
// should be inserted and the remaining instructions should be moved along with the handlers to
// the new block.
- boolean hasCatchHandlers = instruction.getBlock().hasCatchHandlers();
+ boolean hasCatchHandlers = storeBlock.hasCatchHandlers();
if (hasCatchHandlers && instruction.instructionTypeCanThrow()) {
- storeBlock = it.split(this.code, this.blockIterator);
- it = storeBlock.listIterator();
+ storeBlock = instructionIterator.split(this.code, this.blockIterator);
+ instructionIterator = storeBlock.listIterator();
}
- add(store, instruction.getPosition(), it);
+ add(store, instruction.getPosition());
if (hasCatchHandlers && !instruction.instructionTypeCanThrow()) {
- splitAfterStoredOutValue(it);
+ splitAfterStoredOutValue();
}
}
// DebugLocalWrite encodes a store and it needs to consistently split out the catch range after
// its store.
- public void splitAfterStoredOutValue(InstructionListIterator it) {
- it.split(this.code, this.blockIterator);
- this.blockIterator.previous();
+ public void splitAfterStoredOutValue() {
+ instructionIterator.split(this.code, this.blockIterator);
+ blockIterator.previous();
}
- public void popOutType(DexType type, Instruction instruction, InstructionListIterator it) {
- popOutValue(createStackValue(type, 0), instruction, it);
+ public void popOutType(DexType type, Instruction instruction) {
+ popOutValue(createStackValue(type, 0), instruction);
}
- private void popOutValue(Value value, Instruction instruction, InstructionListIterator it) {
- popOutValue(createStackValue(value, 0), instruction, it);
+ private void popOutValue(Value value, Instruction instruction) {
+ popOutValue(createStackValue(value, 0), instruction);
}
- private void popOutValue(
- StackValue newOutValue, Instruction instruction, InstructionListIterator it) {
+ private void popOutValue(StackValue newOutValue, Instruction instruction) {
BasicBlock insertBlock = instruction.getBlock();
if (insertBlock.hasCatchHandlers() && instruction.instructionTypeCanThrow()) {
- insertBlock = it.split(this.code, this.blockIterator);
- it = insertBlock.listIterator();
+ insertBlock = instructionIterator.split(this.code, this.blockIterator);
+ instructionIterator = insertBlock.listIterator();
}
instruction.swapOutValue(newOutValue);
- add(new Pop(newOutValue), instruction.getPosition(), it);
+ add(new Pop(newOutValue), instruction.getPosition());
}
private static class PhiMove {
@@ -255,13 +259,13 @@
}
}
- private void movePhis(List<PhiMove> moves, InstructionListIterator it, Position position) {
+ private void movePhis(List<PhiMove> moves, Position position) {
// TODO(zerny): Accounting for non-interfering phis would lower the max stack size.
int topOfStack = 0;
List<StackValue> temps = new ArrayList<>(moves.size());
for (PhiMove move : moves) {
StackValue tmp = createStackValue(move.phi, topOfStack++);
- add(load(tmp, move.operand), position, it);
+ add(load(tmp, move.operand), position);
temps.add(tmp);
move.operand.removePhiUser(move.phi);
}
@@ -269,7 +273,7 @@
PhiMove move = moves.get(i);
StackValue tmp = temps.get(i);
FixedLocalValue out = new FixedLocalValue(move.phi);
- add(new Store(out, tmp), position, it);
+ add(new Store(out, tmp), position);
move.phi.replaceUsers(out);
}
}
@@ -294,14 +298,12 @@
return new Load(stackValue, value);
}
- private static void add(
- Instruction newInstruction, Instruction existingInstruction, InstructionListIterator it) {
- add(newInstruction, existingInstruction.getPosition(), it);
+ private void add(Instruction newInstruction, Instruction existingInstruction) {
+ add(newInstruction, existingInstruction.getPosition());
}
- private static void add(
- Instruction newInstruction, Position position, InstructionListIterator it) {
+ private void add(Instruction newInstruction, Position position) {
newInstruction.setPosition(position);
- it.add(newInstruction);
+ instructionIterator.add(newInstruction);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingDefinition.java b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingDefinition.java
index 020db76..3a544aa 100644
--- a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingDefinition.java
+++ b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingDefinition.java
@@ -77,7 +77,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java
index cd4d6a4..8bfdfcf 100644
--- a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java
@@ -73,7 +73,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Nothing to do.
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java
index a5cf0e4..3f99c84 100644
--- a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java
+++ b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java
@@ -74,7 +74,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable();
}
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 bebe521..d759235 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
@@ -133,7 +133,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Arguments are defined by locals so nothing to load or store.
}
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 1f6ea43..865d83b 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
@@ -176,9 +176,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
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 ae761d1..ba579de 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
@@ -111,9 +111,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java b/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
index 9419bef..c96f6f6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
@@ -238,8 +238,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Assume.java b/src/main/java/com/android/tools/r8/ir/code/Assume.java
index 279d1b9..e29df9f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Assume.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Assume.java
@@ -214,7 +214,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable(ERROR_MESSAGE);
}
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 9bc7905..7afef24 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
@@ -1175,7 +1175,7 @@
public boolean consistentCatchHandlers() {
// Check that catch handlers are always the first successors of a block.
if (hasCatchHandlers()) {
- assert exit().isGoto() || exit().isThrow();
+ assert exit().isGoto() || exit().isReturn() || exit().isThrow();
CatchHandlers<Integer> catchHandlers = getCatchHandlersWithSuccessorIndexes();
// Check that guards are unique.
assert catchHandlers.getGuards().size()
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
index 4bd1624..4bccf15 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionListIterator.java
@@ -24,6 +24,7 @@
import com.android.tools.r8.ir.optimize.NestUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.IteratorUtils;
+import com.android.tools.r8.utils.ListUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@@ -1010,6 +1011,34 @@
private InstructionListIterator ensureSingleReturnInstruction(
AppView<?> appView, IRCode code, List<BasicBlock> normalExits) {
+ // First ensure that there will be not critical edges after inlining. This is needed since
+ // return blocks are allowed to have catch handlers.
+ if (Iterables.any(normalExits, BasicBlock::hasCatchHandlers)) {
+ normalExits =
+ ListUtils.map(
+ normalExits,
+ exitBlock -> {
+ if (!exitBlock.hasCatchHandlers()) {
+ return exitBlock;
+ }
+ Return exit = exitBlock.exit().asReturn();
+
+ // Create new exit block.
+ BasicBlock newExitBlock = new BasicBlock(code.metadata());
+ newExitBlock.setNumber(code.getNextBlockNumber());
+ Return newReturn =
+ exit.isReturnVoid() ? new Return() : new Return(exit.returnValue());
+ newReturn.setPosition(exit.getPosition());
+ newExitBlock.add(newReturn, code.metadata());
+
+ // Fixup old exit.
+ exit.replace(new Goto());
+ exitBlock.link(newExitBlock);
+ newExitBlock.close(null);
+ code.blocks.add(newExitBlock);
+ return newExitBlock;
+ });
+ }
if (normalExits.size() == 1) {
InstructionListIterator it = normalExits.get(0).listIterator();
it.nextUntil(Instruction::isReturn);
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 12cbc36..207024e 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
@@ -137,9 +137,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
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 9845028..1b1d55c 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
@@ -249,9 +249,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
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 fe1c8b3..5273534 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
@@ -188,8 +188,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@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 54cca22..514e31f 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
@@ -136,8 +136,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@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 cd799fe..5f7f2c5 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
@@ -128,8 +128,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@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 95df669..124b3f7 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
@@ -166,8 +166,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
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 0b2b5e1..590fa00 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
@@ -152,8 +152,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java b/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
index 3e8e999..8b3b71f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
@@ -90,7 +90,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Non-materializing so no stack values are needed.
}
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 7304858..ea4ef1f 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
@@ -64,12 +64,12 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
// A local-write does not have an outgoing stack value, but in writes directly to the local.
assert !instructionTypeCanThrow();
if (getBlock().hasCatchHandlers()) {
- helper.splitAfterStoredOutValue(it);
+ helper.splitAfterStoredOutValue();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java b/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java
index 5852d5e..a8291d6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java
@@ -123,7 +123,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
index 090040a..174392a 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
@@ -74,7 +74,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Nothing to do for positions which are not actual instructions.
}
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 6b3072f..d1bea5b 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
@@ -144,8 +144,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Dup.java b/src/main/java/com/android/tools/r8/ir/code/Dup.java
index 41dea29..071839b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Dup.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Dup.java
@@ -103,7 +103,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Intentionally empty. Dup is a stack operation.
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Dup2.java b/src/main/java/com/android/tools/r8/ir/code/Dup2.java
index eebb405..c05a8af 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Dup2.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Dup2.java
@@ -117,7 +117,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Intentionally empty. Dup2 is a stack operation.
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Goto.java b/src/main/java/com/android/tools/r8/ir/code/Goto.java
index 3c5a357..6bb4e8e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Goto.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Goto.java
@@ -84,7 +84,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Nothing to do.
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/If.java b/src/main/java/com/android/tools/r8/ir/code/If.java
index fac1512..e19b240 100644
--- a/src/main/java/com/android/tools/r8/ir/code/If.java
+++ b/src/main/java/com/android/tools/r8/ir/code/If.java
@@ -243,8 +243,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Inc.java b/src/main/java/com/android/tools/r8/ir/code/Inc.java
index 3b51d7d..37af806 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Inc.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Inc.java
@@ -71,7 +71,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Inc is inserted after load/store insertion, after register allocation.
throw new Unreachable();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InitClass.java b/src/main/java/com/android/tools/r8/ir/code/InitClass.java
index c9039c1..91df093 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InitClass.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InitClass.java
@@ -164,8 +164,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
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 18401ac..90bf26a 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
@@ -210,9 +210,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
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 19b2929..0ea0546 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
@@ -107,9 +107,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
index d54a445..4e3f1ce 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
@@ -250,8 +250,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
}
@Override
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 f9072c0..9da772e 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
@@ -1567,7 +1567,7 @@
public abstract ConstraintWithTarget inliningConstraint(
InliningConstraints inliningConstraints, ProgramMethod context);
- public abstract void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper);
+ public abstract void insertLoadAndStores(LoadStoreHelper helper);
public DexType computeVerificationType(AppView<?> appView, TypeVerificationHelper helper) {
assert outValue == null || !outValue.getType().isReferenceType();
diff --git a/src/main/java/com/android/tools/r8/ir/code/IntSwitch.java b/src/main/java/com/android/tools/r8/ir/code/IntSwitch.java
index de5ce5a..8c2287b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IntSwitch.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IntSwitch.java
@@ -285,8 +285,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
}
@Override
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 6aa12e5..b4dc0ec 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
@@ -317,5 +317,5 @@
* Subclasses must implement load and store handling and make sure to deal with a null out-value
*/
@Override
- public abstract void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper);
+ public abstract void insertLoadAndStores(LoadStoreHelper helper);
}
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 a3f258c..7e03629 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
@@ -187,14 +187,14 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Essentially the same as InvokeMethod but with call site's method proto
// instead of a static called method.
- helper.loadInValues(this, it);
+ helper.loadInValues(this);
if (getCallSite().methodProto.returnType.isVoidType()) {
return;
}
- helper.storeOrPopOutValue(getCallSite().methodProto.returnType, this, it);
+ helper.storeOrPopOutValue(getCallSite().methodProto.returnType, this);
}
@Override
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 c1a5688..e15b67c 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
@@ -265,12 +265,12 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
if (getReturnType().isVoidType()) {
return;
}
- helper.storeOrPopOutValue(getReturnType(), this, it);
+ helper.storeOrPopOutValue(getReturnType(), this);
}
@Override
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 b4256d2..bb1400e 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
@@ -101,9 +101,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOrPopOutValue(type, this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOrPopOutValue(type, this);
}
@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 ac3865d..d9d2c52 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
@@ -91,7 +91,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Nothing to do. This is only hit because loads and stores are insert for phis.
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Monitor.java b/src/main/java/com/android/tools/r8/ir/code/Monitor.java
index 430f8a4..0982912 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Monitor.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Monitor.java
@@ -120,8 +120,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
}
@Override
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 a1c5475..24a777f 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
@@ -121,7 +121,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable(ERROR_MESSAGE);
}
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 4d73577..9d12798 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
@@ -101,8 +101,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
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 1bd40d4..0eb198e 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
@@ -155,9 +155,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java
index 3b44907..bdaeb21 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilled.java
@@ -139,7 +139,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw cfUnsupported();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
index cd21fbc..33a0b7d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
@@ -114,7 +114,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable(ERROR_MESSAGE);
}
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 f946940..a3f05e0 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
@@ -125,8 +125,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java
index cafceff..bc3d425 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewUnboxedEnumInstance.java
@@ -130,8 +130,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/Not.java b/src/main/java/com/android/tools/r8/ir/code/Not.java
index 483aa87..2a98b81 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Not.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Not.java
@@ -96,7 +96,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// JVM has no Not instruction, they should be replaced by "Load -1, Xor" before building CF.
throw new Unreachable();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Pop.java b/src/main/java/com/android/tools/r8/ir/code/Pop.java
index 00554e8..92c7745 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Pop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Pop.java
@@ -121,7 +121,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable("This IR must not be inserted before load and store insertion.");
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/RecordFieldValues.java b/src/main/java/com/android/tools/r8/ir/code/RecordFieldValues.java
index 7ab1c92..0876c64 100644
--- a/src/main/java/com/android/tools/r8/ir/code/RecordFieldValues.java
+++ b/src/main/java/com/android/tools/r8/ir/code/RecordFieldValues.java
@@ -114,9 +114,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/ResourceConstNumber.java b/src/main/java/com/android/tools/r8/ir/code/ResourceConstNumber.java
index d18a410..053384e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ResourceConstNumber.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ResourceConstNumber.java
@@ -56,7 +56,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable("We never write cf code with resource numbers");
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Return.java b/src/main/java/com/android/tools/r8/ir/code/Return.java
index 4e89ab8..b263cb4 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Return.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Return.java
@@ -58,6 +58,10 @@
return !isReturnVoid();
}
+ public Value getReturnValueOrNull() {
+ return hasReturnValue() ? returnValue() : null;
+ }
+
public Value returnValue() {
assert !isReturnVoid();
return inValues.get(0);
@@ -129,13 +133,18 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
if (!isReturnVoid()) {
- helper.loadInValues(this, it);
+ helper.loadInValues(this);
}
}
@Override
+ public boolean isAllowedAfterThrowingInstruction() {
+ return true;
+ }
+
+ @Override
public void buildCf(CfBuilder builder) {
builder.add(
isReturnVoid() ? new CfReturnVoid() : new CfReturn(ValueType.fromType(getReturnType())),
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 b7a26d9..aed2b5e 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
@@ -213,8 +213,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticPut.java b/src/main/java/com/android/tools/r8/ir/code/StaticPut.java
index b201864..dc29a40 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticPut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticPut.java
@@ -230,8 +230,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
}
@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 0ace979..552466d 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
@@ -92,7 +92,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable("This IR must not be inserted before load and store insertion.");
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/StringSwitch.java b/src/main/java/com/android/tools/r8/ir/code/StringSwitch.java
index 506cb80..9968963 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StringSwitch.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StringSwitch.java
@@ -130,7 +130,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Swap.java b/src/main/java/com/android/tools/r8/ir/code/Swap.java
index 3e826c8..097dda3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Swap.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Swap.java
@@ -98,7 +98,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Intentionally empty. Swap is a stack operation.
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Throw.java b/src/main/java/com/android/tools/r8/ir/code/Throw.java
index ab5db40..06bfeaa 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Throw.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Throw.java
@@ -83,8 +83,8 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/UninitializedThisLocalRead.java b/src/main/java/com/android/tools/r8/ir/code/UninitializedThisLocalRead.java
index 3561840..b01312c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/UninitializedThisLocalRead.java
+++ b/src/main/java/com/android/tools/r8/ir/code/UninitializedThisLocalRead.java
@@ -82,7 +82,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
// Non-materializing so no stack values are needed.
}
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 9c65c4e..daf2e77 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
@@ -52,9 +52,9 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
- helper.loadInValues(this, it);
- helper.storeOutValue(this, it);
+ public void insertLoadAndStores(LoadStoreHelper helper) {
+ helper.loadInValues(this);
+ helper.storeOutValue(this);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/UnusedArgument.java b/src/main/java/com/android/tools/r8/ir/code/UnusedArgument.java
index e9ded3f..bd527d6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/UnusedArgument.java
+++ b/src/main/java/com/android/tools/r8/ir/code/UnusedArgument.java
@@ -88,7 +88,7 @@
}
@Override
- public void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper) {
+ public void insertLoadAndStores(LoadStoreHelper helper) {
throw new Unreachable();
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPassCollection.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPassCollection.java
index a6bbd64..24ab29b 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPassCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPassCollection.java
@@ -53,11 +53,14 @@
passes.add(new BranchSimplifier(appView));
passes.add(new SplitBranch(appView));
passes.add(new RedundantConstNumberRemover(appView));
- if (!appView.options().debug) {
+ if (appView.options().isRelease()) {
passes.add(new RedundantFieldLoadAndStoreElimination(appView));
}
passes.add(new BinopRewriter(appView));
passes.add(new ServiceLoaderRewriter(appView));
+ if (appView.options().isRelease()) {
+ passes.add(new SplitReturnRewriter(appView));
+ }
return new CodeRewriterPassCollection(passes);
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/SplitReturnRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/SplitReturnRewriter.java
new file mode 100644
index 0000000..21199d1
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/SplitReturnRewriter.java
@@ -0,0 +1,117 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.ir.conversion.passes;
+
+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.IRCode;
+import com.android.tools.r8.ir.code.Return;
+import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.conversion.MethodProcessor;
+import com.android.tools.r8.ir.conversion.passes.result.CodeRewriterResult;
+import com.android.tools.r8.ir.optimize.AffectedValues;
+import com.google.common.collect.Sets;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Set;
+
+public class SplitReturnRewriter extends CodeRewriterPass<AppInfo> {
+
+ public SplitReturnRewriter(AppView<?> appView) {
+ super(appView);
+ }
+
+ @Override
+ protected String getRewriterId() {
+ return "SplitReturnRewriter";
+ }
+
+ @Override
+ protected boolean shouldRewriteCode(IRCode code, MethodProcessor methodProcessor) {
+ // Disable in tests that need dead switches to be left behind.
+ assert options.isRelease();
+ return appView.options().getTestingOptions().enableDeadSwitchCaseElimination;
+ }
+
+ @Override
+ protected CodeRewriterResult rewriteCode(IRCode code) {
+ boolean changed = false;
+ boolean hasUnreachableBlocks = false;
+ Set<BasicBlock> blocksToRemove = Sets.newIdentityHashSet();
+ Deque<BasicBlock> worklist = new ArrayDeque<>(code.computeNormalExitBlocks());
+ while (!worklist.isEmpty()) {
+ BasicBlock block = worklist.removeFirst();
+ Return returnInstruction = block.entry().asReturn();
+ if (returnInstruction == null) {
+ continue;
+ }
+ Value returnValue = returnInstruction.getReturnValueOrNull();
+ IntList predecessorsToRemove = new IntArrayList();
+ for (int predecessorIndex = 0;
+ predecessorIndex < block.getPredecessors().size();
+ predecessorIndex++) {
+ BasicBlock predecessor = block.getPredecessor(predecessorIndex);
+ if (!predecessor.exit().isGoto()) {
+ continue;
+ }
+ if (predecessor.exit().asGoto().getTarget() != block) {
+ assert predecessor.hasCatchSuccessor(block);
+ continue;
+ }
+ if (block.hasCatchHandlers()) {
+ for (BasicBlock catchHandlerBlock : block.getSuccessors()) {
+ catchHandlerBlock.getMutablePredecessors().clear();
+ }
+ block.getMutableSuccessors().clear();
+ block.clearCatchHandlers();
+ hasUnreachableBlocks = true;
+ } else {
+ assert block.getSuccessors().isEmpty();
+ }
+ Value newReturnValue;
+ if (returnValue != null && returnValue.isPhi() && returnValue.getBlock() == block) {
+ newReturnValue = returnValue.asPhi().getOperand(predecessorIndex);
+ } else {
+ newReturnValue = returnValue;
+ }
+ Return newReturnInstruction =
+ Return.builder().setReturnValue(newReturnValue).setPosition(returnInstruction).build();
+ predecessor.exit().replace(newReturnInstruction);
+ predecessor.removeAllNormalSuccessors();
+ predecessorsToRemove.add(predecessorIndex);
+ worklist.add(predecessor);
+ }
+ if (!predecessorsToRemove.isEmpty()) {
+ if (predecessorsToRemove.size() == block.getPredecessors().size()) {
+ blocksToRemove.add(block);
+ if (returnValue != null) {
+ if (returnValue.isPhi() && returnValue.getBlock() == block) {
+ for (Value operand : returnValue.asPhi().getOperands()) {
+ operand.removePhiUser(returnValue.asPhi());
+ }
+ } else {
+ returnValue.removeUser(returnInstruction);
+ }
+ }
+ } else {
+ block.removePredecessorsByIndex(predecessorsToRemove);
+ block.removePhisByIndex(predecessorsToRemove);
+ }
+ changed = true;
+ }
+ }
+ code.removeBlocks(blocksToRemove);
+ if (hasUnreachableBlocks) {
+ AffectedValues affectedValues = code.removeUnreachableBlocks();
+ affectedValues.narrowingWithAssumeRemoval(appView, code);
+ }
+ if (changed) {
+ code.removeRedundantBlocks();
+ }
+ return CodeRewriterResult.hasChanged(changed);
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java
index 10988dc..471dbf6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java
@@ -7,11 +7,13 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.DynamicType;
+import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.JumpInstruction;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.shaking.AssumeInfoCollection;
import java.util.ArrayList;
import java.util.List;
@@ -38,6 +40,11 @@
returnedTypes.add(returnValue.getDynamicType(appView));
}
}
- return DynamicType.join(appView, returnedTypes);
+ DynamicType dynamicReturnType = DynamicType.join(appView, returnedTypes);
+ AssumeInfoCollection assumeInfoCollection = appView.getAssumeInfoCollection();
+ if (assumeInfoCollection.get(method).getAssumeType().getNullability().isDefinitelyNotNull()) {
+ return dynamicReturnType.withNullability(Nullability.definitelyNotNull());
+ }
+ return dynamicReturnType;
}
}
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 17eb9a8..b58048e 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
@@ -746,17 +746,20 @@
monitorExitBlock.close(null);
}
- for (BasicBlock block : code.blocks) {
+ BasicBlockIterator blockIterator = code.listIterator();
+ while (blockIterator.hasNext()) {
+ BasicBlock block = blockIterator.next();
if (block.exit().isReturn()) {
- // Since return instructions are not allowed after a throwing instruction in a block
- // with catch handlers, the call to prepareBlocksForCatchHandlers() has already taken
- // care of ensuring that all return blocks have no throwing instructions.
- assert !block.canThrow();
-
InstructionListIterator instructionIterator =
block.listIterator(block.getInstructions().size() - 1);
- instructionIterator.setInsertionPosition(Position.syntheticNone());
- instructionIterator.add(new Monitor(MonitorType.EXIT, lockValue));
+ if (block.canThrow()) {
+ BasicBlock splitBlock =
+ instructionIterator.splitCopyCatchHandlers(code, blockIterator, options);
+ instructionIterator = splitBlock.listIterator();
+ }
+ Monitor monitorExit = new Monitor(MonitorType.EXIT, lockValue);
+ monitorExit.setPosition(Position.syntheticNone());
+ instructionIterator.add(monitorExit);
}
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/R8InliningTest.java b/src/test/java/com/android/tools/r8/ir/optimize/R8InliningTest.java
index 12e89e5..818ddcf 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/R8InliningTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/R8InliningTest.java
@@ -341,10 +341,7 @@
assertCounters(ALWAYS_INLINABLE, ALWAYS_INLINABLE, countInvokes(inspector, m));
m = clazz.method("int", "notInlinableDueToSideEffect", ImmutableList.of("inlining.A"));
- assertCounters(
- parameters.isCfRuntime() ? ALWAYS_INLINABLE : NEVER_INLINABLE,
- NEVER_INLINABLE,
- countInvokes(inspector, m));
+ assertCounters(ALWAYS_INLINABLE, NEVER_INLINABLE, countInvokes(inspector, m));
m =
clazz.method(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java
index ade059d..89000f3 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningIntoVisibilityBridgeTest.java
@@ -5,11 +5,9 @@
package com.android.tools.r8.ir.optimize.inliner;
import static com.android.tools.r8.ir.optimize.inliner.testclasses.InliningIntoVisibilityBridgeTestClasses.getClassA;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentIf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.R8TestRunResult;
@@ -64,27 +62,23 @@
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(expectedOutput);
- // Verify that A.method() is only there if there is an explicit -neverinline rule.
+ // Verify that A.method() is removed unless there is an explicit -neverinline rule.
{
ClassSubject classSubject = result.inspector().clazz(getClassA());
- assertThat(classSubject, isPresent());
+ assertThat(classSubject, isPresentIf(neverInline || parameters.isDexRuntime()));
MethodSubject methodSubject = classSubject.uniqueMethodWithOriginalName("method");
assertEquals(neverInline, methodSubject.isPresent());
}
- // Verify that B.method() is still there, and that B.method() is neither a bridge nor a
- // synthetic method unless there is an explicit -neverinline rule.
+ // Verify that B.method() is removed.
{
ClassSubject classSubject =
result.inspector().clazz(InliningIntoVisibilityBridgeTestClassB.class);
- assertThat(classSubject, isPresent());
+ assertThat(classSubject, isPresentIf(neverInline || parameters.isDexRuntime()));
- MethodSubject methodSubject = classSubject.uniqueMethodWithOriginalName("method");
- if (!neverInline) {
- assertThat(methodSubject, isPresentAndRenamed());
- assertFalse(methodSubject.isBridge());
- assertFalse(methodSubject.isSynthetic());
+ if (neverInline) {
+ assertEquals(0, classSubject.allMethods().size());
}
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/switches/B135542760.java b/src/test/java/com/android/tools/r8/ir/optimize/switches/B135542760.java
index 83d1acb..810baae 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/switches/B135542760.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/switches/B135542760.java
@@ -34,7 +34,6 @@
.addOptionsModification(
options -> {
options.testing.enableSwitchToIfRewriting = false;
- options.testing.enableDeadSwitchCaseElimination = true;
})
.enableInliningAnnotations()
.setMinApi(parameters)
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/switches/SwitchCaseRemovalTest.java b/src/test/java/com/android/tools/r8/ir/optimize/switches/SwitchCaseRemovalTest.java
index d3f2fed..319f2f0 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/switches/SwitchCaseRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/switches/SwitchCaseRemovalTest.java
@@ -55,7 +55,6 @@
.addOptionsModification(
options -> {
options.testing.enableSwitchToIfRewriting = false;
- options.testing.enableDeadSwitchCaseElimination = true;
})
.enableInliningAnnotations()
.enableMemberValuePropagationAnnotations()
diff --git a/src/test/java/com/android/tools/r8/rewrite/switches/SwitchRewritingTest.java b/src/test/java/com/android/tools/r8/rewrite/switches/SwitchRewritingTest.java
index 03275f0..3059040 100644
--- a/src/test/java/com/android/tools/r8/rewrite/switches/SwitchRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/switches/SwitchRewritingTest.java
@@ -150,9 +150,7 @@
);
Consumer<InternalOptions> optionsConsumer =
- options -> {
- options.testing.enableDeadSwitchCaseElimination = false;
- };
+ options -> options.testing.enableDeadSwitchCaseElimination = false;
AndroidApp originalApplication = buildApplication(builder);
AndroidApp processedApplication = processApplication(originalApplication, optionsConsumer);
DexEncodedMethod method = getMethod(processedApplication, signature);
diff --git a/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumeNoSideEffectsForJavaLangClassTest.java b/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumeNoSideEffectsForJavaLangClassTest.java
index 9b61b25..f251a9c 100644
--- a/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumeNoSideEffectsForJavaLangClassTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumeNoSideEffectsForJavaLangClassTest.java
@@ -70,19 +70,14 @@
private void inspectMethod(
MethodSubject methodSubject, boolean maybeNullReceiver, boolean maybeSubtype) {
assertThat(methodSubject, isPresent());
- assertThat(
- methodSubject, onlyIf(maybeNullReceiver || maybeSubtype, invokesMethodWithName("equals")));
- assertThat(
- methodSubject,
- onlyIf(maybeNullReceiver || maybeSubtype, invokesMethodWithName("hashCode")));
+ assertThat(methodSubject, onlyIf(maybeSubtype, invokesMethodWithName("equals")));
+ assertThat(methodSubject, onlyIf(maybeSubtype, invokesMethodWithName("hashCode")));
assertThat(
methodSubject,
onlyIf(
maybeNullReceiver,
anyOf(invokesMethodWithName("getClass"), invokesMethodWithName("requireNonNull"))));
- assertThat(
- methodSubject,
- onlyIf(maybeNullReceiver || maybeSubtype, invokesMethodWithName("toString")));
+ assertThat(methodSubject, onlyIf(maybeSubtype, invokesMethodWithName("toString")));
}
static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java b/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
index 9642e4e..237753d 100644
--- a/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
+++ b/src/test/java/com/android/tools/r8/smali/IfSimplificationTest.java
@@ -450,8 +450,8 @@
);
DexCode code = method.getCode().asDexCode();
// TODO(sgjesse): Maybe this test is too fragile, as it leaves quite a lot of code, so the
- // expectation might need changing with other optimizations.
+ // expectation might need changing with other optimizations.
// TODO(zerny): Consider optimizing the fallthrough branch of conditionals to not be return.
- assertEquals(26, code.instructions.length);
+ assertEquals(27, code.instructions.length);
}
}
diff --git a/src/test/java/com/android/tools/r8/smali/OutlineTest.java b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
index 25e8d89..edacb15 100644
--- a/src/test/java/com/android/tools/r8/smali/OutlineTest.java
+++ b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
@@ -15,7 +15,6 @@
import com.android.tools.r8.dex.code.DexConstWideHigh16;
import com.android.tools.r8.dex.code.DexDivInt;
import com.android.tools.r8.dex.code.DexDivInt2Addr;
-import com.android.tools.r8.dex.code.DexGoto;
import com.android.tools.r8.dex.code.DexInstruction;
import com.android.tools.r8.dex.code.DexInvokeStatic;
import com.android.tools.r8.dex.code.DexInvokeStaticRange;
@@ -1294,7 +1293,7 @@
assertTrue(code.instructions[1] instanceof DexInvokeStatic);
assertTrue(code.instructions[2] instanceof DexMoveResult);
assertTrue(code.instructions[3] instanceof DexDivInt2Addr);
- assertTrue(code.instructions[4] instanceof DexGoto);
+ assertTrue(code.instructions[4] instanceof DexReturn);
assertTrue(code.instructions[5] instanceof DexConst4);
assertTrue(code.instructions[6] instanceof DexReturn);
DexInvokeStatic invoke = (DexInvokeStatic) code.instructions[1];