aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/android/tools/r8/ir
diff options
context:
space:
mode:
authorIan Zerny <zerny@google.com>2017-07-03 15:49:19 +0200
committerIan Zerny <zerny@google.com>2017-07-03 15:49:19 +0200
commit3d4e8f27290151539ea30a2be65872001a9b837d (patch)
treec677bafc71e909762d8b91c886ada3da44e4be68 /src/main/java/com/android/tools/r8/ir
parent5cbf5fab13e70af8a5f95f97555761a834db315e (diff)
downloadr8-3d4e8f27290151539ea30a2be65872001a9b837d.tar.gz
Replace DebugLocalRead instruction by annotations directly on instructions.
This is in preperation for emitting exact local changes which requires that the scope-end of a local is attached to the instruction at which it ends. The use of debug-local read instructions did not allow this for, eg, exiting instrucitons. R=ager, sgjesse, shertz Bug: 63243012 Change-Id: I4423452089180654afba982f42f07cf06f757791
Diffstat (limited to 'src/main/java/com/android/tools/r8/ir')
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/BasicBlock.java3
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java20
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java79
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java12
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/IRCode.java3
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/Instruction.java50
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/Phi.java9
-rw-r--r--src/main/java/com/android/tools/r8/ir/code/Value.java25
-rw-r--r--src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java90
-rw-r--r--src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java4
-rw-r--r--src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java6
-rw-r--r--src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java47
12 files changed, 190 insertions, 158 deletions
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 38291549f..b9508b591 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
@@ -541,6 +541,9 @@ public class BasicBlock {
for (Value value : instruction.inValues) {
value.removeUser(instruction);
}
+ for (Value value : instruction.getDebugValues()) {
+ value.removeDebugUser(instruction);
+ }
Value previousLocalValue = instruction.getPreviousLocalValue();
if (previousLocalValue != null) {
previousLocalValue.removeDebugUser(instruction);
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 8e019ccf2..70675cbc5 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
@@ -106,6 +106,9 @@ public class BasicBlockInstructionIterator implements InstructionIterator, Instr
Value value = current.inValues().get(i);
value.removeUser(current);
}
+ for (Value value : current.getDebugValues()) {
+ value.removeDebugUser(current);
+ }
Value previousLocalValue = current.getPreviousLocalValue();
if (previousLocalValue != null) {
previousLocalValue.removeDebugUser(current);
@@ -135,12 +138,29 @@ public class BasicBlockInstructionIterator implements InstructionIterator, Instr
assert newInstruction.outValue() != null;
current.outValue().replaceUsers(newInstruction.outValue());
}
+ for (Value value : current.getDebugValues()) {
+ replaceInstructionInList(current, newInstruction, value.getDebugLocalStarts());
+ replaceInstructionInList(current, newInstruction, value.getDebugLocalEnds());
+ value.removeDebugUser(current);
+ newInstruction.addDebugValue(value);
+ }
newInstruction.setBlock(block);
listIterator.remove();
listIterator.add(newInstruction);
current.clearBlock();
}
+ private static void replaceInstructionInList(
+ Instruction instruction,
+ Instruction newInstruction,
+ List<Instruction> instructions) {
+ for (int i = 0; i < instructions.size(); i++) {
+ if (instructions.get(i) == instruction) {
+ instructions.set(i, newInstruction);
+ }
+ }
+ }
+
private BasicBlock peekPrevious(ListIterator<BasicBlock> blocksIterator) {
BasicBlock block = blocksIterator.previous();
blocksIterator.next();
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
deleted file mode 100644
index f1a6d021f..000000000
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2017, 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.code;
-
-import com.android.tools.r8.dex.Constants;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.ir.conversion.DexBuilder;
-import com.android.tools.r8.utils.InternalOptions;
-
-/**
- * Instruction reading an SSA value with attached local information.
- *
- * This instruction ensures that a value with a local is kept alive until at least this read.
- *
- * This instruction must not be considered dead until live-ranges have been computed for locals
- * after which it will be removed.
- */
-public class DebugLocalRead extends Instruction {
-
- public DebugLocalRead(Value src) {
- super(null, src);
- assert src.getLocalInfo() != null;
- }
-
- public Value src() {
- return inValues.get(0);
- }
-
- @Override
- public boolean isDebugLocalRead() {
- return true;
- }
-
- @Override
- public DebugLocalRead asDebugLocalRead() {
- return this;
- }
-
- @Override
- public boolean identicalNonValueParts(Instruction other) {
- assert other.isDebugLocalRead();
- return true;
- }
-
- @Override
- public int compareNonValueParts(Instruction other) {
- assert other.isDebugLocalRead();
- return 0;
- }
-
- @Override
- public boolean canBeDeadCode(IRCode code, InternalOptions options) {
- return false;
- }
-
- @Override
- public void buildDex(DexBuilder builder) {
- throw new Unreachable();
- }
-
- @Override
- public int maxInValueRegister() {
- return Constants.U16BIT_MAX;
- }
-
- @Override
- public int maxOutValueRegister() {
- throw new Unreachable();
- }
-
- public void addDebugLocalStart() {
- src().addDebugLocalStart(this);
- }
-
- public void addDebugLocalEnd() {
- src().addDebugLocalEnd(this);
- }
-}
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 442fb6d23..a96b67361 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,13 +6,13 @@ package com.android.tools.r8.ir.code;
/**
* Instruction introducing an SSA value with attached local information.
*
- * All instructions may have attached local information (defined as the local information of their
- * outgoing value). This instruction is needed to mark a transition of an existing value (with a
- * possible local attached) to a new value that has a local (possibly the same one). If all ingoing
- * values end up having the same local this can be safely removed.
+ * <p>All instructions may have attached local information (defined as the local information of
+ * their outgoing value). This instruction is needed to mark a transition of an existing value (with
+ * a possible local attached) to a new value that has a local (possibly the same one). If all
+ * ingoing values end up having the same local this can be safely removed.
*
- * For valid debug info, this instruction should have at least one user, namely a DebugLocalRead
- * denoting the end of its range, and thus it should be live.
+ * <p>For valid debug info, this instruction should have at least one debug user, denoting the end
+ * of its range, and thus it should be live.
*/
public class DebugLocalWrite extends Move {
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 8506160a9..b98d857b8 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
@@ -205,7 +205,8 @@ public class IRCode {
}
if (value.debugUsers() != null) {
for (Instruction debugUser : value.debugUsers()) {
- assert debugUser.getPreviousLocalValue() == value;
+ assert debugUser.getPreviousLocalValue() == value
+ || debugUser.getDebugValues().contains(value);
}
}
return true;
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 ae4fd671a..f0ff57cb3 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
@@ -15,6 +15,7 @@ import com.android.tools.r8.utils.CfgPrinter;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
@@ -24,6 +25,7 @@ public abstract class Instruction {
protected final List<Value> inValues = new ArrayList<>();
private BasicBlock block = null;
private int number = -1;
+ private List<Value> debugValues = null;
protected Instruction(Value outValue) {
setOutValue(outValue);
@@ -70,11 +72,23 @@ public abstract class Instruction {
}
}
+ public void addDebugValue(Value value) {
+ assert value.getLocalInfo() != null;
+ if (debugValues == null) {
+ debugValues = new ArrayList<>();
+ }
+ debugValues.add(value);
+ value.addDebugUser(this);
+ }
+
public static void clearUserInfo(Instruction instruction) {
if (instruction.outValue != null) {
instruction.outValue.clearUsersInfo();
}
instruction.inValues.forEach(Value::clearUsersInfo);
+ if (instruction.debugValues != null) {
+ instruction.debugValues.forEach(Value::clearUsersInfo);
+ }
}
public final MoveType outType() {
@@ -92,6 +106,29 @@ public abstract class Instruction {
}
}
+ public void replaceDebugPhi(Phi phi, Value value) {
+ if (debugValues != null) {
+ for (int i = 0; i < debugValues.size(); i++) {
+ if (phi == debugValues.get(i)) {
+ if (value.getLocalInfo() == null) {
+ debugValues.remove(i);
+ } else {
+ debugValues.set(i, value);
+ value.addDebugUser(this);
+ }
+ }
+ }
+ }
+ if (phi == getPreviousLocalValue()) {
+ if (value.getDebugInfo() == null) {
+ replacePreviousLocalValue(null);
+ } else {
+ replacePreviousLocalValue(value);
+ value.addDebugUser(this);
+ }
+ }
+ }
+
/**
* Returns the basic block containing this instruction.
*/
@@ -297,6 +334,10 @@ public abstract class Instruction {
return outValue == null ? null : outValue.getPreviousLocalValue();
}
+ public List<Value> getDebugValues() {
+ return debugValues != null ? debugValues : ImmutableList.of();
+ }
+
public void replacePreviousLocalValue(Value value) {
outValue.replacePreviousLocalValue(value);
}
@@ -672,7 +713,6 @@ public abstract class Instruction {
public boolean isDebugInstruction() {
return isDebugPosition()
|| isDebugLocalWrite()
- || isDebugLocalRead()
|| isDebugLocalUninitialized();
}
@@ -700,14 +740,6 @@ public abstract class Instruction {
return null;
}
- public boolean isDebugLocalRead() {
- return false;
- }
-
- public DebugLocalRead asDebugLocalRead() {
- return null;
- }
-
public boolean isInvokeMethod() {
return false;
}
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 de44e83be..cef139421 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
@@ -203,14 +203,7 @@ public class Phi extends Value {
}
if (debugUsers() != null) {
for (Instruction user : debugUsers()) {
- if (this == user.getPreviousLocalValue()) {
- if (same.getDebugInfo() == null) {
- user.replacePreviousLocalValue(null);
- } else {
- user.replacePreviousLocalValue(same);
- same.addDebugUser(user);
- }
- }
+ user.replaceDebugPhi(this, same);
}
}
// If IR construction is taking place, update the definition users.
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 f208d49f8..92bb7b20a 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
@@ -40,8 +40,8 @@ public class Value {
final DebugLocalInfo local;
Value previousLocalValue;
Set<Instruction> debugUsers = new HashSet<>();
- List<DebugLocalRead> localStarts = new ArrayList<>();
- List<DebugLocalRead> localEnds = new ArrayList<>();
+ List<Instruction> localStarts = new ArrayList<>();
+ List<Instruction> localEnds = new ArrayList<>();
DebugData(DebugInfo info) {
this(info.local, info.previousLocalValue);
@@ -115,20 +115,20 @@ public class Value {
}
}
- public List<DebugLocalRead> getDebugLocalStarts() {
+ public List<Instruction> getDebugLocalStarts() {
return debugData.localStarts;
}
- public List<DebugLocalRead> getDebugLocalEnds() {
+ public List<Instruction> getDebugLocalEnds() {
return debugData.localEnds;
}
- public void addDebugLocalStart(DebugLocalRead start) {
+ public void addDebugLocalStart(Instruction start) {
assert start != null;
debugData.localStarts.add(start);
}
- public void addDebugLocalEnd(DebugLocalRead end) {
+ public void addDebugLocalEnd(Instruction end) {
assert end != null;
debugData.localEnds.add(end);
}
@@ -253,7 +253,6 @@ public class Value {
if (isUninitializedLocal()) {
return;
}
- assert !debugData.debugUsers.contains(user);
debugData.debugUsers.add(user);
}
@@ -307,6 +306,13 @@ public class Value {
}
if (debugData != null) {
for (Instruction user : debugUsers()) {
+ user.getDebugValues().replaceAll(v -> {
+ if (v == this) {
+ newValue.addDebugUser(user);
+ return newValue;
+ }
+ return v;
+ });
if (user.getPreviousLocalValue() == this) {
newValue.addDebugUser(user);
user.replacePreviousLocalValue(newValue);
@@ -387,8 +393,11 @@ public class Value {
builder.append(constNumber.getRawValue());
}
}
+ if (isConstant && hasLocalInfo) {
+ builder.append(", ");
+ }
if (hasLocalInfo) {
- builder.append(", ").append(getLocalInfo());
+ builder.append(getLocalInfo());
}
builder.append(")");
}
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 fba48c95c..8aaac95df 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
@@ -34,7 +34,6 @@ import com.android.tools.r8.ir.code.ConstClass;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.ConstString;
import com.android.tools.r8.ir.code.ConstType;
-import com.android.tools.r8.ir.code.DebugLocalRead;
import com.android.tools.r8.ir.code.DebugLocalUninitialized;
import com.android.tools.r8.ir.code.DebugLocalWrite;
import com.android.tools.r8.ir.code.DebugPosition;
@@ -82,11 +81,11 @@ 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.Int2ReferenceSortedMap;
+import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntArraySet;
import it.unimi.dsi.fastutil.ints.IntIterator;
-import it.unimi.dsi.fastutil.ints.IntSet;
-import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
+import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -266,6 +265,11 @@ public class IRBuilder {
private final InternalOptions options;
+ // Pending local changes.
+ private List<Value> debugLocalStarts = new ArrayList<>();
+ private List<Value> debugLocalReads = new ArrayList<>();
+ private List<Value> debugLocalEnds = new ArrayList<>();
+
public IRBuilder(DexEncodedMethod method, SourceCode source, InternalOptions options) {
this(method, source, new ValueNumberGenerator(), options);
}
@@ -517,23 +521,13 @@ public class IRBuilder {
// We cannot shortcut if the local is defined by a phi as it could end up being trivial.
addDebugLocalWrite(moveType, register, in);
} else {
- DebugLocalRead read = addDebugLocalRead(register, local);
- if (read != null) {
- read.addDebugLocalStart();
+ Value value = getLocalValue(register, local);
+ if (value != null) {
+ debugLocalStarts.add(value);
}
}
}
- public void addDebugLocalEnd(int register, DebugLocalInfo local) {
- if (!options.debug) {
- return;
- }
- DebugLocalRead read = addDebugLocalRead(register, local);
- if (read != null) {
- read.addDebugLocalEnd();
- }
- }
-
private void addDebugLocalWrite(MoveType type, int dest, Value in) {
Value out = writeRegister(dest, type, ThrowingInfo.NO_THROW);
DebugLocalWrite write = new DebugLocalWrite(out, in);
@@ -541,10 +535,7 @@ public class IRBuilder {
addInstruction(write);
}
- public DebugLocalRead addDebugLocalRead(int register, DebugLocalInfo local) {
- if (!options.debug) {
- return null;
- }
+ private Value getLocalValue(int register, DebugLocalInfo local) {
assert local != null;
assert local == getCurrentLocal(register);
MoveType moveType = MoveType.fromDexType(local.type);
@@ -555,10 +546,27 @@ public class IRBuilder {
return null;
}
assert in.getLocalInfo() == local;
- DebugLocalRead readLocal = new DebugLocalRead(in);
- assert !readLocal.instructionTypeCanThrow();
- addInstruction(readLocal);
- return readLocal;
+ return in;
+ }
+
+ public void addDebugLocalRead(int register, DebugLocalInfo local) {
+ if (!options.debug) {
+ return;
+ }
+ Value value = getLocalValue(register, local);
+ if (value != null) {
+ debugLocalReads.add(value);
+ }
+ }
+
+ public void addDebugLocalEnd(int register, DebugLocalInfo local) {
+ if (!options.debug) {
+ return;
+ }
+ Value value = getLocalValue(register, local);
+ if (value != null) {
+ debugLocalEnds.add(value);
+ }
}
public void addAdd(NumericType type, int dest, int left, int right) {
@@ -1549,6 +1557,7 @@ public class IRBuilder {
// Private instruction helpers.
private void addInstruction(Instruction ir) {
+ attachLocalChanges(ir);
if (currentDebugPosition != null && !ir.isMoveException()) {
flushCurrentDebugPosition();
}
@@ -1574,6 +1583,29 @@ public class IRBuilder {
}
}
+ private void attachLocalChanges(Instruction ir) {
+ if (!options.debug) {
+ return;
+ }
+ if (debugLocalStarts.isEmpty() && debugLocalReads.isEmpty() && debugLocalEnds.isEmpty()) {
+ return;
+ }
+ for (Value debugLocalStart : debugLocalStarts) {
+ ir.addDebugValue(debugLocalStart);
+ debugLocalStart.addDebugLocalStart(ir);
+ }
+ for (Value debugLocalRead : debugLocalReads) {
+ ir.addDebugValue(debugLocalRead);
+ }
+ for (Value debugLocalEnd : debugLocalEnds) {
+ ir.addDebugValue(debugLocalEnd);
+ debugLocalEnd.addDebugLocalEnd(ir);
+ }
+ debugLocalStarts.clear();
+ debugLocalReads.clear();
+ debugLocalEnds.clear();
+ }
+
// Package (ie, SourceCode accessed) helpers.
// Ensure there is a block starting at offset.
@@ -1680,8 +1712,7 @@ public class IRBuilder {
private void closeCurrentBlockWithFallThrough(BasicBlock nextBlock) {
assert currentBlock != null;
- flushCurrentDebugPosition();
- currentBlock.add(new Goto());
+ addInstruction(new Goto());
if (currentBlock.hasCatchSuccessor(nextBlock)) {
needGotoToCatchBlocks.add(new BasicBlock.Pair(currentBlock, nextBlock));
} else {
@@ -1731,6 +1762,12 @@ public class IRBuilder {
}
Goto gotoExit = new Goto();
gotoExit.setBlock(block);
+ if (options.debug) {
+ for (Value value : ret.getDebugValues()) {
+ gotoExit.addDebugValue(value);
+ value.removeDebugUser(ret);
+ }
+ }
instructions.set(instructions.size() - 1, gotoExit);
block.link(normalExitBlock);
gotoExit.setTarget(normalExitBlock);
@@ -1934,6 +1971,7 @@ public class IRBuilder {
// Stack-trace support requires position information in both debug and release mode.
flushCurrentDebugPosition();
currentDebugPosition = new DebugPosition(line, file);
+ attachLocalChanges(currentDebugPosition);
}
private void flushCurrentDebugPosition() {
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 dd6832284..a2c1cbdf1 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
@@ -433,14 +433,14 @@ public class JarSourceCode implements SourceCode {
preInstructionState = state.toString();
}
- build(insn, builder);
-
// Process local-variable end scopes if this instruction is not a control-flow instruction.
// For control-flow instructions, processing takes place before closing their respective blocks.
if (!isControlFlowInstruction(insn)) {
processLocalVariableEnd(insn, builder);
}
+ build(insn, builder);
+
if (Log.ENABLED && !(insn instanceof LineNumberNode)) {
int offset = getOffset(insn);
if (insn instanceof LabelNode) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
index b25291525..b683f3a30 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DeadCodeRemover.java
@@ -53,12 +53,14 @@ public class DeadCodeRemover {
}
}
- // Add all blocks from where the in-values to the instruction originates.
+ // Add all blocks from where the in/debug-values to the instruction originates.
private static void updateWorklist(Queue<BasicBlock> worklist, Instruction instruction) {
for (Value inValue : instruction.inValues()) {
updateWorklist(worklist, inValue);
}
-
+ for (Value debugValue : instruction.getDebugValues()) {
+ updateWorklist(worklist, debugValue);
+ }
Value previousLocalValue = instruction.getPreviousLocalValue();
if (previousLocalValue != null) {
updateWorklist(worklist, previousLocalValue);
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index 2eae8e7c5..9d303cfa5 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -289,11 +289,6 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
Iterator<Instruction> instructionIterator = block.getInstructions().iterator();
while (instructionIterator.hasNext()) {
Instruction instruction = instructionIterator.next();
- // Remove any local-read instructions now that live ranges are computed.
- if (instruction.isDebugLocalRead()) {
- instructionIterator.remove();
- continue;
- }
if (!instruction.isDebugPosition()) {
continue;
}
@@ -1674,10 +1669,16 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
live.add(use);
}
}
- Value use = instruction.getPreviousLocalValue();
- if (use != null) {
- assert use.needsRegister();
- live.add(use);
+ if (options.debug) {
+ for (Value use : instruction.getDebugValues()) {
+ assert use.needsRegister();
+ live.add(use);
+ }
+ Value use = instruction.getPreviousLocalValue();
+ if (use != null) {
+ assert use.needsRegister();
+ live.add(use);
+ }
}
}
for (Phi phi : block.getPhis()) {
@@ -1794,15 +1795,27 @@ public class LinearScanRegisterAllocator implements RegisterAllocator {
new LiveIntervalsUse(instruction.getNumber(), instruction.maxInValueRegister()));
}
}
- Value use = instruction.getPreviousLocalValue();
- if (use != null) {
- assert use.needsRegister();
- if (!live.contains(use)) {
- live.add(use);
- addLiveRange(use, block, instruction.getNumber());
+ if (options.debug) {
+ int number = instruction.getNumber();
+ for (Value use : instruction.getDebugValues()) {
+ assert use.needsRegister();
+ if (!live.contains(use)) {
+ live.add(use);
+ addLiveRange(use, block, number);
+ }
+ LiveIntervals useIntervals = use.getLiveIntervals();
+ useIntervals.addUse(new LiveIntervalsUse(number, Constants.U16BIT_MAX));
+ }
+ Value use = instruction.getPreviousLocalValue();
+ if (use != null) {
+ assert use.needsRegister();
+ if (!live.contains(use)) {
+ live.add(use);
+ addLiveRange(use, block, number);
+ }
+ LiveIntervals useIntervals = use.getLiveIntervals();
+ useIntervals.addUse(new LiveIntervalsUse(number, Constants.U16BIT_MAX));
}
- LiveIntervals useIntervals = use.getLiveIntervals();
- useIntervals.addUse(new LiveIntervalsUse(instruction.getNumber(), Constants.U16BIT_MAX));
}
}
}