diff --git a/src/main/java/com/android/tools/r8/JarSizeCompare.java b/src/main/java/com/android/tools/r8/JarSizeCompare.java
new file mode 100644
index 0000000..aa16b1f
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/JarSizeCompare.java
@@ -0,0 +1,482 @@
+// Copyright (c) 2018, 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;
+
+import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.Code;
+import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.naming.ClassNameMapper;
+import com.android.tools.r8.naming.ClassNamingForNameMapper;
+import com.android.tools.r8.naming.MemberNaming.FieldSignature;
+import com.android.tools.r8.naming.MemberNaming.MethodSignature;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.AndroidAppConsumers;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Timing;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.function.BiConsumer;
+
+/**
+ * JarSizeCompare outputs the class, method, field sizes of the given JAR files. For each input, a
+ * ProGuard map can be passed that is used to resolve minified names.
+ *
+ * <p>By default, only shows methods where R8's DEX output is 5 or more instructions larger than
+ * ProGuard+D8's output. Pass {@code --threshold 0} to display all methods.
+ */
+public class JarSizeCompare {
+
+  private static final String USAGE =
+      "Arguments:\n"
+          + "    [--threshold <threshold>]\n"
+          + "    [--lib <lib.jar>]\n"
+          + "    --input <name1> <input1.jar> [<map1.txt>]\n"
+          + "    --input <name2> <input2.jar> [<map2.txt>] ...\n"
+          + "\n"
+          + "JarSizeCompare outputs the class, method, field sizes of the given JAR files.\n"
+          + "For each input, a ProGuard map can be passed that is used to resolve minified names.\n";
+
+  private static final ImmutableMap<String, String> R8_RELOCATIONS =
+      ImmutableMap.<String, String>builder()
+          .put("com.google.common", "com.android.tools.r8.com.google.common")
+          .put("com.google.gson", "com.android.tools.r8.com.google.gson")
+          .put("com.google.thirdparty", "com.android.tools.r8.com.google.thirdparty")
+          .put("joptsimple", "com.android.tools.r8.joptsimple")
+          .put("org.apache.commons", "com.android.tools.r8.org.apache.commons")
+          .put("org.objectweb.asm", "com.android.tools.r8.org.objectweb.asm")
+          .put("it.unimi.dsi.fastutil", "com.android.tools.r8.it.unimi.dsi.fastutil")
+          .build();
+
+  private final List<Path> libraries;
+  private final List<InputParameter> inputParameters;
+  private final int threshold;
+  private final InternalOptions options;
+  private int pgIndex;
+  private int r8Index;
+
+  private JarSizeCompare(
+      List<Path> libraries, List<InputParameter> inputParameters, int threshold) {
+    this.libraries = libraries;
+    this.inputParameters = inputParameters;
+    this.threshold = threshold;
+    options = new InternalOptions();
+    options.enableCfFrontend = true;
+  }
+
+  public void run() throws Exception {
+    List<String> names = new ArrayList<>();
+    List<InputApplication> inputApplicationList = new ArrayList<>();
+    Timing timing = new Timing("JarSizeCompare");
+    for (InputParameter inputParameter : inputParameters) {
+      AndroidApp inputApp = inputParameter.getInputApp(libraries);
+      DexApplication input = inputParameter.getReader(options, inputApp, timing);
+      AndroidAppConsumers appConsumer = new AndroidAppConsumers();
+      D8.run(
+          D8Command.builder(inputApp)
+              .setMinApiLevel(AndroidApiLevel.P.getLevel())
+              .setProgramConsumer(appConsumer.wrapDexIndexedConsumer(null))
+              .build());
+      DexApplication d8Input = inputParameter.getReader(options, appConsumer.build(), timing);
+      InputApplication inputApplication =
+          new InputApplication(input, translateClassNames(input, input.classes()));
+      InputApplication d8Classes =
+          new InputApplication(input, translateClassNames(input, d8Input.classes()));
+      names.add(inputParameter.name + "-input");
+      inputApplicationList.add(inputApplication);
+      names.add(inputParameter.name + "-d8");
+      inputApplicationList.add(d8Classes);
+    }
+    if (threshold != 0) {
+      pgIndex = names.indexOf("pg-d8");
+      r8Index = names.indexOf("r8-d8");
+    }
+    Map<String, InputClass[]> inputClasses = new HashMap<>();
+    for (int i = 0; i < names.size(); i++) {
+      InputApplication classes = inputApplicationList.get(i);
+      for (String className : classes.getClasses()) {
+        inputClasses.computeIfAbsent(className, k -> new InputClass[names.size()])[i] =
+            classes.getInputClass(className);
+      }
+    }
+    for (Entry<String, Map<String, InputClass[]>> library : byLibrary(inputClasses)) {
+      System.out.println("");
+      System.out.println(Strings.repeat("=", 100));
+      String commonPrefix = getCommonPrefix(library.getValue().keySet());
+      if (library.getKey().isEmpty()) {
+        System.out.println("PROGRAM (" + commonPrefix + ")");
+      } else {
+        System.out.println("LIBRARY: " + library.getKey() + " (" + commonPrefix + ")");
+      }
+      printLibrary(library.getValue(), commonPrefix);
+    }
+  }
+
+  private Map<String, DexProgramClass> translateClassNames(
+      DexApplication input, List<DexProgramClass> classes) {
+    Map<String, DexProgramClass> result = new HashMap<>();
+    ClassNameMapper classNameMapper = input.getProguardMap();
+    for (DexProgramClass programClass : classes) {
+      ClassNamingForNameMapper classNaming;
+      if (classNameMapper == null) {
+        classNaming = null;
+      } else {
+        classNaming = classNameMapper.getClassNaming(programClass.type);
+      }
+      String type =
+          classNaming == null ? programClass.type.toSourceString() : classNaming.originalName;
+      result.put(type, programClass);
+    }
+    return result;
+  }
+
+  private String getCommonPrefix(Set<String> classes) {
+    if (classes.size() <= 1) {
+      return "";
+    }
+    String commonPrefix = null;
+    for (String clazz : classes) {
+      if (clazz.equals("r8.GeneratedOutlineSupport")) {
+        continue;
+      }
+      if (commonPrefix == null) {
+        commonPrefix = clazz;
+      } else {
+        int i = 0;
+        while (i < clazz.length()
+            && i < commonPrefix.length()
+            && clazz.charAt(i) == commonPrefix.charAt(i)) {
+          i++;
+        }
+        commonPrefix = commonPrefix.substring(0, i);
+      }
+    }
+    return commonPrefix;
+  }
+
+  private void printLibrary(Map<String, InputClass[]> classMap, String commonPrefix) {
+    List<Entry<String, InputClass[]>> classes = new ArrayList<>(classMap.entrySet());
+    classes.sort(Comparator.comparing(Entry::getKey));
+    for (Entry<String, InputClass[]> clazz : classes) {
+      printClass(
+          clazz.getKey().substring(commonPrefix.length()), new ClassCompare(clazz.getValue()));
+    }
+  }
+
+  private void printClass(String name, ClassCompare inputClasses) {
+    List<MethodSignature> methods = getMethods(inputClasses);
+    List<FieldSignature> fields = getFields(inputClasses);
+    if (methods.isEmpty() && fields.isEmpty()) {
+      return;
+    }
+    System.out.println(name);
+    for (MethodSignature sig : methods) {
+      printSignature(getMethodString(sig), inputClasses.sizes(sig));
+    }
+    for (FieldSignature sig : fields) {
+      printSignature(getFieldString(sig), inputClasses.sizes(sig));
+    }
+  }
+
+  private String getMethodString(MethodSignature sig) {
+    StringBuilder builder = new StringBuilder().append('(');
+    for (int i = 0; i < sig.parameters.length; i++) {
+      builder.append(DescriptorUtils.javaTypeToShorty(sig.parameters[i]));
+    }
+    builder.append(')').append(DescriptorUtils.javaTypeToShorty(sig.type)).append(' ');
+    return builder.append(sig.name).toString();
+  }
+
+  private String getFieldString(FieldSignature sig) {
+    return DescriptorUtils.javaTypeToShorty(sig.type) + ' ' + sig.name;
+  }
+
+  private void printSignature(String key, int[] sizes) {
+    System.out.print(padItem(key));
+    for (int size : sizes) {
+      System.out.print(padValue(size));
+    }
+    System.out.print('\n');
+  }
+
+  private List<MethodSignature> getMethods(ClassCompare inputClasses) {
+    List<MethodSignature> methods = new ArrayList<>();
+    for (MethodSignature methodSignature : inputClasses.getMethods()) {
+      if (threshold == 0 || methodExceedsThreshold(inputClasses, methodSignature)) {
+        methods.add(methodSignature);
+      }
+    }
+    return methods;
+  }
+
+  private boolean methodExceedsThreshold(
+      ClassCompare inputClasses, MethodSignature methodSignature) {
+    assert threshold > 0;
+    assert pgIndex != r8Index;
+    int pgSize = inputClasses.size(methodSignature, pgIndex);
+    int r8Size = inputClasses.size(methodSignature, r8Index);
+    return pgSize != -1 && r8Size != -1 && pgSize + threshold <= r8Size;
+  }
+
+  private List<FieldSignature> getFields(ClassCompare inputClasses) {
+    return threshold == 0 ? inputClasses.getFields() : Collections.emptyList();
+  }
+
+  private String padItem(String s) {
+    return String.format("%-52s", s);
+  }
+
+  private String padValue(int v) {
+    return String.format("%8s", v == -1 ? "---" : v);
+  }
+
+  private List<Map.Entry<String, Map<String, InputClass[]>>> byLibrary(
+      Map<String, InputClass[]> inputClasses) {
+    Map<String, Map<String, InputClass[]>> byLibrary = new HashMap<>();
+    for (Entry<String, InputClass[]> entry : inputClasses.entrySet()) {
+      Map<String, InputClass[]> library =
+          byLibrary.computeIfAbsent(getLibraryName(entry.getKey()), k -> new HashMap<>());
+      library.put(entry.getKey(), entry.getValue());
+    }
+    List<Entry<String, Map<String, InputClass[]>>> list = new ArrayList<>(byLibrary.entrySet());
+    list.sort(Comparator.comparing(Entry::getKey));
+    return list;
+  }
+
+  private String getLibraryName(String className) {
+    for (Entry<String, String> relocation : R8_RELOCATIONS.entrySet()) {
+      if (className.startsWith(relocation.getValue())) {
+        return relocation.getKey();
+      }
+    }
+    return "";
+  }
+
+  static class InputParameter {
+
+    private final String name;
+    private final Path jar;
+    private final Path map;
+
+    InputParameter(String name, Path jar, Path map) {
+      this.name = name;
+      this.jar = jar;
+      this.map = map;
+    }
+
+    DexApplication getReader(InternalOptions options, AndroidApp inputApp, Timing timing)
+        throws Exception {
+      ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
+      return applicationReader.read(map == null ? null : StringResource.fromFile(map)).toDirect();
+    }
+
+    AndroidApp getInputApp(List<Path> libraries) throws Exception {
+      return AndroidApp.builder().addLibraryFiles(libraries).addProgramFiles(jar).build();
+    }
+  }
+
+  static class InputApplication {
+
+    private final DexApplication dexApplication;
+    private final Map<String, DexProgramClass> classMap;
+
+    private InputApplication(DexApplication dexApplication, Map<String, DexProgramClass> classMap) {
+      this.dexApplication = dexApplication;
+      this.classMap = classMap;
+    }
+
+    public Set<String> getClasses() {
+      return classMap.keySet();
+    }
+
+    private InputClass getInputClass(String type) {
+      DexProgramClass inputClass = classMap.get(type);
+      ClassNameMapper proguardMap = dexApplication.getProguardMap();
+      return new InputClass(inputClass, proguardMap);
+    }
+  }
+
+  static class InputClass {
+    private final DexProgramClass programClass;
+    private final ClassNameMapper proguardMap;
+
+    InputClass(DexClass dexClass, ClassNameMapper proguardMap) {
+      this.programClass = dexClass == null ? null : dexClass.asProgramClass();
+      this.proguardMap = proguardMap;
+    }
+
+    void forEachMethod(BiConsumer<MethodSignature, DexEncodedMethod> consumer) {
+      if (programClass == null) {
+        return;
+      }
+      programClass.forEachMethod(
+          dexEncodedMethod -> {
+            MethodSignature originalSignature =
+                proguardMap == null
+                    ? null
+                    : ((MethodSignature) proguardMap.originalSignatureOf(dexEncodedMethod.method));
+            MethodSignature signature = MethodSignature.fromDexMethod(dexEncodedMethod.method);
+            consumer.accept(
+                originalSignature == null ? signature : originalSignature, dexEncodedMethod);
+          });
+    }
+
+    void forEachField(BiConsumer<FieldSignature, DexEncodedField> consumer) {
+      if (programClass == null) {
+        return;
+      }
+      programClass.forEachField(
+          dexEncodedField -> {
+            FieldSignature originalSignature =
+                proguardMap == null ? null : proguardMap.originalSignatureOf(dexEncodedField.field);
+            FieldSignature signature = FieldSignature.fromDexField(dexEncodedField.field);
+            consumer.accept(
+                originalSignature == null ? signature : originalSignature, dexEncodedField);
+          });
+    }
+  }
+
+  private static class ClassCompare {
+    final Map<MethodSignature, DexEncodedMethod[]> methods = new HashMap<>();
+    final Map<FieldSignature, DexEncodedField[]> fields = new HashMap<>();
+    final int classes;
+
+    ClassCompare(InputClass[] inputs) {
+      for (int i = 0; i < inputs.length; i++) {
+        InputClass inputClass = inputs[i];
+        int finalI = i;
+        if (inputClass == null) {
+          continue;
+        }
+        inputClass.forEachMethod(
+            (sig, m) ->
+                methods.computeIfAbsent(sig, o -> new DexEncodedMethod[inputs.length])[finalI] = m);
+        inputClass.forEachField(
+            (sig, f) ->
+                fields.computeIfAbsent(sig, o -> new DexEncodedField[inputs.length])[finalI] = f);
+      }
+      classes = inputs.length;
+    }
+
+    List<MethodSignature> getMethods() {
+      List<MethodSignature> methods = new ArrayList<>(this.methods.keySet());
+      methods.sort(Comparator.comparing(MethodSignature::toString));
+      return methods;
+    }
+
+    List<FieldSignature> getFields() {
+      List<FieldSignature> fields = new ArrayList<>(this.fields.keySet());
+      fields.sort(Comparator.comparing(FieldSignature::toString));
+      return fields;
+    }
+
+    int size(MethodSignature method, int classIndex) {
+      DexEncodedMethod dexEncodedMethod = methods.get(method)[classIndex];
+      if (dexEncodedMethod == null) {
+        return -1;
+      }
+      Code code = dexEncodedMethod.getCode();
+      if (code == null) {
+        return 0;
+      }
+      if (code.isCfCode()) {
+        return code.asCfCode().getInstructions().size();
+      }
+      if (code.isDexCode()) {
+        return code.asDexCode().instructions.length;
+      }
+      throw new Unreachable();
+    }
+
+    int[] sizes(MethodSignature method) {
+      int[] result = new int[classes];
+      for (int i = 0; i < classes; i++) {
+        result[i] = size(method, i);
+      }
+      return result;
+    }
+
+    int size(FieldSignature field, int classIndex) {
+      return fields.get(field)[classIndex] == null ? -1 : 1;
+    }
+
+    int[] sizes(FieldSignature field) {
+      int[] result = new int[classes];
+      for (int i = 0; i < classes; i++) {
+        result[i] = size(field, i);
+      }
+      return result;
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    JarSizeCompare program = JarSizeCompare.parse(args);
+    if (program == null) {
+      System.out.println(USAGE);
+    } else {
+      program.run();
+    }
+  }
+
+  public static JarSizeCompare parse(String[] args) {
+    int i = 0;
+    int threshold = 0;
+    List<Path> libraries = new ArrayList<>();
+    List<InputParameter> inputs = new ArrayList<>();
+    Set<String> names = new HashSet<>();
+    while (i < args.length) {
+      if (args[i].equals("--threshold") && i + 1 < args.length) {
+        threshold = Integer.parseInt(args[i + 1]);
+        i += 2;
+      } else if (args[i].equals("--lib") && i + 1 < args.length) {
+        libraries.add(Paths.get(args[i + 1]));
+        i += 2;
+      } else if (args[i].equals("--input") && i + 2 < args.length) {
+        String name = args[i + 1];
+        Path jar = Paths.get(args[i + 2]);
+        Path map = null;
+        if (i + 3 < args.length && !args[i + 3].startsWith("-")) {
+          map = Paths.get(args[i + 3]);
+          i += 4;
+        } else {
+          i += 3;
+        }
+        inputs.add(new InputParameter(name, jar, map));
+        if (!names.add(name)) {
+          System.out.println("Duplicate name: " + name);
+          return null;
+        }
+      } else {
+        return null;
+      }
+    }
+    if (inputs.size() < 2) {
+      return null;
+    }
+    if (threshold != 0 && (!names.contains("r8") || !names.contains("pg"))) {
+      System.out.println(
+          "You must either specify names \"pg\" and \"r8\" for input files "
+              + "or use \"--threshold 0\".");
+      return null;
+    }
+    return new JarSizeCompare(libraries, inputs, threshold);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/SwissArmyKnife.java b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
index 28e1f93..f54233b 100644
--- a/src/main/java/com/android/tools/r8/SwissArmyKnife.java
+++ b/src/main/java/com/android/tools/r8/SwissArmyKnife.java
@@ -61,6 +61,9 @@
       case "jardiff":
         JarDiff.main(shift(args));
         break;
+      case "jarsizecompare":
+        JarSizeCompare.main(shift(args));
+        break;
       case "maindex":
         GenerateMainDexList.main(shift(args));
         break;
diff --git a/src/main/java/com/android/tools/r8/UsageInformationConsumer.java b/src/main/java/com/android/tools/r8/UsageInformationConsumer.java
deleted file mode 100644
index a572908..0000000
--- a/src/main/java/com/android/tools/r8/UsageInformationConsumer.java
+++ /dev/null
@@ -1,133 +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;
-
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.origin.PathOrigin;
-import com.android.tools.r8.utils.ExceptionDiagnostic;
-import com.android.tools.r8.utils.FileUtils;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.file.Path;
-
-/**
- * Interface for receiving usage feedback from R8.
- *
- * The data is in the format defined for Proguard's <code>-printusage</code> flag. The information
- * will be produced if a consumer is provided. A consumer is automatically setup when running R8
- * with the Proguard <code>-printusage</code> flag set.
- */
-public interface UsageInformationConsumer {
-
-  /**
-   * Callback to receive the usage-information data.
-   *
-   * <p>The consumer is expected not to throw, but instead report any errors via the diagnostics
-   * {@param handler}. If an error is reported via {@param handler} and no exceptions are thrown,
-   * then the compiler guaranties to exit with an error.
-   *
-   * @param data UTF-8 encoded usage information.
-   * @param handler Diagnostics handler for reporting.
-   */
-  void acceptUsageInformation(byte[] data, DiagnosticsHandler handler);
-
-  static EmptyConsumer emptyConsumer() {
-    return EmptyConsumer.EMPTY_CONSUMER;
-  }
-
-  /** Empty consumer to request usage information but ignore the result. */
-  class EmptyConsumer implements UsageInformationConsumer {
-
-    private static final EmptyConsumer EMPTY_CONSUMER = new EmptyConsumer();
-
-    private EmptyConsumer() {}
-
-    @Override
-    public void acceptUsageInformation(byte[] data, DiagnosticsHandler handler) {
-      // Ignore content.
-    }
-  }
-
-    /** Forwarding consumer to delegate to an optional existing consumer. */
-  class ForwardingConsumer implements UsageInformationConsumer {
-
-    private final UsageInformationConsumer consumer;
-
-    /** @param consumer Consumer to forward to, if null, nothing will be forwarded. */
-    public ForwardingConsumer(UsageInformationConsumer consumer) {
-      this.consumer = consumer;
-    }
-
-    @Override
-    public void acceptUsageInformation(byte[] data, DiagnosticsHandler handler) {
-      if (consumer != null) {
-        consumer.acceptUsageInformation(data, handler);
-      }
-    }
-  }
-
-  /** File consumer to write contents to a file-system file. */
-  class FileConsumer extends ForwardingConsumer {
-
-    private final Path outputPath;
-
-    /** Consumer that writes to {@param outputPath}. */
-    public FileConsumer(Path outputPath) {
-      this(outputPath, null);
-    }
-
-    /** Consumer that forwards to {@param consumer} and also writes to {@param outputPath}. */
-    public FileConsumer(Path outputPath, UsageInformationConsumer consumer) {
-      super(consumer);
-      this.outputPath = outputPath;
-    }
-
-    @Override
-    public void acceptUsageInformation(byte[] data, DiagnosticsHandler handler) {
-      super.acceptUsageInformation(data, handler);
-      try {
-        FileUtils.writeToFile(outputPath, null, data);
-      } catch (IOException e) {
-        Origin origin = new PathOrigin(outputPath);
-        handler.error(new ExceptionDiagnostic(e, origin));
-      }
-    }
-  }
-
-  /**
-   * Stream consumer to write contents to an output stream.
-   *
-   * <p>Note: No close events are given to this stream so it should either be a permanent stream or
-   * the closing needs to happen outside of the compilation itself. If the stream is not one of the
-   * standard streams, i.e., System.out or System.err, you should likely implement yor own consumer.
-   */
-  class StreamConsumer extends ForwardingConsumer {
-
-    private final Origin origin;
-    private final OutputStream outputStream;
-
-    /** Consumer that writes to {@param outputStream}. */
-    public StreamConsumer(Origin origin, OutputStream outputStream) {
-      this(origin, outputStream, null);
-    }
-
-    /** Consumer that forwards to {@param consumer} and also writes to {@param outputStream}. */
-    public StreamConsumer(
-        Origin origin, OutputStream outputStream, UsageInformationConsumer consumer) {
-      super(consumer);
-      this.origin = origin;
-      this.outputStream = outputStream;
-    }
-
-    @Override
-    public void acceptUsageInformation(byte[] data, DiagnosticsHandler handler) {
-      super.acceptUsageInformation(data, handler);
-      try {
-        outputStream.write(data);
-      } catch (IOException e) {
-        handler.error(new ExceptionDiagnostic(e, origin));
-      }
-    }
-  }
-}
diff --git a/tools/build_r8lib.py b/tools/build_r8lib.py
index c855bc5..4b7473e 100755
--- a/tools/build_r8lib.py
+++ b/tools/build_r8lib.py
@@ -25,16 +25,21 @@
 ANDROID_JAR = 'third_party/android_jar/lib-v%s/android.jar' % API_LEVEL
 
 
-def build_r8lib():
+def build_r8lib(output_path=None, output_map=None, **kwargs):
+  if output_path is None:
+    output_path = R8LIB_JAR
+  if output_map is None:
+    output_map = R8LIB_MAP_FILE
   toolhelper.run(
       'r8',
       ('--release',
        '--classfile',
        '--lib', utils.RT_JAR,
        utils.R8_JAR,
-       '--output', R8LIB_JAR,
+       '--output', output_path,
        '--pg-conf', utils.R8LIB_KEEP_RULES,
-       '--pg-map-output', R8LIB_MAP_FILE))
+       '--pg-map-output', output_map),
+      **kwargs)
 
 
 def test_d8sample():
diff --git a/tools/r8lib_size_compare.py b/tools/r8lib_size_compare.py
new file mode 100755
index 0000000..4bb49eb
--- /dev/null
+++ b/tools/r8lib_size_compare.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# Copyright (c) 2018, 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.
+
+'''
+Build r8lib.jar with both R8 and ProGuard and print a size comparison.
+
+By default, inlining is disabled in both R8 and ProGuard to make
+method-by-method comparison much easier. Pass --inlining to enable inlining.
+
+By default, only shows methods where R8's DEX output is 5 or more instructions
+larger than ProGuard+D8's output. Pass --threshold 0 to display all methods.
+'''
+
+import argparse
+import build_r8lib
+import os
+import subprocess
+import toolhelper
+import utils
+
+
+parser = argparse.ArgumentParser(description=__doc__.strip(),
+                                 formatter_class=argparse.RawTextHelpFormatter)
+parser.add_argument('-t', '--tmpdir',
+                    help='Store auxiliary files in given directory')
+parser.add_argument('-i', '--inlining', action='store_true',
+                    help='Enable inlining')
+parser.add_argument('--threshold')
+
+R8_RELOCATIONS = [
+  ('com.google.common', 'com.android.tools.r8.com.google.common'),
+  ('com.google.gson', 'com.android.tools.r8.com.google.gson'),
+  ('com.google.thirdparty', 'com.android.tools.r8.com.google.thirdparty'),
+  ('joptsimple', 'com.android.tools.r8.joptsimple'),
+  ('org.apache.commons', 'com.android.tools.r8.org.apache.commons'),
+  ('org.objectweb.asm', 'com.android.tools.r8.org.objectweb.asm'),
+  ('it.unimi.dsi.fastutil', 'com.android.tools.r8.it.unimi.dsi.fastutil'),
+]
+
+
+def is_output_newer(input, output):
+  if not os.path.exists(output):
+    return False
+  return os.stat(input).st_mtime < os.stat(output).st_mtime
+
+
+def check_call(args, **kwargs):
+  utils.PrintCmd(args)
+  return subprocess.check_call(args, **kwargs)
+
+
+def main(tmpdir=None, inlining=True,
+         run_jarsizecompare=True, threshold=None):
+  if tmpdir is None:
+    with utils.TempDir() as tmpdir:
+      return main(tmpdir, inlining)
+
+  inline_suffix = '-inline' if inlining else '-noinline'
+
+  pg_config = utils.R8LIB_KEEP_RULES
+  r8lib_jar = os.path.join(utils.LIBS, 'r8lib%s.jar' % inline_suffix)
+  r8lib_map = os.path.join(utils.LIBS, 'r8lib%s-map.txt' % inline_suffix)
+  r8lib_args = None
+  if not inlining:
+    r8lib_args = ['-Dcom.android.tools.r8.disableinlining=1']
+    pg_config = os.path.join(tmpdir, 'keep-noinline.txt')
+    with open(pg_config, 'w') as new_config:
+      with open(utils.R8LIB_KEEP_RULES) as old_config:
+        new_config.write(old_config.read().rstrip('\n') +
+                         '\n-optimizations !method/inlining/*\n')
+
+  if not is_output_newer(utils.R8_JAR, r8lib_jar):
+    r8lib_memory = os.path.join(tmpdir, 'r8lib%s-memory.txt' % inline_suffix)
+    build_r8lib.build_r8lib(
+        output_path=r8lib_jar, output_map=r8lib_map,
+        extra_args=r8lib_args, track_memory_file=r8lib_memory)
+
+  pg_output = os.path.join(tmpdir, 'r8lib-pg%s.jar' % inline_suffix)
+  pg_memory = os.path.join(tmpdir, 'r8lib-pg%s-memory.txt' % inline_suffix)
+  pg_map = os.path.join(tmpdir, 'r8lib-pg%s-map.txt' % inline_suffix)
+  pg_args = ['tools/track_memory.sh', pg_memory,
+             'third_party/proguard/proguard6.0.2/bin/proguard.sh',
+             '@' + pg_config,
+             '-lib', utils.RT_JAR,
+             '-injar', utils.R8_JAR,
+             '-printmapping', pg_map,
+             '-outjar', pg_output]
+  for library_name, relocated_package in utils.R8_RELOCATIONS:
+    pg_args.extend(['-dontwarn', relocated_package + '.**',
+                    '-dontnote', relocated_package + '.**'])
+  check_call(pg_args)
+  if threshold is None:
+    threshold = 5
+  toolhelper.run('jarsizecompare',
+                 ['--threshold', str(threshold),
+                  '--lib', utils.RT_JAR,
+                  '--input', 'input', utils.R8_JAR,
+                  '--input', 'r8', r8lib_jar, r8lib_map,
+                  '--input', 'pg', pg_output, pg_map])
+
+
+if __name__ == '__main__':
+  main(**vars(parser.parse_args()))
diff --git a/tools/toolhelper.py b/tools/toolhelper.py
index a7f509c..82a2824 100644
--- a/tools/toolhelper.py
+++ b/tools/toolhelper.py
@@ -9,7 +9,7 @@
 import utils
 
 def run(tool, args, build=None, debug=True,
-        profile=False, track_memory_file=None):
+        profile=False, track_memory_file=None, extra_args=None):
   if build is None:
     build, args = extract_build_from_args(args)
   if build:
@@ -18,6 +18,8 @@
   if track_memory_file:
     cmd.extend(['tools/track_memory.sh', track_memory_file])
   cmd.append('java')
+  if extra_args:
+    cmd.extend(extra_args)
   if debug:
     cmd.append('-ea')
   if profile:
