Merge "Shorten names of gradle benchmarks"
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index eb6718d..210a632 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "v1.2.7-dev";
+ public static final String LABEL = "v1.2.9-dev";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java b/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
index f587642..0111aa1 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassAccessFlags.java
@@ -141,6 +141,10 @@
set(Constants.ACC_ANNOTATION);
}
+ public void unsetAnnotation() {
+ unset(Constants.ACC_ANNOTATION);
+ }
+
public boolean isEnum() {
return isSet(Constants.ACC_ENUM);
}
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 2613aae..d437da3 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
@@ -13,6 +13,7 @@
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.Deque;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
@@ -26,6 +27,15 @@
public class IRCode {
+ // Stack marker to denote when all successors of a block have been processed when topologically
+ // sorting.
+ private static class BlockMarker {
+ final BasicBlock block;
+ BlockMarker(BasicBlock block) {
+ this.block = block;
+ }
+ }
+
// When numbering instructions we number instructions only with even numbers. This allows us to
// use odd instruction numbers for the insertion of moves during spilling.
public static final int INSTRUCTION_NUMBER_DELTA = 2;
@@ -252,25 +262,37 @@
* no sorting.
*/
public ImmutableList<BasicBlock> topologicallySortedBlocks() {
- Set<BasicBlock> visitedBlock = new HashSet<>();
- ImmutableList.Builder<BasicBlock> builder = ImmutableList.builder();
- BasicBlock entryBlock = blocks.getFirst();
- depthFirstSorting(visitedBlock, entryBlock, builder);
- ImmutableList<BasicBlock> ordered = builder.build().reverse();
+ ImmutableList<BasicBlock> ordered = depthFirstSorting();
return options.testing.placeExceptionalBlocksLast
? reorderExceptionalBlocksLastForTesting(ordered)
: ordered;
}
- private void depthFirstSorting(Set<BasicBlock> visitedBlock, BasicBlock block,
- ImmutableList.Builder<BasicBlock> builder) {
- if (!visitedBlock.contains(block)) {
- visitedBlock.add(block);
- for (BasicBlock succ : block.getSuccessors()) {
- depthFirstSorting(visitedBlock, succ, builder);
+ private ImmutableList<BasicBlock> depthFirstSorting() {
+ ArrayList<BasicBlock> reverseOrdered = new ArrayList<>(blocks.size());
+ Set<BasicBlock> visitedBlocks = new HashSet<>(blocks.size());
+ Deque<Object> worklist = new ArrayDeque<>(blocks.size());
+ worklist.addLast(blocks.getFirst());
+ while (!worklist.isEmpty()) {
+ Object item = worklist.removeLast();
+ if (item instanceof BlockMarker) {
+ reverseOrdered.add(((BlockMarker) item).block);
+ continue;
}
- builder.add(block);
+ BasicBlock block = (BasicBlock) item;
+ if (!visitedBlocks.contains(block)) {
+ visitedBlocks.add(block);
+ worklist.addLast(new BlockMarker(block));
+ for (int i = block.getSuccessors().size() - 1; i >= 0; i--) {
+ worklist.addLast(block.getSuccessors().get(i));
+ }
+ }
}
+ ImmutableList.Builder<BasicBlock> builder = ImmutableList.builder();
+ for (int i = reverseOrdered.size() - 1; i >= 0; i--) {
+ builder.add(reverseOrdered.get(i));
+ }
+ return builder.build();
}
// Reorder the blocks forcing all exceptional blocks to be at the end.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index 15a90e9..898a2b2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -151,6 +151,7 @@
ClassAccessFlags companionClassFlags = iface.accessFlags.copy();
companionClassFlags.unsetAbstract();
companionClassFlags.unsetInterface();
+ companionClassFlags.unsetAnnotation();
companionClassFlags.setFinal();
companionClassFlags.setSynthetic();
// Companion class must be public so moved methods can be called from anywhere.
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 1e010ce..87a5f83 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
@@ -131,9 +131,7 @@
// The set of registers that are free for allocation.
private TreeSet<Integer> freeRegisters = new TreeSet<>();
// The max register number used.
- private int maxRegisterNumber = 0;
- // The next available register number not yet included in the set of used registers.
- private int nextUnusedRegisterNumber = 0;
+ private int maxRegisterNumber = -1;
// List of all top-level live intervals for all SSA values.
private List<LiveIntervals> liveIntervals = new ArrayList<>();
@@ -164,6 +162,10 @@
RESERVED_MOVE_EXCEPTION_REGISTER;
}
+ private int getNextUnusedRegisterNumber() {
+ return maxRegisterNumber + 1;
+ }
+
public LinearScanRegisterAllocator(IRCode code, InternalOptions options) {
this.code = code;
this.options = options;
@@ -677,8 +679,7 @@
private void clearRegisterAssignments() {
freeRegisters.clear();
- maxRegisterNumber = 0;
- nextUnusedRegisterNumber = 0;
+ maxRegisterNumber = -1;
active.clear();
inactive.clear();
unhandled.clear();
@@ -928,7 +929,7 @@
if (destIntervals.getRegister() == NO_REGISTER) {
// Save the current register allocation state so we can restore it at the end.
TreeSet<Integer> savedFreeRegisters = new TreeSet<>(freeRegisters);
- int savedUnusedRegisterNumber = nextUnusedRegisterNumber;
+ int savedUnusedRegisterNumber = getNextUnusedRegisterNumber();
List<LiveIntervals> savedActive = new LinkedList<>(active);
List<LiveIntervals> savedInactive = new LinkedList<>(inactive);
@@ -956,7 +957,7 @@
allocateLinkedIntervals(destIntervals);
// Restore the register allocation state.
freeRegisters = savedFreeRegisters;
- for (int i = savedUnusedRegisterNumber; i < nextUnusedRegisterNumber; i++) {
+ for (int i = savedUnusedRegisterNumber, j = getNextUnusedRegisterNumber(); i < j; i++) {
freeRegisters.add(i);
}
active = savedActive;
@@ -1033,17 +1034,13 @@
// Update the information about used registers when |register| has been selected for use.
private void updateRegisterState(int register, boolean needsRegisterPair) {
int maxRegister = register + (needsRegisterPair ? 1 : 0);
- if (maxRegister >= nextUnusedRegisterNumber) {
- nextUnusedRegisterNumber = maxRegister + 1;
- }
maxRegisterNumber = Math.max(maxRegisterNumber, maxRegister);
}
private int getSpillRegister(LiveIntervals intervals) {
- int registerNumber = nextUnusedRegisterNumber++;
+ int registerNumber = getNextUnusedRegisterNumber();
maxRegisterNumber = registerNumber;
if (intervals.getType().isWide()) {
- nextUnusedRegisterNumber++;
maxRegisterNumber++;
}
return registerNumber;
@@ -2373,7 +2370,6 @@
}
}
freeRegisters.addAll(unused);
- maxRegisterNumber = Math.max(maxRegisterNumber, first + numberOfRegister - 1);
return first;
}
@@ -2381,7 +2377,8 @@
if (freeRegisters.size() > 0) {
return freeRegisters.pollFirst();
}
- return nextUnusedRegisterNumber++;
+ maxRegisterNumber = getNextUnusedRegisterNumber();
+ return maxRegisterNumber;
}
private void excludeRegistersForInterval(LiveIntervals intervals, Set<Integer> excluded) {
diff --git a/src/test/java/com/android/tools/r8/jasmin/AnnotationCompanionClassTest.java b/src/test/java/com/android/tools/r8/jasmin/AnnotationCompanionClassTest.java
new file mode 100644
index 0000000..033183c
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/jasmin/AnnotationCompanionClassTest.java
@@ -0,0 +1,42 @@
+// 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.jasmin;
+
+import static org.junit.Assert.assertFalse;
+
+import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.DexInspector;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+
+public class AnnotationCompanionClassTest extends JasminTestBase {
+
+ private JasminBuilder buildClass() {
+ JasminBuilder builder = new JasminBuilder(JasminBuilder.ClassFileVersion.JDK_1_4);
+ JasminBuilder.ClassBuilder clazz =
+ builder.addInterface("MyAnnotation", "java/lang/annotation/Annotation");
+
+ clazz.setAccess("public interface abstract annotation");
+
+ clazz.addStaticMethod(
+ "staticMethod", ImmutableList.of(), "V",
+ ".limit stack 0",
+ ".limit locals 0",
+ " return");
+ return builder;
+ }
+
+ @Test
+ public void test() throws Exception {
+ JasminBuilder builder = buildClass();
+ AndroidApp androidApp = compileWithD8(builder);
+
+ DexInspector dexInspector = new DexInspector(androidApp);
+ assertFalse(
+ dexInspector
+ .clazz("LMyAnnotation" + InterfaceMethodRewriter.COMPANION_CLASS_NAME_SUFFIX + ";")
+ .isAnnotation());
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/DexInspector.java b/src/test/java/com/android/tools/r8/utils/DexInspector.java
index af460ef..0cea762 100644
--- a/src/test/java/com/android/tools/r8/utils/DexInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/DexInspector.java
@@ -329,6 +329,8 @@
public abstract boolean isAbstract();
+ public abstract boolean isAnnotation();
+
public String dumpMethods() {
StringBuilder dump = new StringBuilder();
forAllMethods((FoundMethodSubject method) ->
@@ -385,6 +387,11 @@
}
@Override
+ public boolean isAnnotation() {
+ return false;
+ }
+
+ @Override
public DexClass getDexClass() {
return null;
}
@@ -516,6 +523,11 @@
return dexClass.accessFlags.isAbstract();
}
+ @Override
+ public boolean isAnnotation() {
+ return dexClass.accessFlags.isAnnotation();
+ }
+
private DexEncodedField findField(DexEncodedField[] fields, DexField dexField) {
for (DexEncodedField field : fields) {
if (field.field.equals(dexField)) {
diff --git a/tools/test_gradle_benchmarks.py b/tools/test_gradle_benchmarks.py
index a32b2a5..608c055 100755
--- a/tools/test_gradle_benchmarks.py
+++ b/tools/test_gradle_benchmarks.py
@@ -3,7 +3,6 @@
# 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.
-
from __future__ import print_function
import argparse
import os
@@ -12,7 +11,6 @@
import gradle
from enum import Enum
-
BENCHMARKS_ROOT_DIR = os.path.join(utils.REPO_ROOT, 'third_party', 'benchmarks')
def parse_arguments():
@@ -24,9 +22,10 @@
choices=['dx', 'd8'],
required=True,
help='Compiler tool to use.')
+ parser.add_argument('--benchmark',
+ help='Which benchmark to run, default all')
return parser.parse_args()
-
class Benchmark:
class Tools(Enum):
D8 = 1
@@ -92,7 +91,6 @@
def EnsurePresence(self):
EnsurePresence(self.rootDirPath, self.displayName)
-
def EnsurePresence(dir, displayName):
if not os.path.exists(dir) or os.path.getmtime(dir + '.tar.gz')\
< os.path.getmtime(dir + '.tar.gz.sha1'):
@@ -115,7 +113,6 @@
return any(namePattern in taskname for namePattern in acceptedGradleTasks)
-
def PrintBuildTimeForGolem(benchmark, stdOut):
for line in stdOut.splitlines():
if 'BENCH' in line and benchmark.moduleName in line:
@@ -150,7 +147,6 @@
benchmarkName = benchmark.displayName + '-' + taskName
print('{}(RunTimeRaw): {} ms'.format(benchmarkName, commaSplit[2]))
-
def Main():
args = parse_arguments()
@@ -206,10 +202,16 @@
]
- EnsurePresence(os.path.join('third_party', 'benchmarks', 'android-sdk'), 'android SDK')
- EnsurePresence(os.path.join('third_party', 'gradle-plugin'), 'Android Gradle plugin')
-
- for benchmark in buildTimeBenchmarks:
+ EnsurePresence(os.path.join('third_party', 'benchmarks', 'android-sdk'),
+ 'android SDK')
+ EnsurePresence(os.path.join('third_party', 'gradle-plugin'),
+ 'Android Gradle plugin')
+ toRun = buildTimeBenchmarks
+ if args.benchmark:
+ toRun = [b for b in toRun if b.displayName == args.benchmark]
+ if len(toRun) != 1:
+ raise AssertionError("Unknown benchmark: " + args.benchmark)
+ for benchmark in toRun:
benchmark.EnsurePresence()
benchmark.Clean()
stdOut = benchmark.Build(tool, desugarMode)