Merge "Refine type information for MemberType and remove unneeded type from ConstNumber."
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index ad23c03..e93f147 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -218,7 +218,7 @@
ProguardConfiguration.Builder configurationBuilder;
if (proguardConfigs.isEmpty()) {
- configurationBuilder = ProguardConfiguration.builderInitializedWithDefaults(factory);
+ configurationBuilder = ProguardConfiguration.builder(factory);
} else {
ProguardConfigurationParser parser =
new ProguardConfigurationParser(factory, getDiagnosticsHandler());
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 55d52dc..ba10ed5 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
@@ -138,7 +138,8 @@
return true;
}
- protected void addInvokeAndMoveResult(com.android.tools.r8.code.Instruction instruction, DexBuilder builder) {
+ protected void addInvokeAndMoveResult(
+ com.android.tools.r8.code.Instruction instruction, DexBuilder builder) {
if (outValue != null && outValue.needsRegister()) {
MoveType moveType = MoveType.fromValueType(outType());
int register = builder.allocatedRegister(outValue, getNumber());
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java
index 8f6ae85..62c5cc9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/PeepholeOptimizer.java
@@ -285,7 +285,8 @@
}
int outRegister = allocator.getRegisterForValue(outValue, instructionNumber);
ConstNumber numberInRegister = registerToNumber.get(outRegister);
- if (numberInRegister != null && numberInRegister.identicalNonValueNonPositionParts(current)) {
+ if (numberInRegister != null
+ && numberInRegister.identicalNonValueNonPositionParts(current)) {
// This instruction is not needed, the same constant is already in this register.
// We don't consider the positions of the two (non-throwing) instructions.
iterator.remove();
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 523d6db..5783ad4 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
@@ -136,9 +136,9 @@
// List of active intervals.
private List<LiveIntervals> active = new LinkedList<>();
// List of intervals where the current instruction falls into one of their live range holes.
- private List<LiveIntervals> inactive = new LinkedList<>();
+ protected List<LiveIntervals> inactive = new LinkedList<>();
// List of intervals that no register has been allocated to sorted by first live range.
- private PriorityQueue<LiveIntervals> unhandled = new PriorityQueue<>();
+ protected PriorityQueue<LiveIntervals> unhandled = new PriorityQueue<>();
// The first register used for parallel moves. After register allocation the parallel move
// temporary registers are [firstParallelMoveTemporary, maxRegisterNumber].
@@ -1517,7 +1517,7 @@
splitOverlappingInactiveIntervals(unhandledInterval, needsRegisterPair, candidate);
}
- private void splitOverlappingInactiveIntervals(
+ protected void splitOverlappingInactiveIntervals(
LiveIntervals unhandledInterval,
boolean needsRegisterPair,
int candidate) {
@@ -1529,10 +1529,16 @@
(needsRegisterPair && intervals.usesRegister(candidate + 1))) &&
intervals.overlaps(unhandledInterval)) {
if (intervals.isLinked() && !intervals.isArgumentInterval()) {
+ // If the inactive register is linked but not an argument, it needs to get the
+ // same register again at the next use after the start of the unhandled interval.
+ // If there are no such uses, we can use a different register for the remainder
+ // of the inactive interval and therefore do not have to split here.
int nextUsePosition = intervals.firstUseAfter(unhandledInterval.getStart());
- LiveIntervals split = intervals.splitBefore(nextUsePosition);
- split.setRegister(intervals.getRegister());
- newInactive.add(split);
+ if (nextUsePosition != Integer.MAX_VALUE) {
+ LiveIntervals split = intervals.splitBefore(nextUsePosition);
+ split.setRegister(intervals.getRegister());
+ newInactive.add(split);
+ }
}
if (intervals.getStart() > unhandledInterval.getStart()) {
// The inactive live intervals hasn't started yet. Clear the temporary register
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
index bdf7748..f8aa3e2 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -18,13 +18,13 @@
private final List<FilteredClassPath> injars = new ArrayList<>();
private final List<FilteredClassPath> libraryjars = new ArrayList<>();
- private PackageObfuscationMode packageObfuscationMode;
- private String packagePrefix;
+ private PackageObfuscationMode packageObfuscationMode = PackageObfuscationMode.NONE;
+ private String packagePrefix = "";
private boolean allowAccessModification;
private boolean ignoreWarnings;
- private boolean optimizing;
- private boolean obfuscating;
- private boolean shrinking;
+ private boolean optimizing = true;
+ private boolean obfuscating = true;
+ private boolean shrinking = true;
private boolean printUsage;
private Path printUsageFile;
private boolean printMapping;
@@ -49,37 +49,6 @@
private Builder(DexItemFactory dexItemFactory) {
this.dexItemFactory = dexItemFactory;
- resetProguardDefaults();
- }
-
- public void resetProguardDefaults() {
- injars.clear();
- libraryjars.clear();
- packageObfuscationMode = PackageObfuscationMode.NONE;
- packagePrefix = "";
- allowAccessModification = false;
- ignoreWarnings = false;
- optimizing = true;
- obfuscating = true;
- shrinking = true;
- printUsage = false;
- printUsageFile = null;
- printMapping = false;
- printMappingFile = null;
- applyMappingFile = null;
- verbose = false;
- renameSourceFileAttribute = null;
- keepAttributePatterns.clear();
- dontWarnPatterns = ProguardClassFilter.builder();
- rules.clear();
- printSeeds = false;
- seedFile = null;
- obfuscationDictionary = null;
- classObfuscationDictionary = null;
- packageObfuscationDictionary = null;
- useUniqueClassMemberNames = false;
- keepParameterNames = false;
- adaptClassStrings = ProguardClassFilter.builder();
}
public void addInjars(List<FilteredClassPath> injars) {
@@ -217,11 +186,16 @@
}
public ProguardConfiguration build() throws CompilationException {
- ProguardKeepAttributes keepAttributes;
+ boolean rulesWasEmpty = rules.isEmpty();
+ if (rulesWasEmpty) {
+ setObfuscating(false);
+ setShrinking(false);
+ addRule(ProguardKeepRule.defaultKeepAllRule());
+ }
- if (forceProguardCompatibility
- && !isObfuscating()
- && keepAttributePatterns.size() == 0) {
+ ProguardKeepAttributes keepAttributes;
+ if (keepAttributePatterns.isEmpty()
+ && (rulesWasEmpty || (forceProguardCompatibility && !isObfuscating()))) {
keepAttributes = ProguardKeepAttributes.fromPatterns(ProguardKeepAttributes.KEEP_ALL);
} else {
keepAttributes = ProguardKeepAttributes.fromPatterns(keepAttributePatterns);
@@ -358,15 +332,6 @@
return new Builder(dexItemFactory);
}
- public static Builder builderInitializedWithDefaults(DexItemFactory dexItemFactory) {
- Builder builder = new Builder(dexItemFactory);
- builder.setObfuscating(false);
- builder.setShrinking(false);
- builder.addKeepAttributePatterns(ProguardKeepAttributes.KEEP_ALL);
- builder.addRule(ProguardKeepRule.defaultKeepAllRule());
- return builder;
- }
-
public DexItemFactory getDexItemFactory() {
return dexItemFactory;
}
@@ -481,7 +446,7 @@
public static ProguardConfiguration defaultConfiguration(DexItemFactory dexItemFactory) {
try {
- return builderInitializedWithDefaults(dexItemFactory).build();
+ return builder(dexItemFactory).build();
} catch (CompilationException e) {
// Building a builder initialized with defaults will not throw CompilationException because
// DictionaryReader is called with empty lists.
diff --git a/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java b/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
new file mode 100644
index 0000000..1d17e31
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/regalloc/Regress68656641.java
@@ -0,0 +1,83 @@
+// 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.regalloc;
+
+import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.code.ValueNumberGenerator;
+import com.android.tools.r8.ir.code.ValueType;
+import com.android.tools.r8.smali.SmaliTestBase;
+import com.android.tools.r8.utils.InternalOptions;
+import com.google.common.collect.ImmutableList;
+import java.util.PriorityQueue;
+import org.junit.Test;
+
+public class Regress68656641 extends SmaliTestBase {
+
+ private static class MyRegisterAllocator extends LinearScanRegisterAllocator {
+ public MyRegisterAllocator(IRCode code, InternalOptions options) {
+ super(code, options);
+ }
+
+ public void addInactiveIntervals(LiveIntervals intervals) {
+ inactive.add(intervals);
+ }
+
+ public void splitOverlappingInactiveIntervals(LiveIntervals intervals, int register) {
+ splitOverlappingInactiveIntervals(intervals, false, register);
+ }
+
+ public PriorityQueue<LiveIntervals> getUnhandled() {
+ return unhandled;
+ }
+ }
+
+ IRCode simpleCode(InternalOptions options) throws Exception {
+ SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
+ MethodSignature signature = builder.addStaticMethod(
+ "void",
+ DEFAULT_METHOD_NAME,
+ ImmutableList.of(),
+ 1,
+ " return-void");
+ DexApplication application = buildApplication(builder, options);
+ // Build the code, and split the code into three blocks.
+ ValueNumberGenerator valueNumberGenerator = new ValueNumberGenerator();
+ DexEncodedMethod method = getMethod(application, signature);
+ IRCode code = method.buildIR(new InternalOptions(), valueNumberGenerator);
+ return code;
+ }
+
+
+ @Test
+ public void splitOverlappingInactiveIntervalWithNoNextUse() throws Exception {
+ InternalOptions options = new InternalOptions();
+ IRCode code = simpleCode(options);
+ MyRegisterAllocator allocator = new MyRegisterAllocator(code, options);
+ // Setup live an inactive live interval with ranges [0, 10[ and [20, 30[ with only
+ // uses in the first interval and which is linked to another interval.
+ LiveIntervals inactiveIntervals = new LiveIntervals(new Value(0, ValueType.INT, null));
+ inactiveIntervals.addRange(new LiveRange(0, 10));
+ inactiveIntervals.addUse(new LiveIntervalsUse(0, 10));
+ inactiveIntervals.addUse(new LiveIntervalsUse(4, 10));
+ inactiveIntervals.addRange(new LiveRange(20, 30));
+ inactiveIntervals.setRegister(0);
+ LiveIntervals linked = new LiveIntervals(new Value(1, ValueType.INT, null));
+ linked.setRegister(1);
+ inactiveIntervals.link(linked);
+ allocator.addInactiveIntervals(inactiveIntervals);
+ // Setup an unhandled interval that overlaps the inactive interval.
+ LiveIntervals unhandledIntervals = new LiveIntervals(new Value(2, ValueType.INT, null));
+ unhandledIntervals.addRange(new LiveRange(12, 24));
+ // Split the overlapping inactive intervals and check that after the split, the second
+ // part of the inactive interval is unhandled and will therefore get a new register
+ // assigned later during allocation.
+ allocator.splitOverlappingInactiveIntervals(unhandledIntervals, 0);
+ assert allocator.getUnhandled().size() == 1;
+ assert allocator.getUnhandled().peek().getStart() == 20;
+ assert allocator.getUnhandled().peek().getEnd() == 30;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
index c4af25c..6306f91 100644
--- a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
+++ b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
@@ -91,11 +91,9 @@
checkAnnotationContent(INPUT_PATH, result);
}
- /**
- * Check that when dontshrink and dontobfuscate is used the annotation is transmitted.
- */
+ /** Check that when dontshrink and dontobfuscate is used the annotation is transmitted. */
@Test
- public void testSourceDebugExtensionWithShriking1()
+ public void testSourceDebugExtensionWithShrinking1()
throws IOException, CompilationException, ExecutionException {
Path outputPath = tmpOutputDir.newFolder().toPath();
AndroidApp result = compileWithR8(INPUT_PATH, outputPath, DONT_SHRINK_DONT_OBFUSCATE_CONFIG);
@@ -125,7 +123,7 @@
}
/**
- * Check that the annotation is removed when shriking is enabled and that there is not
+ * Check that the annotation is removed when shrinking is enabled and that there is not
* keepattributes option.
*/
@Test
diff --git a/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java b/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
index 46991d6..046a14b 100644
--- a/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
+++ b/src/test/java/com/android/tools/r8/naming/RenameSourceFileDebugTest.java
@@ -31,8 +31,6 @@
compileToDexViaR8(
null,
pg -> {
- pg.resetProguardDefaults();
- pg.addRule(ProguardKeepRule.defaultKeepAllRule());
pg.setRenameSourceFileAttribute(TEST_FILE);
pg.addKeepAttributePatterns(ImmutableList.of("SourceFile", "LineNumberTable"));
},
diff --git a/src/test/java/com/android/tools/r8/utils/R8CommandTest.java b/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
index 2054b22..6dda185 100644
--- a/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/utils/R8CommandTest.java
@@ -229,7 +229,7 @@
R8Command command = parse("@" + argsFile.toString());
assertEquals(CompilationMode.DEBUG, command.getMode());
assertFalse(command.useMinification());
- assertTrue(command.useTreeShaking());
+ assertFalse(command.useTreeShaking()); // We have no keep rules (proguard config file is empty).
assertEquals(1, ToolHelper.getApp(command).getDexProgramResources().size());
}